diff --git a/.gitignore b/.gitignore index a686629..f8f34f3 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ /pkg/ /spec/reports/ /tmp/ +/vendor/ .DS_Store .rspec_status \ No newline at end of file diff --git a/README.md b/README.md index 77da4ae..a71dc47 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ If you don't have an account you can [sign up for a free developer account here] |region| Optional: `us` or `eu`. Defaults to `us` | |max_results| Optional: Defaults to 1000 | |timeout| Optional: Defaults to 60 (requires httparty > 0.16.2) | +|token_expiration_buffer| Optional: Number of seconds before token expiration to trigger refresh. Defaults to 30 | ```ruby require 'onelogin' diff --git a/lib/onelogin/api/client.rb b/lib/onelogin/api/client.rb index 505e691..03a30b4 100644 --- a/lib/onelogin/api/client.rb +++ b/lib/onelogin/api/client.rb @@ -26,6 +26,7 @@ class Client Nokogiri::XML::ParseOptions::NONET DEFAULT_USER_AGENT = "onelogin-ruby-sdk v#{OneLogin::VERSION}".freeze + DEFAULT_TOKEN_EXPIRATION_BUFFER = 30 # seconds # Create a new instance of the Client. # @@ -38,6 +39,7 @@ def initialize(config) @client_secret = options[:client_secret] @region = options[:region] || 'us' @max_results = options[:max_results] || 1000 + @token_expiration_buffer = options[:token_expiration_buffer] || DEFAULT_TOKEN_EXPIRATION_BUFFER if options[:timeout] and defined? self.class.default_timeout self.class.default_timeout options[:timeout] @@ -67,17 +69,26 @@ def clean_error end def expired? - Time.now.utc > @expiration + return true if @expiration.nil? + Time.now.utc > (@expiration - @token_expiration_buffer) end def prepare_token if @access_token.nil? - access_token + get_new_token elsif expired? - regenerate_token + # Try to regenerate token, fall back to getting new token if regeneration fails + regenerate_token || get_new_token end end + # Internal method to get a new access token + # This is separate from the public access_token method to allow internal use + # + def get_new_token + access_token + end + def handle_operation_response(response) result = false begin diff --git a/onelogin.gemspec b/onelogin.gemspec index 015d770..e1296f2 100644 --- a/onelogin.gemspec +++ b/onelogin.gemspec @@ -42,4 +42,5 @@ Gem::Specification.new do |spec| spec.add_development_dependency "bundler" spec.add_development_dependency "rake", "~> 10.0" spec.add_development_dependency "rspec", "~> 3.0" + spec.add_development_dependency "webmock", "~> 3.0" end diff --git a/spec/lib/onelogin/api/token_expiration_spec.rb b/spec/lib/onelogin/api/token_expiration_spec.rb new file mode 100644 index 0000000..673d7d1 --- /dev/null +++ b/spec/lib/onelogin/api/token_expiration_spec.rb @@ -0,0 +1,209 @@ +require "spec_helper" +require "webmock/rspec" + +RSpec.describe "Token Expiration Handling" do + let(:client_id) { 'test_client_id' } + let(:client_secret) { 'test_client_secret' } + let(:region) { 'us' } + let(:token_url) { 'https://api.us.onelogin.com/auth/oauth2/v2/token' } + + let(:test_time) { Time.utc(2025, 1, 1, 12, 0, 0) } + + let(:valid_token_response) { + { + access_token: 'test_access_token', + refresh_token: 'test_refresh_token', + token_type: 'bearer', + expires_in: 36000, + created_at: test_time.iso8601 + }.to_json + } + + let(:refreshed_token_response) { + { + access_token: 'refreshed_access_token', + refresh_token: 'refreshed_refresh_token', + token_type: 'bearer', + expires_in: 36000, + created_at: test_time.iso8601 + }.to_json + } + + before(:each) do + WebMock.disable_net_connect!(allow_localhost: true) + end + + after(:each) do + WebMock.reset! + end + + context 'when token is nil' do + it 'expired? should return true' do + client = OneLogin::Api::Client.new( + client_id: client_id, + client_secret: client_secret, + region: region + ) + + expect(client.send(:expired?)).to be true + end + + it 'prepare_token should get a new token' do + client = OneLogin::Api::Client.new( + client_id: client_id, + client_secret: client_secret, + region: region + ) + + stub_request(:post, token_url) + .with( + body: { 'grant_type' => 'client_credentials' }.to_json, + headers: { + 'Authorization' => "client_id:#{client_id},client_secret:#{client_secret}", + 'Content-Type' => 'application/json' + } + ) + .to_return(status: 200, body: valid_token_response, headers: {}) + + client.send(:prepare_token) + + expect(client.instance_variable_get(:@access_token)).to eq('test_access_token') + end + end + + context 'when token is about to expire' do + it 'expired? should return true when within expiration buffer' do + client = OneLogin::Api::Client.new( + client_id: client_id, + client_secret: client_secret, + region: region, + token_expiration_buffer: 30 + ) + + # Set token to expire in 25 seconds (less than 30 second buffer) + client.instance_variable_set(:@access_token, 'test_token') + client.instance_variable_set(:@refresh_token, 'test_refresh') + client.instance_variable_set(:@expiration, Time.now.utc + 25) + + expect(client.send(:expired?)).to be true + end + + it 'expired? should return false when outside expiration buffer' do + client = OneLogin::Api::Client.new( + client_id: client_id, + client_secret: client_secret, + region: region, + token_expiration_buffer: 30 + ) + + # Set token to expire in 60 seconds (more than 30 second buffer) + client.instance_variable_set(:@access_token, 'test_token') + client.instance_variable_set(:@refresh_token, 'test_refresh') + client.instance_variable_set(:@expiration, Time.now.utc + 60) + + expect(client.send(:expired?)).to be false + end + + it 'prepare_token should regenerate token when expired' do + client = OneLogin::Api::Client.new( + client_id: client_id, + client_secret: client_secret, + region: region, + token_expiration_buffer: 30 + ) + + # Set token to expire in 25 seconds + client.instance_variable_set(:@access_token, 'old_token') + client.instance_variable_set(:@refresh_token, 'old_refresh') + client.instance_variable_set(:@expiration, Time.now.utc + 25) + + stub_request(:post, token_url) + .with( + body: { + 'grant_type' => 'refresh_token', + 'access_token' => 'old_token', + 'refresh_token' => 'old_refresh' + }.to_json, + headers: { + 'Content-Type' => 'application/json' + } + ) + .to_return(status: 200, body: refreshed_token_response, headers: {}) + + client.send(:prepare_token) + + expect(client.instance_variable_get(:@access_token)).to eq('refreshed_access_token') + end + end + + context 'when token regeneration fails' do + it 'should fall back to getting a new token' do + client = OneLogin::Api::Client.new( + client_id: client_id, + client_secret: client_secret, + region: region, + token_expiration_buffer: 30 + ) + + # Set token to be expired + client.instance_variable_set(:@access_token, 'old_token') + client.instance_variable_set(:@refresh_token, 'old_refresh') + client.instance_variable_set(:@expiration, Time.now.utc + 25) + + # First request: regenerate_token fails with 401 + stub_request(:post, token_url) + .with( + body: { + 'grant_type' => 'refresh_token', + 'access_token' => 'old_token', + 'refresh_token' => 'old_refresh' + }.to_json + ) + .to_return(status: 401, body: { error: 'invalid_token' }.to_json, headers: {}) + + # Second request: get new token succeeds + stub_request(:post, token_url) + .with( + body: { 'grant_type' => 'client_credentials' }.to_json, + headers: { + 'Authorization' => "client_id:#{client_id},client_secret:#{client_secret}", + 'Content-Type' => 'application/json' + } + ) + .to_return(status: 200, body: valid_token_response, headers: {}) + + client.send(:prepare_token) + + # Should have new token, not the old one + expect(client.instance_variable_get(:@access_token)).to eq('test_access_token') + end + end + + context 'configurable token expiration buffer' do + it 'allows custom expiration buffer' do + client = OneLogin::Api::Client.new( + client_id: client_id, + client_secret: client_secret, + region: region, + token_expiration_buffer: 60 + ) + + # Set token to expire in 45 seconds (less than 60 second buffer) + client.instance_variable_set(:@access_token, 'test_token') + client.instance_variable_set(:@refresh_token, 'test_refresh') + client.instance_variable_set(:@expiration, Time.now.utc + 45) + + expect(client.send(:expired?)).to be true + end + + it 'uses default buffer of 30 seconds if not specified' do + client = OneLogin::Api::Client.new( + client_id: client_id, + client_secret: client_secret, + region: region + ) + + expect(client.instance_variable_get(:@token_expiration_buffer)).to eq(30) + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/bin/htmldiff b/vendor/bundle/ruby/3.2.0/bin/htmldiff new file mode 100755 index 0000000..58aadf2 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/bin/htmldiff @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby3.2 +# +# This file was generated by RubyGems. +# +# The application 'diff-lcs' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +Gem.use_gemdeps + +version = ">= 0.a" + +str = ARGV.first +if str + str = str.b[/\A_(.*)_\z/, 1] + if str and Gem::Version.correct?(str) + version = str + ARGV.shift + end +end + +if Gem.respond_to?(:activate_bin_path) +load Gem.activate_bin_path('diff-lcs', 'htmldiff', version) +else +gem "diff-lcs", version +load Gem.bin_path("diff-lcs", "htmldiff", version) +end diff --git a/vendor/bundle/ruby/3.2.0/bin/httparty b/vendor/bundle/ruby/3.2.0/bin/httparty new file mode 100755 index 0000000..eae5dd8 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/bin/httparty @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby3.2 +# +# This file was generated by RubyGems. +# +# The application 'httparty' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +Gem.use_gemdeps + +version = ">= 0.a" + +str = ARGV.first +if str + str = str.b[/\A_(.*)_\z/, 1] + if str and Gem::Version.correct?(str) + version = str + ARGV.shift + end +end + +if Gem.respond_to?(:activate_bin_path) +load Gem.activate_bin_path('httparty', 'httparty', version) +else +gem "httparty", version +load Gem.bin_path("httparty", "httparty", version) +end diff --git a/vendor/bundle/ruby/3.2.0/bin/ldiff b/vendor/bundle/ruby/3.2.0/bin/ldiff new file mode 100755 index 0000000..7a54829 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/bin/ldiff @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby3.2 +# +# This file was generated by RubyGems. +# +# The application 'diff-lcs' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +Gem.use_gemdeps + +version = ">= 0.a" + +str = ARGV.first +if str + str = str.b[/\A_(.*)_\z/, 1] + if str and Gem::Version.correct?(str) + version = str + ARGV.shift + end +end + +if Gem.respond_to?(:activate_bin_path) +load Gem.activate_bin_path('diff-lcs', 'ldiff', version) +else +gem "diff-lcs", version +load Gem.bin_path("diff-lcs", "ldiff", version) +end diff --git a/vendor/bundle/ruby/3.2.0/bin/nokogiri b/vendor/bundle/ruby/3.2.0/bin/nokogiri new file mode 100755 index 0000000..28de80d --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/bin/nokogiri @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby3.2 +# +# This file was generated by RubyGems. +# +# The application 'nokogiri' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +Gem.use_gemdeps + +version = ">= 0.a" + +str = ARGV.first +if str + str = str.b[/\A_(.*)_\z/, 1] + if str and Gem::Version.correct?(str) + version = str + ARGV.shift + end +end + +if Gem.respond_to?(:activate_bin_path) +load Gem.activate_bin_path('nokogiri', 'nokogiri', version) +else +gem "nokogiri", version +load Gem.bin_path("nokogiri", "nokogiri", version) +end diff --git a/vendor/bundle/ruby/3.2.0/bin/racc b/vendor/bundle/ruby/3.2.0/bin/racc new file mode 100755 index 0000000..9d74320 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/bin/racc @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby3.2 +# +# This file was generated by RubyGems. +# +# The application 'racc' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +Gem.use_gemdeps + +version = ">= 0.a" + +str = ARGV.first +if str + str = str.b[/\A_(.*)_\z/, 1] + if str and Gem::Version.correct?(str) + version = str + ARGV.shift + end +end + +if Gem.respond_to?(:activate_bin_path) +load Gem.activate_bin_path('racc', 'racc', version) +else +gem "racc", version +load Gem.bin_path("racc", "racc", version) +end diff --git a/vendor/bundle/ruby/3.2.0/bin/rake b/vendor/bundle/ruby/3.2.0/bin/rake new file mode 100755 index 0000000..6b572b3 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/bin/rake @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby3.2 +# +# This file was generated by RubyGems. +# +# The application 'rake' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +Gem.use_gemdeps + +version = ">= 0.a" + +str = ARGV.first +if str + str = str.b[/\A_(.*)_\z/, 1] + if str and Gem::Version.correct?(str) + version = str + ARGV.shift + end +end + +if Gem.respond_to?(:activate_bin_path) +load Gem.activate_bin_path('rake', 'rake', version) +else +gem "rake", version +load Gem.bin_path("rake", "rake", version) +end diff --git a/vendor/bundle/ruby/3.2.0/bin/rspec b/vendor/bundle/ruby/3.2.0/bin/rspec new file mode 100755 index 0000000..b8bf169 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/bin/rspec @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby3.2 +# +# This file was generated by RubyGems. +# +# The application 'rspec-core' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +Gem.use_gemdeps + +version = ">= 0.a" + +str = ARGV.first +if str + str = str.b[/\A_(.*)_\z/, 1] + if str and Gem::Version.correct?(str) + version = str + ARGV.shift + end +end + +if Gem.respond_to?(:activate_bin_path) +load Gem.activate_bin_path('rspec-core', 'rspec', version) +else +gem "rspec-core", version +load Gem.bin_path("rspec-core", "rspec", version) +end diff --git a/vendor/bundle/ruby/3.2.0/cache/bigdecimal-3.3.1.gem b/vendor/bundle/ruby/3.2.0/cache/bigdecimal-3.3.1.gem new file mode 100644 index 0000000..7899e47 Binary files /dev/null and b/vendor/bundle/ruby/3.2.0/cache/bigdecimal-3.3.1.gem differ diff --git a/vendor/bundle/ruby/3.2.0/cache/csv-3.3.5.gem b/vendor/bundle/ruby/3.2.0/cache/csv-3.3.5.gem new file mode 100644 index 0000000..3a1c844 Binary files /dev/null and b/vendor/bundle/ruby/3.2.0/cache/csv-3.3.5.gem differ diff --git a/vendor/bundle/ruby/3.2.0/cache/diff-lcs-1.6.2.gem b/vendor/bundle/ruby/3.2.0/cache/diff-lcs-1.6.2.gem new file mode 100644 index 0000000..21c4c77 Binary files /dev/null and b/vendor/bundle/ruby/3.2.0/cache/diff-lcs-1.6.2.gem differ diff --git a/vendor/bundle/ruby/3.2.0/cache/httparty-0.23.2.gem b/vendor/bundle/ruby/3.2.0/cache/httparty-0.23.2.gem new file mode 100644 index 0000000..b6965d0 Binary files /dev/null and b/vendor/bundle/ruby/3.2.0/cache/httparty-0.23.2.gem differ diff --git a/vendor/bundle/ruby/3.2.0/cache/mini_mime-1.1.5.gem b/vendor/bundle/ruby/3.2.0/cache/mini_mime-1.1.5.gem new file mode 100644 index 0000000..b16e88f Binary files /dev/null and b/vendor/bundle/ruby/3.2.0/cache/mini_mime-1.1.5.gem differ diff --git a/vendor/bundle/ruby/3.2.0/cache/multi_xml-0.7.2.gem b/vendor/bundle/ruby/3.2.0/cache/multi_xml-0.7.2.gem new file mode 100644 index 0000000..a231a25 Binary files /dev/null and b/vendor/bundle/ruby/3.2.0/cache/multi_xml-0.7.2.gem differ diff --git a/vendor/bundle/ruby/3.2.0/cache/nokogiri-1.18.10-x86_64-linux-gnu.gem b/vendor/bundle/ruby/3.2.0/cache/nokogiri-1.18.10-x86_64-linux-gnu.gem new file mode 100644 index 0000000..38e28a0 Binary files /dev/null and b/vendor/bundle/ruby/3.2.0/cache/nokogiri-1.18.10-x86_64-linux-gnu.gem differ diff --git a/vendor/bundle/ruby/3.2.0/cache/racc-1.8.1.gem b/vendor/bundle/ruby/3.2.0/cache/racc-1.8.1.gem new file mode 100644 index 0000000..ad9e6bb Binary files /dev/null and b/vendor/bundle/ruby/3.2.0/cache/racc-1.8.1.gem differ diff --git a/vendor/bundle/ruby/3.2.0/cache/rake-10.5.0.gem b/vendor/bundle/ruby/3.2.0/cache/rake-10.5.0.gem new file mode 100644 index 0000000..0fe2757 Binary files /dev/null and b/vendor/bundle/ruby/3.2.0/cache/rake-10.5.0.gem differ diff --git a/vendor/bundle/ruby/3.2.0/cache/rspec-3.13.2.gem b/vendor/bundle/ruby/3.2.0/cache/rspec-3.13.2.gem new file mode 100644 index 0000000..4b00e2a Binary files /dev/null and b/vendor/bundle/ruby/3.2.0/cache/rspec-3.13.2.gem differ diff --git a/vendor/bundle/ruby/3.2.0/cache/rspec-core-3.13.6.gem b/vendor/bundle/ruby/3.2.0/cache/rspec-core-3.13.6.gem new file mode 100644 index 0000000..98f9a48 Binary files /dev/null and b/vendor/bundle/ruby/3.2.0/cache/rspec-core-3.13.6.gem differ diff --git a/vendor/bundle/ruby/3.2.0/cache/rspec-expectations-3.13.5.gem b/vendor/bundle/ruby/3.2.0/cache/rspec-expectations-3.13.5.gem new file mode 100644 index 0000000..51409fd Binary files /dev/null and b/vendor/bundle/ruby/3.2.0/cache/rspec-expectations-3.13.5.gem differ diff --git a/vendor/bundle/ruby/3.2.0/cache/rspec-mocks-3.13.6.gem b/vendor/bundle/ruby/3.2.0/cache/rspec-mocks-3.13.6.gem new file mode 100644 index 0000000..ab820e2 Binary files /dev/null and b/vendor/bundle/ruby/3.2.0/cache/rspec-mocks-3.13.6.gem differ diff --git a/vendor/bundle/ruby/3.2.0/cache/rspec-support-3.13.6.gem b/vendor/bundle/ruby/3.2.0/cache/rspec-support-3.13.6.gem new file mode 100644 index 0000000..a609350 Binary files /dev/null and b/vendor/bundle/ruby/3.2.0/cache/rspec-support-3.13.6.gem differ diff --git a/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux-gnu/3.2.0/bigdecimal-3.3.1/bigdecimal.so b/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux-gnu/3.2.0/bigdecimal-3.3.1/bigdecimal.so new file mode 100755 index 0000000..78e8578 Binary files /dev/null and b/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux-gnu/3.2.0/bigdecimal-3.3.1/bigdecimal.so differ diff --git a/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux-gnu/3.2.0/bigdecimal-3.3.1/gem.build_complete b/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux-gnu/3.2.0/bigdecimal-3.3.1/gem.build_complete new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux-gnu/3.2.0/bigdecimal-3.3.1/gem_make.out b/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux-gnu/3.2.0/bigdecimal-3.3.1/gem_make.out new file mode 100644 index 0000000..81bc220 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux-gnu/3.2.0/bigdecimal-3.3.1/gem_make.out @@ -0,0 +1,38 @@ +current directory: /home/runner/work/onelogin-ruby-sdk/onelogin-ruby-sdk/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal +/usr/bin/ruby3.2 -I/usr/lib/ruby/vendor_ruby extconf.rb +checking for __builtin_clz()... yes +checking for __builtin_clzl()... yes +checking for __builtin_clzll()... yes +checking for float.h... yes +checking for math.h... yes +checking for stdbool.h... yes +checking for stdlib.h... yes +checking for x86intrin.h... yes +checking for _lzcnt_u32() in x86intrin.h... no +checking for _lzcnt_u64() in x86intrin.h... no +checking for intrin.h... no +checking for ruby/atomic.h... yes +checking for ruby/internal/has/builtin.h... yes +checking for ruby/internal/static_assert.h... yes +checking for rb_complex_real() in ruby.h... yes +checking for rb_complex_imag() in ruby.h... yes +checking for rb_opts_exception_p() in ruby.h... yes +checking for rb_category_warn() in ruby.h... yes +checking for RB_WARN_CATEGORY_DEPRECATED in ruby.h... yes +creating Makefile + +current directory: /home/runner/work/onelogin-ruby-sdk/onelogin-ruby-sdk/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal +make DESTDIR\= sitearchdir\=./.gem.20251029-3435-9fee0y sitelibdir\=./.gem.20251029-3435-9fee0y clean + +current directory: /home/runner/work/onelogin-ruby-sdk/onelogin-ruby-sdk/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal +make DESTDIR\= sitearchdir\=./.gem.20251029-3435-9fee0y sitelibdir\=./.gem.20251029-3435-9fee0y +compiling bigdecimal.c +compiling missing.c +linking shared-object bigdecimal.so + +current directory: /home/runner/work/onelogin-ruby-sdk/onelogin-ruby-sdk/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal +make DESTDIR\= sitearchdir\=./.gem.20251029-3435-9fee0y sitelibdir\=./.gem.20251029-3435-9fee0y install +/usr/bin/install -c -m 0755 bigdecimal.so ./.gem.20251029-3435-9fee0y + +current directory: /home/runner/work/onelogin-ruby-sdk/onelogin-ruby-sdk/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal +make DESTDIR\= sitearchdir\=./.gem.20251029-3435-9fee0y sitelibdir\=./.gem.20251029-3435-9fee0y clean diff --git a/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux-gnu/3.2.0/bigdecimal-3.3.1/mkmf.log b/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux-gnu/3.2.0/bigdecimal-3.3.1/mkmf.log new file mode 100644 index 0000000..03e7683 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux-gnu/3.2.0/bigdecimal-3.3.1/mkmf.log @@ -0,0 +1,424 @@ +have_builtin_func: checking for __builtin_clz()... -------------------- yes + +LD_LIBRARY_PATH=.:/usr/lib/x86_64-linux-gnu "x86_64-linux-gnu-gcc -o conftest -I/usr/include/x86_64-linux-gnu/ruby-3.2.0 -I/usr/include/ruby-3.2.0/ruby/backward -I/usr/include/ruby-3.2.0 -I. -Wdate-time -D_FORTIFY_SOURCE=3 -g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=BUILDDIR=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fdebug-prefix-map=BUILDDIR=/usr/src/ruby3.2-3.2.3-1ubuntu0.24.04.6 -fPIC conftest.c -L. -L/usr/lib/x86_64-linux-gnu -L. -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lruby-3.2 -lm -lpthread -lc" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: int main(int argc, char **argv) +4: { +5: return !!argv[argc]; +6: } +/* end */ + +LD_LIBRARY_PATH=.:/usr/lib/x86_64-linux-gnu "x86_64-linux-gnu-gcc -I/usr/include/x86_64-linux-gnu/ruby-3.2.0 -I/usr/include/ruby-3.2.0/ruby/backward -I/usr/include/ruby-3.2.0 -I. -Wdate-time -D_FORTIFY_SOURCE=3 -g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=BUILDDIR=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fdebug-prefix-map=BUILDDIR=/usr/src/ruby3.2-3.2.3-1ubuntu0.24.04.6 -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: int foo; +4: int main() { __builtin_clz(0); return 0; } +/* end */ + +-------------------- + +have_builtin_func: checking for __builtin_clzl()... -------------------- yes + +LD_LIBRARY_PATH=.:/usr/lib/x86_64-linux-gnu "x86_64-linux-gnu-gcc -I/usr/include/x86_64-linux-gnu/ruby-3.2.0 -I/usr/include/ruby-3.2.0/ruby/backward -I/usr/include/ruby-3.2.0 -I. -Wdate-time -D_FORTIFY_SOURCE=3 -g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=BUILDDIR=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fdebug-prefix-map=BUILDDIR=/usr/src/ruby3.2-3.2.3-1ubuntu0.24.04.6 -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: int foo; +4: int main() { __builtin_clzl(0); return 0; } +/* end */ + +-------------------- + +have_builtin_func: checking for __builtin_clzll()... -------------------- yes + +LD_LIBRARY_PATH=.:/usr/lib/x86_64-linux-gnu "x86_64-linux-gnu-gcc -I/usr/include/x86_64-linux-gnu/ruby-3.2.0 -I/usr/include/ruby-3.2.0/ruby/backward -I/usr/include/ruby-3.2.0 -I. -Wdate-time -D_FORTIFY_SOURCE=3 -g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=BUILDDIR=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fdebug-prefix-map=BUILDDIR=/usr/src/ruby3.2-3.2.3-1ubuntu0.24.04.6 -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: int foo; +4: int main() { __builtin_clzll(0); return 0; } +/* end */ + +-------------------- + +have_header: checking for float.h... -------------------- yes + +LD_LIBRARY_PATH=.:/usr/lib/x86_64-linux-gnu "x86_64-linux-gnu-gcc -I/usr/include/x86_64-linux-gnu/ruby-3.2.0 -I/usr/include/ruby-3.2.0/ruby/backward -I/usr/include/ruby-3.2.0 -I. -Wdate-time -D_FORTIFY_SOURCE=3 -g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=BUILDDIR=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fdebug-prefix-map=BUILDDIR=/usr/src/ruby3.2-3.2.3-1ubuntu0.24.04.6 -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_header: checking for math.h... -------------------- yes + +LD_LIBRARY_PATH=.:/usr/lib/x86_64-linux-gnu "x86_64-linux-gnu-gcc -I/usr/include/x86_64-linux-gnu/ruby-3.2.0 -I/usr/include/ruby-3.2.0/ruby/backward -I/usr/include/ruby-3.2.0 -I. -Wdate-time -D_FORTIFY_SOURCE=3 -g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=BUILDDIR=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fdebug-prefix-map=BUILDDIR=/usr/src/ruby3.2-3.2.3-1ubuntu0.24.04.6 -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_header: checking for stdbool.h... -------------------- yes + +LD_LIBRARY_PATH=.:/usr/lib/x86_64-linux-gnu "x86_64-linux-gnu-gcc -I/usr/include/x86_64-linux-gnu/ruby-3.2.0 -I/usr/include/ruby-3.2.0/ruby/backward -I/usr/include/ruby-3.2.0 -I. -Wdate-time -D_FORTIFY_SOURCE=3 -g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=BUILDDIR=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fdebug-prefix-map=BUILDDIR=/usr/src/ruby3.2-3.2.3-1ubuntu0.24.04.6 -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_header: checking for stdlib.h... -------------------- yes + +LD_LIBRARY_PATH=.:/usr/lib/x86_64-linux-gnu "x86_64-linux-gnu-gcc -I/usr/include/x86_64-linux-gnu/ruby-3.2.0 -I/usr/include/ruby-3.2.0/ruby/backward -I/usr/include/ruby-3.2.0 -I. -Wdate-time -D_FORTIFY_SOURCE=3 -g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=BUILDDIR=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fdebug-prefix-map=BUILDDIR=/usr/src/ruby3.2-3.2.3-1ubuntu0.24.04.6 -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_header: checking for x86intrin.h... -------------------- yes + +LD_LIBRARY_PATH=.:/usr/lib/x86_64-linux-gnu "x86_64-linux-gnu-gcc -I/usr/include/x86_64-linux-gnu/ruby-3.2.0 -I/usr/include/ruby-3.2.0/ruby/backward -I/usr/include/ruby-3.2.0 -I. -Wdate-time -D_FORTIFY_SOURCE=3 -g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=BUILDDIR=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fdebug-prefix-map=BUILDDIR=/usr/src/ruby3.2-3.2.3-1ubuntu0.24.04.6 -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_func: checking for _lzcnt_u32() in x86intrin.h... -------------------- no + +LD_LIBRARY_PATH=.:/usr/lib/x86_64-linux-gnu "x86_64-linux-gnu-gcc -o conftest -I/usr/include/x86_64-linux-gnu/ruby-3.2.0 -I/usr/include/ruby-3.2.0/ruby/backward -I/usr/include/ruby-3.2.0 -I. -Wdate-time -D_FORTIFY_SOURCE=3 -g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=BUILDDIR=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fdebug-prefix-map=BUILDDIR=/usr/src/ruby3.2-3.2.3-1ubuntu0.24.04.6 -fPIC conftest.c -L. -L/usr/lib/x86_64-linux-gnu -L. -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lruby-3.2 -lm -lpthread -lc" +/usr/bin/ld: /tmp/ccbipjoI.o: in function `t': +/home/runner/work/onelogin-ruby-sdk/onelogin-ruby-sdk/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/conftest.c:16:(.text+0xb): undefined reference to `_lzcnt_u32' +collect2: error: ld returned 1 exit status +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { void ((*volatile p)()); p = (void ((*)()))_lzcnt_u32; return !p; } +/* end */ + +LD_LIBRARY_PATH=.:/usr/lib/x86_64-linux-gnu "x86_64-linux-gnu-gcc -o conftest -I/usr/include/x86_64-linux-gnu/ruby-3.2.0 -I/usr/include/ruby-3.2.0/ruby/backward -I/usr/include/ruby-3.2.0 -I. -Wdate-time -D_FORTIFY_SOURCE=3 -g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=BUILDDIR=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fdebug-prefix-map=BUILDDIR=/usr/src/ruby3.2-3.2.3-1ubuntu0.24.04.6 -fPIC conftest.c -L. -L/usr/lib/x86_64-linux-gnu -L. -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lruby-3.2 -lm -lpthread -lc" +conftest.c:16:13: error: conflicting types for ‘_lzcnt_u32’; have ‘void()’ + 16 | extern void _lzcnt_u32(); + | ^~~~~~~~~~ +In file included from /usr/lib/gcc/x86_64-linux-gnu/13/include/x86gprintrin.h:61, + from /usr/lib/gcc/x86_64-linux-gnu/13/include/x86intrin.h:27, + from conftest.c:3: +/usr/lib/gcc/x86_64-linux-gnu/13/include/lzcntintrin.h:51:1: note: previous definition of ‘_lzcnt_u32’ with type ‘unsigned int(unsigned int)’ + 51 | _lzcnt_u32 (unsigned int __X) + | ^~~~~~~~~~ +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: extern void _lzcnt_u32(); +17: int t(void) { _lzcnt_u32(); return 0; } +/* end */ + +-------------------- + +have_func: checking for _lzcnt_u64() in x86intrin.h... -------------------- no + +LD_LIBRARY_PATH=.:/usr/lib/x86_64-linux-gnu "x86_64-linux-gnu-gcc -o conftest -I/usr/include/x86_64-linux-gnu/ruby-3.2.0 -I/usr/include/ruby-3.2.0/ruby/backward -I/usr/include/ruby-3.2.0 -I. -Wdate-time -D_FORTIFY_SOURCE=3 -g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=BUILDDIR=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fdebug-prefix-map=BUILDDIR=/usr/src/ruby3.2-3.2.3-1ubuntu0.24.04.6 -fPIC conftest.c -L. -L/usr/lib/x86_64-linux-gnu -L. -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lruby-3.2 -lm -lpthread -lc" +/usr/bin/ld: /tmp/ccUxQ9MP.o: in function `t': +/home/runner/work/onelogin-ruby-sdk/onelogin-ruby-sdk/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/conftest.c:16:(.text+0xb): undefined reference to `_lzcnt_u64' +collect2: error: ld returned 1 exit status +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { void ((*volatile p)()); p = (void ((*)()))_lzcnt_u64; return !p; } +/* end */ + +LD_LIBRARY_PATH=.:/usr/lib/x86_64-linux-gnu "x86_64-linux-gnu-gcc -o conftest -I/usr/include/x86_64-linux-gnu/ruby-3.2.0 -I/usr/include/ruby-3.2.0/ruby/backward -I/usr/include/ruby-3.2.0 -I. -Wdate-time -D_FORTIFY_SOURCE=3 -g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=BUILDDIR=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fdebug-prefix-map=BUILDDIR=/usr/src/ruby3.2-3.2.3-1ubuntu0.24.04.6 -fPIC conftest.c -L. -L/usr/lib/x86_64-linux-gnu -L. -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lruby-3.2 -lm -lpthread -lc" +conftest.c:16:13: error: conflicting types for ‘_lzcnt_u64’; have ‘void()’ + 16 | extern void _lzcnt_u64(); + | ^~~~~~~~~~ +In file included from /usr/lib/gcc/x86_64-linux-gnu/13/include/x86gprintrin.h:61, + from /usr/lib/gcc/x86_64-linux-gnu/13/include/x86intrin.h:27, + from conftest.c:3: +/usr/lib/gcc/x86_64-linux-gnu/13/include/lzcntintrin.h:64:1: note: previous definition of ‘_lzcnt_u64’ with type ‘long long unsigned int(long long unsigned int)’ + 64 | _lzcnt_u64 (unsigned long long __X) + | ^~~~~~~~~~ +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: extern void _lzcnt_u64(); +17: int t(void) { _lzcnt_u64(); return 0; } +/* end */ + +-------------------- + +have_header: checking for intrin.h... -------------------- no + +LD_LIBRARY_PATH=.:/usr/lib/x86_64-linux-gnu "x86_64-linux-gnu-gcc -I/usr/include/x86_64-linux-gnu/ruby-3.2.0 -I/usr/include/ruby-3.2.0/ruby/backward -I/usr/include/ruby-3.2.0 -I. -Wdate-time -D_FORTIFY_SOURCE=3 -g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=BUILDDIR=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fdebug-prefix-map=BUILDDIR=/usr/src/ruby3.2-3.2.3-1ubuntu0.24.04.6 -fPIC -c conftest.c" +conftest.c:3:10: fatal error: intrin.h: No such file or directory + 3 | #include + | ^~~~~~~~~~ +compilation terminated. +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_header: checking for ruby/atomic.h... -------------------- yes + +LD_LIBRARY_PATH=.:/usr/lib/x86_64-linux-gnu "x86_64-linux-gnu-gcc -I/usr/include/x86_64-linux-gnu/ruby-3.2.0 -I/usr/include/ruby-3.2.0/ruby/backward -I/usr/include/ruby-3.2.0 -I. -Wdate-time -D_FORTIFY_SOURCE=3 -g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=BUILDDIR=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fdebug-prefix-map=BUILDDIR=/usr/src/ruby3.2-3.2.3-1ubuntu0.24.04.6 -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_header: checking for ruby/internal/has/builtin.h... -------------------- yes + +LD_LIBRARY_PATH=.:/usr/lib/x86_64-linux-gnu "x86_64-linux-gnu-gcc -I/usr/include/x86_64-linux-gnu/ruby-3.2.0 -I/usr/include/ruby-3.2.0/ruby/backward -I/usr/include/ruby-3.2.0 -I. -Wdate-time -D_FORTIFY_SOURCE=3 -g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=BUILDDIR=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fdebug-prefix-map=BUILDDIR=/usr/src/ruby3.2-3.2.3-1ubuntu0.24.04.6 -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_header: checking for ruby/internal/static_assert.h... -------------------- yes + +LD_LIBRARY_PATH=.:/usr/lib/x86_64-linux-gnu "x86_64-linux-gnu-gcc -I/usr/include/x86_64-linux-gnu/ruby-3.2.0 -I/usr/include/ruby-3.2.0/ruby/backward -I/usr/include/ruby-3.2.0 -I. -Wdate-time -D_FORTIFY_SOURCE=3 -g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=BUILDDIR=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fdebug-prefix-map=BUILDDIR=/usr/src/ruby3.2-3.2.3-1ubuntu0.24.04.6 -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_func: checking for rb_complex_real() in ruby.h... -------------------- yes + +LD_LIBRARY_PATH=.:/usr/lib/x86_64-linux-gnu "x86_64-linux-gnu-gcc -o conftest -I/usr/include/x86_64-linux-gnu/ruby-3.2.0 -I/usr/include/ruby-3.2.0/ruby/backward -I/usr/include/ruby-3.2.0 -I. -Wdate-time -D_FORTIFY_SOURCE=3 -g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=BUILDDIR=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fdebug-prefix-map=BUILDDIR=/usr/src/ruby3.2-3.2.3-1ubuntu0.24.04.6 -fPIC conftest.c -L. -L/usr/lib/x86_64-linux-gnu -L. -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lruby-3.2 -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_complex_real; return !p; } +/* end */ + +-------------------- + +have_func: checking for rb_complex_imag() in ruby.h... -------------------- yes + +LD_LIBRARY_PATH=.:/usr/lib/x86_64-linux-gnu "x86_64-linux-gnu-gcc -o conftest -I/usr/include/x86_64-linux-gnu/ruby-3.2.0 -I/usr/include/ruby-3.2.0/ruby/backward -I/usr/include/ruby-3.2.0 -I. -Wdate-time -D_FORTIFY_SOURCE=3 -g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=BUILDDIR=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fdebug-prefix-map=BUILDDIR=/usr/src/ruby3.2-3.2.3-1ubuntu0.24.04.6 -fPIC conftest.c -L. -L/usr/lib/x86_64-linux-gnu -L. -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lruby-3.2 -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_complex_imag; return !p; } +/* end */ + +-------------------- + +have_func: checking for rb_opts_exception_p() in ruby.h... -------------------- yes + +LD_LIBRARY_PATH=.:/usr/lib/x86_64-linux-gnu "x86_64-linux-gnu-gcc -o conftest -I/usr/include/x86_64-linux-gnu/ruby-3.2.0 -I/usr/include/ruby-3.2.0/ruby/backward -I/usr/include/ruby-3.2.0 -I. -Wdate-time -D_FORTIFY_SOURCE=3 -g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=BUILDDIR=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fdebug-prefix-map=BUILDDIR=/usr/src/ruby3.2-3.2.3-1ubuntu0.24.04.6 -fPIC conftest.c -L. -L/usr/lib/x86_64-linux-gnu -L. -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lruby-3.2 -lm -lpthread -lc" +conftest.c: In function ‘t’: +conftest.c:16:57: error: ‘rb_opts_exception_p’ undeclared (first use in this function); did you mean ‘rb_make_exception’? + 16 | int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_opts_exception_p; return !p; } + | ^~~~~~~~~~~~~~~~~~~ + | rb_make_exception +conftest.c:16:57: note: each undeclared identifier is reported only once for each function it appears in +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_opts_exception_p; return !p; } +/* end */ + +LD_LIBRARY_PATH=.:/usr/lib/x86_64-linux-gnu "x86_64-linux-gnu-gcc -o conftest -I/usr/include/x86_64-linux-gnu/ruby-3.2.0 -I/usr/include/ruby-3.2.0/ruby/backward -I/usr/include/ruby-3.2.0 -I. -Wdate-time -D_FORTIFY_SOURCE=3 -g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=BUILDDIR=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fdebug-prefix-map=BUILDDIR=/usr/src/ruby3.2-3.2.3-1ubuntu0.24.04.6 -fPIC conftest.c -L. -L/usr/lib/x86_64-linux-gnu -L. -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lruby-3.2 -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: extern void rb_opts_exception_p(); +17: int t(void) { rb_opts_exception_p(); return 0; } +/* end */ + +-------------------- + +have_func: checking for rb_category_warn() in ruby.h... -------------------- yes + +LD_LIBRARY_PATH=.:/usr/lib/x86_64-linux-gnu "x86_64-linux-gnu-gcc -o conftest -I/usr/include/x86_64-linux-gnu/ruby-3.2.0 -I/usr/include/ruby-3.2.0/ruby/backward -I/usr/include/ruby-3.2.0 -I. -Wdate-time -D_FORTIFY_SOURCE=3 -g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=BUILDDIR=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fdebug-prefix-map=BUILDDIR=/usr/src/ruby3.2-3.2.3-1ubuntu0.24.04.6 -fPIC conftest.c -L. -L/usr/lib/x86_64-linux-gnu -L. -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lruby-3.2 -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_category_warn; return !p; } +/* end */ + +-------------------- + +have_const: checking for RB_WARN_CATEGORY_DEPRECATED in ruby.h... -------------------- yes + +LD_LIBRARY_PATH=.:/usr/lib/x86_64-linux-gnu "x86_64-linux-gnu-gcc -I/usr/include/x86_64-linux-gnu/ruby-3.2.0 -I/usr/include/ruby-3.2.0/ruby/backward -I/usr/include/ruby-3.2.0 -I. -Wdate-time -D_FORTIFY_SOURCE=3 -g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=BUILDDIR=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fdebug-prefix-map=BUILDDIR=/usr/src/ruby3.2-3.2.3-1ubuntu0.24.04.6 -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +4: +5: /*top*/ +6: typedef int conftest_type; +7: conftest_type conftestval = (int)RB_WARN_CATEGORY_DEPRECATED; +/* end */ + +-------------------- + diff --git a/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux-gnu/3.2.0/racc-1.8.1/gem.build_complete b/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux-gnu/3.2.0/racc-1.8.1/gem.build_complete new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux-gnu/3.2.0/racc-1.8.1/gem_make.out b/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux-gnu/3.2.0/racc-1.8.1/gem_make.out new file mode 100644 index 0000000..5689e13 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux-gnu/3.2.0/racc-1.8.1/gem_make.out @@ -0,0 +1,18 @@ +current directory: /home/runner/work/onelogin-ruby-sdk/onelogin-ruby-sdk/vendor/bundle/ruby/3.2.0/gems/racc-1.8.1/ext/racc/cparse +/usr/bin/ruby3.2 -I/usr/lib/ruby/vendor_ruby extconf.rb +creating Makefile + +current directory: /home/runner/work/onelogin-ruby-sdk/onelogin-ruby-sdk/vendor/bundle/ruby/3.2.0/gems/racc-1.8.1/ext/racc/cparse +make DESTDIR\= sitearchdir\=./.gem.20251029-3435-l9mcwx sitelibdir\=./.gem.20251029-3435-l9mcwx clean + +current directory: /home/runner/work/onelogin-ruby-sdk/onelogin-ruby-sdk/vendor/bundle/ruby/3.2.0/gems/racc-1.8.1/ext/racc/cparse +make DESTDIR\= sitearchdir\=./.gem.20251029-3435-l9mcwx sitelibdir\=./.gem.20251029-3435-l9mcwx +compiling cparse.c +linking shared-object racc/cparse.so + +current directory: /home/runner/work/onelogin-ruby-sdk/onelogin-ruby-sdk/vendor/bundle/ruby/3.2.0/gems/racc-1.8.1/ext/racc/cparse +make DESTDIR\= sitearchdir\=./.gem.20251029-3435-l9mcwx sitelibdir\=./.gem.20251029-3435-l9mcwx install +/usr/bin/install -c -m 0755 cparse.so ./.gem.20251029-3435-l9mcwx/racc + +current directory: /home/runner/work/onelogin-ruby-sdk/onelogin-ruby-sdk/vendor/bundle/ruby/3.2.0/gems/racc-1.8.1/ext/racc/cparse +make DESTDIR\= sitearchdir\=./.gem.20251029-3435-l9mcwx sitelibdir\=./.gem.20251029-3435-l9mcwx clean diff --git a/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux-gnu/3.2.0/racc-1.8.1/racc/cparse.so b/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux-gnu/3.2.0/racc-1.8.1/racc/cparse.so new file mode 100755 index 0000000..190a27e Binary files /dev/null and b/vendor/bundle/ruby/3.2.0/extensions/x86_64-linux-gnu/3.2.0/racc-1.8.1/racc/cparse.so differ diff --git a/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/LICENSE b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/LICENSE new file mode 100644 index 0000000..a1f19ff --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/LICENSE @@ -0,0 +1,56 @@ +Ruby is copyrighted free software by Yukihiro Matsumoto . +You can redistribute it and/or modify it under either the terms of the +2-clause BSDL (see the file BSDL), or the conditions below: + + 1. You may make and give away verbatim copies of the source form of the + software without restriction, provided that you duplicate all of the + original copyright notices and associated disclaimers. + + 2. You may modify your copy of the software in any way, provided that + you do at least ONE of the following: + + a) place your modifications in the Public Domain or otherwise + make them Freely Available, such as by posting said + modifications to Usenet or an equivalent medium, or by allowing + the author to include your modifications in the software. + + b) use the modified software only within your corporation or + organization. + + c) give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d) make other distribution arrangements with the author. + + 3. You may distribute the software in object code or binary form, + provided that you do at least ONE of the following: + + a) distribute the binaries and library files of the software, + together with instructions (in the manual page or equivalent) + on where to get the original distribution. + + b) accompany the distribution with the machine-readable source of + the software. + + c) give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d) make other distribution arrangements with the author. + + 4. You may modify and include the part of the software into any other + software (possibly commercial). But some files in the distribution + are not written by the author, so that they are not under these terms. + + For the list of those files and their copying conditions, see the + file LEGAL. + + 5. The scripts and library files supplied as input to or produced as + output from the software do not automatically fall under the + copyright of the software, but belong to whomever generated them, + and may be sold commercially, and may be aggregated with this + software. + + 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. diff --git a/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/bigdecimal.gemspec b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/bigdecimal.gemspec new file mode 100644 index 0000000..b6ef8fd --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/bigdecimal.gemspec @@ -0,0 +1,57 @@ +# coding: utf-8 + +name = File.basename(__FILE__, '.*') +source_version = ["", "ext/#{name}/"].find do |dir| + begin + break File.foreach(File.join(__dir__, "#{dir}#{name}.c")) {|line| + break $1.sub("-", ".") if /^#define\s+#{name.upcase}_VERSION\s+"(.+)"/o =~ line + } + rescue Errno::ENOENT + end +end or raise "can't find #{name.upcase}_VERSION" + +Gem::Specification.new do |s| + s.name = name + s.version = source_version + s.authors = ["Kenta Murata", "Zachary Scott", "Shigeo Kobayashi"] + s.email = ["mrkn@mrkn.jp"] + + s.summary = "Arbitrary-precision decimal floating-point number library." + s.description = "This library provides arbitrary-precision decimal floating-point number class." + s.homepage = "https://github.com/ruby/bigdecimal" + s.licenses = ["Ruby", "BSD-2-Clause"] + + s.require_paths = %w[lib] + s.files = %w[ + LICENSE + bigdecimal.gemspec + lib/bigdecimal.rb + lib/bigdecimal/jacobian.rb + lib/bigdecimal/ludcmp.rb + lib/bigdecimal/math.rb + lib/bigdecimal/newton.rb + lib/bigdecimal/util.rb + sample/linear.rb + sample/nlsolve.rb + sample/pi.rb + ] + if Gem::Platform === s.platform and s.platform =~ 'java' or RUBY_ENGINE == 'jruby' + s.platform = 'java' + else + s.extensions = %w[ext/bigdecimal/extconf.rb] + s.files += %w[ + ext/bigdecimal/bigdecimal.c + ext/bigdecimal/bigdecimal.h + ext/bigdecimal/bits.h + ext/bigdecimal/feature.h + ext/bigdecimal/missing.c + ext/bigdecimal/missing.h + ext/bigdecimal/missing/dtoa.c + ext/bigdecimal/static_assert.h + ] + end + + s.required_ruby_version = Gem::Requirement.new(">= 2.5.0") + + s.metadata["changelog_uri"] = s.homepage + "/blob/master/CHANGES.md" +end diff --git a/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/Makefile b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/Makefile new file mode 100644 index 0000000..f9ceffa --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/Makefile @@ -0,0 +1,270 @@ + +SHELL = /bin/sh + +# V=0 quiet, V=1 verbose. other values don't work. +V = 0 +V0 = $(V:0=) +Q1 = $(V:1=) +Q = $(Q1:0=@) +ECHO1 = $(V:1=@ :) +ECHO = $(ECHO1:0=@ echo) +NULLCMD = : + +#### Start of system configuration section. #### + +srcdir = . +topdir = /usr/include/ruby-3.2.0 +hdrdir = $(topdir) +arch_hdrdir = /usr/include/x86_64-linux-gnu/ruby-3.2.0 +PATH_SEPARATOR = : +VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby +prefix = $(DESTDIR)/usr +rubysitearchprefix = $(sitearchlibdir)/$(RUBY_BASE_NAME) +rubyarchprefix = $(archlibdir)/$(RUBY_BASE_NAME) +rubylibprefix = $(libdir)/$(RUBY_BASE_NAME) +exec_prefix = $(prefix) +vendorarchhdrdir = $(sitearchincludedir)/$(RUBY_VERSION_NAME)/vendor_ruby +sitearchhdrdir = $(sitearchincludedir)/$(RUBY_VERSION_NAME)/site_ruby +rubyarchhdrdir = $(archincludedir)/$(RUBY_VERSION_NAME) +vendorhdrdir = $(rubyhdrdir)/vendor_ruby +sitehdrdir = $(rubyhdrdir)/site_ruby +rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME) +vendorarchdir = $(rubysitearchprefix)/vendor_ruby/$(ruby_version) +vendorlibdir = $(vendordir)/$(ruby_version) +vendordir = $(rubylibprefix)/vendor_ruby +sitearchdir = $(DESTDIR)/usr/local/lib/x86_64-linux-gnu/site_ruby +sitelibdir = $(sitedir)/$(ruby_version) +sitedir = $(DESTDIR)/usr/local/lib/site_ruby +rubyarchdir = $(rubyarchprefix)/$(ruby_version) +rubylibdir = $(rubylibprefix)/$(ruby_version) +sitearchincludedir = $(includedir)/$(sitearch) +archincludedir = $(includedir)/$(arch) +sitearchlibdir = $(libdir)/$(sitearch) +archlibdir = $(libdir)/$(arch) +ridir = $(datarootdir)/$(RI_BASE_NAME) +mandir = $(datarootdir)/man +localedir = $(datarootdir)/locale +libdir = $(exec_prefix)/lib +psdir = $(docdir) +pdfdir = $(docdir) +dvidir = $(docdir) +htmldir = $(docdir) +infodir = $(datarootdir)/info +docdir = $(datarootdir)/doc/$(PACKAGE) +oldincludedir = $(DESTDIR)/usr/include +includedir = $(prefix)/include +runstatedir = $(DESTDIR)/var/run +localstatedir = $(DESTDIR)/var +sharedstatedir = $(prefix)/com +sysconfdir = $(DESTDIR)/etc +datadir = $(datarootdir) +datarootdir = $(prefix)/share +libexecdir = $(exec_prefix)/libexec +sbindir = $(exec_prefix)/sbin +bindir = $(exec_prefix)/bin +archdir = $(rubyarchdir) + + +CC_WRAPPER = +CC = x86_64-linux-gnu-gcc +CXX = x86_64-linux-gnu-g++ +LIBRUBY = $(LIBRUBY_SO) +LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a +LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME) +LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static $(MAINLIBS) +empty = +OUTFLAG = -o $(empty) +COUTFLAG = -o $(empty) +CSRCFLAG = $(empty) + +RUBY_EXTCONF_H = +cflags = $(optflags) $(debugflags) $(warnflags) +cxxflags = +optflags = -O3 -fno-fast-math +debugflags = -ggdb3 +warnflags = -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wundef +cppflags = +CCDLFLAGS = -fPIC +CFLAGS = $(CCDLFLAGS) -g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=BUILDDIR=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fdebug-prefix-map=BUILDDIR=/usr/src/ruby3.2-3.2.3-1ubuntu0.24.04.6 -fPIC $(ARCH_FLAG) +INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir) +DEFS = +CPPFLAGS = -DHAVE_BUILTIN___BUILTIN_CLZ -DHAVE_BUILTIN___BUILTIN_CLZL -DHAVE_BUILTIN___BUILTIN_CLZLL -DHAVE_FLOAT_H -DHAVE_MATH_H -DHAVE_STDBOOL_H -DHAVE_STDLIB_H -DHAVE_X86INTRIN_H -DHAVE_RUBY_ATOMIC_H -DHAVE_RUBY_INTERNAL_HAS_BUILTIN_H -DHAVE_RUBY_INTERNAL_STATIC_ASSERT_H -DHAVE_RB_COMPLEX_REAL -DHAVE_RB_COMPLEX_IMAG -DHAVE_RB_OPTS_EXCEPTION_P -DHAVE_RB_CATEGORY_WARN -DHAVE_CONST_RB_WARN_CATEGORY_DEPRECATED -Wdate-time -D_FORTIFY_SOURCE=3 $(DEFS) $(cppflags) +CXXFLAGS = $(CCDLFLAGS) -g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=BUILDDIR=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fdebug-prefix-map=BUILDDIR=/usr/src/ruby3.2-3.2.3-1ubuntu0.24.04.6 $(ARCH_FLAG) +ldflags = -L. -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed +dldflags = -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now +ARCH_FLAG = +DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG) +LDSHARED = $(CC) -shared +LDSHAREDXX = $(CXX) -shared +AR = x86_64-linux-gnu-gcc-ar +EXEEXT = + +RUBY_INSTALL_NAME = $(RUBY_BASE_NAME)3.2 +RUBY_SO_NAME = ruby-3.2 +RUBYW_INSTALL_NAME = +RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version) +RUBYW_BASE_NAME = rubyw +RUBY_BASE_NAME = ruby + +arch = x86_64-linux-gnu +sitearch = $(arch) +ruby_version = 3.2.0 +ruby = $(bindir)/$(RUBY_BASE_NAME)3.2 +RUBY = $(ruby) +BUILTRUBY = $(bindir)/$(RUBY_BASE_NAME)3.2 +ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/backward.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h + +RM = rm -f +RM_RF = rm -fr +RMDIRS = rmdir --ignore-fail-on-non-empty -p +MAKEDIRS = /bin/mkdir -p +INSTALL = /usr/bin/install -c +INSTALL_PROG = $(INSTALL) -m 0755 +INSTALL_DATA = $(INSTALL) -m 644 +COPY = cp +TOUCH = exit > + +#### End of system configuration section. #### + +preload = +libpath = . $(archlibdir) +LIBPATH = -L. -L$(archlibdir) +DEFFILE = + +CLEANFILES = mkmf.log +DISTCLEANFILES = +DISTCLEANDIRS = + +extout = +extout_prefix = +target_prefix = +LOCAL_LIBS = +LIBS = $(LIBRUBYARG_SHARED) -lm -lpthread -lc +ORIG_SRCS = bigdecimal.c missing.c +SRCS = $(ORIG_SRCS) +OBJS = bigdecimal.o missing.o +HDRS = $(srcdir)/bigdecimal.h $(srcdir)/bits.h $(srcdir)/feature.h $(srcdir)/missing.h $(srcdir)/static_assert.h +LOCAL_HDRS = +TARGET = bigdecimal +TARGET_NAME = bigdecimal +TARGET_ENTRY = Init_$(TARGET_NAME) +DLLIB = $(TARGET).so +EXTSTATIC = +STATIC_LIB = + +TIMESTAMP_DIR = . +BINDIR = $(bindir) +RUBYCOMMONDIR = $(sitedir)$(target_prefix) +RUBYLIBDIR = $(sitelibdir)$(target_prefix) +RUBYARCHDIR = $(sitearchdir)$(target_prefix) +HDRDIR = $(sitehdrdir)$(target_prefix) +ARCHHDRDIR = $(sitearchhdrdir)$(target_prefix) +TARGET_SO_DIR = +TARGET_SO = $(TARGET_SO_DIR)$(DLLIB) +CLEANLIBS = $(TARGET_SO) false +CLEANOBJS = $(OBJS) *.bak +TARGET_SO_DIR_TIMESTAMP = $(TIMESTAMP_DIR)/.sitearchdir.time +BIGDECIMAL_RB = $(srcdir)/../../lib/bigdecimal.rb + +all: $(DLLIB) +static: $(STATIC_LIB) +.PHONY: all install static install-so install-rb +.PHONY: clean clean-so clean-static clean-rb + +clean-static:: +clean-rb-default:: +clean-rb:: +clean-so:: +clean: clean-so clean-static clean-rb-default clean-rb + -$(Q)$(RM_RF) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time + +distclean-rb-default:: +distclean-rb:: +distclean-so:: +distclean-static:: +distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb + -$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log + -$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) + -$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true + +realclean: distclean +install: install-so install-rb + +install-so: $(DLLIB) $(TARGET_SO_DIR_TIMESTAMP) + $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR) +clean-static:: + -$(Q)$(RM) $(STATIC_LIB) +install-rb: pre-install-rb do-install-rb install-rb-default +install-rb-default: pre-install-rb-default do-install-rb-default +pre-install-rb: Makefile +pre-install-rb-default: Makefile +do-install-rb: +do-install-rb-default: +pre-install-rb-default: + @$(NULLCMD) +$(TARGET_SO_DIR_TIMESTAMP): + $(Q) $(MAKEDIRS) $(@D) $(RUBYARCHDIR) + $(Q) $(TOUCH) $@ + +site-install: site-install-so site-install-rb +site-install-so: install-so +site-install-rb: install-rb + +.SUFFIXES: .c .m .cc .mm .cxx .cpp .o .S + +.cc.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cc.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.mm.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.mm.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cxx.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cxx.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cpp.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cpp.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.c.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.c.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.m.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.m.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +$(TARGET_SO): $(OBJS) Makefile + $(ECHO) linking shared-object $(DLLIB) + -$(Q)$(RM) $(@) + $(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS) + + + +$(OBJS): $(HDRS) $(ruby_headers) diff --git a/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/bigdecimal.c b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/bigdecimal.c new file mode 100644 index 0000000..594459d --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/bigdecimal.c @@ -0,0 +1,6238 @@ +/* + * + * Ruby BigDecimal(Variable decimal precision) extension library. + * + * Copyright(C) 2002 by Shigeo Kobayashi(shigeo@tinyforest.gr.jp) + * + */ + +/* #define BIGDECIMAL_DEBUG 1 */ + +#include "bigdecimal.h" +#include "ruby/util.h" + +#ifndef BIGDECIMAL_DEBUG +# undef NDEBUG +# define NDEBUG +#endif +#include + +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_IEEEFP_H +#include +#endif + +#include "bits.h" +#include "static_assert.h" + +#define BIGDECIMAL_VERSION "3.3.1" + +/* #define ENABLE_NUMERIC_STRING */ + +#define SIGNED_VALUE_MAX INTPTR_MAX +#define SIGNED_VALUE_MIN INTPTR_MIN +#define MUL_OVERFLOW_SIGNED_VALUE_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, SIGNED_VALUE_MIN, SIGNED_VALUE_MAX) +#define ADD_OVERFLOW_SIGNED_VALUE_P(a, b) ADD_OVERFLOW_SIGNED_INTEGER_P(a, b, SIGNED_VALUE_MIN, SIGNED_VALUE_MAX) + +/* max_value = 0.9999_9999_9999E[exponent], exponent <= SIGNED_VALUE_MAX */ +#define VP_EXPONENT_MAX (SIGNED_VALUE_MAX / BASE_FIG) +/* min_value = 0.0001_0000_0000E[exponent], exponent-(BASE_FIG-1) >= SIGNED_VALUE_MIN */ +#define VP_EXPONENT_MIN ((SIGNED_VALUE_MIN + BASE_FIG - 1) / BASE_FIG) +#define EXPONENT_MAX (VP_EXPONENT_MAX * BASE_FIG) +#define EXPONENT_MIN (VP_EXPONENT_MIN * BASE_FIG - (BASE_FIG - 1)) + +VALUE rb_cBigDecimal; + +static ID id_BigDecimal_exception_mode; +static ID id_BigDecimal_rounding_mode; +static ID id_BigDecimal_precision_limit; + +static ID id_up; +static ID id_down; +static ID id_truncate; +static ID id_half_up; +static ID id_default; +static ID id_half_down; +static ID id_half_even; +static ID id_banker; +static ID id_ceiling; +static ID id_ceil; +static ID id_floor; +static ID id_to_r; +static ID id_eq; +static ID id_half; + +#define RBD_NUM_ROUNDING_MODES 11 + +static struct { + ID id; + uint8_t mode; +} rbd_rounding_modes[RBD_NUM_ROUNDING_MODES]; + +typedef struct { + VALUE bigdecimal; + Real *real; +} BDVALUE; + +typedef struct { + VALUE bigdecimal_or_nil; + Real *real_or_null; +} NULLABLE_BDVALUE; + +static inline BDVALUE +bdvalue_nonnullable(NULLABLE_BDVALUE v) +{ + assert(v.real_or_null != NULL); + return (BDVALUE) { v.bigdecimal_or_nil, v.real_or_null }; +} + +static inline NULLABLE_BDVALUE +bdvalue_nullable(BDVALUE v) +{ + return (NULLABLE_BDVALUE) { v.bigdecimal, v.real }; +} + +#define BASE_FIG BIGDECIMAL_COMPONENT_FIGURES +#define BASE BIGDECIMAL_BASE + +#define HALF_BASE (BASE/2) +#define BASE1 (BASE/10) + +#ifndef MAYBE_UNUSED +# define MAYBE_UNUSED(x) x +#endif + +#define BIGDECIMAL_POSITIVE_P(bd) ((bd)->sign > 0) +#define BIGDECIMAL_NEGATIVE_P(bd) ((bd)->sign < 0) + +/* + * ================== Memory allocation ============================ + */ + +#ifdef BIGDECIMAL_DEBUG +static size_t rbd_allocation_count = 0; /* Memory allocation counter */ +static inline void +atomic_allocation_count_inc(void) +{ + RUBY_ATOMIC_SIZE_INC(rbd_allocation_count); +} +static inline void +atomic_allocation_count_dec_nounderflow(void) +{ + if (rbd_allocation_count == 0) return; + RUBY_ATOMIC_SIZE_DEC(rbd_allocation_count); +} +static void +check_allocation_count_nonzero(void) +{ + if (rbd_allocation_count != 0) return; + rb_bug("[bigdecimal][rbd_free_struct] Too many memory free calls"); +} +#else +# define atomic_allocation_count_inc() /* nothing */ +# define atomic_allocation_count_dec_nounderflow() /* nothing */ +# define check_allocation_count_nonzero() /* nothing */ +#endif /* BIGDECIMAL_DEBUG */ + +/* VpMult VpDivd helpers */ +#define VPMULT_RESULT_PREC(a, b) (a->Prec + b->Prec) +/* To calculate VpDivd with n-digits precision, quotient needs n+2*BASE_FIG-1 digits space */ +/* In the worst precision case 0001_1111_1111 / 9999 = 0000_0001_1112, there are 2*BASE_FIG-1 leading zeros */ +#define VPDIVD_QUO_DIGITS(required_digits) ((required_digits) + 2 * BASE_FIG - 1) +/* Required r.MaxPrec for calculating VpDivd(c, r, a, b) */ +#define VPDIVD_REM_PREC(a, b, c) Max(a->Prec, b->Prec + c->MaxPrec - 1) + +static NULLABLE_BDVALUE +CreateFromString(const char *str, VALUE klass, bool strict_p, bool raise_exception); + +PUREFUNC(static inline size_t rbd_struct_size(size_t const)); + +static inline size_t +rbd_struct_size(size_t const internal_digits) +{ + size_t const frac_len = (internal_digits == 0) ? 1 : internal_digits; + return offsetof(Real, frac) + frac_len * sizeof(DECDIG); +} + +static inline Real * +rbd_allocate_struct(size_t const internal_digits) +{ + size_t const size = rbd_struct_size(internal_digits); + Real *real = ruby_xcalloc(1, size); + atomic_allocation_count_inc(); + real->MaxPrec = internal_digits; + return real; +} + +static inline Real * +rbd_allocate_struct_decimal_digits(size_t const decimal_digits) +{ + return rbd_allocate_struct(roomof(decimal_digits, BASE_FIG)); +} + +static void +rbd_free_struct(Real *real) +{ + if (real != NULL) { + check_allocation_count_nonzero(); + ruby_xfree(real); + atomic_allocation_count_dec_nounderflow(); + } +} + +MAYBE_UNUSED(static inline Real * rbd_allocate_struct_zero(int sign, size_t const digits)); +#define NewZero rbd_allocate_struct_zero +static inline Real * +rbd_allocate_struct_zero(int sign, size_t const digits) +{ + Real *real = rbd_allocate_struct_decimal_digits(digits); + VpSetZero(real, sign); + return real; +} + +/* + * ================== Ruby Interface part ========================== + */ +#define DoSomeOne(x,y,f) rb_num_coerce_bin(x,y,f) + +/* + * VP routines used in BigDecimal part + */ +static unsigned short VpGetException(void); +static void VpSetException(unsigned short f); +static void VpCheckException(Real *p, bool always); +static int AddExponent(Real *a, SIGNED_VALUE n); +static VALUE CheckGetValue(BDVALUE v); +static void VpInternalRound(Real *c, size_t ixDigit, DECDIG vPrev, DECDIG v); +static int VpLimitRound(Real *c, size_t ixDigit); +static Real *VpCopy(Real *pv, Real const* const x); +static int VPrint(FILE *fp,const char *cntl_chr,Real *a); + +/* + * **** BigDecimal part **** + */ + +static VALUE BigDecimal_nan(void); +static VALUE BigDecimal_positive_infinity(void); +static VALUE BigDecimal_negative_infinity(void); +static VALUE BigDecimal_positive_zero(void); +static VALUE BigDecimal_negative_zero(void); +static VALUE BigDecimal_addsub_with_coerce(VALUE self, VALUE r, size_t prec, int operation); +static VALUE BigDecimal_mult_with_coerce(VALUE self, VALUE r, size_t prec); + +static void +BigDecimal_delete(void *pv) +{ + rbd_free_struct(pv); +} + +static size_t +BigDecimal_memsize(const void *ptr) +{ + const Real *pv = ptr; + return (sizeof(*pv) + pv->MaxPrec * sizeof(DECDIG)); +} + +#ifndef HAVE_RB_EXT_RACTOR_SAFE +# undef RUBY_TYPED_FROZEN_SHAREABLE +# define RUBY_TYPED_FROZEN_SHAREABLE 0 +#endif + +static const rb_data_type_t BigDecimal_data_type = { + "BigDecimal", + { 0, BigDecimal_delete, BigDecimal_memsize, }, +#ifdef RUBY_TYPED_FREE_IMMEDIATELY + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE | RUBY_TYPED_WB_PROTECTED +#endif +}; + +// TypedData_Wrap_Struct may fail if there is no memory, or GC.add_stress_to_class(BigDecimal) is set. +// We need to first allocate empty struct, allocate Real struct, and then set the data pointer. +typedef struct { VALUE _obj; } NULL_WRAPPED_VALUE; +static NULL_WRAPPED_VALUE +BigDecimal_alloc_empty_struct(VALUE klass) +{ + return (NULL_WRAPPED_VALUE) { TypedData_Wrap_Struct(klass, &BigDecimal_data_type, NULL) }; +} + +static VALUE +BigDecimal_wrap_struct(NULL_WRAPPED_VALUE v, Real *real) +{ + VALUE obj = v._obj; + assert(RTYPEDDATA_DATA(obj) == NULL); + RTYPEDDATA_DATA(obj) = real; + RB_OBJ_FREEZE(obj); + return obj; +} + +MAYBE_UNUSED(static inline BDVALUE rbd_allocate_struct_zero_wrap(int sign, size_t const digits)); +#define NewZeroWrap rbd_allocate_struct_zero_wrap +static BDVALUE +rbd_allocate_struct_zero_wrap(int sign, size_t const digits) +{ + NULL_WRAPPED_VALUE null_wrapped = BigDecimal_alloc_empty_struct(rb_cBigDecimal); + Real *real = rbd_allocate_struct_zero(sign, digits); + return (BDVALUE) { BigDecimal_wrap_struct(null_wrapped, real), real }; +} + +static inline int +is_kind_of_BigDecimal(VALUE const v) +{ + return rb_typeddata_is_kind_of(v, &BigDecimal_data_type); +} + +NORETURN(static void cannot_be_coerced_into_BigDecimal(VALUE, VALUE)); + +static void +cannot_be_coerced_into_BigDecimal(VALUE exc_class, VALUE v) +{ + VALUE str; + + if (rb_special_const_p(v)) { + str = rb_inspect(v); + } + else { + str = rb_class_name(rb_obj_class(v)); + } + + str = rb_str_cat2(rb_str_dup(str), " can't be coerced into BigDecimal"); + rb_exc_raise(rb_exc_new3(exc_class, str)); +} + +static inline VALUE BigDecimal_div2(VALUE, VALUE, VALUE); +static VALUE rb_inum_convert_to_BigDecimal(VALUE val); +static VALUE rb_float_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception); +static VALUE rb_rational_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception); +static VALUE rb_cstr_convert_to_BigDecimal(const char *c_str, int raise_exception); +static VALUE rb_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception); + +static NULLABLE_BDVALUE +GetBDValueWithPrecInternal(VALUE v, size_t prec, int must) +{ + switch(TYPE(v)) { + case T_FLOAT: + v = rb_float_convert_to_BigDecimal(v, 0, true); + break; + + case T_RATIONAL: + v = rb_rational_convert_to_BigDecimal(v, prec, true); + break; + + case T_DATA: + if (!is_kind_of_BigDecimal(v)) { + goto SomeOneMayDoIt; + } + break; + + case T_FIXNUM: + case T_BIGNUM: { + v = rb_inum_convert_to_BigDecimal(v); + break; + } + +#ifdef ENABLE_NUMERIC_STRING + case T_STRING: { + const char *c_str = StringValueCStr(v); + v = rb_cstr_convert_to_BigDecimal(c_str, must); + break; + } +#endif /* ENABLE_NUMERIC_STRING */ + + default: + goto SomeOneMayDoIt; + } + + Real *vp; + TypedData_Get_Struct(v, Real, &BigDecimal_data_type, vp); + return (NULLABLE_BDVALUE) { v, vp }; + +SomeOneMayDoIt: + if (must) { + cannot_be_coerced_into_BigDecimal(rb_eTypeError, v); + } + return (NULLABLE_BDVALUE) { Qnil, NULL }; /* NULL means to coerce */ +} + +static inline NULLABLE_BDVALUE +GetBDValueWithPrec(VALUE v, size_t prec) +{ + return GetBDValueWithPrecInternal(v, prec, 0); +} + + +static inline BDVALUE +GetBDValueWithPrecMust(VALUE v, size_t prec) +{ + return bdvalue_nonnullable(GetBDValueWithPrecInternal(v, prec, 1)); +} + +// self must be a receiver of BigDecimal instance method or a gc guarded BigDecimal object. +static inline Real* +GetSelfVpValue(VALUE self) +{ + return GetBDValueWithPrecMust(self, 0).real; +} + +static inline BDVALUE +GetBDValueMust(VALUE v) +{ + return GetBDValueWithPrecMust(v, 0); +} + +/* call-seq: + * BigDecimal.double_fig -> integer + * + * Returns the number of digits a Float object is allowed to have; + * the result is system-dependent: + * + * BigDecimal.double_fig # => 16 + * + */ +static inline VALUE +BigDecimal_double_fig(VALUE self) +{ + return INT2FIX(BIGDECIMAL_DOUBLE_FIGURES); +} + +/* call-seq: + * precs -> array + * + * Returns an Array of two Integer values that represent platform-dependent + * internal storage properties. + * + * This method is deprecated and will be removed in the future. + * Instead, use BigDecimal#n_significant_digits for obtaining the number of + * significant digits in scientific notation, and BigDecimal#precision for + * obtaining the number of digits in decimal notation. + * + */ + +static VALUE +BigDecimal_prec(VALUE self) +{ + BDVALUE v; + VALUE obj; + + rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, + "BigDecimal#precs is deprecated and will be removed in the future; " + "use BigDecimal#precision instead."); + + v = GetBDValueMust(self); + obj = rb_assoc_new(SIZET2NUM(v.real->Prec*VpBaseFig()), + SIZET2NUM(v.real->MaxPrec*VpBaseFig())); + + RB_GC_GUARD(v.bigdecimal); + return obj; +} + +static void +VpCountPrecisionAndScale(Real *p, ssize_t *out_precision, ssize_t *out_scale) +{ + if (out_precision == NULL && out_scale == NULL) + return; + if (VpIsZero(p) || !VpIsDef(p)) { + zero: + if (out_precision) *out_precision = 0; + if (out_scale) *out_scale = 0; + return; + } + + DECDIG x; + + ssize_t n = p->Prec; /* The length of frac without zeros. */ + while (n > 0 && p->frac[n-1] == 0) --n; + if (n == 0) goto zero; + + int nlz = BASE_FIG; + for (x = p->frac[0]; x > 0; x /= 10) --nlz; + + int ntz = 0; + for (x = p->frac[n-1]; x > 0 && x % 10 == 0; x /= 10) ++ntz; + + /* + * Calculate the precision and the scale + * ------------------------------------- + * + * The most significant digit is frac[0], and the least significant digit + * is frac[Prec-1]. When the exponent is zero, the decimal point is + * located just before frac[0]. + * + * When the exponent is negative, the decimal point moves to leftward. + * In this case, the precision can be calculated by + * + * precision = BASE_FIG * (-exponent + n) - ntz, + * + * and the scale is the same as precision. + * + * 0 . 0000 0000 | frac[0] ... frac[n-1] | + * |<----------| exponent == -2 | + * |---------------------------------->| precision + * |---------------------------------->| scale + * + * + * Conversely, when the exponent is positive, the decimal point moves to + * rightward. In this case, the scale equals to + * + * BASE_FIG * (n - exponent) - ntz. + * + * the precision equals to + * + * scale + BASE_FIG * exponent - nlz. + * + * | frac[0] frac[1] . frac[2] ... frac[n-1] | + * |---------------->| exponent == 2 | + * | |---------------------->| scale + * |---------------------------------------->| precision + */ + + ssize_t ex = p->exponent; + + /* Count the number of decimal digits before frac[1]. */ + ssize_t n_digits_head = BASE_FIG; + if (ex < 0) { + n_digits_head += (-ex) * BASE_FIG; /* The number of leading zeros before frac[0]. */ + ex = 0; + } + else if (ex > 0) { + /* Count the number of decimal digits without the leading zeros in + * the most significant digit in the integral part. + */ + n_digits_head -= nlz; /* Make the number of digits */ + } + + if (out_precision) { + ssize_t precision = n_digits_head; + + /* Count the number of decimal digits after frac[0]. */ + if (ex > (ssize_t)n) { + /* In this case the number is an integer with some trailing zeros. */ + precision += (ex - 1) * BASE_FIG; + } + else if (n > 0) { + precision += (n - 1) * BASE_FIG; + + if (ex < (ssize_t)n) { + precision -= ntz; + } + } + + *out_precision = precision; + } + + if (out_scale) { + ssize_t scale = 0; + + if (p->exponent < 0) { + scale = n_digits_head + (n - 1) * BASE_FIG - ntz; + } + else if (n > p->exponent) { + scale = (n - p->exponent) * BASE_FIG - ntz; + } + + *out_scale = scale; + } +} + +static void +BigDecimal_count_precision_and_scale(VALUE self, ssize_t *out_precision, ssize_t *out_scale) +{ + BDVALUE v = GetBDValueMust(self); + VpCountPrecisionAndScale(v.real, out_precision, out_scale); + RB_GC_GUARD(v.bigdecimal); +} + +/* + * call-seq: + * precision -> integer + * + * Returns the number of decimal digits in +self+: + * + * BigDecimal("0").precision # => 0 + * BigDecimal("1").precision # => 1 + * BigDecimal("1.1").precision # => 2 + * BigDecimal("3.1415").precision # => 5 + * BigDecimal("-1e20").precision # => 21 + * BigDecimal("1e-20").precision # => 20 + * BigDecimal("Infinity").precision # => 0 + * BigDecimal("-Infinity").precision # => 0 + * BigDecimal("NaN").precision # => 0 + * + */ +static VALUE +BigDecimal_precision(VALUE self) +{ + ssize_t precision; + BigDecimal_count_precision_and_scale(self, &precision, NULL); + return SSIZET2NUM(precision); +} + +/* + * call-seq: + * scale -> integer + * + * Returns the number of decimal digits following the decimal digits in +self+. + * + * BigDecimal("0").scale # => 0 + * BigDecimal("1").scale # => 0 + * BigDecimal("1.1").scale # => 1 + * BigDecimal("3.1415").scale # => 4 + * BigDecimal("-1e20").scale # => 0 + * BigDecimal("1e-20").scale # => 20 + * BigDecimal("Infinity").scale # => 0 + * BigDecimal("-Infinity").scale # => 0 + * BigDecimal("NaN").scale # => 0 + */ +static VALUE +BigDecimal_scale(VALUE self) +{ + ssize_t scale; + BigDecimal_count_precision_and_scale(self, NULL, &scale); + return SSIZET2NUM(scale); +} + +/* + * call-seq: + * precision_scale -> [integer, integer] + * + * Returns a 2-length array; the first item is the result of + * BigDecimal#precision and the second one is of BigDecimal#scale. + * + * See BigDecimal#precision. + * See BigDecimal#scale. + */ +static VALUE +BigDecimal_precision_scale(VALUE self) +{ + ssize_t precision, scale; + BigDecimal_count_precision_and_scale(self, &precision, &scale); + return rb_assoc_new(SSIZET2NUM(precision), SSIZET2NUM(scale)); +} + +/* + * call-seq: + * n_significant_digits -> integer + * + * Returns the number of decimal significant digits in +self+. + * + * BigDecimal("0").n_significant_digits # => 0 + * BigDecimal("1").n_significant_digits # => 1 + * BigDecimal("1.1").n_significant_digits # => 2 + * BigDecimal("3.1415").n_significant_digits # => 5 + * BigDecimal("-1e20").n_significant_digits # => 1 + * BigDecimal("1e-20").n_significant_digits # => 1 + * BigDecimal("Infinity").n_significant_digits # => 0 + * BigDecimal("-Infinity").n_significant_digits # => 0 + * BigDecimal("NaN").n_significant_digits # => 0 + */ +static VALUE +BigDecimal_n_significant_digits(VALUE self) +{ + BDVALUE v = GetBDValueMust(self); + if (VpIsZero(v.real) || !VpIsDef(v.real)) { + return INT2FIX(0); + } + + ssize_t n = v.real->Prec; /* The length of frac without trailing zeros. */ + for (n = v.real->Prec; n > 0 && v.real->frac[n-1] == 0; --n); + if (n == 0) return INT2FIX(0); + + DECDIG x; + int nlz = BASE_FIG; + for (x = v.real->frac[0]; x > 0; x /= 10) --nlz; + + int ntz = 0; + for (x = v.real->frac[n-1]; x > 0 && x % 10 == 0; x /= 10) ++ntz; + + RB_GC_GUARD(v.bigdecimal); + ssize_t n_significant_digits = BASE_FIG*n - nlz - ntz; + return SSIZET2NUM(n_significant_digits); +} + +/* + * call-seq: + * hash -> integer + * + * Returns the integer hash value for +self+. + * + * Two instances of \BigDecimal have the same hash value if and only if + * they have equal: + * + * - Sign. + * - Fractional part. + * - Exponent. + * + */ +static VALUE +BigDecimal_hash(VALUE self) +{ + BDVALUE v = GetBDValueMust(self); + st_index_t hash = (st_index_t)v.real->sign; + /* hash!=2: the case for 0(1),NaN(0) or +-Infinity(3) is sign itself */ + if(hash == 2 || hash == (st_index_t)-2) { + hash ^= rb_memhash(v.real->frac, sizeof(DECDIG)*v.real->Prec); + hash += v.real->exponent; + } + RB_GC_GUARD(v.bigdecimal); + return ST2FIX(hash); +} + +/* + * call-seq: + * _dump -> string + * + * Returns a string representing the marshalling of +self+. + * See module Marshal. + * + * inf = BigDecimal('Infinity') # => Infinity + * dumped = inf._dump # => "9:Infinity" + * BigDecimal._load(dumped) # => Infinity + * + */ +static VALUE +BigDecimal_dump(int argc, VALUE *argv, VALUE self) +{ + BDVALUE v; + char *psz; + VALUE dummy; + volatile VALUE dump; + size_t len; + + rb_scan_args(argc, argv, "01", &dummy); + v = GetBDValueMust(self); + dump = rb_str_new(0, VpNumOfChars(v.real, "E")+50); + psz = RSTRING_PTR(dump); + snprintf(psz, RSTRING_LEN(dump), "%"PRIuSIZE":", v.real->Prec*VpBaseFig()); + len = strlen(psz); + VpToString(v.real, psz+len, RSTRING_LEN(dump)-len, 0, 0); + rb_str_resize(dump, strlen(psz)); + + RB_GC_GUARD(v.bigdecimal); + return dump; +} + +/* + * Internal method used to provide marshalling support. See the Marshal module. + */ +static VALUE +BigDecimal_load(VALUE self, VALUE str) +{ + BDVALUE v; + unsigned char *pch; + unsigned char ch; + + pch = (unsigned char *)StringValueCStr(str); + /* First skip max prec. Don't trust the value. */ + while((*pch) != (unsigned char)'\0' && (ch = *pch++) != (unsigned char)':') { + if(!ISDIGIT(ch)) { + rb_raise(rb_eTypeError, "load failed: invalid character in the marshaled string"); + } + } + v = bdvalue_nonnullable(CreateFromString((char *)pch, self, true, true)); + return CheckGetValue(v); +} + +static unsigned short +check_rounding_mode_option(VALUE const opts) +{ + VALUE mode; + char const *s; + long l; + + assert(RB_TYPE_P(opts, T_HASH)); + + if (NIL_P(opts)) + goto no_opt; + + mode = rb_hash_lookup2(opts, ID2SYM(id_half), Qundef); + if (mode == Qundef || NIL_P(mode)) + goto no_opt; + + if (SYMBOL_P(mode)) + mode = rb_sym2str(mode); + else if (!RB_TYPE_P(mode, T_STRING)) { + VALUE str_mode = rb_check_string_type(mode); + if (NIL_P(str_mode)) + goto invalid; + mode = str_mode; + } + s = RSTRING_PTR(mode); + l = RSTRING_LEN(mode); + switch (l) { + case 2: + if (strncasecmp(s, "up", 2) == 0) + return VP_ROUND_HALF_UP; + break; + case 4: + if (strncasecmp(s, "even", 4) == 0) + return VP_ROUND_HALF_EVEN; + else if (strncasecmp(s, "down", 4) == 0) + return VP_ROUND_HALF_DOWN; + break; + default: + break; + } + + invalid: + rb_raise(rb_eArgError, "invalid rounding mode (%"PRIsVALUE")", mode); + + no_opt: + return VpGetRoundMode(); +} + +static unsigned short +check_rounding_mode(VALUE const v) +{ + unsigned short sw; + ID id; + if (RB_TYPE_P(v, T_SYMBOL)) { + int i; + id = SYM2ID(v); + for (i = 0; i < RBD_NUM_ROUNDING_MODES; ++i) { + if (rbd_rounding_modes[i].id == id) { + return rbd_rounding_modes[i].mode; + } + } + rb_raise(rb_eArgError, "invalid rounding mode (%"PRIsVALUE")", v); + } + else { + sw = NUM2USHORT(v); + if (!VpIsRoundMode(sw)) { + rb_raise(rb_eArgError, "invalid rounding mode (%"PRIsVALUE")", v); + } + return sw; + } +} + +/* call-seq: + * BigDecimal.mode(mode, setting = nil) -> integer + * + * Returns an integer representing the mode settings + * for exception handling and rounding. + * + * These modes control exception handling: + * + * - \BigDecimal::EXCEPTION_NaN. + * - \BigDecimal::EXCEPTION_INFINITY. + * - \BigDecimal::EXCEPTION_UNDERFLOW. + * - \BigDecimal::EXCEPTION_OVERFLOW. + * - \BigDecimal::EXCEPTION_ZERODIVIDE. + * - \BigDecimal::EXCEPTION_ALL. + * + * Values for +setting+ for exception handling: + * + * - +true+: sets the given +mode+ to +true+. + * - +false+: sets the given +mode+ to +false+. + * - +nil+: does not modify the mode settings. + * + * You can use method BigDecimal.save_exception_mode + * to temporarily change, and then automatically restore, exception modes. + * + * For clarity, some examples below begin by setting all + * exception modes to +false+. + * + * This mode controls the way rounding is to be performed: + * + * - \BigDecimal::ROUND_MODE + * + * You can use method BigDecimal.save_rounding_mode + * to temporarily change, and then automatically restore, the rounding mode. + * + * NaNs + * + * Mode \BigDecimal::EXCEPTION_NaN controls behavior + * when a \BigDecimal NaN is created. + * + * Settings: + * + * - +false+ (default): Returns BigDecimal('NaN'). + * - +true+: Raises FloatDomainError. + * + * Examples: + * + * BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0 + * BigDecimal('NaN') # => NaN + * BigDecimal.mode(BigDecimal::EXCEPTION_NaN, true) # => 2 + * BigDecimal('NaN') # Raises FloatDomainError + * + * Infinities + * + * Mode \BigDecimal::EXCEPTION_INFINITY controls behavior + * when a \BigDecimal Infinity or -Infinity is created. + * Settings: + * + * - +false+ (default): Returns BigDecimal('Infinity') + * or BigDecimal('-Infinity'). + * - +true+: Raises FloatDomainError. + * + * Examples: + * + * BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0 + * BigDecimal('Infinity') # => Infinity + * BigDecimal('-Infinity') # => -Infinity + * BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, true) # => 1 + * BigDecimal('Infinity') # Raises FloatDomainError + * BigDecimal('-Infinity') # Raises FloatDomainError + * + * Underflow + * + * Mode \BigDecimal::EXCEPTION_UNDERFLOW controls behavior + * when a \BigDecimal underflow occurs. + * Settings: + * + * - +false+ (default): Returns BigDecimal('0') + * or BigDecimal('-Infinity'). + * - +true+: Raises FloatDomainError. + * + * Examples: + * + * BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0 + * def flow_under + * x = BigDecimal('0.1') + * 100.times { x *= x } + * end + * flow_under # => 100 + * BigDecimal.mode(BigDecimal::EXCEPTION_UNDERFLOW, true) # => 4 + * flow_under # Raises FloatDomainError + * + * Overflow + * + * Mode \BigDecimal::EXCEPTION_OVERFLOW controls behavior + * when a \BigDecimal overflow occurs. + * Settings: + * + * - +false+ (default): Returns BigDecimal('Infinity') + * or BigDecimal('-Infinity'). + * - +true+: Raises FloatDomainError. + * + * Examples: + * + * BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0 + * def flow_over + * x = BigDecimal('10') + * 100.times { x *= x } + * end + * flow_over # => 100 + * BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, true) # => 1 + * flow_over # Raises FloatDomainError + * + * Zero Division + * + * Mode \BigDecimal::EXCEPTION_ZERODIVIDE controls behavior + * when a zero-division occurs. + * Settings: + * + * - +false+ (default): Returns BigDecimal('Infinity') + * or BigDecimal('-Infinity'). + * - +true+: Raises FloatDomainError. + * + * Examples: + * + * BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0 + * one = BigDecimal('1') + * zero = BigDecimal('0') + * one / zero # => Infinity + * BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, true) # => 16 + * one / zero # Raises FloatDomainError + * + * All Exceptions + * + * Mode \BigDecimal::EXCEPTION_ALL controls all of the above: + * + * BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0 + * BigDecimal.mode(BigDecimal::EXCEPTION_ALL, true) # => 23 + * + * Rounding + * + * Mode \BigDecimal::ROUND_MODE controls the way rounding is to be performed; + * its +setting+ values are: + * + * - +ROUND_UP+: Round away from zero. + * Aliased as +:up+. + * - +ROUND_DOWN+: Round toward zero. + * Aliased as +:down+ and +:truncate+. + * - +ROUND_HALF_UP+: Round toward the nearest neighbor; + * if the neighbors are equidistant, round away from zero. + * Aliased as +:half_up+ and +:default+. + * - +ROUND_HALF_DOWN+: Round toward the nearest neighbor; + * if the neighbors are equidistant, round toward zero. + * Aliased as +:half_down+. + * - +ROUND_HALF_EVEN+ (Banker's rounding): Round toward the nearest neighbor; + * if the neighbors are equidistant, round toward the even neighbor. + * Aliased as +:half_even+ and +:banker+. + * - +ROUND_CEILING+: Round toward positive infinity. + * Aliased as +:ceiling+ and +:ceil+. + * - +ROUND_FLOOR+: Round toward negative infinity. + * Aliased as +:floor:+. + * + */ +static VALUE +BigDecimal_mode(int argc, VALUE *argv, VALUE self) +{ + VALUE which; + VALUE val; + unsigned long f,fo; + + rb_scan_args(argc, argv, "11", &which, &val); + f = (unsigned long)NUM2INT(which); + + if (f & VP_EXCEPTION_ALL) { + /* Exception mode setting */ + fo = VpGetException(); + if (val == Qnil) return INT2FIX(fo); + if (val != Qfalse && val!=Qtrue) { + rb_raise(rb_eArgError, "second argument must be true or false"); + return Qnil; /* Not reached */ + } + if (f & VP_EXCEPTION_INFINITY) { + VpSetException((unsigned short)((val == Qtrue) ? (fo | VP_EXCEPTION_INFINITY) : + (fo & (~VP_EXCEPTION_INFINITY)))); + } + fo = VpGetException(); + if (f & VP_EXCEPTION_NaN) { + VpSetException((unsigned short)((val == Qtrue) ? (fo | VP_EXCEPTION_NaN) : + (fo & (~VP_EXCEPTION_NaN)))); + } + fo = VpGetException(); + if (f & VP_EXCEPTION_UNDERFLOW) { + VpSetException((unsigned short)((val == Qtrue) ? (fo | VP_EXCEPTION_UNDERFLOW) : + (fo & (~VP_EXCEPTION_UNDERFLOW)))); + } + fo = VpGetException(); + if(f & VP_EXCEPTION_ZERODIVIDE) { + VpSetException((unsigned short)((val == Qtrue) ? (fo | VP_EXCEPTION_ZERODIVIDE) : + (fo & (~VP_EXCEPTION_ZERODIVIDE)))); + } + fo = VpGetException(); + return INT2FIX(fo); + } + if (VP_ROUND_MODE == f) { + /* Rounding mode setting */ + unsigned short sw; + fo = VpGetRoundMode(); + if (NIL_P(val)) return INT2FIX(fo); + sw = check_rounding_mode(val); + fo = VpSetRoundMode(sw); + return INT2FIX(fo); + } + rb_raise(rb_eTypeError, "first argument for BigDecimal.mode invalid"); + return Qnil; +} + +static size_t +GetAddSubPrec(Real *a, Real *b) +{ + if (!VpIsDef(a) || !VpIsDef(b)) return (size_t)-1L; + ssize_t min_a = a->exponent - a->Prec; + ssize_t min_b = b->exponent - b->Prec; + return Max(a->exponent, b->exponent) - Min(min_a, min_b); +} + +static inline SIGNED_VALUE +check_int_precision(VALUE v) +{ + SIGNED_VALUE n; +#if SIZEOF_VALUE <= SIZEOF_LONG + n = (SIGNED_VALUE)NUM2LONG(v); +#elif SIZEOF_VALUE <= SIZEOF_LONG_LONG + n = (SIGNED_VALUE)NUM2LL(v); +#else +# error SIZEOF_VALUE is too large +#endif + if (n < 0) { + rb_raise(rb_eArgError, "negative precision"); + } + return n; +} + +static NULLABLE_BDVALUE +CreateFromString(const char *str, VALUE klass, bool strict_p, bool raise_exception) +{ + NULL_WRAPPED_VALUE null_wrapped = BigDecimal_alloc_empty_struct(klass); + Real *pv = VpAlloc(str, strict_p, raise_exception); + if (!pv) return (NULLABLE_BDVALUE) { Qnil, NULL }; + return (NULLABLE_BDVALUE) { BigDecimal_wrap_struct(null_wrapped, pv), pv }; +} + +static Real * +VpCopy(Real *pv, Real const* const x) +{ + assert(x != NULL); + + pv = (Real *)ruby_xrealloc(pv, rbd_struct_size(x->MaxPrec)); + pv->MaxPrec = x->MaxPrec; + pv->Prec = x->Prec; + pv->exponent = x->exponent; + pv->sign = x->sign; + pv->flag = x->flag; + MEMCPY(pv->frac, x->frac, DECDIG, pv->MaxPrec); + + return pv; +} + +/* Returns True if the value is Not a Number. */ +static VALUE +BigDecimal_IsNaN(VALUE self) +{ + Real *p = GetSelfVpValue(self); + if (VpIsNaN(p)) return Qtrue; + return Qfalse; +} + +/* Returns nil, -1, or +1 depending on whether the value is finite, + * -Infinity, or +Infinity. + */ +static VALUE +BigDecimal_IsInfinite(VALUE self) +{ + Real *p = GetSelfVpValue(self); + if (VpIsPosInf(p)) return INT2FIX(1); + if (VpIsNegInf(p)) return INT2FIX(-1); + return Qnil; +} + +/* Returns True if the value is finite (not NaN or infinite). */ +static VALUE +BigDecimal_IsFinite(VALUE self) +{ + Real *p = GetSelfVpValue(self); + if (VpIsNaN(p)) return Qfalse; + if (VpIsInf(p)) return Qfalse; + return Qtrue; +} + +static void +BigDecimal_check_num(Real *p) +{ + VpCheckException(p, true); +} + +static VALUE BigDecimal_fix(VALUE self); +static VALUE BigDecimal_split(VALUE self); + +/* Returns the value as an Integer. + * + * If the BigDecimal is infinity or NaN, raises FloatDomainError. + */ +static VALUE +BigDecimal_to_i(VALUE self) +{ + BDVALUE v; + VALUE ret; + + v = GetBDValueMust(self); + BigDecimal_check_num(v.real); + + if (v.real->exponent <= 0) return INT2FIX(0); + if (v.real->exponent == 1) { + ret = LONG2NUM((long)(VpGetSign(v.real) * (DECDIG_DBL_SIGNED)v.real->frac[0])); + } + else { + VALUE fix = (ssize_t)v.real->Prec > v.real->exponent ? BigDecimal_fix(self) : self; + VALUE digits = RARRAY_AREF(BigDecimal_split(fix), 1); + ssize_t dpower = VpExponent10(v.real) - (ssize_t)RSTRING_LEN(digits); + ret = rb_funcall(digits, rb_intern("to_i"), 0); + + if (BIGDECIMAL_NEGATIVE_P(v.real)) { + ret = rb_funcall(ret, '*', 1, INT2FIX(-1)); + } + if (dpower) { + VALUE pow10 = rb_funcall(INT2FIX(10), rb_intern("**"), 1, SSIZET2NUM(dpower)); + // In Ruby < 3.4, int**int may return Float::INFINITY + if (RB_TYPE_P(pow10, T_FLOAT)) rb_raise(rb_eFloatDomainError, "Infinity"); + + ret = rb_funcall(ret, '*', 1, pow10); + } + } + + RB_GC_GUARD(v.bigdecimal); + return ret; +} + +/* Returns a new Float object having approximately the same value as the + * BigDecimal number. Normal accuracy limits and built-in errors of binary + * Float arithmetic apply. + */ +static VALUE +BigDecimal_to_f(VALUE self) +{ + double d; + SIGNED_VALUE e; + char *buf; + volatile VALUE str; + BDVALUE v = GetBDValueMust(self); + bool negative = BIGDECIMAL_NEGATIVE_P(v.real); + + if (VpVtoD(&d, &e, v.real) != 1) + return rb_float_new(d); + if (e > (SIGNED_VALUE)(DBL_MAX_10_EXP+BASE_FIG)) + goto overflow; + if (e < (SIGNED_VALUE)(DBL_MIN_10_EXP-DBL_DIG)) + goto underflow; + + str = rb_str_new(0, VpNumOfChars(v.real, "E")); + buf = RSTRING_PTR(str); + VpToString(v.real, buf, RSTRING_LEN(str), 0, 0); + + RB_GC_GUARD(v.bigdecimal); + + errno = 0; + d = strtod(buf, 0); + if (errno == ERANGE) { + if (d == 0.0) goto underflow; + if (fabs(d) >= HUGE_VAL) goto overflow; + } + return rb_float_new(d); + +overflow: + VpException(VP_EXCEPTION_OVERFLOW, "BigDecimal to Float conversion", 0); + if (negative) + return rb_float_new(VpGetDoubleNegInf()); + else + return rb_float_new(VpGetDoublePosInf()); + +underflow: + VpException(VP_EXCEPTION_UNDERFLOW, "BigDecimal to Float conversion", 0); + if (negative) + return rb_float_new(-0.0); + else + return rb_float_new(0.0); +} + + +/* Converts a BigDecimal to a Rational. + */ +static VALUE +BigDecimal_to_r(VALUE self) +{ + BDVALUE v; + ssize_t sign, power, denomi_power; + VALUE a, digits, numerator; + + v = GetBDValueMust(self); + BigDecimal_check_num(v.real); + sign = VpGetSign(v.real); + power = VpExponent10(v.real); + RB_GC_GUARD(v.bigdecimal); + + a = BigDecimal_split(self); + digits = RARRAY_AREF(a, 1); + denomi_power = power - RSTRING_LEN(digits); + numerator = rb_funcall(digits, rb_intern("to_i"), 0); + + if (sign < 0) { + numerator = rb_funcall(numerator, '*', 1, INT2FIX(-1)); + } + if (denomi_power < 0) { + return rb_Rational(numerator, + rb_funcall(INT2FIX(10), rb_intern("**"), 1, + INT2FIX(-denomi_power))); + } + else { + return rb_Rational1(rb_funcall(numerator, '*', 1, + rb_funcall(INT2FIX(10), rb_intern("**"), 1, + INT2FIX(denomi_power)))); + } +} + +static size_t +GetCoercePrec(Real *a, size_t prec) +{ + if (prec == 0) prec = a->Prec * BASE_FIG; + if (prec < 2 * BIGDECIMAL_DOUBLE_FIGURES) prec = 2 * BIGDECIMAL_DOUBLE_FIGURES; + return prec; +} + +/* The coerce method provides support for Ruby type coercion. It is not + * enabled by default. + * + * This means that binary operations like + * / or - can often be performed + * on a BigDecimal and an object of another type, if the other object can + * be coerced into a BigDecimal value. + * + * e.g. + * a = BigDecimal("1.0") + * b = a / 2.0 #=> 0.5 + * + * Note that coercing a String to a BigDecimal is not supported by default; + * it requires a special compile-time option when building Ruby. + */ +static VALUE +BigDecimal_coerce(VALUE self, VALUE other) +{ + Real* pv = DATA_PTR(self); + BDVALUE b = GetBDValueWithPrecMust(other, GetCoercePrec(pv, 0)); + return rb_assoc_new(CheckGetValue(b), self); +} + +/* + * call-seq: + * +big_decimal -> self + * + * Returns +self+: + * + * +BigDecimal(5) # => 0.5e1 + * +BigDecimal(-5) # => -0.5e1 + * + */ + +static VALUE +BigDecimal_uplus(VALUE self) +{ + return self; +} + +static bool +is_coerceable_to_BigDecimal(VALUE r) +{ + return is_kind_of_BigDecimal(r) || + RB_INTEGER_TYPE_P(r) || + RB_TYPE_P(r, T_FLOAT) || + RB_TYPE_P(r, T_RATIONAL); +} + + /* + * call-seq: + * self + value -> bigdecimal + * + * Returns the \BigDecimal sum of +self+ and +value+: + * + * b = BigDecimal('111111.111') # => 0.111111111e6 + * b + 2 # => 0.111113111e6 + * b + 2.0 # => 0.111113111e6 + * b + Rational(2, 1) # => 0.111113111e6 + * b + Complex(2, 0) # => (0.111113111e6+0i) + * + * See the {Note About Precision}[BigDecimal.html#class-BigDecimal-label-A+Note+About+Precision]. + * + */ + +static VALUE +BigDecimal_add(VALUE self, VALUE r) +{ + if (!is_coerceable_to_BigDecimal(r)) return DoSomeOne(self, r, '+'); + return BigDecimal_addsub_with_coerce(self, r, 0, +1); +} + +static VALUE +BigDecimal_addsub_with_coerce(VALUE self, VALUE r, size_t prec, int operation) +{ + BDVALUE a, b, c; + size_t mx; + + a = GetBDValueMust(self); + b = GetBDValueWithPrecMust(r, GetCoercePrec(a.real, prec)); + + if (VpIsNaN(a.real)) return CheckGetValue(a); + if (VpIsNaN(b.real)) return CheckGetValue(b); + + mx = GetAddSubPrec(a.real, b.real); + if (mx == (size_t)-1L) { + /* a or b is inf */ + c = NewZeroWrap(1, BASE_FIG); + VpAddSub(c.real, a.real, b.real, operation); + } + else { + c = NewZeroWrap(1, (mx + 1) * BASE_FIG); + size_t pl = VpGetPrecLimit(); + if (prec) VpSetPrecLimit(prec); + // Let VpAddSub round the result + VpAddSub(c.real, a.real, b.real, operation); + if (prec) VpSetPrecLimit(pl); + } + + RB_GC_GUARD(a.bigdecimal); + RB_GC_GUARD(b.bigdecimal); + return CheckGetValue(c); +} + + /* + * call-seq: + * self - value -> bigdecimal + * + * Returns the \BigDecimal difference of +self+ and +value+: + * + * b = BigDecimal('333333.333') # => 0.333333333e6 + * b - 2 # => 0.333331333e6 + * b - 2.0 # => 0.333331333e6 + * b - Rational(2, 1) # => 0.333331333e6 + * b - Complex(2, 0) # => (0.333331333e6+0i) + * + * See the {Note About Precision}[BigDecimal.html#class-BigDecimal-label-A+Note+About+Precision]. + * + */ +static VALUE +BigDecimal_sub(VALUE self, VALUE r) +{ + if (!is_coerceable_to_BigDecimal(r)) return DoSomeOne(self, r, '-'); + return BigDecimal_addsub_with_coerce(self, r, 0, -1); +} + +static VALUE +BigDecimalCmp(VALUE self, VALUE r,char op) +{ + SIGNED_VALUE e; + BDVALUE a = GetBDValueMust(self); + NULLABLE_BDVALUE b = GetBDValueWithPrec(r, GetCoercePrec(a.real, 0)); + + if (b.real_or_null == NULL) { + ID f = 0; + + switch (op) { + case '*': + return rb_num_coerce_cmp(self, r, rb_intern("<=>")); + + case '=': + return RTEST(rb_num_coerce_cmp(self, r, rb_intern("=="))) ? Qtrue : Qfalse; + + case 'G': + f = rb_intern(">="); + break; + + case 'L': + f = rb_intern("<="); + break; + + case '>': + /* fall through */ + case '<': + f = (ID)op; + break; + + default: + break; + } + return rb_num_coerce_relop(self, r, f); + } + e = VpComp(a.real, b.real_or_null); + + RB_GC_GUARD(a.bigdecimal); + RB_GC_GUARD(b.bigdecimal_or_nil); + + if (e == 999) + return (op == '*') ? Qnil : Qfalse; + switch (op) { + case '*': + return INT2FIX(e); /* any op */ + + case '=': + if (e == 0) return Qtrue; + return Qfalse; + + case 'G': + if (e >= 0) return Qtrue; + return Qfalse; + + case '>': + if (e > 0) return Qtrue; + return Qfalse; + + case 'L': + if (e <= 0) return Qtrue; + return Qfalse; + + case '<': + if (e < 0) return Qtrue; + return Qfalse; + + default: + break; + } + + rb_bug("Undefined operation in BigDecimalCmp()"); + + UNREACHABLE; +} + +/* Returns True if the value is zero. */ +static VALUE +BigDecimal_zero(VALUE self) +{ + Real *a = GetSelfVpValue(self); + return VpIsZero(a) ? Qtrue : Qfalse; +} + +/* Returns self if the value is non-zero, nil otherwise. */ +static VALUE +BigDecimal_nonzero(VALUE self) +{ + Real *a = GetSelfVpValue(self); + return VpIsZero(a) ? Qnil : self; +} + +/* The comparison operator. + * a <=> b is 0 if a == b, 1 if a > b, -1 if a < b. + */ +static VALUE +BigDecimal_comp(VALUE self, VALUE r) +{ + return BigDecimalCmp(self, r, '*'); +} + +/* + * Tests for value equality; returns true if the values are equal. + * + * The == and === operators and the eql? method have the same implementation + * for BigDecimal. + * + * Values may be coerced to perform the comparison: + * + * BigDecimal('1.0') == 1.0 #=> true + */ +static VALUE +BigDecimal_eq(VALUE self, VALUE r) +{ + return BigDecimalCmp(self, r, '='); +} + +/* call-seq: + * self < other -> true or false + * + * Returns +true+ if +self+ is less than +other+, +false+ otherwise: + * + * b = BigDecimal('1.5') # => 0.15e1 + * b < 2 # => true + * b < 2.0 # => true + * b < Rational(2, 1) # => true + * b < 1.5 # => false + * + * Raises an exception if the comparison cannot be made. + * + */ +static VALUE +BigDecimal_lt(VALUE self, VALUE r) +{ + return BigDecimalCmp(self, r, '<'); +} + +/* call-seq: + * self <= other -> true or false + * + * Returns +true+ if +self+ is less or equal to than +other+, +false+ otherwise: + * + * b = BigDecimal('1.5') # => 0.15e1 + * b <= 2 # => true + * b <= 2.0 # => true + * b <= Rational(2, 1) # => true + * b <= 1.5 # => true + * b < 1 # => false + * + * Raises an exception if the comparison cannot be made. + * + */ +static VALUE +BigDecimal_le(VALUE self, VALUE r) +{ + return BigDecimalCmp(self, r, 'L'); +} + +/* call-seq: + * self > other -> true or false + * + * Returns +true+ if +self+ is greater than +other+, +false+ otherwise: + * + * b = BigDecimal('1.5') + * b > 1 # => true + * b > 1.0 # => true + * b > Rational(1, 1) # => true + * b > 2 # => false + * + * Raises an exception if the comparison cannot be made. + * + */ +static VALUE +BigDecimal_gt(VALUE self, VALUE r) +{ + return BigDecimalCmp(self, r, '>'); +} + +/* call-seq: + * self >= other -> true or false + * + * Returns +true+ if +self+ is greater than or equal to +other+, +false+ otherwise: + * + * b = BigDecimal('1.5') + * b >= 1 # => true + * b >= 1.0 # => true + * b >= Rational(1, 1) # => true + * b >= 1.5 # => true + * b > 2 # => false + * + * Raises an exception if the comparison cannot be made. + * + */ +static VALUE +BigDecimal_ge(VALUE self, VALUE r) +{ + return BigDecimalCmp(self, r, 'G'); +} + +/* + * call-seq: + * -self -> bigdecimal + * + * Returns the \BigDecimal negation of self: + * + * b0 = BigDecimal('1.5') + * b1 = -b0 # => -0.15e1 + * b2 = -b1 # => 0.15e1 + * + */ + +static VALUE +BigDecimal_neg(VALUE self) +{ + BDVALUE a = GetBDValueMust(self); + BDVALUE c = NewZeroWrap(1, a.real->Prec * BASE_FIG); + VpAsgn(c.real, a.real, -10); + RB_GC_GUARD(a.bigdecimal); + return CheckGetValue(c); +} + +/* + * call-seq: + * a * b -> bigdecimal + * + * Multiply by the specified value. + * + * The result precision will be the precision of the sum of each precision. + * + * See BigDecimal#mult. + */ +static VALUE +BigDecimal_mult(VALUE self, VALUE r) +{ + if (!is_coerceable_to_BigDecimal(r)) return DoSomeOne(self, r, '*'); + return BigDecimal_mult_with_coerce(self, r, 0); +} + +static VALUE +BigDecimal_mult_with_coerce(VALUE self, VALUE r, size_t prec) +{ + BDVALUE a, b, c; + + a = GetBDValueMust(self); + b = GetBDValueWithPrecMust(r, GetCoercePrec(a.real, prec)); + + c = NewZeroWrap(1, VPMULT_RESULT_PREC(a.real, b.real) * BASE_FIG); + VpMult(c.real, a.real, b.real); + if (prec) { + VpLeftRound(c.real, VpGetRoundMode(), prec); + } + else { + VpLimitRound(c.real, 0); + } + + RB_GC_GUARD(a.bigdecimal); + RB_GC_GUARD(b.bigdecimal); + return CheckGetValue(c); +} + +static bool BigDecimal_DoDivmod(VALUE self, VALUE r, NULLABLE_BDVALUE *div, NULLABLE_BDVALUE *mod, bool truncate); + +/* call-seq: + * a / b -> bigdecimal + * + * Divide by the specified value. + * + * The result precision will be the precision of the larger operand, + * but its minimum is 2*Float::DIG. + * + * See BigDecimal#div. + * See BigDecimal#quo. + */ +static VALUE +BigDecimal_div(VALUE self, VALUE r) +/* For c = self/r: with round operation */ +{ + if (!is_coerceable_to_BigDecimal(r)) return DoSomeOne(self, r, '/'); + return BigDecimal_div2(self, r, INT2FIX(0)); +} + +static VALUE BigDecimal_round(int argc, VALUE *argv, VALUE self); + +/* call-seq: + * quo(value) -> bigdecimal + * quo(value, digits) -> bigdecimal + * + * Divide by the specified value. + * + * digits:: If specified and less than the number of significant digits of + * the result, the result is rounded to the given number of digits, + * according to the rounding mode indicated by BigDecimal.mode. + * + * If digits is 0 or omitted, the result is the same as for the + * / operator. + * + * See BigDecimal#/. + * See BigDecimal#div. + */ +static VALUE +BigDecimal_quo(int argc, VALUE *argv, VALUE self) +{ + VALUE value, digits, result; + SIGNED_VALUE n = -1; + + argc = rb_scan_args(argc, argv, "11", &value, &digits); + if (argc > 1) { + n = check_int_precision(digits); + } + + if (n > 0) { + result = BigDecimal_div2(self, value, digits); + } + else { + result = BigDecimal_div(self, value); + } + + return result; +} + +/* + * %: mod = a%b = a - (a.to_f/b).floor * b + * div = (a.to_f/b).floor + * In truncate mode, use truncate instead of floor. + */ +static bool +BigDecimal_DoDivmod(VALUE self, VALUE r, NULLABLE_BDVALUE *div, NULLABLE_BDVALUE *mod, bool truncate) +{ + BDVALUE a, b, dv, md, res; + NULLABLE_BDVALUE b2; + ssize_t a_exponent, b_exponent; + size_t mx, rx, pl; + + a = GetBDValueMust(self); + + b2 = GetBDValueWithPrec(r, GetCoercePrec(a.real, 0)); + if (!b2.real_or_null) return false; + b = bdvalue_nonnullable(b2); + + if (VpIsNaN(a.real) || VpIsNaN(b.real) || (VpIsInf(a.real) && VpIsInf(b.real))) { + VALUE nan = BigDecimal_nan(); + *div = *mod = (NULLABLE_BDVALUE) { nan, DATA_PTR(nan) }; + goto Done; + } + if (VpIsZero(b.real)) { + rb_raise(rb_eZeroDivError, "divided by 0"); + } + if (VpIsInf(a.real)) { + if (VpGetSign(a.real) == VpGetSign(b.real)) { + VALUE inf = BigDecimal_positive_infinity(); + *div = (NULLABLE_BDVALUE) { inf, DATA_PTR(inf) }; + } + else { + VALUE inf = BigDecimal_negative_infinity(); + *div = (NULLABLE_BDVALUE) { inf, DATA_PTR(inf) }; + } + VALUE nan = BigDecimal_nan(); + *mod = (NULLABLE_BDVALUE) { nan, DATA_PTR(nan) }; + goto Done; + } + if (VpIsZero(a.real)) { + VALUE zero = BigDecimal_positive_zero(); + *div = (NULLABLE_BDVALUE) { zero, DATA_PTR(zero) }; + *mod = bdvalue_nullable(a); + goto Done; + } + if (VpIsInf(b.real)) { + if (!truncate && VpGetSign(a.real) * VpGetSign(b.real) < 0) { + BDVALUE minus_one = NewZeroWrap(1, BASE_FIG); + VpSetOne(minus_one.real); + VpSetSign(minus_one.real, -1); + RB_GC_GUARD(minus_one.bigdecimal); + *div = bdvalue_nullable(minus_one); + *mod = bdvalue_nullable(b); + } else { + VALUE zero = BigDecimal_positive_zero(); + *div = (NULLABLE_BDVALUE) { zero, DATA_PTR(zero) }; + *mod = bdvalue_nullable(a); + } + goto Done; + } + + a_exponent = VpExponent10(a.real); + b_exponent = VpExponent10(b.real); + mx = a_exponent > b_exponent ? a_exponent - b_exponent + 1 : 1; + dv = NewZeroWrap(1, VPDIVD_QUO_DIGITS(mx)); + + /* res is reused for VpDivd remainder and VpMult result */ + rx = VPDIVD_REM_PREC(a.real, b.real, dv.real); + mx = VPMULT_RESULT_PREC(dv.real, b.real); + res = NewZeroWrap(1, Max(rx, mx) * BASE_FIG); + /* AddSub needs one more prec */ + md = NewZeroWrap(1, (res.real->MaxPrec + 1) * BASE_FIG); + + VpDivd(dv.real, res.real, a.real, b.real); + VpMidRound(dv.real, VP_ROUND_DOWN, 0); + VpMult(res.real, dv.real, b.real); + pl = VpGetPrecLimit(); + VpSetPrecLimit(0); + VpAddSub(md.real, a.real, res.real, -1); + VpSetPrecLimit(pl); + + if (!truncate && !VpIsZero(md.real) && (VpGetSign(a.real) * VpGetSign(b.real) < 0)) { + /* result adjustment for negative case */ + BDVALUE dv2 = NewZeroWrap(1, (dv.real->MaxPrec + 1) * BASE_FIG); + BDVALUE md2 = NewZeroWrap(1, (GetAddSubPrec(md.real, b.real) + 1) * BASE_FIG); + VpSetPrecLimit(0); + VpAddSub(dv2.real, dv.real, VpOne(), -1); + VpAddSub(md2.real, md.real, b.real, 1); + VpSetPrecLimit(pl); + *div = bdvalue_nullable(dv2); + *mod = bdvalue_nullable(md2); + RB_GC_GUARD(dv2.bigdecimal); + RB_GC_GUARD(md2.bigdecimal); + } + else { + *div = bdvalue_nullable(dv); + *mod = bdvalue_nullable(md); + } + +Done: + RB_GC_GUARD(a.bigdecimal); + RB_GC_GUARD(b.bigdecimal); + RB_GC_GUARD(dv.bigdecimal); + RB_GC_GUARD(md.bigdecimal); + RB_GC_GUARD(res.bigdecimal); + return true; +} + +/* call-seq: + * a % b + * a.modulo(b) + * + * Returns the modulus from dividing by b. + * + * See BigDecimal#divmod. + */ +static VALUE +BigDecimal_mod(VALUE self, VALUE r) /* %: a%b = a - (a.to_f/b).floor * b */ +{ + NULLABLE_BDVALUE div, mod; + + if (BigDecimal_DoDivmod(self, r, &div, &mod, false)) { + return CheckGetValue(bdvalue_nonnullable(mod)); + } + return DoSomeOne(self, r, '%'); +} + +/* call-seq: + * remainder(value) + * + * Returns the remainder from dividing by the value. + * + * x.remainder(y) means x-y*(x/y).truncate + */ +static VALUE +BigDecimal_remainder(VALUE self, VALUE r) /* remainder */ +{ + NULLABLE_BDVALUE div, mod = { Qnil, NULL }; + + if (BigDecimal_DoDivmod(self, r, &div, &mod, true)) { + return CheckGetValue(bdvalue_nonnullable(mod)); + } + return DoSomeOne(self, r, rb_intern("remainder")); +} + +/* call-seq: + * divmod(value) + * + * Divides by the specified value, and returns the quotient and modulus + * as BigDecimal numbers. The quotient is rounded towards negative infinity. + * + * For example: + * + * require 'bigdecimal' + * + * a = BigDecimal("42") + * b = BigDecimal("9") + * + * q, m = a.divmod(b) + * + * c = q * b + m + * + * a == c #=> true + * + * The quotient q is (a/b).floor, and the modulus is the amount that must be + * added to q * b to get a. + */ +static VALUE +BigDecimal_divmod(VALUE self, VALUE r) +{ + NULLABLE_BDVALUE div, mod; + + if (BigDecimal_DoDivmod(self, r, &div, &mod, false)) { + return rb_assoc_new(CheckGetValue(bdvalue_nonnullable(div)), CheckGetValue(bdvalue_nonnullable(mod))); + } + return DoSomeOne(self,r,rb_intern("divmod")); +} + +/* + * Do the same manner as Float#div when n is nil. + * Do the same manner as BigDecimal#quo when n is 0. + */ +static inline VALUE +BigDecimal_div2(VALUE self, VALUE b, VALUE n) +{ + SIGNED_VALUE ix; + BDVALUE av, bv, cv, res; + + if (NIL_P(n)) { /* div in Float sense */ + NULLABLE_BDVALUE div; + NULLABLE_BDVALUE mod; + if (BigDecimal_DoDivmod(self, b, &div, &mod, false)) { + return BigDecimal_to_i(CheckGetValue(bdvalue_nonnullable(div))); + } + return DoSomeOne(self, b, rb_intern("div")); + } + + /* div in BigDecimal sense */ + ix = check_int_precision(n); + + av = GetBDValueMust(self); + bv = GetBDValueWithPrecMust(b, GetCoercePrec(av.real, ix)); + + if (ix == 0) { + ssize_t a_prec, b_prec, limit = VpGetPrecLimit(); + VpCountPrecisionAndScale(av.real, &a_prec, NULL); + VpCountPrecisionAndScale(bv.real, &b_prec, NULL); + ix = ((a_prec > b_prec) ? a_prec : b_prec) + BIGDECIMAL_DOUBLE_FIGURES; + if (2 * BIGDECIMAL_DOUBLE_FIGURES > ix) + ix = 2 * BIGDECIMAL_DOUBLE_FIGURES; + if (limit && limit < ix) ix = limit; + } + + // Needs to calculate 1 extra digit for rounding. + cv = NewZeroWrap(1, VPDIVD_QUO_DIGITS(ix + 1)); + res = NewZeroWrap(1, VPDIVD_REM_PREC(av.real, bv.real, cv.real) * BASE_FIG); + VpDivd(cv.real, res.real, av.real, bv.real); + + if (!VpIsZero(res.real)) { + // Remainder value affects rounding result. + // ROUND_UP cv = 0.1e0 with idx=10 will be: + // 0.1e0 if remainder == 0 + // 0.1000000001e0 if remainder != 0 + size_t idx = roomof(ix, BASE_FIG); + while (cv.real->Prec <= idx) cv.real->frac[cv.real->Prec++] = 0; + if (cv.real->frac[idx] == 0 || cv.real->frac[idx] == HALF_BASE) cv.real->frac[idx]++; + } + VpLeftRound(cv.real, VpGetRoundMode(), ix); + + RB_GC_GUARD(av.bigdecimal); + RB_GC_GUARD(bv.bigdecimal); + RB_GC_GUARD(res.bigdecimal); + return CheckGetValue(cv); +} + + /* + * Document-method: BigDecimal#div + * + * call-seq: + * div(value) -> integer + * div(value, digits) -> bigdecimal or integer + * + * Divide by the specified value. + * + * digits:: If specified and less than the number of significant digits of the + * result, the result is rounded to that number of digits, according + * to BigDecimal.mode. + * + * If digits is 0, the result is the same as for the / operator + * or #quo. + * + * If digits is not specified, the result is an integer, + * by analogy with Float#div; see also BigDecimal#divmod. + * + * See BigDecimal#/. + * See BigDecimal#quo. + * + * Examples: + * + * a = BigDecimal("4") + * b = BigDecimal("3") + * + * a.div(b, 3) # => 0.133e1 + * + * a.div(b, 0) # => 0.1333333333333333333e1 + * a / b # => 0.1333333333333333333e1 + * a.quo(b) # => 0.1333333333333333333e1 + * + * a.div(b) # => 1 + */ +static VALUE +BigDecimal_div3(int argc, VALUE *argv, VALUE self) +{ + VALUE b,n; + + rb_scan_args(argc, argv, "11", &b, &n); + + return BigDecimal_div2(self, b, n); +} + + /* + * call-seq: + * add(value, ndigits) -> new_bigdecimal + * + * Returns the \BigDecimal sum of +self+ and +value+ + * with a precision of +ndigits+ decimal digits. + * + * When +ndigits+ is less than the number of significant digits + * in the sum, the sum is rounded to that number of digits, + * according to the current rounding mode; see BigDecimal.mode. + * + * Examples: + * + * # Set the rounding mode. + * BigDecimal.mode(BigDecimal::ROUND_MODE, :half_up) + * b = BigDecimal('111111.111') + * b.add(1, 0) # => 0.111112111e6 + * b.add(1, 3) # => 0.111e6 + * b.add(1, 6) # => 0.111112e6 + * b.add(1, 15) # => 0.111112111e6 + * b.add(1.0, 15) # => 0.111112111e6 + * b.add(Rational(1, 1), 15) # => 0.111112111e6 + * + */ + +static VALUE +BigDecimal_add2(VALUE self, VALUE b, VALUE n) +{ + return BigDecimal_addsub_with_coerce(self, b, check_int_precision(n), +1); +} + +/* call-seq: + * sub(value, digits) -> bigdecimal + * + * Subtract the specified value. + * + * e.g. + * c = a.sub(b,n) + * + * digits:: If specified and less than the number of significant digits of the + * result, the result is rounded to that number of digits, according + * to BigDecimal.mode. + * + */ +static VALUE +BigDecimal_sub2(VALUE self, VALUE b, VALUE n) +{ + return BigDecimal_addsub_with_coerce(self, b, check_int_precision(n), -1); +} + + /* + * call-seq: + * mult(other, ndigits) -> bigdecimal + * + * Returns the \BigDecimal product of +self+ and +value+ + * with a precision of +ndigits+ decimal digits. + * + * When +ndigits+ is less than the number of significant digits + * in the sum, the sum is rounded to that number of digits, + * according to the current rounding mode; see BigDecimal.mode. + * + * Examples: + * + * # Set the rounding mode. + * BigDecimal.mode(BigDecimal::ROUND_MODE, :half_up) + * b = BigDecimal('555555.555') + * b.mult(3, 0) # => 0.1666666665e7 + * b.mult(3, 3) # => 0.167e7 + * b.mult(3, 6) # => 0.166667e7 + * b.mult(3, 15) # => 0.1666666665e7 + * b.mult(3.0, 0) # => 0.1666666665e7 + * b.mult(Rational(3, 1), 0) # => 0.1666666665e7 + * b.mult(Complex(3, 0), 0) # => (0.1666666665e7+0.0i) + * + */ + +static VALUE +BigDecimal_mult2(VALUE self, VALUE b, VALUE n) +{ + return BigDecimal_mult_with_coerce(self, b, check_int_precision(n)); +} + +/* + * call-seq: + * abs -> bigdecimal + * + * Returns the \BigDecimal absolute value of +self+: + * + * BigDecimal('5').abs # => 0.5e1 + * BigDecimal('-3').abs # => 0.3e1 + * + */ + +static VALUE +BigDecimal_abs(VALUE self) +{ + BDVALUE a = GetBDValueMust(self); + BDVALUE c = NewZeroWrap(1, a.real->Prec * BASE_FIG); + VpAsgn(c.real, a.real, 10); + VpChangeSign(c.real, 1); + RB_GC_GUARD(a.bigdecimal); + return CheckGetValue(c); +} + +/* Return the integer part of the number, as a BigDecimal. + */ +static VALUE +BigDecimal_fix(VALUE self) +{ + BDVALUE a = GetBDValueMust(self); + BDVALUE c = NewZeroWrap(1, (a.real->Prec + 1) * BASE_FIG); + VpActiveRound(c.real, a.real, VP_ROUND_DOWN, 0); /* 0: round off */ + RB_GC_GUARD(a.bigdecimal); + return CheckGetValue(c); +} + +/* call-seq: + * round(n, mode) + * + * Round to the nearest integer (by default), returning the result as a + * BigDecimal if n is specified and positive, or as an Integer if it isn't. + * + * BigDecimal('3.14159').round #=> 3 + * BigDecimal('8.7').round #=> 9 + * BigDecimal('-9.9').round #=> -10 + * + * BigDecimal('3.14159').round(2).class.name #=> "BigDecimal" + * BigDecimal('3.14159').round.class.name #=> "Integer" + * BigDecimal('3.14159').round(0).class.name #=> "Integer" + * + * If n is specified and positive, the fractional part of the result has no + * more than that many digits. + * + * If n is specified and negative, at least that many digits to the left of the + * decimal point will be 0 in the result, and return value will be an Integer. + * + * BigDecimal('3.14159').round(3) #=> 3.142 + * BigDecimal('13345.234').round(-2) #=> 13300 + * + * The value of the optional mode argument can be used to determine how + * rounding is performed; see BigDecimal.mode. + */ +static VALUE +BigDecimal_round(int argc, VALUE *argv, VALUE self) +{ + BDVALUE c, a; + int iLoc = 0; + VALUE vLoc; + VALUE vRound; + int round_to_int = 0; + size_t mx; + + unsigned short sw = VpGetRoundMode(); + + switch (rb_scan_args(argc, argv, "02", &vLoc, &vRound)) { + case 0: + iLoc = 0; + round_to_int = 1; + break; + case 1: + if (RB_TYPE_P(vLoc, T_HASH)) { + sw = check_rounding_mode_option(vLoc); + } + else { + iLoc = NUM2INT(vLoc); + if (iLoc < 1) round_to_int = 1; + } + break; + case 2: + iLoc = NUM2INT(vLoc); + if (RB_TYPE_P(vRound, T_HASH)) { + sw = check_rounding_mode_option(vRound); + } + else { + sw = check_rounding_mode(vRound); + } + break; + default: + break; + } + + a = GetBDValueMust(self); + mx = (a.real->Prec + 1) * BASE_FIG; + c = NewZeroWrap(1, mx); + + VpActiveRound(c.real, a.real, sw, iLoc); + + RB_GC_GUARD(a.bigdecimal); + + if (round_to_int) { + return BigDecimal_to_i(CheckGetValue(c)); + } + return CheckGetValue(c); +} + +static VALUE +BigDecimal_truncate_floor_ceil(int argc, VALUE *argv, VALUE self, unsigned short rounding_mode) +{ + BDVALUE c, a; + int iLoc; + VALUE vLoc; + size_t mx; + + if (rb_scan_args(argc, argv, "01", &vLoc) == 0) { + iLoc = 0; + } + else { + iLoc = NUM2INT(vLoc); + } + + a = GetBDValueMust(self); + mx = (a.real->Prec + 1) * BASE_FIG; + c = NewZeroWrap(1, mx); + VpActiveRound(c.real, a.real, rounding_mode, iLoc); + + RB_GC_GUARD(a.bigdecimal); + + if (argc == 0) { + return BigDecimal_to_i(CheckGetValue(c)); + } + return CheckGetValue(c); +} + +/* call-seq: + * truncate(n) + * + * Truncate to the nearest integer (by default), returning the result as a + * BigDecimal. + * + * BigDecimal('3.14159').truncate #=> 3 + * BigDecimal('8.7').truncate #=> 8 + * BigDecimal('-9.9').truncate #=> -9 + * + * If n is specified and positive, the fractional part of the result has no + * more than that many digits. + * + * If n is specified and negative, at least that many digits to the left of the + * decimal point will be 0 in the result. + * + * BigDecimal('3.14159').truncate(3) #=> 3.141 + * BigDecimal('13345.234').truncate(-2) #=> 13300.0 + */ +static VALUE +BigDecimal_truncate(int argc, VALUE *argv, VALUE self) +{ + return BigDecimal_truncate_floor_ceil(argc, argv, self, VP_ROUND_DOWN); +} + +/* Return the fractional part of the number, as a BigDecimal. + */ +static VALUE +BigDecimal_frac(VALUE self) +{ + BDVALUE a = GetBDValueMust(self); + BDVALUE c = NewZeroWrap(1, (a.real->Prec + 1) * BASE_FIG); + VpFrac(c.real, a.real); + RB_GC_GUARD(a.bigdecimal); + return CheckGetValue(c); +} + +/* call-seq: + * floor(n) + * + * Return the largest integer less than or equal to the value, as a BigDecimal. + * + * BigDecimal('3.14159').floor #=> 3 + * BigDecimal('-9.1').floor #=> -10 + * + * If n is specified and positive, the fractional part of the result has no + * more than that many digits. + * + * If n is specified and negative, at least that + * many digits to the left of the decimal point will be 0 in the result. + * + * BigDecimal('3.14159').floor(3) #=> 3.141 + * BigDecimal('13345.234').floor(-2) #=> 13300.0 + */ +static VALUE +BigDecimal_floor(int argc, VALUE *argv, VALUE self) +{ + return BigDecimal_truncate_floor_ceil(argc, argv, self, VP_ROUND_FLOOR); +} + +/* call-seq: + * ceil(n) + * + * Return the smallest integer greater than or equal to the value, as a BigDecimal. + * + * BigDecimal('3.14159').ceil #=> 4 + * BigDecimal('-9.1').ceil #=> -9 + * + * If n is specified and positive, the fractional part of the result has no + * more than that many digits. + * + * If n is specified and negative, at least that + * many digits to the left of the decimal point will be 0 in the result. + * + * BigDecimal('3.14159').ceil(3) #=> 3.142 + * BigDecimal('13345.234').ceil(-2) #=> 13400.0 + */ +static VALUE +BigDecimal_ceil(int argc, VALUE *argv, VALUE self) +{ + return BigDecimal_truncate_floor_ceil(argc, argv, self, VP_ROUND_CEIL); +} + +/* call-seq: + * to_s(s) + * + * Converts the value to a string. + * + * The default format looks like 0.xxxxEnn. + * + * The optional parameter s consists of either an integer; or an optional '+' + * or ' ', followed by an optional number, followed by an optional 'E' or 'F'. + * + * If there is a '+' at the start of s, positive values are returned with + * a leading '+'. + * + * A space at the start of s returns positive values with a leading space. + * + * If s contains a number, a space is inserted after each group of that many + * digits, starting from '.' and counting outwards. + * + * If s ends with an 'E', scientific notation (0.xxxxEnn) is used. + * + * If s ends with an 'F', conventional floating point notation is used. + * + * Examples: + * + * BigDecimal('-1234567890123.45678901234567890').to_s('5F') + * #=> '-123 45678 90123.45678 90123 45678 9' + * + * BigDecimal('1234567890123.45678901234567890').to_s('+8F') + * #=> '+12345 67890123.45678901 23456789' + * + * BigDecimal('1234567890123.45678901234567890').to_s(' F') + * #=> ' 1234567890123.4567890123456789' + */ +static VALUE +BigDecimal_to_s(int argc, VALUE *argv, VALUE self) +{ + int fmt = 0; /* 0: E format, 1: F format */ + int fPlus = 0; /* 0: default, 1: set ' ' before digits, 2: set '+' before digits. */ + BDVALUE v; + volatile VALUE str; + char *psz; + char ch; + size_t nc, mc = 0; + SIGNED_VALUE m; + VALUE f; + + v = GetBDValueMust(self); + + if (rb_scan_args(argc, argv, "01", &f) == 1) { + if (RB_TYPE_P(f, T_STRING)) { + psz = StringValueCStr(f); + if (*psz == ' ') { + fPlus = 1; + psz++; + } + else if (*psz == '+') { + fPlus = 2; + psz++; + } + while ((ch = *psz++) != 0) { + if (ISSPACE(ch)) { + continue; + } + if (!ISDIGIT(ch)) { + if (ch == 'F' || ch == 'f') { + fmt = 1; /* F format */ + } + break; + } + mc = mc*10 + ch - '0'; + } + } + else { + m = NUM2INT(f); + if (m <= 0) { + rb_raise(rb_eArgError, "argument must be positive"); + } + mc = (size_t)m; + } + } + if (fmt) { + nc = VpNumOfChars(v.real, "F"); + } + else { + nc = VpNumOfChars(v.real, "E"); + } + if (mc > 0) { + nc += (nc + mc - 1) / mc + 1; + } + + str = rb_usascii_str_new(0, nc); + psz = RSTRING_PTR(str); + + if (fmt) { + VpToFString(v.real, psz, RSTRING_LEN(str), mc, fPlus); + } + else { + VpToString (v.real, psz, RSTRING_LEN(str), mc, fPlus); + } + rb_str_resize(str, strlen(psz)); + + RB_GC_GUARD(v.bigdecimal); + return str; +} + +/* Splits a BigDecimal number into four parts, returned as an array of values. + * + * The first value represents the sign of the BigDecimal, and is -1 or 1, or 0 + * if the BigDecimal is Not a Number. + * + * The second value is a string representing the significant digits of the + * BigDecimal, with no leading zeros. + * + * The third value is the base used for arithmetic (currently always 10) as an + * Integer. + * + * The fourth value is an Integer exponent. + * + * If the BigDecimal can be represented as 0.xxxxxx*10**n, then xxxxxx is the + * string of significant digits with no leading zeros, and n is the exponent. + * + * From these values, you can translate a BigDecimal to a float as follows: + * + * sign, significant_digits, base, exponent = a.split + * f = sign * "0.#{significant_digits}".to_f * (base ** exponent) + * + * (Note that the to_f method is provided as a more convenient way to translate + * a BigDecimal to a Float.) + */ +static VALUE +BigDecimal_split(VALUE self) +{ + BDVALUE v; + VALUE obj,str; + ssize_t e, s; + char *psz1; + + v = GetBDValueMust(self); + str = rb_str_new(0, VpNumOfChars(v.real, "E")); + psz1 = RSTRING_PTR(str); + VpSzMantissa(v.real, psz1, RSTRING_LEN(str)); + s = 1; + if(psz1[0] == '-') { + size_t len = strlen(psz1 + 1); + + memmove(psz1, psz1 + 1, len); + psz1[len] = '\0'; + s = -1; + } + if (psz1[0] == 'N') s = 0; /* NaN */ + e = VpExponent10(v.real); + obj = rb_ary_new2(4); + rb_ary_push(obj, INT2FIX(s)); + rb_ary_push(obj, str); + rb_str_resize(str, strlen(psz1)); + rb_ary_push(obj, INT2FIX(10)); + rb_ary_push(obj, SSIZET2NUM(e)); + + RB_GC_GUARD(v.bigdecimal); + return obj; +} + +/* Returns the exponent of the BigDecimal number, as an Integer. + * + * If the number can be represented as 0.xxxxxx*10**n where xxxxxx is a string + * of digits with no leading zeros, then n is the exponent. + */ +static VALUE +BigDecimal_exponent(VALUE self) +{ + ssize_t e = VpExponent10(GetSelfVpValue(self)); + return SSIZET2NUM(e); +} + +/* Returns a string representation of self. + * + * BigDecimal("1234.5678").inspect + * #=> "0.12345678e4" + */ +static VALUE +BigDecimal_inspect(VALUE self) +{ + BDVALUE v; + volatile VALUE str; + size_t nc; + + v = GetBDValueMust(self); + nc = VpNumOfChars(v.real, "E"); + + str = rb_str_new(0, nc); + VpToString(v.real, RSTRING_PTR(str), RSTRING_LEN(str), 0, 0); + rb_str_resize(str, strlen(RSTRING_PTR(str))); + + RB_GC_GUARD(v.bigdecimal); + return str; +} + +/* Returns self * 10**v without changing the precision. + * This method is currently for internal use. + * + * BigDecimal("0.123e10")._decimal_shift(20) #=> "0.123e30" + * BigDecimal("0.123e10")._decimal_shift(-20) #=> "0.123e-10" + */ +static VALUE +BigDecimal_decimal_shift(VALUE self, VALUE v) +{ + BDVALUE a, c; + ssize_t shift, exponentShift; + bool shiftDown; + size_t prec; + DECDIG ex, iex; + + a = GetBDValueMust(self); + shift = NUM2SSIZET(rb_to_int(v)); + + if (VpIsZero(a.real) || VpIsNaN(a.real) || VpIsInf(a.real) || shift == 0) return CheckGetValue(a); + + exponentShift = shift > 0 ? shift / BASE_FIG : (shift + 1) / BASE_FIG - 1; + shift -= exponentShift * BASE_FIG; + ex = 1; + for (int i = 0; i < shift; i++) ex *= 10; + shiftDown = a.real->frac[0] * (DECDIG_DBL)ex >= BASE; + iex = BASE / ex; + + prec = a.real->Prec + shiftDown; + c = NewZeroWrap(1, prec * BASE_FIG); + if (shift == 0) { + VpAsgn(c.real, a.real, 1); + } else if (shiftDown) { + DECDIG carry = 0; + exponentShift++; + for (size_t i = 0; i < a.real->Prec; i++) { + DECDIG v = a.real->frac[i]; + c.real->frac[i] = carry * ex + v / iex; + carry = v % iex; + } + c.real->frac[a.real->Prec] = carry * ex; + } else { + DECDIG carry = 0; + for (ssize_t i = a.real->Prec - 1; i >= 0; i--) { + DECDIG v = a.real->frac[i]; + c.real->frac[i] = v % iex * ex + carry; + carry = v / iex; + } + } + while (c.real->frac[prec - 1] == 0) prec--; + c.real->Prec = prec; + c.real->sign = a.real->sign; + c.real->exponent = a.real->exponent; + AddExponent(c.real, exponentShift); + RB_GC_GUARD(a.bigdecimal); + return CheckGetValue(c); +} + +inline static int +is_zero(VALUE x) +{ + VALUE num; + + switch (TYPE(x)) { + case T_FIXNUM: + return FIX2LONG(x) == 0; + + case T_BIGNUM: + return Qfalse; + + case T_RATIONAL: + num = rb_rational_num(x); + return FIXNUM_P(num) && FIX2LONG(num) == 0; + + default: + break; + } + + return RTEST(rb_funcall(x, id_eq, 1, INT2FIX(0))); +} + +/* :nodoc: */ +static VALUE +BigDecimal_clone(VALUE self) +{ + return self; +} + +#ifdef HAVE_RB_OPTS_EXCEPTION_P +int rb_opts_exception_p(VALUE opts, int default_value); +#define opts_exception_p(opts) rb_opts_exception_p((opts), 1) +#else +static int +opts_exception_p(VALUE opts) +{ + static ID kwds[1]; + VALUE exception; + if (!kwds[0]) { + kwds[0] = rb_intern_const("exception"); + } + if (!rb_get_kwargs(opts, kwds, 0, 1, &exception)) return 1; + switch (exception) { + case Qtrue: case Qfalse: + break; + default: + rb_raise(rb_eArgError, "true or false is expected as exception: %+"PRIsVALUE, + exception); + } + return exception != Qfalse; +} +#endif + +static VALUE +check_exception(VALUE bd) +{ + assert(is_kind_of_BigDecimal(bd)); + + Real *vp; + TypedData_Get_Struct(bd, Real, &BigDecimal_data_type, vp); + VpCheckException(vp, false); + + return bd; +} + +static VALUE +rb_uint64_convert_to_BigDecimal(uint64_t uval) +{ + NULL_WRAPPED_VALUE null_wrapped = BigDecimal_alloc_empty_struct(rb_cBigDecimal); + Real *vp; + if (uval == 0) { + vp = rbd_allocate_struct(1); + vp->Prec = 1; + vp->exponent = 1; + VpSetZero(vp, 1); + vp->frac[0] = 0; + } + else if (uval < BASE) { + vp = rbd_allocate_struct(1); + vp->Prec = 1; + vp->exponent = 1; + VpSetSign(vp, 1); + vp->frac[0] = (DECDIG)uval; + } + else { + DECDIG buf[BIGDECIMAL_INT64_MAX_LENGTH] = {0,}; + DECDIG r = uval % BASE; + size_t len = 0, ntz = 0; + if (r == 0) { + // Count and skip trailing zeros + for (; r == 0 && uval > 0; ++ntz) { + uval /= BASE; + r = uval % BASE; + } + } + for (; uval > 0; ++len) { + // Store digits + buf[BIGDECIMAL_INT64_MAX_LENGTH - len - 1] = r; + uval /= BASE; + r = uval % BASE; + } + + const size_t exp = len + ntz; + vp = rbd_allocate_struct(len); + vp->Prec = len; + vp->exponent = exp; + VpSetSign(vp, 1); + MEMCPY(vp->frac, buf + BIGDECIMAL_INT64_MAX_LENGTH - len, DECDIG, len); + } + + return BigDecimal_wrap_struct(null_wrapped, vp); +} + +static VALUE +rb_int64_convert_to_BigDecimal(int64_t ival) +{ + const uint64_t uval = (ival < 0) ? (((uint64_t)-(ival+1))+1) : (uint64_t)ival; + VALUE bd = rb_uint64_convert_to_BigDecimal(uval); + if (ival < 0) { + Real *vp; + TypedData_Get_Struct(bd, Real, &BigDecimal_data_type, vp); + VpSetSign(vp, -1); + } + return bd; +} + +static VALUE +rb_big_convert_to_BigDecimal(VALUE val) +{ + assert(RB_TYPE_P(val, T_BIGNUM)); + + int leading_zeros; + size_t size = rb_absint_size(val, &leading_zeros); + int sign = FIX2INT(rb_big_cmp(val, INT2FIX(0))); + if (sign < 0 && leading_zeros == 0) { + size += 1; + } + if (size <= sizeof(long)) { + if (sign < 0) { + return rb_int64_convert_to_BigDecimal(NUM2LONG(val)); + } + else { + return rb_uint64_convert_to_BigDecimal(NUM2ULONG(val)); + } + } +#if defined(SIZEOF_LONG_LONG) && SIZEOF_LONG < SIZEOF_LONG_LONG + else if (size <= sizeof(LONG_LONG)) { + if (sign < 0) { + return rb_int64_convert_to_BigDecimal(NUM2LL(val)); + } + else { + return rb_uint64_convert_to_BigDecimal(NUM2ULL(val)); + } + } +#endif + else { + VALUE str = rb_big2str(val, 10); + BDVALUE v = bdvalue_nonnullable(CreateFromString( + RSTRING_PTR(str), + rb_cBigDecimal, + true, + true + )); + RB_GC_GUARD(str); + return CheckGetValue(v); + } +} + +static VALUE +rb_inum_convert_to_BigDecimal(VALUE val) +{ + assert(RB_INTEGER_TYPE_P(val)); + if (FIXNUM_P(val)) { + return rb_int64_convert_to_BigDecimal(FIX2LONG(val)); + } + else { + return rb_big_convert_to_BigDecimal(val); + } +} + +static VALUE +rb_float_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception) +{ + assert(RB_FLOAT_TYPE_P(val)); + + double d = RFLOAT_VALUE(val); + + if (isnan(d)) { + VALUE obj = BigDecimal_nan(); + return check_exception(obj); + } + else if (isinf(d)) { + VALUE obj; + if (d > 0) { + obj = BigDecimal_positive_infinity(); + } + else { + obj = BigDecimal_negative_infinity(); + } + return check_exception(obj); + } + else if (d == 0.0) { + if (1/d < 0.0) { + return BigDecimal_negative_zero(); + } + else { + return BigDecimal_positive_zero(); + } + } + + if (digs == SIZE_MAX) { + digs = 0; + } + else if (digs > BIGDECIMAL_DOUBLE_FIGURES) { + if (!raise_exception) + return Qnil; + rb_raise(rb_eArgError, "precision too large."); + } + + /* Use the same logic in flo_to_s to convert a float to a decimal string */ + char buf[BIGDECIMAL_DOUBLE_FIGURES + BASE_FIG + 2 + 1]; /* sizeof(buf) == 28 in the typical case */ + int decpt, negative_p; + char *e; + const int mode = digs == 0 ? 0 : 2; + char *p = BigDecimal_dtoa(d, mode, (int)digs, &decpt, &negative_p, &e); + int len10 = (int)(e - p); + if (len10 > BIGDECIMAL_DOUBLE_FIGURES) { + /* TODO: Presumably, rounding should be done here. */ + len10 = BIGDECIMAL_DOUBLE_FIGURES; + } + memcpy(buf, p, len10); + xfree(p); + + VALUE inum; + size_t RB_UNUSED_VAR(prec) = 0; + SIGNED_VALUE exp = 0; + if (decpt > 0) { + if (decpt < len10) { + /* + * len10 |---------------| + * : |-------| frac_len10 = len10 - decpt + * decpt |-------| |--| ntz10 = BASE_FIG - frac_len10 % BASE_FIG + * : : : + * 00 dd dddd.dddd dd 00 + * prec |-----.----.----.-----| prec = exp + roomof(frac_len, BASE_FIG) + * exp |-----.----| exp = roomof(decpt, BASE_FIG) + */ + const size_t frac_len10 = len10 - decpt; + const size_t ntz10 = BASE_FIG - frac_len10 % BASE_FIG; + memset(buf + len10, '0', ntz10); + buf[len10 + ntz10] = '\0'; + inum = rb_cstr_to_inum(buf, 10, false); + + exp = roomof(decpt, BASE_FIG); + prec = exp + roomof(frac_len10, BASE_FIG); + } + else { + /* + * decpt |-----------------------| + * len10 |----------| : + * : |------------| exp10 + * : : : + * 00 dd dddd dd 00 0000 0000.0 + * : : : : + * : |--| ntz10 = exp10 % BASE_FIG + * prec |-----.----.-----| : + * : |----.----| exp10 / BASE_FIG + * exp |-----.----.-----.----.----| + */ + const size_t exp10 = decpt - len10; + const size_t ntz10 = exp10 % BASE_FIG; + + memset(buf + len10, '0', ntz10); + buf[len10 + ntz10] = '\0'; + inum = rb_cstr_to_inum(buf, 10, false); + + prec = roomof(len10 + ntz10, BASE_FIG); + exp = prec + exp10 / BASE_FIG; + } + } + else if (decpt == 0) { + /* + * len10 |------------| + * : : + * 0.dddd dddd dd 00 + * : : : + * : |--| ntz10 = prec * BASE_FIG - len10 + * prec |----.----.-----| roomof(len10, BASE_FIG) + */ + prec = roomof(len10, BASE_FIG); + const size_t ntz10 = prec * BASE_FIG - len10; + + memset(buf + len10, '0', ntz10); + buf[len10 + ntz10] = '\0'; + inum = rb_cstr_to_inum(buf, 10, false); + } + else { + /* + * len10 |---------------| + * : : + * decpt |-------| |--| ntz10 = prec * BASE_FIG - nlz10 - len10 + * : : : + * 0.0000 00 dd dddd dddd dd 00 + * : : : + * nlz10 |--| : decpt % BASE_FIG + * prec |-----.----.----.-----| roomof(decpt + len10, BASE_FIG) - exp + * exp |----| decpt / BASE_FIG + */ + decpt = -decpt; + + const size_t nlz10 = decpt % BASE_FIG; + exp = decpt / BASE_FIG; + prec = roomof(decpt + len10, BASE_FIG) - exp; + const size_t ntz10 = prec * BASE_FIG - nlz10 - len10; + + if (nlz10 > 0) { + memmove(buf + nlz10, buf, len10); + memset(buf, '0', nlz10); + } + memset(buf + nlz10 + len10, '0', ntz10); + buf[nlz10 + len10 + ntz10] = '\0'; + inum = rb_cstr_to_inum(buf, 10, false); + + exp = -exp; + } + + VALUE bd = rb_inum_convert_to_BigDecimal(inum); + Real *vp; + TypedData_Get_Struct(bd, Real, &BigDecimal_data_type, vp); + assert(vp->Prec == prec); + vp->exponent = exp; + + if (negative_p) VpSetSign(vp, -1); + return bd; +} + +static VALUE +rb_rational_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception) +{ + assert(RB_TYPE_P(val, T_RATIONAL)); + + if (digs == SIZE_MAX) { + if (!raise_exception) + return Qnil; + rb_raise(rb_eArgError, + "can't omit precision for a %"PRIsVALUE".", + CLASS_OF(val)); + } + + VALUE num = rb_inum_convert_to_BigDecimal(rb_rational_num(val)); + VALUE d = BigDecimal_div2(num, rb_rational_den(val), SIZET2NUM(digs)); + return d; +} + +static VALUE +rb_cstr_convert_to_BigDecimal(const char *c_str, int raise_exception) +{ + NULLABLE_BDVALUE v = CreateFromString(c_str, rb_cBigDecimal, true, raise_exception); + if (v.bigdecimal_or_nil == Qnil) return Qnil; + return CheckGetValue(bdvalue_nonnullable(v)); +} + +static inline VALUE +rb_str_convert_to_BigDecimal(VALUE val, int raise_exception) +{ + const char *c_str = StringValueCStr(val); + return rb_cstr_convert_to_BigDecimal(c_str, raise_exception); +} + +static VALUE +rb_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception) +{ + switch (val) { + case Qnil: + case Qtrue: + case Qfalse: + if (raise_exception) { + const char *cname = NIL_P(val) ? "nil" : + val == Qtrue ? "true" : + val == Qfalse ? "false" : + NULL; + rb_raise(rb_eTypeError, + "can't convert %s into BigDecimal", cname); + } + return Qnil; + + default: + break; + } + + if (is_kind_of_BigDecimal(val)) { + if (digs == SIZE_MAX) + return check_exception(val); + + NULL_WRAPPED_VALUE null_wrapped = BigDecimal_alloc_empty_struct(rb_cBigDecimal); + Real *vp; + TypedData_Get_Struct(val, Real, &BigDecimal_data_type, vp); + vp = VpCopy(NULL, vp); + RB_GC_GUARD(val); + + VALUE copy = BigDecimal_wrap_struct(null_wrapped, vp); + /* TODO: rounding */ + return check_exception(copy); + } + else if (RB_INTEGER_TYPE_P(val)) { + return rb_inum_convert_to_BigDecimal(val); + } + else if (RB_FLOAT_TYPE_P(val)) { + return rb_float_convert_to_BigDecimal(val, digs, raise_exception); + } + else if (RB_TYPE_P(val, T_RATIONAL)) { + return rb_rational_convert_to_BigDecimal(val, digs, raise_exception); + } + else if (RB_TYPE_P(val, T_COMPLEX)) { + VALUE im = rb_complex_imag(val); + if (!is_zero(im)) { + /* TODO: handle raise_exception */ + rb_raise(rb_eArgError, + "Unable to make a BigDecimal from non-zero imaginary number"); + } + return rb_convert_to_BigDecimal(rb_complex_real(val), digs, raise_exception); + } + else if (RB_TYPE_P(val, T_STRING)) { + return rb_str_convert_to_BigDecimal(val, raise_exception); + } + + /* TODO: chheck to_d */ + /* TODO: chheck to_int */ + + VALUE str = rb_check_convert_type(val, T_STRING, "String", "to_str"); + if (!RB_TYPE_P(str, T_STRING)) { + if (raise_exception) { + rb_raise(rb_eTypeError, + "can't convert %"PRIsVALUE" into BigDecimal", rb_obj_class(val)); + } + return Qnil; + } + return rb_str_convert_to_BigDecimal(str, raise_exception); +} + +/* call-seq: + * BigDecimal(value, exception: true) -> bigdecimal + * BigDecimal(value, ndigits, exception: true) -> bigdecimal + * + * Returns the \BigDecimal converted from +value+ + * with a precision of +ndigits+ decimal digits. + * + * When +ndigits+ is less than the number of significant digits + * in the value, the result is rounded to that number of digits, + * according to the current rounding mode; see BigDecimal.mode. + * + * When +ndigits+ is 0, the number of digits to correctly represent a float number + * is determined automatically. + * + * Returns +value+ converted to a \BigDecimal, depending on the type of +value+: + * + * - Integer, Float, Rational, Complex, or BigDecimal: converted directly: + * + * # Integer, Complex, Float, or BigDecimal value does not require ndigits; ignored if given. + * BigDecimal(2) # => 0.2e1 + * BigDecimal(Complex(2, 0)) # => 0.2e1 + * BigDecimal(BigDecimal(2)) # => 0.2e1 + * BigDecimal(2.0) # => 0.2e1 + * # Rational value requires ndigits. + * BigDecimal(Rational(2, 1), 0) # => 0.2e1 + * + * - String: converted by parsing if it contains an integer or floating-point literal; + * leading and trailing whitespace is ignored: + * + * # String does not require ndigits; ignored if given. + * BigDecimal('2') # => 0.2e1 + * BigDecimal('2.0') # => 0.2e1 + * BigDecimal('0.2e1') # => 0.2e1 + * BigDecimal(' 2.0 ') # => 0.2e1 + * + * - Other type that responds to method :to_str: + * first converted to a string, then converted to a \BigDecimal, as above. + * + * - Other type: + * + * - Raises an exception if keyword argument +exception+ is +true+. + * - Returns +nil+ if keyword argument +exception+ is +false+. + * + * Raises an exception if +value+ evaluates to a Float + * and +digits+ is larger than Float::DIG + 1. + * + */ +static VALUE +f_BigDecimal(int argc, VALUE *argv, VALUE self) +{ + VALUE val, digs_v, opts = Qnil; + argc = rb_scan_args(argc, argv, "11:", &val, &digs_v, &opts); + int exception = opts_exception_p(opts); + + size_t digs = SIZE_MAX; /* this means digs is omitted */ + if (argc > 1) { + digs_v = rb_to_int(digs_v); + if (FIXNUM_P(digs_v)) { + long n = FIX2LONG(digs_v); + if (n < 0) + goto negative_digs; + digs = (size_t)n; + } + else { + if (RBIGNUM_NEGATIVE_P(digs_v)) { + negative_digs: + if (!exception) + return Qnil; + rb_raise(rb_eArgError, "negative precision"); + } + digs = NUM2SIZET(digs_v); + } + } + + return rb_convert_to_BigDecimal(val, digs, exception); +} + +/* call-seq: + * BigDecimal.interpret_loosely(string) -> bigdecimal + * + * Returns the +BigDecimal+ converted loosely from +string+. + */ + +static VALUE +BigDecimal_s_interpret_loosely(VALUE klass, VALUE str) +{ + char const *c_str = StringValueCStr(str); + NULLABLE_BDVALUE v = CreateFromString(c_str, klass, false, true); + if (v.bigdecimal_or_nil == Qnil) + return Qnil; + else + return CheckGetValue(bdvalue_nonnullable(v)); +} + + /* + * call-seq: + * BigDecimal.limit(digits) + * + * Limit the number of significant digits in newly created BigDecimal + * numbers to the specified value. Rounding is performed as necessary, + * as specified by BigDecimal.mode. + * + * A limit of 0, the default, means no upper limit. + * + * The limit specified by this method takes less priority over any limit + * specified to instance methods such as ceil, floor, truncate, or round. + */ +static VALUE +BigDecimal_limit(int argc, VALUE *argv, VALUE self) +{ + VALUE nFig; + VALUE nCur = SIZET2NUM(VpGetPrecLimit()); + + if (rb_scan_args(argc, argv, "01", &nFig) == 1) { + int nf; + if (NIL_P(nFig)) return nCur; + nf = NUM2INT(nFig); + if (nf < 0) { + rb_raise(rb_eArgError, "argument must be positive"); + } + VpSetPrecLimit(nf); + } + return nCur; +} + +/* Returns the sign of the value. + * + * Returns a positive value if > 0, a negative value if < 0. + * It behaves the same with zeros - + * it returns a positive value for a positive zero (BigDecimal('0')) and + * a negative value for a negative zero (BigDecimal('-0')). + * + * The specific value returned indicates the type and sign of the BigDecimal, + * as follows: + * + * BigDecimal::SIGN_NaN:: value is Not a Number + * BigDecimal::SIGN_POSITIVE_ZERO:: value is +0 + * BigDecimal::SIGN_NEGATIVE_ZERO:: value is -0 + * BigDecimal::SIGN_POSITIVE_INFINITE:: value is +Infinity + * BigDecimal::SIGN_NEGATIVE_INFINITE:: value is -Infinity + * BigDecimal::SIGN_POSITIVE_FINITE:: value is positive + * BigDecimal::SIGN_NEGATIVE_FINITE:: value is negative + */ +static VALUE +BigDecimal_sign(VALUE self) +{ /* sign */ + int s = GetSelfVpValue(self)->sign; + return INT2FIX(s); +} + +/* + * call-seq: BigDecimal.save_exception_mode { ... } + * + * Execute the provided block, but preserve the exception mode + * + * BigDecimal.save_exception_mode do + * BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) + * BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) + * + * BigDecimal(BigDecimal('Infinity')) + * BigDecimal(BigDecimal('-Infinity')) + * BigDecimal(BigDecimal('NaN')) + * end + * + * For use with the BigDecimal::EXCEPTION_* + * + * See BigDecimal.mode + */ +static VALUE +BigDecimal_save_exception_mode(VALUE self) +{ + unsigned short const exception_mode = VpGetException(); + int state; + VALUE ret = rb_protect(rb_yield, Qnil, &state); + VpSetException(exception_mode); + if (state) rb_jump_tag(state); + return ret; +} + +/* + * call-seq: BigDecimal.save_rounding_mode { ... } + * + * Execute the provided block, but preserve the rounding mode + * + * BigDecimal.save_rounding_mode do + * BigDecimal.mode(BigDecimal::ROUND_MODE, :up) + * puts BigDecimal.mode(BigDecimal::ROUND_MODE) + * end + * + * For use with the BigDecimal::ROUND_* + * + * See BigDecimal.mode + */ +static VALUE +BigDecimal_save_rounding_mode(VALUE self) +{ + unsigned short const round_mode = VpGetRoundMode(); + int state; + VALUE ret = rb_protect(rb_yield, Qnil, &state); + VpSetRoundMode(round_mode); + if (state) rb_jump_tag(state); + return ret; +} + +/* + * call-seq: BigDecimal.save_limit { ... } + * + * Execute the provided block, but preserve the precision limit + * + * BigDecimal.limit(100) + * puts BigDecimal.limit + * BigDecimal.save_limit do + * BigDecimal.limit(200) + * puts BigDecimal.limit + * end + * puts BigDecimal.limit + * + */ +static VALUE +BigDecimal_save_limit(VALUE self) +{ + size_t const limit = VpGetPrecLimit(); + int state; + VALUE ret = rb_protect(rb_yield, Qnil, &state); + VpSetPrecLimit(limit); + if (state) rb_jump_tag(state); + return ret; +} + +static VALUE BIGDECIMAL_NAN = Qnil; + +static VALUE +BigDecimal_nan(void) +{ + return BIGDECIMAL_NAN; +} + +static VALUE BIGDECIMAL_POSITIVE_INFINITY = Qnil; + +static VALUE +BigDecimal_positive_infinity(void) +{ + return BIGDECIMAL_POSITIVE_INFINITY; +} + +static VALUE BIGDECIMAL_NEGATIVE_INFINITY = Qnil; + +static VALUE +BigDecimal_negative_infinity(void) +{ + return BIGDECIMAL_NEGATIVE_INFINITY; +} + +static VALUE BIGDECIMAL_POSITIVE_ZERO = Qnil; + +static VALUE +BigDecimal_positive_zero(void) +{ + return BIGDECIMAL_POSITIVE_ZERO; +} + +static VALUE BIGDECIMAL_NEGATIVE_ZERO = Qnil; + +static VALUE +BigDecimal_negative_zero(void) +{ + return BIGDECIMAL_NEGATIVE_ZERO; +} + +static inline VALUE +BigDecimal_literal(const char *str) +{ + VALUE arg = rb_str_new_cstr(str); + VALUE val = f_BigDecimal(1, &arg, rb_cBigDecimal); + rb_gc_register_mark_object(val); + return val; +} + +#define BIGDECIMAL_LITERAL(var, val) (BIGDECIMAL_ ## var = BigDecimal_literal(#val)) + +#ifdef BIGDECIMAL_USE_VP_TEST_METHODS +VALUE +BigDecimal_vpdivd(VALUE self, VALUE r, VALUE cprec) { + BDVALUE a,b,c,d; + size_t cn = NUM2INT(cprec); + a = GetBDValueMust(self); + b = GetBDValueMust(r); + c = NewZeroWrap(1, cn * BASE_FIG); + d = NewZeroWrap(1, VPDIVD_REM_PREC(a.real, b.real, c.real) * BASE_FIG); + VpDivd(c.real, d.real, a.real, b.real); + RB_GC_GUARD(a.bigdecimal); + RB_GC_GUARD(b.bigdecimal); + return rb_assoc_new(c.bigdecimal, d.bigdecimal); +} + +VALUE +BigDecimal_vpmult(VALUE self, VALUE v) { + BDVALUE a,b,c; + a = GetBDValueMust(self); + b = GetBDValueMust(v); + c = NewZeroWrap(1, VPMULT_RESULT_PREC(a.real, b.real) * BASE_FIG); + VpMult(c.real, a.real, b.real); + RB_GC_GUARD(a.bigdecimal); + RB_GC_GUARD(b.bigdecimal); + return c.bigdecimal; +} +#endif /* BIGDECIMAL_USE_VP_TEST_METHODS */ + +/* Document-class: BigDecimal + * BigDecimal provides arbitrary-precision floating point decimal arithmetic. + * + * == Introduction + * + * Ruby provides built-in support for arbitrary precision integer arithmetic. + * + * For example: + * + * 42**13 #=> 1265437718438866624512 + * + * BigDecimal provides similar support for very large or very accurate floating + * point numbers. + * + * Decimal arithmetic is also useful for general calculation, because it + * provides the correct answers people expect--whereas normal binary floating + * point arithmetic often introduces subtle errors because of the conversion + * between base 10 and base 2. + * + * For example, try: + * + * sum = 0 + * 10_000.times do + * sum = sum + 0.0001 + * end + * print sum #=> 0.9999999999999062 + * + * and contrast with the output from: + * + * require 'bigdecimal' + * + * sum = BigDecimal("0") + * 10_000.times do + * sum = sum + BigDecimal("0.0001") + * end + * print sum #=> 0.1E1 + * + * Similarly: + * + * (BigDecimal("1.2") - BigDecimal("1.0")) == BigDecimal("0.2") #=> true + * + * (1.2 - 1.0) == 0.2 #=> false + * + * == A Note About Precision + * + * For a calculation using a \BigDecimal and another +value+, + * the precision of the result depends on the type of +value+: + * + * - If +value+ is a \Float, + * the precision is Float::DIG + 1. + * - If +value+ is a \Rational, the precision is larger than Float::DIG + 1. + * - If +value+ is a \BigDecimal, the precision is +value+'s precision in the + * internal representation, which is platform-dependent. + * - If +value+ is other object, the precision is determined by the result of +BigDecimal(value)+. + * + * == Special features of accurate decimal arithmetic + * + * Because BigDecimal is more accurate than normal binary floating point + * arithmetic, it requires some special values. + * + * === Infinity + * + * BigDecimal sometimes needs to return infinity, for example if you divide + * a value by zero. + * + * BigDecimal("1.0") / BigDecimal("0.0") #=> Infinity + * BigDecimal("-1.0") / BigDecimal("0.0") #=> -Infinity + * + * You can represent infinite numbers to BigDecimal using the strings + * 'Infinity', '+Infinity' and + * '-Infinity' (case-sensitive) + * + * === Not a Number + * + * When a computation results in an undefined value, the special value +NaN+ + * (for 'not a number') is returned. + * + * Example: + * + * BigDecimal("0.0") / BigDecimal("0.0") #=> NaN + * + * You can also create undefined values. + * + * NaN is never considered to be the same as any other value, even NaN itself: + * + * n = BigDecimal('NaN') + * n == 0.0 #=> false + * n == n #=> false + * + * === Positive and negative zero + * + * If a computation results in a value which is too small to be represented as + * a BigDecimal within the currently specified limits of precision, zero must + * be returned. + * + * If the value which is too small to be represented is negative, a BigDecimal + * value of negative zero is returned. + * + * BigDecimal("1.0") / BigDecimal("-Infinity") #=> -0.0 + * + * If the value is positive, a value of positive zero is returned. + * + * BigDecimal("1.0") / BigDecimal("Infinity") #=> 0.0 + * + * (See BigDecimal.mode for how to specify limits of precision.) + * + * Note that +-0.0+ and +0.0+ are considered to be the same for the purposes of + * comparison. + * + * Note also that in mathematics, there is no particular concept of negative + * or positive zero; true mathematical zero has no sign. + * + * == bigdecimal/util + * + * When you require +bigdecimal/util+, the #to_d method will be + * available on BigDecimal and the native Integer, Float, Rational, + * String, Complex, and NilClass classes: + * + * require 'bigdecimal/util' + * + * 42.to_d # => 0.42e2 + * 0.5.to_d # => 0.5e0 + * (2/3r).to_d(3) # => 0.667e0 + * "0.5".to_d # => 0.5e0 + * Complex(0.1234567, 0).to_d(4) # => 0.1235e0 + * nil.to_d # => 0.0 + * + * == Methods for Working with \JSON + * + * - {::json_create}[https://docs.ruby-lang.org/en/master/BigDecimal.html#method-c-json_create]: + * Returns a new \BigDecimal object constructed from the given object. + * - {#as_json}[https://docs.ruby-lang.org/en/master/BigDecimal.html#method-i-as_json]: + * Returns a 2-element hash representing +self+. + * - {#to_json}[https://docs.ruby-lang.org/en/master/BigDecimal.html#method-i-to_json]: + * Returns a \JSON string representing +self+. + * + * These methods are provided by the {JSON gem}[https://github.com/flori/json]. To make these methods available: + * + * require 'json/add/bigdecimal' + * + * * == License + * + * Copyright (C) 2002 by Shigeo Kobayashi . + * + * BigDecimal is released under the Ruby and 2-clause BSD licenses. + * See LICENSE.txt for details. + * + * Maintained by mrkn and ruby-core members. + * + * Documented by zzak , mathew , and + * many other contributors. + */ +void +Init_bigdecimal(void) +{ +#ifdef HAVE_RB_EXT_RACTOR_SAFE + rb_ext_ractor_safe(true); +#endif + + id_BigDecimal_exception_mode = rb_intern_const("BigDecimal.exception_mode"); + id_BigDecimal_rounding_mode = rb_intern_const("BigDecimal.rounding_mode"); + id_BigDecimal_precision_limit = rb_intern_const("BigDecimal.precision_limit"); + + /* Initialize VP routines */ + VpInit(0UL); + + /* Class and method registration */ + rb_cBigDecimal = rb_define_class("BigDecimal", rb_cNumeric); + + /* Global function */ + rb_define_global_function("BigDecimal", f_BigDecimal, -1); + + /* Class methods */ + rb_undef_alloc_func(rb_cBigDecimal); + rb_undef_method(CLASS_OF(rb_cBigDecimal), "new"); + rb_define_singleton_method(rb_cBigDecimal, "interpret_loosely", BigDecimal_s_interpret_loosely, 1); + rb_define_singleton_method(rb_cBigDecimal, "mode", BigDecimal_mode, -1); + rb_define_singleton_method(rb_cBigDecimal, "limit", BigDecimal_limit, -1); + rb_define_singleton_method(rb_cBigDecimal, "double_fig", BigDecimal_double_fig, 0); + rb_define_singleton_method(rb_cBigDecimal, "_load", BigDecimal_load, 1); + + rb_define_singleton_method(rb_cBigDecimal, "save_exception_mode", BigDecimal_save_exception_mode, 0); + rb_define_singleton_method(rb_cBigDecimal, "save_rounding_mode", BigDecimal_save_rounding_mode, 0); + rb_define_singleton_method(rb_cBigDecimal, "save_limit", BigDecimal_save_limit, 0); + + /* Constants definition */ + + /* + * The version of bigdecimal library + */ + rb_define_const(rb_cBigDecimal, "VERSION", rb_str_new2(BIGDECIMAL_VERSION)); + + /* + * Base value used in internal calculations. On a 32 bit system, BASE + * is 10000, indicating that calculation is done in groups of 4 digits. + * (If it were larger, BASE**2 wouldn't fit in 32 bits, so you couldn't + * guarantee that two groups could always be multiplied together without + * overflow.) + */ + rb_define_const(rb_cBigDecimal, "BASE", INT2FIX((SIGNED_VALUE)BASE)); + + /* Exceptions */ + + /* + * 0xff: Determines whether overflow, underflow or zero divide result in + * an exception being thrown. See BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "EXCEPTION_ALL", INT2FIX(VP_EXCEPTION_ALL)); + + /* + * 0x02: Determines what happens when the result of a computation is not a + * number (NaN). See BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "EXCEPTION_NaN", INT2FIX(VP_EXCEPTION_NaN)); + + /* + * 0x01: Determines what happens when the result of a computation is + * infinity. See BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "EXCEPTION_INFINITY", INT2FIX(VP_EXCEPTION_INFINITY)); + + /* + * 0x04: Determines what happens when the result of a computation is an + * underflow (a result too small to be represented). See BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "EXCEPTION_UNDERFLOW", INT2FIX(VP_EXCEPTION_UNDERFLOW)); + + /* + * 0x01: Determines what happens when the result of a computation is an + * overflow (a result too large to be represented). See BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "EXCEPTION_OVERFLOW", INT2FIX(VP_EXCEPTION_OVERFLOW)); + + /* + * 0x10: Determines what happens when a division by zero is performed. + * See BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "EXCEPTION_ZERODIVIDE", INT2FIX(VP_EXCEPTION_ZERODIVIDE)); + + /* + * 0x100: Determines what happens when a result must be rounded in order to + * fit in the appropriate number of significant digits. See + * BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "ROUND_MODE", INT2FIX(VP_ROUND_MODE)); + + /* 1: Indicates that values should be rounded away from zero. See + * BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "ROUND_UP", INT2FIX(VP_ROUND_UP)); + + /* 2: Indicates that values should be rounded towards zero. See + * BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "ROUND_DOWN", INT2FIX(VP_ROUND_DOWN)); + + /* 3: Indicates that digits >= 5 should be rounded up, others rounded down. + * See BigDecimal.mode. */ + rb_define_const(rb_cBigDecimal, "ROUND_HALF_UP", INT2FIX(VP_ROUND_HALF_UP)); + + /* 4: Indicates that digits >= 6 should be rounded up, others rounded down. + * See BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "ROUND_HALF_DOWN", INT2FIX(VP_ROUND_HALF_DOWN)); + /* 5: Round towards +Infinity. See BigDecimal.mode. */ + rb_define_const(rb_cBigDecimal, "ROUND_CEILING", INT2FIX(VP_ROUND_CEIL)); + + /* 6: Round towards -Infinity. See BigDecimal.mode. */ + rb_define_const(rb_cBigDecimal, "ROUND_FLOOR", INT2FIX(VP_ROUND_FLOOR)); + + /* 7: Round towards the even neighbor. See BigDecimal.mode. */ + rb_define_const(rb_cBigDecimal, "ROUND_HALF_EVEN", INT2FIX(VP_ROUND_HALF_EVEN)); + + /* 0: Indicates that a value is not a number. See BigDecimal.sign. */ + rb_define_const(rb_cBigDecimal, "SIGN_NaN", INT2FIX(VP_SIGN_NaN)); + + /* 1: Indicates that a value is +0. See BigDecimal.sign. */ + rb_define_const(rb_cBigDecimal, "SIGN_POSITIVE_ZERO", INT2FIX(VP_SIGN_POSITIVE_ZERO)); + + /* -1: Indicates that a value is -0. See BigDecimal.sign. */ + rb_define_const(rb_cBigDecimal, "SIGN_NEGATIVE_ZERO", INT2FIX(VP_SIGN_NEGATIVE_ZERO)); + + /* 2: Indicates that a value is positive and finite. See BigDecimal.sign. */ + rb_define_const(rb_cBigDecimal, "SIGN_POSITIVE_FINITE", INT2FIX(VP_SIGN_POSITIVE_FINITE)); + + /* -2: Indicates that a value is negative and finite. See BigDecimal.sign. */ + rb_define_const(rb_cBigDecimal, "SIGN_NEGATIVE_FINITE", INT2FIX(VP_SIGN_NEGATIVE_FINITE)); + + /* 3: Indicates that a value is positive and infinite. See BigDecimal.sign. */ + rb_define_const(rb_cBigDecimal, "SIGN_POSITIVE_INFINITE", INT2FIX(VP_SIGN_POSITIVE_INFINITE)); + + /* -3: Indicates that a value is negative and infinite. See BigDecimal.sign. */ + rb_define_const(rb_cBigDecimal, "SIGN_NEGATIVE_INFINITE", INT2FIX(VP_SIGN_NEGATIVE_INFINITE)); + + /* Positive zero value. */ + BIGDECIMAL_LITERAL(POSITIVE_ZERO, +0); + + /* Negative zero value. */ + BIGDECIMAL_LITERAL(NEGATIVE_ZERO, -0); + + /* Positive infinity[rdoc-ref:BigDecimal@Infinity] value. */ + rb_define_const(rb_cBigDecimal, "INFINITY", BIGDECIMAL_LITERAL(POSITIVE_INFINITY, +Infinity)); + + /* Negative infinity value. */ + BIGDECIMAL_LITERAL(NEGATIVE_INFINITY, -Infinity); + + /* '{Not a Number}[rdoc-ref:BigDecimal@Not+a+Number]' value. */ + rb_define_const(rb_cBigDecimal, "NAN", BIGDECIMAL_LITERAL(NAN, NaN)); + + /* instance methods */ + rb_define_method(rb_cBigDecimal, "precs", BigDecimal_prec, 0); + rb_define_method(rb_cBigDecimal, "precision", BigDecimal_precision, 0); + rb_define_method(rb_cBigDecimal, "scale", BigDecimal_scale, 0); + rb_define_method(rb_cBigDecimal, "precision_scale", BigDecimal_precision_scale, 0); + rb_define_method(rb_cBigDecimal, "n_significant_digits", BigDecimal_n_significant_digits, 0); + + rb_define_method(rb_cBigDecimal, "add", BigDecimal_add2, 2); + rb_define_method(rb_cBigDecimal, "sub", BigDecimal_sub2, 2); + rb_define_method(rb_cBigDecimal, "mult", BigDecimal_mult2, 2); + rb_define_method(rb_cBigDecimal, "div", BigDecimal_div3, -1); + rb_define_method(rb_cBigDecimal, "hash", BigDecimal_hash, 0); + rb_define_method(rb_cBigDecimal, "to_s", BigDecimal_to_s, -1); + rb_define_method(rb_cBigDecimal, "to_i", BigDecimal_to_i, 0); + rb_define_method(rb_cBigDecimal, "to_int", BigDecimal_to_i, 0); + rb_define_method(rb_cBigDecimal, "to_r", BigDecimal_to_r, 0); + rb_define_method(rb_cBigDecimal, "split", BigDecimal_split, 0); + rb_define_method(rb_cBigDecimal, "+", BigDecimal_add, 1); + rb_define_method(rb_cBigDecimal, "-", BigDecimal_sub, 1); + rb_define_method(rb_cBigDecimal, "+@", BigDecimal_uplus, 0); + rb_define_method(rb_cBigDecimal, "-@", BigDecimal_neg, 0); + rb_define_method(rb_cBigDecimal, "*", BigDecimal_mult, 1); + rb_define_method(rb_cBigDecimal, "/", BigDecimal_div, 1); + rb_define_method(rb_cBigDecimal, "quo", BigDecimal_quo, -1); + rb_define_method(rb_cBigDecimal, "%", BigDecimal_mod, 1); + rb_define_method(rb_cBigDecimal, "modulo", BigDecimal_mod, 1); + rb_define_method(rb_cBigDecimal, "remainder", BigDecimal_remainder, 1); + rb_define_method(rb_cBigDecimal, "divmod", BigDecimal_divmod, 1); + rb_define_method(rb_cBigDecimal, "clone", BigDecimal_clone, 0); + rb_define_method(rb_cBigDecimal, "dup", BigDecimal_clone, 0); + rb_define_method(rb_cBigDecimal, "to_f", BigDecimal_to_f, 0); + rb_define_method(rb_cBigDecimal, "abs", BigDecimal_abs, 0); + rb_define_method(rb_cBigDecimal, "fix", BigDecimal_fix, 0); + rb_define_method(rb_cBigDecimal, "round", BigDecimal_round, -1); + rb_define_method(rb_cBigDecimal, "frac", BigDecimal_frac, 0); + rb_define_method(rb_cBigDecimal, "floor", BigDecimal_floor, -1); + rb_define_method(rb_cBigDecimal, "ceil", BigDecimal_ceil, -1); + rb_define_method(rb_cBigDecimal, "<=>", BigDecimal_comp, 1); + rb_define_method(rb_cBigDecimal, "==", BigDecimal_eq, 1); + rb_define_method(rb_cBigDecimal, "===", BigDecimal_eq, 1); + rb_define_method(rb_cBigDecimal, "eql?", BigDecimal_eq, 1); + rb_define_method(rb_cBigDecimal, "<", BigDecimal_lt, 1); + rb_define_method(rb_cBigDecimal, "<=", BigDecimal_le, 1); + rb_define_method(rb_cBigDecimal, ">", BigDecimal_gt, 1); + rb_define_method(rb_cBigDecimal, ">=", BigDecimal_ge, 1); + rb_define_method(rb_cBigDecimal, "zero?", BigDecimal_zero, 0); + rb_define_method(rb_cBigDecimal, "nonzero?", BigDecimal_nonzero, 0); + rb_define_method(rb_cBigDecimal, "coerce", BigDecimal_coerce, 1); + rb_define_method(rb_cBigDecimal, "inspect", BigDecimal_inspect, 0); + rb_define_method(rb_cBigDecimal, "exponent", BigDecimal_exponent, 0); + rb_define_method(rb_cBigDecimal, "sign", BigDecimal_sign, 0); + rb_define_method(rb_cBigDecimal, "nan?", BigDecimal_IsNaN, 0); + rb_define_method(rb_cBigDecimal, "infinite?", BigDecimal_IsInfinite, 0); + rb_define_method(rb_cBigDecimal, "finite?", BigDecimal_IsFinite, 0); + rb_define_method(rb_cBigDecimal, "truncate", BigDecimal_truncate, -1); + rb_define_method(rb_cBigDecimal, "_decimal_shift", BigDecimal_decimal_shift, 1); + rb_define_method(rb_cBigDecimal, "_dump", BigDecimal_dump, -1); + +#ifdef BIGDECIMAL_USE_VP_TEST_METHODS + rb_define_method(rb_cBigDecimal, "vpdivd", BigDecimal_vpdivd, 2); + rb_define_method(rb_cBigDecimal, "vpmult", BigDecimal_vpmult, 1); +#endif /* BIGDECIMAL_USE_VP_TEST_METHODS */ + +#define ROUNDING_MODE(i, name, value) \ + id_##name = rb_intern_const(#name); \ + rbd_rounding_modes[i].id = id_##name; \ + rbd_rounding_modes[i].mode = value; + + ROUNDING_MODE(0, up, RBD_ROUND_UP); + ROUNDING_MODE(1, down, RBD_ROUND_DOWN); + ROUNDING_MODE(2, half_up, RBD_ROUND_HALF_UP); + ROUNDING_MODE(3, half_down, RBD_ROUND_HALF_DOWN); + ROUNDING_MODE(4, ceil, RBD_ROUND_CEIL); + ROUNDING_MODE(5, floor, RBD_ROUND_FLOOR); + ROUNDING_MODE(6, half_even, RBD_ROUND_HALF_EVEN); + + ROUNDING_MODE(7, default, RBD_ROUND_DEFAULT); + ROUNDING_MODE(8, truncate, RBD_ROUND_TRUNCATE); + ROUNDING_MODE(9, banker, RBD_ROUND_BANKER); + ROUNDING_MODE(10, ceiling, RBD_ROUND_CEILING); + +#undef ROUNDING_MODE + + id_to_r = rb_intern_const("to_r"); + id_eq = rb_intern_const("=="); + id_half = rb_intern_const("half"); + + (void)VPrint; /* suppress unused warning */ +} + +/* + * + * ============================================================================ + * + * vp_ routines begin from here. + * + * ============================================================================ + * + */ +#ifdef BIGDECIMAL_DEBUG +static int gfDebug = 1; /* Debug switch */ +#endif /* BIGDECIMAL_DEBUG */ + +static Real *VpConstOne; /* constant 1.0 */ + +enum op_sw { + OP_SW_ADD = 1, /* + */ + OP_SW_SUB, /* - */ + OP_SW_MULT, /* * */ + OP_SW_DIV /* / */ +}; + +static int VpIsDefOP(Real *c, Real *a, Real *b, enum op_sw sw); +static DECDIG VpAddAbs(Real *a,Real *b,Real *c); +static DECDIG VpSubAbs(Real *a,Real *b,Real *c); +static size_t VpSetPTR(Real *a, Real *b, Real *c, size_t *a_pos, size_t *b_pos, size_t *c_pos, DECDIG *av, DECDIG *bv); +static void VpFormatSt(char *psz, size_t fFmt); +static int VpRdup(Real *m, size_t ind_m); + +#ifdef BIGDECIMAL_DEBUG +# ifdef HAVE_RB_EXT_RACTOR_SAFE +# error Need to make rewiting gnAlloc atomic +# endif +static int gnAlloc = 0; /* Memory allocation counter */ +#endif /* BIGDECIMAL_DEBUG */ + +/* + * EXCEPTION Handling. + */ + +#define bigdecimal_set_thread_local_exception_mode(mode) \ + rb_thread_local_aset( \ + rb_thread_current(), \ + id_BigDecimal_exception_mode, \ + INT2FIX((int)(mode)) \ + ) + +static unsigned short +VpGetException (void) +{ + VALUE const vmode = rb_thread_local_aref( + rb_thread_current(), + id_BigDecimal_exception_mode + ); + + if (NIL_P(vmode)) { + bigdecimal_set_thread_local_exception_mode(BIGDECIMAL_EXCEPTION_MODE_DEFAULT); + return BIGDECIMAL_EXCEPTION_MODE_DEFAULT; + } + + return NUM2USHORT(vmode); +} + +static void +VpSetException(unsigned short f) +{ + bigdecimal_set_thread_local_exception_mode(f); +} + +static void +VpCheckException(Real *p, bool always) +{ + if (VpIsNaN(p)) { + VpException(VP_EXCEPTION_NaN, "Computation results in 'NaN' (Not a Number)", always); + } + else if (VpIsPosInf(p)) { + VpException(VP_EXCEPTION_INFINITY, "Computation results in 'Infinity'", always); + } + else if (VpIsNegInf(p)) { + VpException(VP_EXCEPTION_INFINITY, "Computation results in '-Infinity'", always); + } +} + +static VALUE +CheckGetValue(BDVALUE v) +{ + VpCheckException(v.real, false); + return v.bigdecimal; +} + +/* + * Precision limit. + */ + +#define bigdecimal_set_thread_local_precision_limit(limit) \ + rb_thread_local_aset( \ + rb_thread_current(), \ + id_BigDecimal_precision_limit, \ + SIZET2NUM(limit) \ + ) +#define BIGDECIMAL_PRECISION_LIMIT_DEFAULT ((size_t)0) + +/* These 2 functions added at v1.1.7 */ +VP_EXPORT size_t +VpGetPrecLimit(void) +{ + VALUE const vlimit = rb_thread_local_aref( + rb_thread_current(), + id_BigDecimal_precision_limit + ); + + if (NIL_P(vlimit)) { + bigdecimal_set_thread_local_precision_limit(BIGDECIMAL_PRECISION_LIMIT_DEFAULT); + return BIGDECIMAL_PRECISION_LIMIT_DEFAULT; + } + + return NUM2SIZET(vlimit); +} + +VP_EXPORT void +VpSetPrecLimit(size_t n) +{ + bigdecimal_set_thread_local_precision_limit(n); +} + +/* + * Rounding mode. + */ + +#define bigdecimal_set_thread_local_rounding_mode(mode) \ + rb_thread_local_aset( \ + rb_thread_current(), \ + id_BigDecimal_rounding_mode, \ + INT2FIX((int)(mode)) \ + ) + +VP_EXPORT unsigned short +VpGetRoundMode(void) +{ + VALUE const vmode = rb_thread_local_aref( + rb_thread_current(), + id_BigDecimal_rounding_mode + ); + + if (NIL_P(vmode)) { + bigdecimal_set_thread_local_rounding_mode(BIGDECIMAL_ROUNDING_MODE_DEFAULT); + return BIGDECIMAL_ROUNDING_MODE_DEFAULT; + } + + return NUM2USHORT(vmode); +} + +VP_EXPORT int +VpIsRoundMode(unsigned short n) +{ + switch (n) { + case VP_ROUND_UP: + case VP_ROUND_DOWN: + case VP_ROUND_HALF_UP: + case VP_ROUND_HALF_DOWN: + case VP_ROUND_CEIL: + case VP_ROUND_FLOOR: + case VP_ROUND_HALF_EVEN: + return 1; + + default: + return 0; + } +} + +VP_EXPORT unsigned short +VpSetRoundMode(unsigned short n) +{ + if (VpIsRoundMode(n)) { + bigdecimal_set_thread_local_rounding_mode(n); + return n; + } + + return VpGetRoundMode(); +} + +/* + * 0.0 & 1.0 generator + * These gZero_..... and gOne_..... can be any name + * referenced from nowhere except Zero() and One(). + * gZero_..... and gOne_..... must have global scope + * (to let the compiler know they may be changed in outside + * (... but not actually..)). + */ +volatile const double gOne_ABCED9B4_CE73__00400511F31D = 1.0; + +static double +One(void) +{ + return gOne_ABCED9B4_CE73__00400511F31D; +} + +/* + ---------------------------------------------------------------- + Value of sign in Real structure is reserved for future use. + short sign; + ==0 : NaN + 1 : Positive zero + -1 : Negative zero + 2 : Positive number + -2 : Negative number + 3 : Positive infinite number + -3 : Negative infinite number + ---------------------------------------------------------------- +*/ + +VP_EXPORT double +VpGetDoubleNaN(void) /* Returns the value of NaN */ +{ + return nan(""); +} + +VP_EXPORT double +VpGetDoublePosInf(void) /* Returns the value of +Infinity */ +{ + return HUGE_VAL; +} + +VP_EXPORT double +VpGetDoubleNegInf(void) /* Returns the value of -Infinity */ +{ + return -HUGE_VAL; +} + +VP_EXPORT double +VpGetDoubleNegZero(void) /* Returns the value of -0 */ +{ + static double nzero = 1000.0; + if (nzero != 0.0) nzero = (One()/VpGetDoubleNegInf()); + return nzero; +} + +VP_EXPORT int +VpException(unsigned short f, const char *str,int always) +{ + unsigned short const exception_mode = VpGetException(); + + if (f == VP_EXCEPTION_OP) always = 1; + + if (always || (exception_mode & f)) { + switch(f) { + /* case VP_EXCEPTION_OVERFLOW: */ + case VP_EXCEPTION_ZERODIVIDE: + case VP_EXCEPTION_INFINITY: + case VP_EXCEPTION_NaN: + case VP_EXCEPTION_UNDERFLOW: + case VP_EXCEPTION_OP: + rb_raise(rb_eFloatDomainError, "%s", str); + break; + default: + rb_fatal("%s", str); + } + } + return 0; /* 0 Means VpException() raised no exception */ +} + +/* Throw exception or returns 0,when resulting c is Inf or NaN */ +/* sw=1:+ 2:- 3:* 4:/ */ +static int +VpIsDefOP(Real *c, Real *a, Real *b, enum op_sw sw) +{ + if (VpIsNaN(a) || VpIsNaN(b)) { + /* at least a or b is NaN */ + VpSetNaN(c); + goto NaN; + } + + if (VpIsInf(a)) { + if (VpIsInf(b)) { + switch(sw) { + case OP_SW_ADD: /* + */ + if (VpGetSign(a) == VpGetSign(b)) { + VpSetInf(c, VpGetSign(a)); + goto Inf; + } + else { + VpSetNaN(c); + goto NaN; + } + case OP_SW_SUB: /* - */ + if (VpGetSign(a) != VpGetSign(b)) { + VpSetInf(c, VpGetSign(a)); + goto Inf; + } + else { + VpSetNaN(c); + goto NaN; + } + case OP_SW_MULT: /* * */ + VpSetInf(c, VpGetSign(a)*VpGetSign(b)); + goto Inf; + case OP_SW_DIV: /* / */ + VpSetNaN(c); + goto NaN; + } + VpSetNaN(c); + goto NaN; + } + /* Inf op Finite */ + switch(sw) { + case OP_SW_ADD: /* + */ + case OP_SW_SUB: /* - */ + VpSetInf(c, VpGetSign(a)); + break; + case OP_SW_MULT: /* * */ + if (VpIsZero(b)) { + VpSetNaN(c); + goto NaN; + } + VpSetInf(c, VpGetSign(a)*VpGetSign(b)); + break; + case OP_SW_DIV: /* / */ + VpSetInf(c, VpGetSign(a)*VpGetSign(b)); + } + goto Inf; + } + + if (VpIsInf(b)) { + switch(sw) { + case OP_SW_ADD: /* + */ + VpSetInf(c, VpGetSign(b)); + break; + case OP_SW_SUB: /* - */ + VpSetInf(c, -VpGetSign(b)); + break; + case OP_SW_MULT: /* * */ + if (VpIsZero(a)) { + VpSetNaN(c); + goto NaN; + } + VpSetInf(c, VpGetSign(a)*VpGetSign(b)); + break; + case OP_SW_DIV: /* / */ + VpSetZero(c, VpGetSign(a)*VpGetSign(b)); + } + goto Inf; + } + return 1; /* Results OK */ + +Inf: + if (VpIsPosInf(c)) { + return VpException(VP_EXCEPTION_INFINITY, "Computation results to 'Infinity'", 0); + } + else { + return VpException(VP_EXCEPTION_INFINITY, "Computation results to '-Infinity'", 0); + } + +NaN: + return VpException(VP_EXCEPTION_NaN, "Computation results to 'NaN'", 0); +} + +/* + ---------------------------------------------------------------- +*/ + +/* + * returns number of chars needed to represent vp in specified format. + */ +VP_EXPORT size_t +VpNumOfChars(Real *vp,const char *pszFmt) +{ + SIGNED_VALUE ex; + size_t nc; + + if (vp == NULL) return BASE_FIG*2+6; + if (!VpIsDef(vp)) return 32; /* not sure,may be OK */ + + switch(*pszFmt) { + case 'F': + nc = BASE_FIG*(vp->Prec + 1)+2; + ex = vp->exponent; + if (ex < 0) { + nc += BASE_FIG*(size_t)(-ex); + } + else { + if ((size_t)ex > vp->Prec) { + nc += BASE_FIG*((size_t)ex - vp->Prec); + } + } + break; + case 'E': + /* fall through */ + default: + nc = BASE_FIG * vp->Prec + 25; /* "-0."(3) + digits_chars + "e-"(2) + 64bit_exponent_chars(19) + null(1) */ + } + return nc; +} + +/* + * Initializer for Vp routines and constants used. + * [Input] + * BaseVal: Base value(assigned to BASE) for Vp calculation. + * It must be the form BaseVal=10**n.(n=1,2,3,...) + * If Base <= 0L,then the BASE will be calculated so + * that BASE is as large as possible satisfying the + * relation MaxVal <= BASE*(BASE+1). Where the value + * MaxVal is the largest value which can be represented + * by one DECDIG word in the computer used. + * + * [Returns] + * BIGDECIMAL_DOUBLE_FIGURES ... OK + */ +VP_EXPORT size_t +VpInit(DECDIG BaseVal) +{ + /* Setup +/- Inf NaN -0 */ + VpGetDoubleNegZero(); + + /* Const 1.0 */ + VpConstOne = NewZero(1, 1); + VpSetOne(VpConstOne); + +#ifdef BIGDECIMAL_DEBUG + gnAlloc = 0; +#endif /* BIGDECIMAL_DEBUG */ + + return BIGDECIMAL_DOUBLE_FIGURES; +} + +VP_EXPORT Real * +VpOne(void) +{ + return VpConstOne; +} + +/* If exponent overflows,then raise exception or returns 0 */ +static int +AddExponent(Real *a, SIGNED_VALUE n) +{ + SIGNED_VALUE e = a->exponent; + SIGNED_VALUE m = e+n; + if (e > 0 && n > 0) { + if (n > VP_EXPONENT_MAX - e) goto overflow; + } else if (e < 0 && n < 0) { + if (n < VP_EXPONENT_MIN - e) goto underflow; + } else if (m > VP_EXPONENT_MAX) { + goto overflow; + } else if (m < VP_EXPONENT_MIN) { + goto underflow; + } + a->exponent = m; + return 1; + +/* Overflow/Underflow ==> Raise exception or returns 0 */ +underflow: + VpSetZero(a, VpGetSign(a)); + return VpException(VP_EXCEPTION_UNDERFLOW, "Exponent underflow", 0); + +overflow: + VpSetInf(a, VpGetSign(a)); + return VpException(VP_EXCEPTION_OVERFLOW, "Exponent overflow", 0); +} + +Real * +bigdecimal_parse_special_string(const char *str) +{ + static const struct { + const char *str; + size_t len; + int sign; + } table[] = { + { SZ_INF, sizeof(SZ_INF) - 1, VP_SIGN_POSITIVE_INFINITE }, + { SZ_PINF, sizeof(SZ_PINF) - 1, VP_SIGN_POSITIVE_INFINITE }, + { SZ_NINF, sizeof(SZ_NINF) - 1, VP_SIGN_NEGATIVE_INFINITE }, + { SZ_NaN, sizeof(SZ_NaN) - 1, VP_SIGN_NaN } + }; + static const size_t table_length = sizeof(table) / sizeof(table[0]); + size_t i; + + for (i = 0; i < table_length; ++i) { + const char *p; + if (strncmp(str, table[i].str, table[i].len) != 0) { + continue; + } + + p = str + table[i].len; + while (*p && ISSPACE(*p)) ++p; + if (*p == '\0') { + Real *vp = rbd_allocate_struct(1); + switch (table[i].sign) { + default: + UNREACHABLE; break; + case VP_SIGN_POSITIVE_INFINITE: + VpSetPosInf(vp); + return vp; + case VP_SIGN_NEGATIVE_INFINITE: + VpSetNegInf(vp); + return vp; + case VP_SIGN_NaN: + VpSetNaN(vp); + return vp; + } + } + } + + return NULL; +} + +struct VpCtoV_args { + Real *a; + const char *int_chr; + size_t ni; + const char *frac; + size_t nf; + const char *exp_chr; + size_t ne; +}; + +static VALUE +call_VpCtoV(VALUE arg) +{ + struct VpCtoV_args *x = (struct VpCtoV_args *)arg; + return (VALUE)VpCtoV(x->a, x->int_chr, x->ni, x->frac, x->nf, x->exp_chr, x->ne); +} + +static int +protected_VpCtoV(Real *a, const char *int_chr, size_t ni, const char *frac, size_t nf, const char *exp_chr, size_t ne, int free_on_error) +{ + struct VpCtoV_args args; + int state = 0; + + args.a = a; + args.int_chr = int_chr; + args.ni = ni; + args.frac = frac; + args.nf = nf; + args.exp_chr = exp_chr; + args.ne = ne; + + VALUE result = rb_protect(call_VpCtoV, (VALUE)&args, &state); + if (state) { + if (free_on_error) { + rbd_free_struct(a); + } + rb_jump_tag(state); + } + + return (int)result; +} + +/* + * Allocates variable. + * [Input] + * szVal ... The value assigned(char). + * + * [Returns] + * Pointer to the newly allocated variable, or + * NULL be returned if memory allocation is failed,or any error. + */ +VP_EXPORT Real * +VpAlloc(const char *szVal, int strict_p, int exc) +{ + const char *orig_szVal = szVal; + size_t i, j, ni, ipf, nf, ipe, ne, exp_seen, nalloc; + char v, *psz; + int sign=1; + Real *vp = NULL; + VALUE buf; + + /* Skipping leading spaces */ + while (ISSPACE(*szVal)) szVal++; + + /* Check on Inf & NaN */ + if ((vp = bigdecimal_parse_special_string(szVal)) != NULL) { + return vp; + } + + /* Skip leading `#`. + * It used to be a mark to indicate that an extra MaxPrec should be allocated, + * but now it has no effect. + */ + if (*szVal == '#') ++szVal; + + /* Scanning digits */ + + /* A buffer for keeping scanned digits */ + buf = rb_str_tmp_new(strlen(szVal) + 1); + psz = RSTRING_PTR(buf); + + /* cursor: i for psz, and j for szVal */ + i = j = 0; + + /* Scanning: sign part */ + v = psz[i] = szVal[j]; + if ((v == '-') || (v == '+')) { + sign = -(v == '-'); + ++i; + ++j; + } + + /* Scanning: integer part */ + ni = 0; /* number of digits in the integer part */ + while ((v = psz[i] = szVal[j]) != '\0') { + if (!strict_p && ISSPACE(v)) { + v = psz[i] = '\0'; + break; + } + if (v == '_') { + if (ni > 0) { + v = szVal[j+1]; + if (v == '\0' || ISSPACE(v) || ISDIGIT(v)) { + ++j; + continue; + } + if (!strict_p) { + v = psz[i] = '\0'; + break; + } + } + goto invalid_value; + } + if (!ISDIGIT(v)) { + break; + } + ++ni; + ++i; + ++j; + } + + /* Scanning: fractional part */ + nf = 0; /* number of digits in the fractional part */ + ne = 0; /* number of digits in the exponential part */ + ipf = 0; /* index of the beginning of the fractional part */ + ipe = 0; /* index of the beginning of the exponential part */ + exp_seen = 0; + + if (v != '\0') { + /* Scanning fractional part */ + if ((psz[i] = szVal[j]) == '.') { + ++i; + ++j; + ipf = i; + while ((v = psz[i] = szVal[j]) != '\0') { + if (!strict_p && ISSPACE(v)) { + v = psz[i] = '\0'; + break; + } + if (v == '_') { + if (nf > 0 && ISDIGIT(szVal[j+1])) { + ++j; + continue; + } + if (!strict_p) { + v = psz[i] = '\0'; + break; + } + goto invalid_value; + } + if (!ISDIGIT(v)) break; + ++i; + ++j; + ++nf; + } + } + + /* Scanning exponential part */ + if (v != '\0') { + switch ((psz[i] = szVal[j])) { + case '\0': + break; + case 'e': case 'E': + case 'd': case 'D': + exp_seen = 1; + ++i; + ++j; + ipe = i; + v = psz[i] = szVal[j]; + if ((v == '-') || (v == '+')) { + ++i; + ++j; + } + while ((v = psz[i] = szVal[j]) != '\0') { + if (!strict_p && ISSPACE(v)) { + v = psz[i] = '\0'; + break; + } + if (v == '_') { + if (ne > 0 && ISDIGIT(szVal[j+1])) { + ++j; + continue; + } + if (!strict_p) { + v = psz[i] = '\0'; + if (ne == 0) { + exp_seen = 0; + } + break; + } + goto invalid_value; + } + if (!ISDIGIT(v)) break; + ++i; + ++j; + ++ne; + } + break; + default: + break; + } + } + + if (v != '\0') { + /* Scanning trailing spaces */ + while (ISSPACE(szVal[j])) ++j; + + /* Invalid character */ + if (szVal[j] && strict_p) { + goto invalid_value; + } + } + } + + psz[i] = '\0'; + + if (strict_p && ((ni == 0 && nf == 0) || (exp_seen && ne == 0))) { + VALUE str; + invalid_value: + if (!strict_p) { + return NewZero(1, 1); + } + if (!exc) { + return NULL; + } + str = rb_str_new2(orig_szVal); + rb_raise(rb_eArgError, "invalid value for BigDecimal(): \"%"PRIsVALUE"\"", str); + } + + nalloc = (ni + nf + BASE_FIG - 1) / BASE_FIG + 1; /* set effective allocation */ + /* units for szVal[] */ + vp = rbd_allocate_struct(nalloc); + VpSetZero(vp, sign); + protected_VpCtoV(vp, psz, ni, psz + ipf, nf, psz + ipe, ne, true); + rb_str_resize(buf, 0); + return vp; +} + +/* + * Assignment(c=a). + * [Input] + * a ... RHSV + * isw ... switch for assignment. + * c = a when isw > 0 + * c = -a when isw < 0 + * if c->MaxPrec < a->Prec,then round operation + * will be performed. + * [Output] + * c ... LHSV + */ +VP_EXPORT size_t +VpAsgn(Real *c, Real *a, int isw) +{ + size_t n; + if (VpIsNaN(a)) { + VpSetNaN(c); + return 0; + } + if (VpIsInf(a)) { + VpSetInf(c, isw * VpGetSign(a)); + return 0; + } + + /* check if the RHS is zero */ + if (!VpIsZero(a)) { + c->exponent = a->exponent; /* store exponent */ + VpSetSign(c, isw * VpGetSign(a)); /* set sign */ + n = (a->Prec < c->MaxPrec) ? (a->Prec) : (c->MaxPrec); + c->Prec = n; + memcpy(c->frac, a->frac, n * sizeof(DECDIG)); + /* Needs round ? */ + if (isw != 10 && isw != -10) { + /* Not in ActiveRound */ + if(c->Prec < a->Prec) { + VpInternalRound(c, n, (n>0) ? a->frac[n-1] : 0, a->frac[n]); + } + else { + VpLimitRound(c,0); + } + } + } + else { + /* The value of 'a' is zero. */ + VpSetZero(c, isw * VpGetSign(a)); + return 1; + } + return c->Prec * BASE_FIG; +} + +/* + * c = a + b when operation = 1 or 2 + * c = a - b when operation = -1 or -2. + * Returns number of significant digits of c + */ +VP_EXPORT size_t +VpAddSub(Real *c, Real *a, Real *b, int operation) +{ + short sw, isw, sign; + Real *a_ptr, *b_ptr; + size_t n, na, nb, i; + DECDIG mrv; + + if (!VpIsDefOP(c, a, b, (operation > 0) ? OP_SW_ADD : OP_SW_SUB)) return 0; /* No significant digits */ + + /* check if a or b is zero */ + if (VpIsZero(a)) { + /* a is zero,then assign b to c */ + if (!VpIsZero(b)) { + VpAsgn(c, b, operation); + } + else { + /* Both a and b are zero. */ + if (VpGetSign(a) < 0 && operation * VpGetSign(b) < 0) { + /* -0 -0 */ + VpSetZero(c, -1); + } + else { + VpSetZero(c, 1); + } + return 1; /* 0: 1 significant digits */ + } + return c->Prec * BASE_FIG; + } + if (VpIsZero(b)) { + /* b is zero,then assign a to c. */ + VpAsgn(c, a, 1); + return c->Prec*BASE_FIG; + } + + if (operation < 0) sw = -1; + else sw = 1; + + /* compare absolute value. As a result,|a_ptr|>=|b_ptr| */ + if (a->exponent > b->exponent) { + a_ptr = a; + b_ptr = b; + } /* |a|>|b| */ + else if (a->exponent < b->exponent) { + a_ptr = b; + b_ptr = a; + } /* |a|<|b| */ + else { + /* Exponent part of a and b is the same,then compare fraction */ + /* part */ + na = a->Prec; + nb = b->Prec; + n = Min(na, nb); + for (i=0; i < n; ++i) { + if (a->frac[i] > b->frac[i]) { + a_ptr = a; + b_ptr = b; + goto end_if; + } + else if (a->frac[i] < b->frac[i]) { + a_ptr = b; + b_ptr = a; + goto end_if; + } + } + if (na > nb) { + a_ptr = a; + b_ptr = b; + goto end_if; + } + else if (na < nb) { + a_ptr = b; + b_ptr = a; + goto end_if; + } + /* |a| == |b| */ + if (VpGetSign(a) + sw *VpGetSign(b) == 0) { + VpSetZero(c, 1); /* abs(a)=abs(b) and operation = '-' */ + return c->Prec * BASE_FIG; + } + a_ptr = a; + b_ptr = b; + } + +end_if: + isw = VpGetSign(a) + sw *VpGetSign(b); + /* + * isw = 0 ...( 1)+(-1),( 1)-( 1),(-1)+(1),(-1)-(-1) + * = 2 ...( 1)+( 1),( 1)-(-1) + * =-2 ...(-1)+(-1),(-1)-( 1) + * If isw==0, then c =(Sign a_ptr)(|a_ptr|-|b_ptr|) + * else c =(Sign ofisw)(|a_ptr|+|b_ptr|) + */ + if (isw) { /* addition */ + VpSetSign(c, 1); + mrv = VpAddAbs(a_ptr, b_ptr, c); + sign = isw / 2; + } + else { /* subtraction */ + VpSetSign(c, 1); + mrv = VpSubAbs(a_ptr, b_ptr, c); + sign = a_ptr == a ? VpGetSign(a) : VpGetSign(a_ptr) * sw; + } + if (VpIsInf(c)) { + VpSetInf(c, sign); + } + else { + VpSetSign(c, sign); + VpInternalRound(c, 0, (c->Prec > 0) ? c->frac[c->Prec-1] : 0, mrv); + } + + return c->Prec * BASE_FIG; +} + +/* + * Addition of two values with variable precision + * a and b assuming abs(a)>abs(b). + * c = abs(a) + abs(b) ; where |a|>=|b| + */ +static DECDIG +VpAddAbs(Real *a, Real *b, Real *c) +{ + size_t word_shift; + size_t ap; + size_t bp; + size_t cp; + size_t a_pos; + size_t b_pos, b_pos_with_word_shift; + size_t c_pos; + DECDIG av, bv, carry, mrv; + + word_shift = VpSetPTR(a, b, c, &ap, &bp, &cp, &av, &bv); + a_pos = ap; + b_pos = bp; + c_pos = cp; + + if (word_shift == (size_t)-1L) return 0; /* Overflow */ + if (b_pos == (size_t)-1L) goto Assign_a; + + mrv = av + bv; /* Most right val. Used for round. */ + + /* Just assign the last few digits of b to c because a has no */ + /* corresponding digits to be added. */ + if (b_pos > 0) { + while (b_pos > 0 && b_pos + word_shift > a_pos) { + c->frac[--c_pos] = b->frac[--b_pos]; + } + } + if (b_pos == 0 && word_shift > a_pos) { + while (word_shift-- > a_pos) { + c->frac[--c_pos] = 0; + } + } + + /* Just assign the last few digits of a to c because b has no */ + /* corresponding digits to be added. */ + b_pos_with_word_shift = b_pos + word_shift; + while (a_pos > b_pos_with_word_shift) { + c->frac[--c_pos] = a->frac[--a_pos]; + } + carry = 0; /* set first carry be zero */ + + /* Now perform addition until every digits of b will be */ + /* exhausted. */ + while (b_pos > 0) { + c->frac[--c_pos] = a->frac[--a_pos] + b->frac[--b_pos] + carry; + if (c->frac[c_pos] >= BASE) { + c->frac[c_pos] -= BASE; + carry = 1; + } + else { + carry = 0; + } + } + + /* Just assign the first few digits of a with considering */ + /* the carry obtained so far because b has been exhausted. */ + while (a_pos > 0) { + c->frac[--c_pos] = a->frac[--a_pos] + carry; + if (c->frac[c_pos] >= BASE) { + c->frac[c_pos] -= BASE; + carry = 1; + } + else { + carry = 0; + } + } + if (c_pos) c->frac[c_pos - 1] += carry; + goto Exit; + +Assign_a: + VpAsgn(c, a, 1); + mrv = 0; + +Exit: + + return mrv; +} + +/* + * c = abs(a) - abs(b) + */ +static DECDIG +VpSubAbs(Real *a, Real *b, Real *c) +{ + size_t word_shift; + size_t ap; + size_t bp; + size_t cp; + size_t a_pos; + size_t b_pos, b_pos_with_word_shift; + size_t c_pos; + DECDIG av, bv, borrow, mrv; + + word_shift = VpSetPTR(a, b, c, &ap, &bp, &cp, &av, &bv); + a_pos = ap; + b_pos = bp; + c_pos = cp; + if (word_shift == (size_t)-1L) return 0; /* Overflow */ + if (b_pos == (size_t)-1L) goto Assign_a; + + if (av >= bv) { + mrv = av - bv; + borrow = 0; + } + else { + mrv = 0; + borrow = 1; + } + + /* Just assign the values which are the BASE subtracted by */ + /* each of the last few digits of the b because the a has no */ + /* corresponding digits to be subtracted. */ + if (b_pos + word_shift > a_pos) { + while (b_pos > 0 && b_pos + word_shift > a_pos) { + c->frac[--c_pos] = BASE - b->frac[--b_pos] - borrow; + borrow = 1; + } + if (b_pos == 0) { + while (word_shift > a_pos) { + --word_shift; + c->frac[--c_pos] = BASE - borrow; + borrow = 1; + } + } + } + /* Just assign the last few digits of a to c because b has no */ + /* corresponding digits to subtract. */ + + b_pos_with_word_shift = b_pos + word_shift; + while (a_pos > b_pos_with_word_shift) { + c->frac[--c_pos] = a->frac[--a_pos]; + } + + /* Now perform subtraction until every digits of b will be */ + /* exhausted. */ + while (b_pos > 0) { + --c_pos; + if (a->frac[--a_pos] < b->frac[--b_pos] + borrow) { + c->frac[c_pos] = BASE + a->frac[a_pos] - b->frac[b_pos] - borrow; + borrow = 1; + } + else { + c->frac[c_pos] = a->frac[a_pos] - b->frac[b_pos] - borrow; + borrow = 0; + } + } + + /* Just assign the first few digits of a with considering */ + /* the borrow obtained so far because b has been exhausted. */ + while (a_pos > 0) { + --c_pos; + if (a->frac[--a_pos] < borrow) { + c->frac[c_pos] = BASE + a->frac[a_pos] - borrow; + borrow = 1; + } + else { + c->frac[c_pos] = a->frac[a_pos] - borrow; + borrow = 0; + } + } + if (c_pos) c->frac[c_pos - 1] -= borrow; + goto Exit; + +Assign_a: + VpAsgn(c, a, 1); + mrv = 0; + +Exit: + return mrv; +} + +/* + * Note: If(av+bv)>= HALF_BASE,then 1 will be added to the least significant + * digit of c(In case of addition). + * ------------------------- figure of output ----------------------------------- + * a = xxxxxxxxxxx + * b = xxxxxxxxxx + * c =xxxxxxxxxxxxxxx + * word_shift = | | + * right_word = | | (Total digits in RHSV) + * left_word = | | (Total digits in LHSV) + * a_pos = | + * b_pos = | + * c_pos = | + */ +static size_t +VpSetPTR(Real *a, Real *b, Real *c, size_t *a_pos, size_t *b_pos, size_t *c_pos, DECDIG *av, DECDIG *bv) +{ + size_t left_word, right_word, word_shift; + + size_t const round_limit = (VpGetPrecLimit() + BASE_FIG - 1) / BASE_FIG; + + assert(a->exponent >= b->exponent); + + c->frac[0] = 0; + *av = *bv = 0; + + word_shift = (a->exponent - b->exponent); + left_word = b->Prec + word_shift; + right_word = Max(a->Prec, left_word); + left_word = c->MaxPrec - 1; /* -1 ... prepare for round up */ + + /* + * check if 'round' is needed. + */ + if (right_word > left_word) { /* round ? */ + /*--------------------------------- + * Actual size of a = xxxxxxAxx + * Actual size of b = xxxBxxxxx + * Max. size of c = xxxxxx + * Round off = |-----| + * c_pos = | + * right_word = | + * a_pos = | + */ + *c_pos = right_word = left_word + 1; /* Set resulting precision */ + /* be equal to that of c */ + if (a->Prec >= c->MaxPrec) { + /* + * a = xxxxxxAxxx + * c = xxxxxx + * a_pos = | + */ + *a_pos = left_word; + if (*a_pos <= round_limit) { + *av = a->frac[*a_pos]; /* av is 'A' shown in above. */ + } + } + else { + /* + * a = xxxxxxx + * c = xxxxxxxxxx + * a_pos = | + */ + *a_pos = a->Prec; + } + if (b->Prec + word_shift >= c->MaxPrec) { + /* + * a = xxxxxxxxx + * b = xxxxxxxBxxx + * c = xxxxxxxxxxx + * b_pos = | + */ + if (c->MaxPrec >= word_shift + 1) { + *b_pos = c->MaxPrec - word_shift - 1; + if (*b_pos + word_shift <= round_limit) { + *bv = b->frac[*b_pos]; + } + } + else { + *b_pos = -1L; + } + } + else { + /* + * a = xxxxxxxxxxxxxxxx + * b = xxxxxx + * c = xxxxxxxxxxxxx + * b_pos = | + */ + *b_pos = b->Prec; + } + } + else { /* The MaxPrec of c - 1 > The Prec of a + b */ + /* + * a = xxxxxxx + * b = xxxxxx + * c = xxxxxxxxxxx + * c_pos = | + */ + *b_pos = b->Prec; + *a_pos = a->Prec; + *c_pos = right_word + 1; + } + c->Prec = *c_pos; + c->exponent = a->exponent; + if (!AddExponent(c, 1)) return (size_t)-1L; + return word_shift; +} + +/* + * Return number of significant digits + * c = a * b , Where a = a0a1a2 ... an + * b = b0b1b2 ... bm + * c = c0c1c2 ... cl + * a0 a1 ... an * bm + * a0 a1 ... an * bm-1 + * . . . + * . . . + * a0 a1 .... an * b0 + * +_____________________________ + * c0 c1 c2 ...... cl + * nc <---| + * MaxAB |--------------------| + */ +VP_EXPORT size_t +VpMult(Real *c, Real *a, Real *b) +{ + size_t MxIndA, MxIndB, MxIndAB; + size_t ind_c, i, ii, nc; + size_t ind_as, ind_ae, ind_bs; + DECDIG carry; + DECDIG_DBL s; + + if (!VpIsDefOP(c, a, b, OP_SW_MULT)) return 0; /* No significant digit */ + + if (VpIsZero(a) || VpIsZero(b)) { + /* at least a or b is zero */ + VpSetZero(c, VpGetSign(a) * VpGetSign(b)); + return 1; /* 0: 1 significant digit */ + } + + if (VpIsOne(a)) { + VpAsgn(c, b, 10 * VpGetSign(a)); + goto Exit; + } + if (VpIsOne(b)) { + VpAsgn(c, a, 10 * VpGetSign(b)); + goto Exit; + } + if (b->Prec > a->Prec) { + /* Adjust so that digits(a)>digits(b) */ + Real *w = a; + a = b; + b = w; + } + MxIndA = a->Prec - 1; + MxIndB = b->Prec - 1; + MxIndAB = a->Prec + b->Prec - 1; + + /* set LHSV c info */ + + c->exponent = a->exponent; /* set exponent */ + VpSetSign(c, VpGetSign(a) * VpGetSign(b)); /* set sign */ + if (!AddExponent(c, b->exponent)) return 0; + carry = 0; + nc = ind_c = MxIndAB; + memset(c->frac, 0, (nc + 1) * sizeof(DECDIG)); /* Initialize c */ + c->Prec = nc + 1; /* set precision */ + for (nc = 0; nc < MxIndAB; ++nc, --ind_c) { + if (nc < MxIndB) { /* The left triangle of the Fig. */ + ind_as = MxIndA - nc; + ind_ae = MxIndA; + ind_bs = MxIndB; + } + else if (nc <= MxIndA) { /* The middle rectangular of the Fig. */ + ind_as = MxIndA - nc; + ind_ae = MxIndA - (nc - MxIndB); + ind_bs = MxIndB; + } + else /* if (nc > MxIndA) */ { /* The right triangle of the Fig. */ + ind_as = 0; + ind_ae = MxIndAB - nc - 1; + ind_bs = MxIndB - (nc - MxIndA); + } + + for (i = ind_as; i <= ind_ae; ++i) { + s = (DECDIG_DBL)a->frac[i] * b->frac[ind_bs--]; + carry = (DECDIG)(s / BASE); + s -= (DECDIG_DBL)carry * BASE; + c->frac[ind_c] += (DECDIG)s; + if (c->frac[ind_c] >= BASE) { + s = c->frac[ind_c] / BASE; + carry += (DECDIG)s; + c->frac[ind_c] -= (DECDIG)(s * BASE); + } + if (carry) { + ii = ind_c; + while (ii-- > 0) { + c->frac[ii] += carry; + if (c->frac[ii] >= BASE) { + carry = c->frac[ii] / BASE; + c->frac[ii] -= (carry * BASE); + } + else { + break; + } + } + } + } + } + VpNmlz(c); + +Exit: + return c->Prec*BASE_FIG; +} + +/* + * c = a / b, remainder = r + * XXXX_YYYY_ZZZZ / 0001 = XXXX_YYYY_ZZZZ + * XXXX_YYYY_ZZZZ / 1111 = 000X_000Y_000Z + * 00XX_XXYY_YYZZ / 1000 = 0000_0XXX_XYYY + * 0001_0000_0000 / 9999 = 0000_0001_0001 + */ +VP_EXPORT size_t +VpDivd(Real *c, Real *r, Real *a, Real *b) +{ + size_t word_a, word_b, word_c, word_r; + size_t i, n, ind_a, ind_b, ind_c, ind_r; + size_t nLoop; + DECDIG_DBL q, b1, b1p1, b1b2, b1b2p1, r1r2; + DECDIG borrow1, borrow2; + DECDIG_DBL qb; + + VpSetNaN(r); + if (!VpIsDefOP(c, a, b, OP_SW_DIV)) goto Exit; + if (VpIsZero(a) && VpIsZero(b)) { + VpSetNaN(c); + return VpException(VP_EXCEPTION_NaN, "Computation results to 'NaN'", 0); + } + if (VpIsZero(b)) { + VpSetInf(c, VpGetSign(a) * VpGetSign(b)); + return VpException(VP_EXCEPTION_ZERODIVIDE, "Divide by zero", 0); + } + if (VpIsZero(a)) { + /* numerator a is zero */ + VpSetZero(c, VpGetSign(a) * VpGetSign(b)); + VpSetZero(r, VpGetSign(a) * VpGetSign(b)); + goto Exit; + } + + word_a = a->Prec; + word_b = b->Prec; + word_c = c->MaxPrec; + word_r = r->MaxPrec; + + if (word_a > word_r || word_b + word_c - 2 >= word_r) goto space_error; + + for (i = 0; i < word_a; ++i) r->frac[i] = a->frac[i]; + for (i = word_a; i < word_r; ++i) r->frac[i] = 0; + for (i = 0; i < word_c; ++i) c->frac[i] = 0; + + /* initial procedure */ + b1 = b1p1 = b->frac[0]; + if (b->Prec <= 1) { + b1b2p1 = b1b2 = b1p1 * BASE; + } + else { + b1p1 = b1 + 1; + b1b2p1 = b1b2 = b1 * BASE + b->frac[1]; + if (b->Prec > 2) ++b1b2p1; + } + + /* */ + /* loop start */ + nLoop = Min(word_c, word_r); + ind_c = 0; + while (ind_c < nLoop) { + if (r->frac[ind_c] == 0) { + ++ind_c; + continue; + } + r1r2 = (DECDIG_DBL)r->frac[ind_c] * BASE + (ind_c + 1 < word_r ? r->frac[ind_c + 1] : 0); + if (r1r2 == b1b2) { + /* The first two word digits is the same */ + ind_b = 2; + ind_a = ind_c + 2; + while (ind_b < word_b) { + if (r->frac[ind_a] < b->frac[ind_b]) goto div_b1p1; + if (r->frac[ind_a] > b->frac[ind_b]) break; + ++ind_a; + ++ind_b; + } + /* The first few word digits of r and b is the same and */ + /* the first different word digit of w is greater than that */ + /* of b, so quotient is 1. */ + q = 1; + ++c->frac[ind_c]; + ind_r = b->Prec + ind_c - 1; + goto sub_mult; + } + /* The first two word digits is not the same, */ + /* then compare magnitude, and divide actually. */ + if (r1r2 >= b1b2p1) { + q = r1r2 / b1b2p1; /* q == (DECDIG)q */ + c->frac[ind_c] += (DECDIG)q; + ind_r = b->Prec + ind_c - 1; + goto sub_mult; + } + +div_b1p1: + if (ind_c + 1 >= word_c) goto out_side; + q = r1r2 / b1p1; /* q == (DECDIG)q */ + c->frac[ind_c + 1] += (DECDIG)q; + ind_r = b->Prec + ind_c; + +sub_mult: + borrow1 = borrow2 = 0; + ind_b = word_b - 1; + if (ind_r >= word_r) goto space_error; + n = ind_b; + for (i = 0; i <= n; ++i) { + /* now, perform r = r - q * b */ + qb = q * b->frac[ind_b]; + if (qb < BASE) borrow1 = 0; + else { + borrow1 = (DECDIG)(qb / BASE); + qb -= (DECDIG_DBL)borrow1 * BASE; /* get qb < BASE */ + } + if(r->frac[ind_r] < qb) { + r->frac[ind_r] += (DECDIG)(BASE - qb); + borrow2 = borrow2 + borrow1 + 1; + } + else { + r->frac[ind_r] -= (DECDIG)qb; + borrow2 += borrow1; + } + if (borrow2) { + if(r->frac[ind_r - 1] < borrow2) { + r->frac[ind_r - 1] += (BASE - borrow2); + borrow2 = 1; + } + else { + r->frac[ind_r - 1] -= borrow2; + borrow2 = 0; + } + } + --ind_r; + --ind_b; + } + + r->frac[ind_r] -= borrow2; + } + /* End of operation, now final arrangement */ +out_side: + c->Prec = word_c; + c->exponent = a->exponent; + VpSetSign(c, VpGetSign(a) * VpGetSign(b)); + if (!AddExponent(c, 1)) return 0; + if (!AddExponent(c, -(b->exponent))) return 0; + + VpNmlz(c); /* normalize c */ + r->Prec = word_r; + r->exponent = a->exponent; + VpSetSign(r, VpGetSign(a)); + VpNmlz(r); /* normalize r(remainder) */ + goto Exit; + +space_error: + rb_bug("ERROR(VpDivd): space for remainder too small."); + +Exit: + return c->Prec * BASE_FIG; +} + +/* + * Input a = 00000xxxxxxxx En(5 preceding zeros) + * Output a = xxxxxxxx En-5 + */ +static int +VpNmlz(Real *a) +{ + size_t ind_a, i; + + if (!VpIsDef(a)) goto NoVal; + if (VpIsZero(a)) goto NoVal; + + ind_a = a->Prec; + while (ind_a--) { + if (a->frac[ind_a]) { + a->Prec = ind_a + 1; + i = 0; + while (a->frac[i] == 0) ++i; /* skip the first few zeros */ + if (i) { + a->Prec -= i; + if (!AddExponent(a, -(SIGNED_VALUE)i)) return 0; + memmove(&a->frac[0], &a->frac[i], a->Prec*sizeof(DECDIG)); + } + return 1; + } + } + /* a is zero(no non-zero digit) */ + VpSetZero(a, VpGetSign(a)); + return 0; + +NoVal: + a->frac[0] = 0; + a->Prec = 1; + return 0; +} + +/* + * VpComp = 0 ... if a=b, + * Pos ... a>b, + * Neg ... asign - b->sign; + else e = a->sign; + + if (e > 0) return 1; + else if (e < 0) return -1; + else return 0; + } + if (!VpIsDef(b)) { + e = -b->sign; + if (e > 0) return 1; + else return -1; + } + /* Zero check */ + if (VpIsZero(a)) { + if (VpIsZero(b)) return 0; /* both zero */ + val = -VpGetSign(b); + goto Exit; + } + if (VpIsZero(b)) { + val = VpGetSign(a); + goto Exit; + } + + /* compare sign */ + if (VpGetSign(a) > VpGetSign(b)) { + val = 1; /* a>b */ + goto Exit; + } + if (VpGetSign(a) < VpGetSign(b)) { + val = -1; /* aexponent > b->exponent) { + val = VpGetSign(a); + goto Exit; + } + if (a->exponent < b->exponent) { + val = -VpGetSign(b); + goto Exit; + } + + /* a and b have same exponent, then compare their significand. */ + mx = (a->Prec < b->Prec) ? a->Prec : b->Prec; + ind = 0; + while (ind < mx) { + if (a->frac[ind] > b->frac[ind]) { + val = VpGetSign(a); + goto Exit; + } + if (a->frac[ind] < b->frac[ind]) { + val = -VpGetSign(b); + goto Exit; + } + ++ind; + } + if (a->Prec > b->Prec) { + val = VpGetSign(a); + } + else if (a->Prec < b->Prec) { + val = -VpGetSign(b); + } + +Exit: + if (val > 1) val = 1; + else if (val < -1) val = -1; + + return (int)val; +} + +/* + * cntl_chr ... ASCIIZ Character, print control characters + * Available control codes: + * % ... VP variable. To print '%', use '%%'. + * \n ... new line + * \b ... backspace + * \t ... tab + * Note: % must not appear more than once + * a ... VP variable to be printed + */ +static int +VPrint(FILE *fp, const char *cntl_chr, Real *a) +{ + size_t i, j, nc, nd, ZeroSup, sep = 10; + DECDIG m, e, nn; + + j = 0; + nd = nc = 0; /* nd : number of digits in fraction part(every 10 digits, */ + /* nd<=10). */ + /* nc : number of characters printed */ + ZeroSup = 1; /* Flag not to print the leading zeros as 0.00xxxxEnn */ + while (*(cntl_chr + j)) { + if (*(cntl_chr + j) == '%' && *(cntl_chr + j + 1) != '%') { + nc = 0; + if (VpIsNaN(a)) { + fprintf(fp, SZ_NaN); + nc += 8; + } + else if (VpIsPosInf(a)) { + fprintf(fp, SZ_INF); + nc += 8; + } + else if (VpIsNegInf(a)) { + fprintf(fp, SZ_NINF); + nc += 9; + } + else if (!VpIsZero(a)) { + if (BIGDECIMAL_NEGATIVE_P(a)) { + fprintf(fp, "-"); + ++nc; + } + nc += fprintf(fp, "0."); + switch (*(cntl_chr + j + 1)) { + default: + break; + + case '0': case 'z': + ZeroSup = 0; + ++j; + sep = cntl_chr[j] == 'z' ? BIGDECIMAL_COMPONENT_FIGURES : 10; + break; + } + for (i = 0; i < a->Prec; ++i) { + m = BASE1; + e = a->frac[i]; + while (m) { + nn = e / m; + if (!ZeroSup || nn) { + nc += fprintf(fp, "%lu", (unsigned long)nn); /* The leading zero(s) */ + /* as 0.00xx will not */ + /* be printed. */ + ++nd; + ZeroSup = 0; /* Set to print succeeding zeros */ + } + if (nd >= sep) { /* print ' ' after every 10 digits */ + nd = 0; + nc += fprintf(fp, " "); + } + e = e - nn * m; + m /= 10; + } + } + nc += fprintf(fp, "E%"PRIdSIZE, VpExponent10(a)); + nc += fprintf(fp, " (%"PRIdVALUE", %"PRIuSIZE", %"PRIuSIZE")", a->exponent, a->Prec, a->MaxPrec); + } + else { + nc += fprintf(fp, "0.0"); + } + } + else { + ++nc; + if (*(cntl_chr + j) == '\\') { + switch (*(cntl_chr + j + 1)) { + case 'n': + fprintf(fp, "\n"); + ++j; + break; + case 't': + fprintf(fp, "\t"); + ++j; + break; + case 'b': + fprintf(fp, "\n"); + ++j; + break; + default: + fprintf(fp, "%c", *(cntl_chr + j)); + break; + } + } + else { + fprintf(fp, "%c", *(cntl_chr + j)); + if (*(cntl_chr + j) == '%') ++j; + } + } + j++; + } + + return (int)nc; +} + +static void +VpFormatSt(char *psz, size_t fFmt) +{ + size_t iend, idig = 0, iexp = 0, nspaces; + char *p; + + if (fFmt == 0) return; + + iend = strlen(psz); + + if ((p = strchr(psz, '.'))) { + idig = (p - psz) + 1; + } + if ((p = strchr(psz, 'E')) || (p = strchr(psz, 'e'))) { + iexp = p - psz; + } + if (idig == 0 || idig > iexp) return; + + nspaces = (iexp - idig - 1) / fFmt; + p = psz + iend + 1; + for (size_t i = nspaces; i > 0; i--) { + char *src = psz + idig + i * fFmt; + char *dst = psz + idig + i * (fFmt + 1); + memmove(dst, src, p - src); + dst[-1] = ' '; + p = src; + } +} + +VP_EXPORT ssize_t +VpExponent10(Real *a) +{ + ssize_t ex; + size_t n; + + if (!VpHasVal(a)) return 0; + + ex = a->exponent * (ssize_t)BASE_FIG; + n = BASE1; + while ((a->frac[0] / n) == 0) { + --ex; + n /= 10; + } + return ex; +} + +VP_EXPORT void +VpSzMantissa(Real *a, char *buf, size_t buflen) +{ + size_t i, n, ZeroSup; + DECDIG_DBL m, e, nn; + + if (VpIsNaN(a)) { + snprintf(buf, buflen, SZ_NaN); + return; + } + if (VpIsPosInf(a)) { + snprintf(buf, buflen, SZ_INF); + return; + } + if (VpIsNegInf(a)) { + snprintf(buf, buflen, SZ_NINF); + return; + } + + ZeroSup = 1; /* Flag not to print the leading zeros as 0.00xxxxEnn */ + if (!VpIsZero(a)) { + if (BIGDECIMAL_NEGATIVE_P(a)) *buf++ = '-'; + n = a->Prec; + for (i = 0; i < n; ++i) { + m = BASE1; + e = a->frac[i]; + while (m) { + nn = e / m; + if (!ZeroSup || nn) { + snprintf(buf, buflen, "%lu", (unsigned long)nn); /* The leading zero(s) */ + buf += strlen(buf); + /* as 0.00xx will be ignored. */ + ZeroSup = 0; /* Set to print succeeding zeros */ + } + e = e - nn * m; + m /= 10; + } + } + *buf = 0; + while (buf[-1] == '0') *(--buf) = 0; + } + else { + if (VpIsPosZero(a)) snprintf(buf, buflen, "0"); + else snprintf(buf, buflen, "-0"); + } +} + +VP_EXPORT int +VpToSpecialString(Real *a, char *buf, size_t buflen, int fPlus) +/* fPlus = 0: default, 1: set ' ' before digits, 2: set '+' before digits. */ +{ + if (VpIsNaN(a)) { + snprintf(buf, buflen, SZ_NaN); + return 1; + } + + if (VpIsPosInf(a)) { + if (fPlus == 1) { + *buf++ = ' '; + } + else if (fPlus == 2) { + *buf++ = '+'; + } + snprintf(buf, buflen, SZ_INF); + return 1; + } + if (VpIsNegInf(a)) { + snprintf(buf, buflen, SZ_NINF); + return 1; + } + if (VpIsZero(a)) { + if (VpIsPosZero(a)) { + if (fPlus == 1) snprintf(buf, buflen, " 0.0"); + else if (fPlus == 2) snprintf(buf, buflen, "+0.0"); + else snprintf(buf, buflen, "0.0"); + } + else snprintf(buf, buflen, "-0.0"); + return 1; + } + return 0; +} + +VP_EXPORT void +VpToString(Real *a, char *buf, size_t buflen, size_t fFmt, int fPlus) +/* fPlus = 0: default, 1: set ' ' before digits, 2: set '+' before digits. */ +{ + size_t i, n, ZeroSup; + DECDIG shift, m, e, nn; + char *p = buf; + size_t plen = buflen; + ssize_t ex; + + if (VpToSpecialString(a, buf, buflen, fPlus)) return; + + ZeroSup = 1; /* Flag not to print the leading zeros as 0.00xxxxEnn */ + +#define ADVANCE(n) do { \ + if (plen < n) goto overflow; \ + p += n; \ + plen -= n; \ +} while (0) + + if (BIGDECIMAL_NEGATIVE_P(a)) { + *p = '-'; + ADVANCE(1); + } + else if (fPlus == 1) { + *p = ' '; + ADVANCE(1); + } + else if (fPlus == 2) { + *p = '+'; + ADVANCE(1); + } + + *p = '0'; ADVANCE(1); + *p = '.'; ADVANCE(1); + + n = a->Prec; + for (i = 0; i < n; ++i) { + m = BASE1; + e = a->frac[i]; + while (m) { + nn = e / m; + if (!ZeroSup || nn) { + /* The reading zero(s) */ + size_t n = (size_t)snprintf(p, plen, "%lu", (unsigned long)nn); + if (n > plen) goto overflow; + ADVANCE(n); + /* as 0.00xx will be ignored. */ + ZeroSup = 0; /* Set to print succeeding zeros */ + } + e = e - nn * m; + m /= 10; + } + } + + ex = a->exponent * (ssize_t)BASE_FIG; + shift = BASE1; + while (a->frac[0] / shift == 0) { + --ex; + shift /= 10; + } + while (p - 1 > buf && p[-1] == '0') { + *(--p) = '\0'; + ++plen; + } + snprintf(p, plen, "e%"PRIdSIZE, ex); + if (fFmt) VpFormatSt(buf, fFmt); + + overflow: + return; +#undef ADVANCE +} + +VP_EXPORT void +VpToFString(Real *a, char *buf, size_t buflen, size_t fFmt, int fPlus) +/* fPlus = 0: default, 1: set ' ' before digits, 2: set '+' before digits. */ +{ + size_t i, n; + DECDIG m, e; + char *p = buf; + size_t plen = buflen, delim = fFmt; + ssize_t ex; + + if (VpToSpecialString(a, buf, buflen, fPlus)) return; + +#define APPEND(c, group) do { \ + if (plen < 1) goto overflow; \ + if (group && delim == 0) { \ + *p = ' '; \ + p += 1; \ + plen -= 1; \ + } \ + if (plen < 1) goto overflow; \ + *p = c; \ + p += 1; \ + plen -= 1; \ + if (group) delim = (delim + 1) % fFmt; \ +} while (0) + + + if (BIGDECIMAL_NEGATIVE_P(a)) { + APPEND('-', false); + } + else if (fPlus == 1) { + APPEND(' ', false); + } + else if (fPlus == 2) { + APPEND('+', false); + } + + n = a->Prec; + ex = a->exponent; + if (ex <= 0) { + APPEND('0', false); + APPEND('.', false); + } + while (ex < 0) { + for (i=0; i < BASE_FIG; ++i) { + APPEND('0', fFmt > 0); + } + ++ex; + } + + for (i = 0; i < n; ++i) { + m = BASE1; + e = a->frac[i]; + if (i == 0 && ex > 0) { + for (delim = 0; e / m == 0; delim++) { + m /= 10; + } + if (fFmt > 0) { + delim = 2*fFmt - (ex * BASE_FIG - delim) % fFmt; + } + } + while (m && (e || (i < n - 1) || ex > 0)) { + APPEND((char)(e / m + '0'), fFmt > 0); + e %= m; + m /= 10; + } + if (--ex == 0) { + APPEND('.', false); + delim = fFmt; + } + } + + while (ex > 0) { + for (i=0; i < BASE_FIG; ++i) { + APPEND('0', fFmt > 0); + } + if (--ex == 0) { + APPEND('.', false); + } + } + + *p = '\0'; + if (p - 1 > buf && p[-1] == '.') { + snprintf(p, plen, "0"); + } + + overflow: + return; +#undef APPEND +} + +/* + * [Output] + * a[] ... variable to be assigned the value. + * [Input] + * int_chr[] ... integer part(may include '+/-'). + * ni ... number of characters in int_chr[],not including '+/-'. + * frac[] ... fraction part. + * nf ... number of characters in frac[]. + * exp_chr[] ... exponent part(including '+/-'). + * ne ... number of characters in exp_chr[],not including '+/-'. + */ +VP_EXPORT int +VpCtoV(Real *a, const char *int_chr, size_t ni, const char *frac, size_t nf, const char *exp_chr, size_t ne) +{ + size_t i, j, ind_a, ma, mi, me; + SIGNED_VALUE e; + int sign, signe, exponent_overflow; + + /* get exponent part */ + e = 0; + ma = a->MaxPrec; + mi = ni; + me = ne; + signe = 1; + exponent_overflow = 0; + memset(a->frac, 0, ma * sizeof(DECDIG)); + if (ne > 0) { + i = 0; + if (exp_chr[0] == '-') { + signe = -1; + ++i; + ++me; + } + else if (exp_chr[0] == '+') { + ++i; + ++me; + } + while (i < me) { + int dig = exp_chr[i] - '0'; + if (MUL_OVERFLOW_SIGNED_VALUE_P(e, 10) || + ADD_OVERFLOW_SIGNED_VALUE_P(e * 10, signe * dig)) { + exponent_overflow = 1; + break; + } + e = e * 10 + signe * dig; + ++i; + } + } + + /* get integer part */ + i = 0; + sign = 1; + if (1 /*ni >= 0*/) { + if (int_chr[0] == '-') { + sign = -1; + ++i; + ++mi; + } + else if (int_chr[0] == '+') { + ++i; + ++mi; + } + } + /* skip leading zeros in integer part */ + while (i < mi && int_chr[i] == '0') { + ++i; + --ni; + } + + /* set actual exponent size. */ + if (ADD_OVERFLOW_SIGNED_VALUE_P(e, (SIGNED_VALUE)ni)) { + exponent_overflow = 1; + } else { + e += ni; + } + + /* Adjust the exponent so that it is the multiple of BASE_FIG. */ + j = (BASE_FIG - e % BASE_FIG) % BASE_FIG; + if (ADD_OVERFLOW_SIGNED_VALUE_P(e, (SIGNED_VALUE)j)) { + exponent_overflow = 1; + } else { + e += j; + } + + if (exponent_overflow || e < EXPONENT_MIN || e > EXPONENT_MAX) { + int zero = 1; + for ( ; i < mi && zero; i++) zero = int_chr[i] == '0'; + for (i = 0; i < nf && zero; i++) zero = frac[i] == '0'; + if (!zero && e > 0) { + VpSetInf(a, sign); + VpException(VP_EXCEPTION_INFINITY, "exponent overflow",0); + } + else VpSetZero(a, sign); + return 1; + } + + ind_a = 0; + while (i < mi) { + a->frac[ind_a] = 0; + while (j < BASE_FIG && i < mi) { + a->frac[ind_a] = a->frac[ind_a] * 10 + int_chr[i] - '0'; + ++j; + ++i; + } + if (i < mi) { + ++ind_a; + if (ind_a >= ma) goto over_flow; + j = 0; + } + } + + /* get fraction part */ + + i = 0; + while (i < nf) { + while (j < BASE_FIG && i < nf) { + a->frac[ind_a] = a->frac[ind_a] * 10 + frac[i] - '0'; + ++j; + ++i; + } + if (i < nf) { + ++ind_a; + if (ind_a >= ma) goto over_flow; + j = 0; + } + } + goto Final; + +over_flow: + rb_warn("Conversion from String to BigDecimal overflow (last few digits discarded)."); + +Final: + if (ind_a >= ma) ind_a = ma - 1; + while (j < BASE_FIG) { + a->frac[ind_a] = a->frac[ind_a] * 10; + ++j; + } + a->Prec = ind_a + 1; + a->exponent = e / (SIGNED_VALUE)BASE_FIG; + VpSetSign(a, sign); + VpNmlz(a); + return 1; +} + +/* + * [Input] + * *m ... Real + * [Output] + * *d ... fraction part of m(d = 0.xxxxxxx). where # of 'x's is fig. + * *e ... exponent of m. + * BIGDECIMAL_DOUBLE_FIGURES ... Number of digits in a double variable. + * + * m -> d*10**e, 0Prec); + *d = 0.0; + div = 1.; + while (ind_m < mm) { + div /= (double)BASE; + *d = *d + (double)m->frac[ind_m++] * div; + } + *e = m->exponent * (SIGNED_VALUE)BASE_FIG; + *d *= VpGetSign(m); + +Exit: + return f; +} + +/* + * Round relatively from the decimal point. + * f: rounding mode + * nf: digit location to round from the decimal point. + */ +VP_EXPORT int +VpMidRound(Real *y, unsigned short f, ssize_t nf) +{ + /* fracf: any positive digit under rounding position? */ + /* fracf_1further: any positive digits under one further than the rounding position? */ + /* exptoadd: number of digits needed to compensate negative nf */ + int fracf, fracf_1further; + ssize_t n,i,ix,ioffset, exptoadd; + DECDIG v, shifter; + DECDIG div; + + nf += y->exponent * (ssize_t)BASE_FIG; + exptoadd=0; + if (nf < 0) { + /* rounding position too left(large). */ + if (f != VP_ROUND_CEIL && f != VP_ROUND_FLOOR) { + VpSetZero(y, VpGetSign(y)); /* truncate everything */ + return 0; + } + exptoadd = -nf; + nf = 0; + } + + ix = nf / (ssize_t)BASE_FIG; + if ((size_t)ix >= y->Prec) return 0; /* rounding position too right(small). */ + v = y->frac[ix]; + + ioffset = nf - ix*(ssize_t)BASE_FIG; + n = (ssize_t)BASE_FIG - ioffset - 1; + for (shifter = 1, i = 0; i < n; ++i) shifter *= 10; + + /* so the representation used (in y->frac) is an array of DECDIG, where + each DECDIG contains a value between 0 and BASE-1, consisting of BASE_FIG + decimal places. + + (that numbers of decimal places are typed as ssize_t is somewhat confusing) + + nf is now position (in decimal places) of the digit from the start of + the array. + + ix is the position (in DECDIGs) of the DECDIG containing the decimal digit, + from the start of the array. + + v is the value of this DECDIG + + ioffset is the number of extra decimal places along of this decimal digit + within v. + + n is the number of decimal digits remaining within v after this decimal digit + shifter is 10**n, + + v % shifter are the remaining digits within v + v % (shifter * 10) are the digit together with the remaining digits within v + v / shifter are the digit's predecessors together with the digit + div = v / shifter / 10 is just the digit's precessors + (v / shifter) - div*10 is just the digit, which is what v ends up being reassigned to. + */ + + fracf = (v % (shifter * 10) > 0); + fracf_1further = ((v % shifter) > 0); + + v /= shifter; + div = v / 10; + v = v - div*10; + /* now v is just the digit required. + now fracf is whether the digit or any of the remaining digits within v are non-zero + now fracf_1further is whether any of the remaining digits within v are non-zero + */ + + /* now check all the remaining DECDIGs for zero-ness a whole DECDIG at a time. + if we spot any non-zeroness, that means that we found a positive digit under + rounding position, and we also found a positive digit under one further than + the rounding position, so both searches (to see if any such non-zero digit exists) + can stop */ + + for (i = ix + 1; (size_t)i < y->Prec; i++) { + if (y->frac[i] % BASE) { + fracf = fracf_1further = 1; + break; + } + } + + /* now fracf = does any positive digit exist under the rounding position? + now fracf_1further = does any positive digit exist under one further than the + rounding position? + now v = the first digit under the rounding position */ + + /* drop digits after pointed digit */ + memset(y->frac + ix + 1, 0, (y->Prec - (ix + 1)) * sizeof(DECDIG)); + + switch (f) { + case VP_ROUND_DOWN: /* Truncate */ + break; + case VP_ROUND_UP: /* Roundup */ + if (fracf) ++div; + break; + case VP_ROUND_HALF_UP: + if (v>=5) ++div; + break; + case VP_ROUND_HALF_DOWN: + if (v > 5 || (v == 5 && fracf_1further)) ++div; + break; + case VP_ROUND_CEIL: + if (fracf && BIGDECIMAL_POSITIVE_P(y)) ++div; + break; + case VP_ROUND_FLOOR: + if (fracf && BIGDECIMAL_NEGATIVE_P(y)) ++div; + break; + case VP_ROUND_HALF_EVEN: /* Banker's rounding */ + if (v > 5) ++div; + else if (v == 5) { + if (fracf_1further) { + ++div; + } + else { + if (ioffset == 0) { + /* v is the first decimal digit of its DECDIG; + need to grab the previous DECDIG if present + to check for evenness of the previous decimal + digit (which is same as that of the DECDIG since + base 10 has a factor of 2) */ + if (ix && (y->frac[ix-1] % 2)) ++div; + } + else { + if (div % 2) ++div; + } + } + } + break; + } + for (i = 0; i <= n; ++i) div *= 10; + if (div >= BASE) { + if (ix) { + y->frac[ix] = 0; + VpRdup(y, ix); + } + else { + short s = VpGetSign(y); + SIGNED_VALUE e = y->exponent; + VpSetOne(y); + VpSetSign(y, s); + y->exponent = e + 1; + } + } + else { + y->frac[ix] = div; + VpNmlz(y); + } + if (exptoadd > 0) { + y->exponent += (SIGNED_VALUE)(exptoadd / BASE_FIG); + exptoadd %= (ssize_t)BASE_FIG; + for (i = 0; i < exptoadd; i++) { + y->frac[0] *= 10; + if (y->frac[0] >= BASE) { + y->frac[0] /= BASE; + y->exponent++; + } + } + } + return 1; +} + +VP_EXPORT int +VpLeftRound(Real *y, unsigned short f, ssize_t nf) +/* + * Round from the left hand side of the digits. + */ +{ + DECDIG v; + if (!VpHasVal(y)) return 0; /* Unable to round */ + v = y->frac[0]; + nf -= y->exponent * (ssize_t)BASE_FIG; + while ((v /= 10) != 0) nf--; + nf += (ssize_t)BASE_FIG-1; + return VpMidRound(y, f, nf); +} + +VP_EXPORT int +VpActiveRound(Real *y, Real *x, unsigned short f, ssize_t nf) +{ + /* First,assign whole value in truncation mode */ + if (VpAsgn(y, x, 10) <= 1) return 0; /* Zero,NaN,or Infinity */ + return VpMidRound(y, f, nf); +} + +static int +VpLimitRound(Real *c, size_t ixDigit) +{ + size_t ix = VpGetPrecLimit(); + if (!VpNmlz(c)) return -1; + if (!ix) return 0; + if (!ixDigit) ixDigit = c->Prec-1; + if ((ix + BASE_FIG - 1) / BASE_FIG > ixDigit + 1) return 0; + return VpLeftRound(c, VpGetRoundMode(), (ssize_t)ix); +} + +/* If I understand correctly, this is only ever used to round off the final decimal + digit of precision */ +static void +VpInternalRound(Real *c, size_t ixDigit, DECDIG vPrev, DECDIG v) +{ + int f = 0; + + unsigned short const rounding_mode = VpGetRoundMode(); + + if (VpLimitRound(c, ixDigit)) return; + if (!v) return; + + v /= BASE1; + switch (rounding_mode) { + case VP_ROUND_DOWN: + break; + case VP_ROUND_UP: + if (v) f = 1; + break; + case VP_ROUND_HALF_UP: + if (v >= 5) f = 1; + break; + case VP_ROUND_HALF_DOWN: + /* this is ok - because this is the last digit of precision, + the case where v == 5 and some further digits are nonzero + will never occur */ + if (v >= 6) f = 1; + break; + case VP_ROUND_CEIL: + if (v && BIGDECIMAL_POSITIVE_P(c)) f = 1; + break; + case VP_ROUND_FLOOR: + if (v && BIGDECIMAL_NEGATIVE_P(c)) f = 1; + break; + case VP_ROUND_HALF_EVEN: /* Banker's rounding */ + /* as per VP_ROUND_HALF_DOWN, because this is the last digit of precision, + there is no case to worry about where v == 5 and some further digits are nonzero */ + if (v > 5) f = 1; + else if (v == 5 && vPrev % 2) f = 1; + break; + } + if (f) { + VpRdup(c, ixDigit); + VpNmlz(c); + } +} + +/* + * Rounds up m(plus one to final digit of m). + */ +static int +VpRdup(Real *m, size_t ind_m) +{ + DECDIG carry; + + if (!ind_m) ind_m = m->Prec; + + carry = 1; + while (carry > 0 && ind_m--) { + m->frac[ind_m] += carry; + if (m->frac[ind_m] >= BASE) m->frac[ind_m] -= BASE; + else carry = 0; + } + if (carry > 0) { /* Overflow,count exponent and set fraction part be 1 */ + if (!AddExponent(m, 1)) return 0; + m->Prec = m->frac[0] = 1; + } + else { + VpNmlz(m); + } + return 1; +} + +/* + * y = x - fix(x) + */ +VP_EXPORT void +VpFrac(Real *y, Real *x) +{ + size_t my, ind_y, ind_x; + + if (!VpHasVal(x)) { + VpAsgn(y, x, 1); + goto Exit; + } + + if (x->exponent > 0 && (size_t)x->exponent >= x->Prec) { + VpSetZero(y, VpGetSign(x)); + goto Exit; + } + else if (x->exponent <= 0) { + VpAsgn(y, x, 1); + goto Exit; + } + + /* satisfy: x->exponent > 0 */ + + y->Prec = x->Prec - (size_t)x->exponent; + y->Prec = Min(y->Prec, y->MaxPrec); + y->exponent = 0; + VpSetSign(y, VpGetSign(x)); + ind_y = 0; + my = y->Prec; + ind_x = x->exponent; + while (ind_y < my) { + y->frac[ind_y] = x->frac[ind_x]; + ++ind_y; + ++ind_x; + } + VpNmlz(y); + +Exit: + return; +} + +#ifdef BIGDECIMAL_DEBUG +int +VpVarCheck(Real * v) +/* + * Checks the validity of the Real variable v. + * [Input] + * v ... Real *, variable to be checked. + * [Returns] + * 0 ... correct v. + * other ... error + */ +{ + size_t i; + + if (v->MaxPrec == 0) { + printf("ERROR(VpVarCheck): Illegal Max. Precision(=%"PRIuSIZE")\n", + v->MaxPrec); + return 1; + } + if (v->Prec == 0 || v->Prec > v->MaxPrec) { + printf("ERROR(VpVarCheck): Illegal Precision(=%"PRIuSIZE")\n", v->Prec); + printf(" Max. Prec.=%"PRIuSIZE"\n", v->MaxPrec); + return 2; + } + for (i = 0; i < v->Prec; ++i) { + if (v->frac[i] >= BASE) { + printf("ERROR(VpVarCheck): Illegal fraction\n"); + printf(" Frac[%"PRIuSIZE"]=%"PRIuDECDIG"\n", i, v->frac[i]); + printf(" Prec. =%"PRIuSIZE"\n", v->Prec); + printf(" Exp. =%"PRIdVALUE"\n", v->exponent); + printf(" BASE =%"PRIuDECDIG"\n", BASE); + return 3; + } + } + return 0; +} +#endif /* BIGDECIMAL_DEBUG */ diff --git a/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/bigdecimal.h b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/bigdecimal.h new file mode 100644 index 0000000..82c88a2 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/bigdecimal.h @@ -0,0 +1,292 @@ +/* + * + * Ruby BigDecimal(Variable decimal precision) extension library. + * + * Copyright(C) 2002 by Shigeo Kobayashi(shigeo@tinyforest.gr.jp) + * + */ + +#ifndef RUBY_BIG_DECIMAL_H +#define RUBY_BIG_DECIMAL_H 1 + +#define RUBY_NO_OLD_COMPATIBILITY +#include "ruby/ruby.h" +#include "missing.h" + +#ifdef HAVE_FLOAT_H +# include +#endif + +#if defined(HAVE_INT64_T) && !defined(BIGDECIMAL_USE_DECDIG_UINT16_T) +# define DECDIG uint32_t +# define DECDIG_DBL uint64_t +# define DECDIG_DBL_SIGNED int64_t +# define SIZEOF_DECDIG 4 +# define PRI_DECDIG_PREFIX "" +# ifdef PRI_LL_PREFIX +# define PRI_DECDIG_DBL_PREFIX PRI_LL_PREFIX +# else +# define PRI_DECDIG_DBL_PREFIX "l" +# endif +#else +# define DECDIG uint16_t +# define DECDIG_DBL uint32_t +# define DECDIG_DBL_SIGNED int32_t +# define SIZEOF_DECDIG 2 +# define PRI_DECDIG_PREFIX "h" +# define PRI_DECDIG_DBL_PREFIX "" +#endif + +#define PRIdDECDIG PRI_DECDIG_PREFIX"d" +#define PRIiDECDIG PRI_DECDIG_PREFIX"i" +#define PRIoDECDIG PRI_DECDIG_PREFIX"o" +#define PRIuDECDIG PRI_DECDIG_PREFIX"u" +#define PRIxDECDIG PRI_DECDIG_PREFIX"x" +#define PRIXDECDIG PRI_DECDIG_PREFIX"X" + +#define PRIdDECDIG_DBL PRI_DECDIG_DBL_PREFIX"d" +#define PRIiDECDIG_DBL PRI_DECDIG_DBL_PREFIX"i" +#define PRIoDECDIG_DBL PRI_DECDIG_DBL_PREFIX"o" +#define PRIuDECDIG_DBL PRI_DECDIG_DBL_PREFIX"u" +#define PRIxDECDIG_DBL PRI_DECDIG_DBL_PREFIX"x" +#define PRIXDECDIG_DBL PRI_DECDIG_DBL_PREFIX"X" + +#if SIZEOF_DECDIG == 4 +# define BIGDECIMAL_BASE ((DECDIG)1000000000U) +# define BIGDECIMAL_COMPONENT_FIGURES 9 +/* + * The number of components required for a 64-bit integer. + * + * INT64_MAX: 9_223372036_854775807 + * UINT64_MAX: 18_446744073_709551615 + */ +# define BIGDECIMAL_INT64_MAX_LENGTH 3 + +#elif SIZEOF_DECDIG == 2 +# define BIGDECIMAL_BASE ((DECDIG)10000U) +# define BIGDECIMAL_COMPONENT_FIGURES 4 +/* + * The number of components required for a 64-bit integer. + * + * INT64_MAX: 922_3372_0368_5477_5807 + * UINT64_MAX: 1844_6744_0737_0955_1615 + */ +# define BIGDECIMAL_INT64_MAX_LENGTH 5 + +#else +# error Unknown size of DECDIG +#endif + +#define BIGDECIMAL_DOUBLE_FIGURES (1+DBL_DIG) + +#if defined(__cplusplus) +extern "C" { +#if 0 +} /* satisfy cc-mode */ +#endif +#endif + +extern VALUE rb_cBigDecimal; + +/* + * NaN & Infinity + */ +#define SZ_NaN "NaN" +#define SZ_INF "Infinity" +#define SZ_PINF "+Infinity" +#define SZ_NINF "-Infinity" + +/* + * #define VP_EXPORT other than static to let VP_ routines + * be called from outside of this module. + */ +#define VP_EXPORT static + +/* Exception mode */ +#define VP_EXCEPTION_ALL ((unsigned short)0x00FF) +#define VP_EXCEPTION_INFINITY ((unsigned short)0x0001) +#define VP_EXCEPTION_NaN ((unsigned short)0x0002) +#define VP_EXCEPTION_UNDERFLOW ((unsigned short)0x0004) +#define VP_EXCEPTION_OVERFLOW ((unsigned short)0x0001) /* 0x0008) */ +#define VP_EXCEPTION_ZERODIVIDE ((unsigned short)0x0010) + +/* Following 2 exceptions can't controlled by user */ +#define VP_EXCEPTION_OP ((unsigned short)0x0020) + +#define BIGDECIMAL_EXCEPTION_MODE_DEFAULT 0U + +/* This is used in BigDecimal#mode */ +#define VP_ROUND_MODE ((unsigned short)0x0100) + +/* Rounding mode */ +#define VP_ROUND_UP RBD_ROUND_UP +#define VP_ROUND_DOWN RBD_ROUND_DOWN +#define VP_ROUND_HALF_UP RBD_ROUND_HALF_UP +#define VP_ROUND_HALF_DOWN RBD_ROUND_HALF_DOWN +#define VP_ROUND_CEIL RBD_ROUND_CEIL +#define VP_ROUND_FLOOR RBD_ROUND_FLOOR +#define VP_ROUND_HALF_EVEN RBD_ROUND_HALF_EVEN + +enum rbd_rounding_mode { + RBD_ROUND_UP = 1, + RBD_ROUND_DOWN = 2, + RBD_ROUND_HALF_UP = 3, + RBD_ROUND_HALF_DOWN = 4, + RBD_ROUND_CEIL = 5, + RBD_ROUND_FLOOR = 6, + RBD_ROUND_HALF_EVEN = 7, + + RBD_ROUND_DEFAULT = RBD_ROUND_HALF_UP, + RBD_ROUND_TRUNCATE = RBD_ROUND_DOWN, + RBD_ROUND_BANKER = RBD_ROUND_HALF_EVEN, + RBD_ROUND_CEILING = RBD_ROUND_CEIL +}; + +#define BIGDECIMAL_ROUNDING_MODE_DEFAULT VP_ROUND_HALF_UP + +/* Sign flag */ +#define VP_SIGN_NaN 0 /* NaN */ +#define VP_SIGN_POSITIVE_ZERO 1 /* Positive zero */ +#define VP_SIGN_NEGATIVE_ZERO -1 /* Negative zero */ +#define VP_SIGN_POSITIVE_FINITE 2 /* Positive finite number */ +#define VP_SIGN_NEGATIVE_FINITE -2 /* Negative finite number */ +#define VP_SIGN_POSITIVE_INFINITE 3 /* Positive infinite number */ +#define VP_SIGN_NEGATIVE_INFINITE -3 /* Negative infinite number */ + +/* The size of fraction part array */ +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +#define FLEXIBLE_ARRAY_SIZE /* */ +#elif defined(__GNUC__) && !defined(__STRICT_ANSI__) +#define FLEXIBLE_ARRAY_SIZE 0 +#else +#define FLEXIBLE_ARRAY_SIZE 1 +#endif + +/* + * VP representation + * r = 0.xxxxxxxxx *BASE**exponent + */ +typedef struct { + size_t MaxPrec; /* Maximum precision size */ + /* This is the actual size of frac[] */ + /*(frac[0] to frac[MaxPrec] are available). */ + size_t Prec; /* Current precision size. */ + /* This indicates how much the */ + /* array frac[] is actually used. */ + SIGNED_VALUE exponent; /* Exponent part. */ + short sign; /* Attributes of the value. */ + /* + * ==0 : NaN + * 1 : Positive zero + * -1 : Negative zero + * 2 : Positive number + * -2 : Negative number + * 3 : Positive infinite number + * -3 : Negative infinite number + */ + short flag; /* Not used in vp_routines,space for user. */ + DECDIG frac[FLEXIBLE_ARRAY_SIZE]; /* Array of fraction part. */ +} Real; + +/* + * ------------------ + * EXPORTables. + * ------------------ + */ + +#define VpBaseFig() BIGDECIMAL_COMPONENT_FIGURES + +/* Zero,Inf,NaN (isinf(),isnan() used to check) */ +VP_EXPORT double VpGetDoubleNaN(void); +VP_EXPORT double VpGetDoublePosInf(void); +VP_EXPORT double VpGetDoubleNegInf(void); +VP_EXPORT double VpGetDoubleNegZero(void); + +/* These 2 functions added at v1.1.7 */ +VP_EXPORT size_t VpGetPrecLimit(void); +VP_EXPORT void VpSetPrecLimit(size_t n); + +/* Round mode */ +VP_EXPORT int VpIsRoundMode(unsigned short n); +VP_EXPORT unsigned short VpGetRoundMode(void); +VP_EXPORT unsigned short VpSetRoundMode(unsigned short n); + +VP_EXPORT int VpException(unsigned short f,const char *str,int always); +VP_EXPORT size_t VpNumOfChars(Real *vp,const char *pszFmt); +VP_EXPORT size_t VpInit(DECDIG BaseVal); +VP_EXPORT Real *VpAlloc(const char *szVal, int strict_p, int exc); +VP_EXPORT size_t VpAsgn(Real *c, Real *a, int isw); +VP_EXPORT size_t VpAddSub(Real *c,Real *a,Real *b,int operation); +VP_EXPORT size_t VpMult(Real *c,Real *a,Real *b); +VP_EXPORT size_t VpDivd(Real *c,Real *r,Real *a,Real *b); +VP_EXPORT int VpNmlz(Real *a); +VP_EXPORT int VpComp(Real *a,Real *b); +VP_EXPORT ssize_t VpExponent10(Real *a); +VP_EXPORT void VpSzMantissa(Real *a, char *buf, size_t bufsize); +VP_EXPORT int VpToSpecialString(Real *a, char *buf, size_t bufsize, int fPlus); +VP_EXPORT void VpToString(Real *a, char *buf, size_t bufsize, size_t fFmt, int fPlus); +VP_EXPORT void VpToFString(Real *a, char *buf, size_t bufsize, size_t fFmt, int fPlus); +VP_EXPORT int VpCtoV(Real *a, const char *int_chr, size_t ni, const char *frac, size_t nf, const char *exp_chr, size_t ne); +VP_EXPORT int VpVtoD(double *d, SIGNED_VALUE *e, Real *m); +VP_EXPORT int VpActiveRound(Real *y, Real *x, unsigned short f, ssize_t il); +VP_EXPORT int VpMidRound(Real *y, unsigned short f, ssize_t nf); +VP_EXPORT int VpLeftRound(Real *y, unsigned short f, ssize_t nf); +VP_EXPORT void VpFrac(Real *y, Real *x); + +/* VP constants */ +VP_EXPORT Real *VpOne(void); + +/* + * ------------------ + * MACRO definitions. + * ------------------ + */ +#define Abs(a) (((a)>= 0)?(a):(-(a))) +#define Max(a, b) (((a)>(b))?(a):(b)) +#define Min(a, b) (((a)>(b))?(b):(a)) + +/* Sign */ + +/* VpGetSign(a) returns 1,-1 if a>0,a<0 respectively */ +#define VpGetSign(a) (((a)->sign>0)?1:(-1)) +/* Change sign of a to a>0,a<0 if s = 1,-1 respectively */ +#define VpChangeSign(a,s) {if((s)>0) (a)->sign=(short)Abs((ssize_t)(a)->sign);else (a)->sign=-(short)Abs((ssize_t)(a)->sign);} +/* Sets sign of a to a>0,a<0 if s = 1,-1 respectively */ +#define VpSetSign(a,s) {if((s)>0) (a)->sign=(short)VP_SIGN_POSITIVE_FINITE;else (a)->sign=(short)VP_SIGN_NEGATIVE_FINITE;} + +/* 1 */ +#define VpSetOne(a) {(a)->Prec=(a)->exponent=(a)->frac[0]=1;(a)->sign=VP_SIGN_POSITIVE_FINITE;} + +/* ZEROs */ +#define VpIsPosZero(a) ((a)->sign==VP_SIGN_POSITIVE_ZERO) +#define VpIsNegZero(a) ((a)->sign==VP_SIGN_NEGATIVE_ZERO) +#define VpIsZero(a) (VpIsPosZero(a) || VpIsNegZero(a)) +#define VpSetPosZero(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_POSITIVE_ZERO) +#define VpSetNegZero(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_NEGATIVE_ZERO) +#define VpSetZero(a,s) (void)(((s)>0)?VpSetPosZero(a):VpSetNegZero(a)) + +/* NaN */ +#define VpIsNaN(a) ((a)->sign==VP_SIGN_NaN) +#define VpSetNaN(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_NaN) + +/* Infinity */ +#define VpIsPosInf(a) ((a)->sign==VP_SIGN_POSITIVE_INFINITE) +#define VpIsNegInf(a) ((a)->sign==VP_SIGN_NEGATIVE_INFINITE) +#define VpIsInf(a) (VpIsPosInf(a) || VpIsNegInf(a)) +#define VpIsDef(a) ( !(VpIsNaN(a)||VpIsInf(a)) ) +#define VpSetPosInf(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_POSITIVE_INFINITE) +#define VpSetNegInf(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_NEGATIVE_INFINITE) +#define VpSetInf(a,s) (void)(((s)>0)?VpSetPosInf(a):VpSetNegInf(a)) +#define VpHasVal(a) (a->frac[0]) +#define VpIsOne(a) ((a->Prec==1)&&(a->frac[0]==1)&&(a->exponent==1)) +#ifdef BIGDECIMAL_DEBUG +int VpVarCheck(Real * v); +#endif /* BIGDECIMAL_DEBUG */ + +#if defined(__cplusplus) +#if 0 +{ /* satisfy cc-mode */ +#endif +} /* extern "C" { */ +#endif +#endif /* RUBY_BIG_DECIMAL_H */ diff --git a/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/bits.h b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/bits.h new file mode 100644 index 0000000..66efce4 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/bits.h @@ -0,0 +1,144 @@ +#ifndef BIGDECIMAL_BITS_H +#define BIGDECIMAL_BITS_H + +#include "feature.h" +#include "static_assert.h" + +#if defined(__x86_64__) && defined(HAVE_X86INTRIN_H) +# include /* for _lzcnt_u64, etc. */ +#elif defined(_MSC_VER) && defined(HAVE_INTRIN_H) +# include /* for the following intrinsics */ +#endif + +#if defined(_MSC_VER) && defined(__AVX2__) +# pragma intrinsic(__lzcnt) +# pragma intrinsic(__lzcnt64) +#endif + +#define numberof(array) ((int)(sizeof(array) / sizeof((array)[0]))) +#define roomof(x, y) (((x) + (y) - 1) / (y)) +#define type_roomof(x, y) roomof(sizeof(x), sizeof(y)) + +#define MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, min, max) ( \ + (a) == 0 ? 0 : \ + (a) == -1 ? (b) < -(max) : \ + (a) > 0 ? \ + ((b) > 0 ? (max) / (a) < (b) : (min) / (a) > (b)) : \ + ((b) > 0 ? (min) / (a) < (b) : (max) / (a) > (b))) + +#define ADD_OVERFLOW_SIGNED_INTEGER_P(a, b, min, max) ( \ + ((a) > 0) == ((b) > 0) && ((a) > 0 ? (max) - (a) < (b) : (min) - (a) > (b))) + +#ifdef HAVE_UINT128_T +# define bit_length(x) \ + (unsigned int) \ + (sizeof(x) <= sizeof(int32_t) ? 32 - nlz_int32((uint32_t)(x)) : \ + sizeof(x) <= sizeof(int64_t) ? 64 - nlz_int64((uint64_t)(x)) : \ + 128 - nlz_int128((uint128_t)(x))) +#else +# define bit_length(x) \ + (unsigned int) \ + (sizeof(x) <= sizeof(int32_t) ? 32 - nlz_int32((uint32_t)(x)) : \ + 64 - nlz_int64((uint64_t)(x))) +#endif + +static inline unsigned nlz_int32(uint32_t x); +static inline unsigned nlz_int64(uint64_t x); +#ifdef HAVE_UINT128_T +static inline unsigned nlz_int128(uint128_t x); +#endif + +static inline unsigned int +nlz_int32(uint32_t x) +{ +#if defined(_MSC_VER) && defined(__AVX2__) && defined(HAVE___LZCNT) + /* Note: It seems there is no such thing like __LZCNT__ predefined in MSVC. + * AMD CPUs have had this instruction for decades (since K10) but for + * Intel, Haswell is the oldest one. We need to use __AVX2__ for maximum + * safety. */ + return (unsigned int)__lzcnt(x); + +#elif defined(__x86_64__) && defined(__LZCNT__) && defined(HAVE__LZCNT_U32) + return (unsigned int)_lzcnt_u32(x); + +#elif defined(_MSC_VER) && defined(HAVE__BITSCANREVERSE) + unsigned long r; + return _BitScanReverse(&r, x) ? (31 - (int)r) : 32; + +#elif __has_builtin(__builtin_clz) + STATIC_ASSERT(sizeof_int, sizeof(int) * CHAR_BIT == 32); + return x ? (unsigned int)__builtin_clz(x) : 32; + +#else + uint32_t y; + unsigned n = 32; + y = x >> 16; if (y) {n -= 16; x = y;} + y = x >> 8; if (y) {n -= 8; x = y;} + y = x >> 4; if (y) {n -= 4; x = y;} + y = x >> 2; if (y) {n -= 2; x = y;} + y = x >> 1; if (y) {return n - 2;} + return (unsigned int)(n - x); +#endif +} + +static inline unsigned int +nlz_int64(uint64_t x) +{ +#if defined(_MSC_VER) && defined(__AVX2__) && defined(HAVE___LZCNT64) + return (unsigned int)__lzcnt64(x); + +#elif defined(__x86_64__) && defined(__LZCNT__) && defined(HAVE__LZCNT_U64) + return (unsigned int)_lzcnt_u64(x); + +#elif defined(_WIN64) && defined(_MSC_VER) && defined(HAVE__BITSCANREVERSE64) + unsigned long r; + return _BitScanReverse64(&r, x) ? (63u - (unsigned int)r) : 64; + +#elif __has_builtin(__builtin_clzl) && __has_builtin(__builtin_clzll) && !(defined(__sun) && defined(__sparc)) + if (x == 0) { + return 64; + } + else if (sizeof(long) * CHAR_BIT == 64) { + return (unsigned int)__builtin_clzl((unsigned long)x); + } + else if (sizeof(long long) * CHAR_BIT == 64) { + return (unsigned int)__builtin_clzll((unsigned long long)x); + } + else { + /* :FIXME: Is there a way to make this branch a compile-time error? */ + __builtin_unreachable(); + } + +#else + uint64_t y; + unsigned int n = 64; + y = x >> 32; if (y) {n -= 32; x = y;} + y = x >> 16; if (y) {n -= 16; x = y;} + y = x >> 8; if (y) {n -= 8; x = y;} + y = x >> 4; if (y) {n -= 4; x = y;} + y = x >> 2; if (y) {n -= 2; x = y;} + y = x >> 1; if (y) {return n - 2;} + return (unsigned int)(n - x); + +#endif +} + +#ifdef HAVE_UINT128_T +static inline unsigned int +nlz_int128(uint128_t x) +{ + uint64_t y = (uint64_t)(x >> 64); + + if (x == 0) { + return 128; + } + else if (y == 0) { + return (unsigned int)nlz_int64(x) + 64; + } + else { + return (unsigned int)nlz_int64(y); + } +} +#endif + +#endif /* BIGDECIMAL_BITS_H */ diff --git a/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/extconf.rb b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/extconf.rb new file mode 100644 index 0000000..0fcc7c9 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/extconf.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: false +require 'mkmf' + +def have_builtin_func(name, check_expr, opt = "", &b) + checking_for checking_message(name.funcall_style, nil, opt) do + if try_compile(< +#endif + +#ifdef RBIMPL_HAS_BUILTIN +# define BIGDECIMAL_HAS_BUILTIN(...) RBIMPL_HAS_BUILTIN(__VA_ARGS__) + +#else +# /* The following section is copied from CRuby's builtin.h */ +# +# ifdef __has_builtin +# if defined(__INTEL_COMPILER) +# /* :TODO: Intel C Compiler has __has_builtin (since 19.1 maybe?), and is +# * reportedly broken. We have to skip them. However the situation can +# * change. They might improve someday. We need to revisit here later. */ +# elif defined(__GNUC__) && ! __has_builtin(__builtin_alloca) +# /* FreeBSD's defines its own *broken* version of +# * __has_builtin. Cygwin copied that content to be a victim of the +# * broken-ness. We don't take them into account. */ +# else +# define HAVE___HAS_BUILTIN 1 +# endif +# endif +# +# if defined(HAVE___HAS_BUILTIN) +# define BIGDECIMAL_HAS_BUILTIN(_) __has_builtin(_) +# +# elif defined(__GNUC__) +# define BIGDECIMAL_HAS_BUILTIN(_) BIGDECIMAL_HAS_BUILTIN_ ## _ +# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 6)) +# define BIGDECIMAL_HAS_BUILTIN___builtin_clz 1 +# define BIGDECIMAL_HAS_BUILTIN___builtin_clzl 1 +# else +# define BIGDECIMAL_HAS_BUILTIN___builtin_clz 0 +# define BIGDECIMAL_HAS_BUILTIN___builtin_clzl 0 +# endif +# elif defined(_MSC_VER) +# define BIGDECIMAL_HAS_BUILTIN(_) 0 +# +# else +# define BIGDECIMAL_HAS_BUILTIN(_) BIGDECIMAL_HAS_BUILTIN_ ## _ +# define BIGDECIMAL_HAS_BUILTIN___builtin_clz HAVE_BUILTIN___BUILTIN_CLZ +# define BIGDECIMAL_HAS_BUILTIN___builtin_clzl HAVE_BUILTIN___BUILTIN_CLZL +# endif +#endif /* RBIMPL_HAS_BUILTIN */ + +#ifndef __has_builtin +# define __has_builtin(...) BIGDECIMAL_HAS_BUILTIN(__VA_ARGS__) +#endif + +#endif /* BIGDECIMAL_HAS_FEATURE_H */ diff --git a/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/missing.c b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/missing.c new file mode 100644 index 0000000..1454c28 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/missing.c @@ -0,0 +1,28 @@ +#include + +#ifdef HAVE_RUBY_ATOMIC_H +# include +#endif + +#ifdef RUBY_ATOMIC_PTR_CAS +# define ATOMIC_PTR_CAS(var, old, new) RUBY_ATOMIC_PTR_CAS(var, old, new) +#endif + +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +/* GCC warns about unknown sanitizer, which is annoying. */ +# undef NO_SANITIZE +# define NO_SANITIZE(x, y) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wattributes\"") \ + __attribute__((__no_sanitize__(x))) y; \ + _Pragma("GCC diagnostic pop") \ + y +#endif + +#undef strtod +#define strtod BigDecimal_strtod +#undef dtoa +#define dtoa BigDecimal_dtoa +#undef hdtoa +#define hdtoa BigDecimal_hdtoa +#include "missing/dtoa.c" diff --git a/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/missing.h b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/missing.h new file mode 100644 index 0000000..e8a8cab --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/missing.h @@ -0,0 +1,104 @@ +#ifndef MISSING_H +#define MISSING_H 1 + +#if defined(__cplusplus) +extern "C" { +#if 0 +} /* satisfy cc-mode */ +#endif +#endif + +#ifndef RB_UNUSED_VAR +# if defined(_MSC_VER) && _MSC_VER >= 1911 +# define RB_UNUSED_VAR(x) x [[maybe_unused]] + +# elif defined(__has_cpp_attribute) && __has_cpp_attribute(maybe_unused) +# define RB_UNUSED_VAR(x) x [[maybe_unused]] + +# elif defined(__has_c_attribute) && __has_c_attribute(maybe_unused) +# define RB_UNUSED_VAR(x) x [[maybe_unused]] + +# elif defined(__GNUC__) +# define RB_UNUSED_VAR(x) x __attribute__ ((unused)) + +# else +# define RB_UNUSED_VAR(x) x +# endif +#endif /* RB_UNUSED_VAR */ + +#if defined(_MSC_VER) && _MSC_VER >= 1310 +# define HAVE___ASSUME 1 + +#elif defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1300 +# define HAVE___ASSUME 1 +#endif + +#ifndef UNREACHABLE +# if __has_builtin(__builtin_unreachable) +# define UNREACHABLE __builtin_unreachable() + +# elif defined(HAVE___ASSUME) +# define UNREACHABLE __assume(0) + +# else +# define UNREACHABLE /* unreachable */ +# endif +#endif /* UNREACHABLE */ + +/* bool */ + +#ifndef __bool_true_false_are_defined +# include +#endif + +/* dtoa */ +char *BigDecimal_dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve); + +/* complex */ + +#ifndef HAVE_RB_COMPLEX_REAL +static inline VALUE +rb_complex_real(VALUE cmp) +{ +#ifdef RCOMPLEX + return RCOMPLEX(cmp)->real; +#else + return rb_funcall(cmp, rb_intern("real"), 0); +#endif +} +#endif + +#ifndef HAVE_RB_COMPLEX_IMAG +static inline VALUE +rb_complex_imag(VALUE cmp) +{ +# ifdef RCOMPLEX + return RCOMPLEX(cmp)->imag; +# else + return rb_funcall(cmp, rb_intern("imag"), 0); +# endif +} +#endif + +/* st */ + +#ifndef ST2FIX +# undef RB_ST2FIX +# define RB_ST2FIX(h) LONG2FIX((long)(h)) +# define ST2FIX(h) RB_ST2FIX(h) +#endif + +/* warning */ + +#if !defined(HAVE_RB_CATEGORY_WARN) || !defined(HAVE_CONST_RB_WARN_CATEGORY_DEPRECATED) +# define rb_category_warn(category, ...) rb_warn(__VA_ARGS__) +#endif + +#if defined(__cplusplus) +#if 0 +{ /* satisfy cc-mode */ +#endif +} /* extern "C" { */ +#endif + +#endif /* MISSING_H */ diff --git a/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/missing/dtoa.c b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/missing/dtoa.c new file mode 100644 index 0000000..41b0a22 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/missing/dtoa.c @@ -0,0 +1,3462 @@ +/**************************************************************** + * + * The author of this software is David M. Gay. + * + * Copyright (c) 1991, 2000, 2001 by Lucent Technologies. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + * + ***************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +/* On a machine with IEEE extended-precision registers, it is + * necessary to specify double-precision (53-bit) rounding precision + * before invoking strtod or dtoa. If the machine uses (the equivalent + * of) Intel 80x87 arithmetic, the call + * _control87(PC_53, MCW_PC); + * does this with many compilers. Whether this or another call is + * appropriate depends on the compiler; for this to work, it may be + * necessary to #include "float.h" or another system-dependent header + * file. + */ + +/* strtod for IEEE-, VAX-, and IBM-arithmetic machines. + * + * This strtod returns a nearest machine number to the input decimal + * string (or sets errno to ERANGE). With IEEE arithmetic, ties are + * broken by the IEEE round-even rule. Otherwise ties are broken by + * biased rounding (add half and chop). + * + * Inspired loosely by William D. Clinger's paper "How to Read Floating + * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. + * + * Modifications: + * + * 1. We only require IEEE, IBM, or VAX double-precision + * arithmetic (not IEEE double-extended). + * 2. We get by with floating-point arithmetic in a case that + * Clinger missed -- when we're computing d * 10^n + * for a small integer d and the integer n is not too + * much larger than 22 (the maximum integer k for which + * we can represent 10^k exactly), we may be able to + * compute (d*10^k) * 10^(e-k) with just one roundoff. + * 3. Rather than a bit-at-a-time adjustment of the binary + * result in the hard case, we use floating-point + * arithmetic to determine the adjustment to within + * one bit; only in really hard cases do we need to + * compute a second residual. + * 4. Because of 3., we don't need a large table of powers of 10 + * for ten-to-e (just some small tables, e.g. of 10^k + * for 0 <= k <= 22). + */ + +/* + * #define IEEE_LITTLE_ENDIAN for IEEE-arithmetic machines where the least + * significant byte has the lowest address. + * #define IEEE_BIG_ENDIAN for IEEE-arithmetic machines where the most + * significant byte has the lowest address. + * #define Long int on machines with 32-bit ints and 64-bit longs. + * #define IBM for IBM mainframe-style floating-point arithmetic. + * #define VAX for VAX-style floating-point arithmetic (D_floating). + * #define No_leftright to omit left-right logic in fast floating-point + * computation of dtoa. + * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 + * and strtod and dtoa should round accordingly. + * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 + * and Honor_FLT_ROUNDS is not #defined. + * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines + * that use extended-precision instructions to compute rounded + * products and quotients) with IBM. + * #define ROUND_BIASED for IEEE-format with biased rounding. + * #define Inaccurate_Divide for IEEE-format with correctly rounded + * products but inaccurate quotients, e.g., for Intel i860. + * #define NO_LONG_LONG on machines that do not have a "long long" + * integer type (of >= 64 bits). On such machines, you can + * #define Just_16 to store 16 bits per 32-bit Long when doing + * high-precision integer arithmetic. Whether this speeds things + * up or slows things down depends on the machine and the number + * being converted. If long long is available and the name is + * something other than "long long", #define Llong to be the name, + * and if "unsigned Llong" does not work as an unsigned version of + * Llong, #define #ULLong to be the corresponding unsigned type. + * #define KR_headers for old-style C function headers. + * #define Bad_float_h if your system lacks a float.h or if it does not + * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, + * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. + * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) + * if memory is available and otherwise does something you deem + * appropriate. If MALLOC is undefined, malloc will be invoked + * directly -- and assumed always to succeed. + * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making + * memory allocations from a private pool of memory when possible. + * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes, + * unless #defined to be a different length. This default length + * suffices to get rid of MALLOC calls except for unusual cases, + * such as decimal-to-binary conversion of a very long string of + * digits. The longest string dtoa can return is about 751 bytes + * long. For conversions by strtod of strings of 800 digits and + * all dtoa conversions in single-threaded executions with 8-byte + * pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte + * pointers, PRIVATE_MEM >= 7112 appears adequate. + * #define INFNAN_CHECK on IEEE systems to cause strtod to check for + * Infinity and NaN (case insensitively). On some systems (e.g., + * some HP systems), it may be necessary to #define NAN_WORD0 + * appropriately -- to the most significant word of a quiet NaN. + * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) + * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined, + * strtod also accepts (case insensitively) strings of the form + * NaN(x), where x is a string of hexadecimal digits and spaces; + * if there is only one string of hexadecimal digits, it is taken + * for the 52 fraction bits of the resulting NaN; if there are two + * or more strings of hex digits, the first is for the high 20 bits, + * the second and subsequent for the low 32 bits, with intervening + * white space ignored; but if this results in none of the 52 + * fraction bits being on (an IEEE Infinity symbol), then NAN_WORD0 + * and NAN_WORD1 are used instead. + * #define MULTIPLE_THREADS if the system offers preemptively scheduled + * multiple threads. In this case, you must provide (or suitably + * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed + * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed + * in pow5mult, ensures lazy evaluation of only one copy of high + * powers of 5; omitting this lock would introduce a small + * probability of wasting memory, but would otherwise be harmless.) + * You must also invoke freedtoa(s) to free the value s returned by + * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined. + * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that + * avoids underflows on inputs whose result does not underflow. + * If you #define NO_IEEE_Scale on a machine that uses IEEE-format + * floating-point numbers and flushes underflows to zero rather + * than implementing gradual underflow, then you must also #define + * Sudden_Underflow. + * #define YES_ALIAS to permit aliasing certain double values with + * arrays of ULongs. This leads to slightly better code with + * some compilers and was always used prior to 19990916, but it + * is not strictly legal and can cause trouble with aggressively + * optimizing compilers (e.g., gcc 2.95.1 under -O2). + * #define USE_LOCALE to use the current locale's decimal_point value. + * #define SET_INEXACT if IEEE arithmetic is being used and extra + * computation should be done to set the inexact flag when the + * result is inexact and avoid setting inexact when the result + * is exact. In this case, dtoa.c must be compiled in + * an environment, perhaps provided by #include "dtoa.c" in a + * suitable wrapper, that defines two functions, + * int get_inexact(void); + * void clear_inexact(void); + * such that get_inexact() returns a nonzero value if the + * inexact bit is already set, and clear_inexact() sets the + * inexact bit to 0. When SET_INEXACT is #defined, strtod + * also does extra computations to set the underflow and overflow + * flags when appropriate (i.e., when the result is tiny and + * inexact or when it is a numeric value rounded to +-infinity). + * #define NO_ERRNO if strtod should not assign errno = ERANGE when + * the result overflows to +-Infinity or underflows to 0. + */ + +#ifdef WORDS_BIGENDIAN +#define IEEE_BIG_ENDIAN +#else +#define IEEE_LITTLE_ENDIAN +#endif + +#ifdef __vax__ +#define VAX +#undef IEEE_BIG_ENDIAN +#undef IEEE_LITTLE_ENDIAN +#endif + +#if defined(__arm__) && !defined(__VFP_FP__) +#define IEEE_BIG_ENDIAN +#undef IEEE_LITTLE_ENDIAN +#endif + +#undef Long +#undef ULong + +#include + +#if (INT_MAX >> 30) && !(INT_MAX >> 31) +#define Long int +#define ULong unsigned int +#elif (LONG_MAX >> 30) && !(LONG_MAX >> 31) +#define Long long int +#define ULong unsigned long int +#else +#error No 32bit integer +#endif + +#if HAVE_LONG_LONG +#define Llong LONG_LONG +#else +#define NO_LONG_LONG +#endif + +#ifdef DEBUG +#include +#define Bug(x) {fprintf(stderr, "%s\n", (x)); exit(EXIT_FAILURE);} +#endif + +#ifndef ISDIGIT +#include +#define ISDIGIT(c) isdigit(c) +#endif +#include +#include +#include + +#ifdef USE_LOCALE +#include +#endif + +#ifdef MALLOC +extern void *MALLOC(size_t); +#else +#define MALLOC xmalloc +#endif +#ifdef FREE +extern void FREE(void*); +#else +#define FREE xfree +#endif +#ifndef NO_SANITIZE +#define NO_SANITIZE(x, y) y +#endif + +#ifndef Omit_Private_Memory +#ifndef PRIVATE_MEM +#define PRIVATE_MEM 2304 +#endif +#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) +static double private_mem[PRIVATE_mem], *pmem_next = private_mem; +#endif + +#undef IEEE_Arith +#undef Avoid_Underflow +#ifdef IEEE_BIG_ENDIAN +#define IEEE_Arith +#endif +#ifdef IEEE_LITTLE_ENDIAN +#define IEEE_Arith +#endif + +#ifdef Bad_float_h + +#ifdef IEEE_Arith +#define DBL_DIG 15 +#define DBL_MAX_10_EXP 308 +#define DBL_MAX_EXP 1024 +#define FLT_RADIX 2 +#endif /*IEEE_Arith*/ + +#ifdef IBM +#define DBL_DIG 16 +#define DBL_MAX_10_EXP 75 +#define DBL_MAX_EXP 63 +#define FLT_RADIX 16 +#define DBL_MAX 7.2370055773322621e+75 +#endif + +#ifdef VAX +#define DBL_DIG 16 +#define DBL_MAX_10_EXP 38 +#define DBL_MAX_EXP 127 +#define FLT_RADIX 2 +#define DBL_MAX 1.7014118346046923e+38 +#endif + +#ifndef LONG_MAX +#define LONG_MAX 2147483647 +#endif + +#else /* ifndef Bad_float_h */ +#include +#endif /* Bad_float_h */ + +#include + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* satisfy cc-mode */ +#endif +#endif + +#ifndef hexdigit +static const char hexdigit[] = "0123456789abcdef0123456789ABCDEF"; +#endif + +#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + defined(IBM) != 1 +Exactly one of IEEE_LITTLE_ENDIAN, IEEE_BIG_ENDIAN, VAX, or IBM should be defined. +#endif + +typedef union { double d; ULong L[2]; } U; + +#ifdef YES_ALIAS +typedef double double_u; +# define dval(x) (x) +# ifdef IEEE_LITTLE_ENDIAN +# define word0(x) (((ULong *)&(x))[1]) +# define word1(x) (((ULong *)&(x))[0]) +# else +# define word0(x) (((ULong *)&(x))[0]) +# define word1(x) (((ULong *)&(x))[1]) +# endif +#else +typedef U double_u; +# ifdef IEEE_LITTLE_ENDIAN +# define word0(x) ((x).L[1]) +# define word1(x) ((x).L[0]) +# else +# define word0(x) ((x).L[0]) +# define word1(x) ((x).L[1]) +# endif +# define dval(x) ((x).d) +#endif + +/* The following definition of Storeinc is appropriate for MIPS processors. + * An alternative that might be better on some machines is + * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) + */ +#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm__) +#define Storeinc(a,b,c) (((unsigned short *)(a))[1] = (unsigned short)(b), \ +((unsigned short *)(a))[0] = (unsigned short)(c), (a)++) +#else +#define Storeinc(a,b,c) (((unsigned short *)(a))[0] = (unsigned short)(b), \ +((unsigned short *)(a))[1] = (unsigned short)(c), (a)++) +#endif + +/* #define P DBL_MANT_DIG */ +/* Ten_pmax = floor(P*log(2)/log(5)) */ +/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ +/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ +/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ + +#ifdef IEEE_Arith +#define Exp_shift 20 +#define Exp_shift1 20 +#define Exp_msk1 0x100000 +#define Exp_msk11 0x100000 +#define Exp_mask 0x7ff00000 +#define P 53 +#define Bias 1023 +#define Emin (-1022) +#define Exp_1 0x3ff00000 +#define Exp_11 0x3ff00000 +#define Ebits 11 +#define Frac_mask 0xfffff +#define Frac_mask1 0xfffff +#define Ten_pmax 22 +#define Bletch 0x10 +#define Bndry_mask 0xfffff +#define Bndry_mask1 0xfffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 1 +#define Tiny0 0 +#define Tiny1 1 +#define Quick_max 14 +#define Int_max 14 +#ifndef NO_IEEE_Scale +#define Avoid_Underflow +#ifdef Flush_Denorm /* debugging option */ +#undef Sudden_Underflow +#endif +#endif + +#ifndef Flt_Rounds +#ifdef FLT_ROUNDS +#define Flt_Rounds FLT_ROUNDS +#else +#define Flt_Rounds 1 +#endif +#endif /*Flt_Rounds*/ + +#ifdef Honor_FLT_ROUNDS +#define Rounding rounding +#undef Check_FLT_ROUNDS +#define Check_FLT_ROUNDS +#else +#define Rounding Flt_Rounds +#endif + +#else /* ifndef IEEE_Arith */ +#undef Check_FLT_ROUNDS +#undef Honor_FLT_ROUNDS +#undef SET_INEXACT +#undef Sudden_Underflow +#define Sudden_Underflow +#ifdef IBM +#undef Flt_Rounds +#define Flt_Rounds 0 +#define Exp_shift 24 +#define Exp_shift1 24 +#define Exp_msk1 0x1000000 +#define Exp_msk11 0x1000000 +#define Exp_mask 0x7f000000 +#define P 14 +#define Bias 65 +#define Exp_1 0x41000000 +#define Exp_11 0x41000000 +#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ +#define Frac_mask 0xffffff +#define Frac_mask1 0xffffff +#define Bletch 4 +#define Ten_pmax 22 +#define Bndry_mask 0xefffff +#define Bndry_mask1 0xffffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 4 +#define Tiny0 0x100000 +#define Tiny1 0 +#define Quick_max 14 +#define Int_max 15 +#else /* VAX */ +#undef Flt_Rounds +#define Flt_Rounds 1 +#define Exp_shift 23 +#define Exp_shift1 7 +#define Exp_msk1 0x80 +#define Exp_msk11 0x800000 +#define Exp_mask 0x7f80 +#define P 56 +#define Bias 129 +#define Exp_1 0x40800000 +#define Exp_11 0x4080 +#define Ebits 8 +#define Frac_mask 0x7fffff +#define Frac_mask1 0xffff007f +#define Ten_pmax 24 +#define Bletch 2 +#define Bndry_mask 0xffff007f +#define Bndry_mask1 0xffff007f +#define LSB 0x10000 +#define Sign_bit 0x8000 +#define Log2P 1 +#define Tiny0 0x80 +#define Tiny1 0 +#define Quick_max 15 +#define Int_max 15 +#endif /* IBM, VAX */ +#endif /* IEEE_Arith */ + +#ifndef IEEE_Arith +#define ROUND_BIASED +#endif + +#ifdef RND_PRODQUOT +#define rounded_product(a,b) ((a) = rnd_prod((a), (b))) +#define rounded_quotient(a,b) ((a) = rnd_quot((a), (b))) +extern double rnd_prod(double, double), rnd_quot(double, double); +#else +#define rounded_product(a,b) ((a) *= (b)) +#define rounded_quotient(a,b) ((a) /= (b)) +#endif + +#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) +#define Big1 0xffffffff + +#ifndef Pack_32 +#define Pack_32 +#endif + +#define FFFFFFFF 0xffffffffUL + +#ifdef NO_LONG_LONG +#undef ULLong +#ifdef Just_16 +#undef Pack_32 +/* When Pack_32 is not defined, we store 16 bits per 32-bit Long. + * This makes some inner loops simpler and sometimes saves work + * during multiplications, but it often seems to make things slightly + * slower. Hence the default is now to store 32 bits per Long. + */ +#endif +#else /* long long available */ +#ifndef Llong +#define Llong long long +#endif +#ifndef ULLong +#define ULLong unsigned Llong +#endif +#endif /* NO_LONG_LONG */ + +#define MULTIPLE_THREADS 1 + +#ifndef MULTIPLE_THREADS +#define ACQUIRE_DTOA_LOCK(n) /*nothing*/ +#define FREE_DTOA_LOCK(n) /*nothing*/ +#else +#define ACQUIRE_DTOA_LOCK(n) /*unused right now*/ +#define FREE_DTOA_LOCK(n) /*unused right now*/ +#endif + +#ifndef ATOMIC_PTR_CAS +#define ATOMIC_PTR_CAS(var, old, new) ((var) = (new), (old)) +#endif +#ifndef LIKELY +#define LIKELY(x) (x) +#endif +#ifndef UNLIKELY +#define UNLIKELY(x) (x) +#endif +#ifndef ASSUME +#define ASSUME(x) (void)(x) +#endif + +#define Kmax 15 + +struct Bigint { + struct Bigint *next; + int k, maxwds, sign, wds; + ULong x[1]; +}; + +typedef struct Bigint Bigint; + +static Bigint *freelist[Kmax+1]; + +static Bigint * +Balloc(int k) +{ + int x; + Bigint *rv; +#ifndef Omit_Private_Memory + size_t len; +#endif + + rv = 0; + ACQUIRE_DTOA_LOCK(0); + if (k <= Kmax) { + rv = freelist[k]; + while (rv) { + Bigint *rvn = rv; + rv = ATOMIC_PTR_CAS(freelist[k], rv, rv->next); + if (LIKELY(rvn == rv)) { + ASSUME(rv); + break; + } + } + } + if (!rv) { + x = 1 << k; +#ifdef Omit_Private_Memory + rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); +#else + len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) + /sizeof(double); + if (k <= Kmax) { + double *pnext = pmem_next; + while (pnext - private_mem + len <= PRIVATE_mem) { + double *p = pnext; + pnext = ATOMIC_PTR_CAS(pmem_next, pnext, pnext + len); + if (LIKELY(p == pnext)) { + rv = (Bigint*)pnext; + ASSUME(rv); + break; + } + } + } + if (!rv) + rv = (Bigint*)MALLOC(len*sizeof(double)); +#endif + rv->k = k; + rv->maxwds = x; + } + FREE_DTOA_LOCK(0); + rv->sign = rv->wds = 0; + return rv; +} + +static void +Bfree(Bigint *v) +{ + Bigint *vn; + if (v) { + if (v->k > Kmax) { + FREE(v); + return; + } + ACQUIRE_DTOA_LOCK(0); + do { + vn = v->next = freelist[v->k]; + } while (UNLIKELY(ATOMIC_PTR_CAS(freelist[v->k], vn, v) != vn)); + FREE_DTOA_LOCK(0); + } +} + +#define Bcopy(x,y) memcpy((char *)&(x)->sign, (char *)&(y)->sign, \ +(y)->wds*sizeof(Long) + 2*sizeof(int)) + +static Bigint * +multadd(Bigint *b, int m, int a) /* multiply by m and add a */ +{ + int i, wds; + ULong *x; +#ifdef ULLong + ULLong carry, y; +#else + ULong carry, y; +#ifdef Pack_32 + ULong xi, z; +#endif +#endif + Bigint *b1; + + wds = b->wds; + x = b->x; + i = 0; + carry = a; + do { +#ifdef ULLong + y = *x * (ULLong)m + carry; + carry = y >> 32; + *x++ = (ULong)(y & FFFFFFFF); +#else +#ifdef Pack_32 + xi = *x; + y = (xi & 0xffff) * m + carry; + z = (xi >> 16) * m + (y >> 16); + carry = z >> 16; + *x++ = (z << 16) + (y & 0xffff); +#else + y = *x * m + carry; + carry = y >> 16; + *x++ = y & 0xffff; +#endif +#endif + } while (++i < wds); + if (carry) { + if (wds >= b->maxwds) { + b1 = Balloc(b->k+1); + Bcopy(b1, b); + Bfree(b); + b = b1; + } + b->x[wds++] = (ULong)carry; + b->wds = wds; + } + return b; +} + +static Bigint * +s2b(const char *s, int nd0, int nd, ULong y9) +{ + Bigint *b; + int i, k; + Long x, y; + + x = (nd + 8) / 9; + for (k = 0, y = 1; x > y; y <<= 1, k++) ; +#ifdef Pack_32 + b = Balloc(k); + b->x[0] = y9; + b->wds = 1; +#else + b = Balloc(k+1); + b->x[0] = y9 & 0xffff; + b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; +#endif + + i = 9; + if (9 < nd0) { + s += 9; + do { + b = multadd(b, 10, *s++ - '0'); + } while (++i < nd0); + s++; + } + else + s += 10; + for (; i < nd; i++) + b = multadd(b, 10, *s++ - '0'); + return b; +} + +static int +hi0bits(register ULong x) +{ + register int k = 0; + + if (!(x & 0xffff0000)) { + k = 16; + x <<= 16; + } + if (!(x & 0xff000000)) { + k += 8; + x <<= 8; + } + if (!(x & 0xf0000000)) { + k += 4; + x <<= 4; + } + if (!(x & 0xc0000000)) { + k += 2; + x <<= 2; + } + if (!(x & 0x80000000)) { + k++; + if (!(x & 0x40000000)) + return 32; + } + return k; +} + +static int +lo0bits(ULong *y) +{ + register int k; + register ULong x = *y; + + if (x & 7) { + if (x & 1) + return 0; + if (x & 2) { + *y = x >> 1; + return 1; + } + *y = x >> 2; + return 2; + } + k = 0; + if (!(x & 0xffff)) { + k = 16; + x >>= 16; + } + if (!(x & 0xff)) { + k += 8; + x >>= 8; + } + if (!(x & 0xf)) { + k += 4; + x >>= 4; + } + if (!(x & 0x3)) { + k += 2; + x >>= 2; + } + if (!(x & 1)) { + k++; + x >>= 1; + if (!x) + return 32; + } + *y = x; + return k; +} + +static Bigint * +i2b(int i) +{ + Bigint *b; + + b = Balloc(1); + b->x[0] = i; + b->wds = 1; + return b; +} + +static Bigint * +mult(Bigint *a, Bigint *b) +{ + Bigint *c; + int k, wa, wb, wc; + ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; + ULong y; +#ifdef ULLong + ULLong carry, z; +#else + ULong carry, z; +#ifdef Pack_32 + ULong z2; +#endif +#endif + + if (a->wds < b->wds) { + c = a; + a = b; + b = c; + } + k = a->k; + wa = a->wds; + wb = b->wds; + wc = wa + wb; + if (wc > a->maxwds) + k++; + c = Balloc(k); + for (x = c->x, xa = x + wc; x < xa; x++) + *x = 0; + xa = a->x; + xae = xa + wa; + xb = b->x; + xbe = xb + wb; + xc0 = c->x; +#ifdef ULLong + for (; xb < xbe; xc0++) { + if ((y = *xb++) != 0) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * (ULLong)y + *xc + carry; + carry = z >> 32; + *xc++ = (ULong)(z & FFFFFFFF); + } while (x < xae); + *xc = (ULong)carry; + } + } +#else +#ifdef Pack_32 + for (; xb < xbe; xb++, xc0++) { + if ((y = *xb & 0xffff) != 0) { + x = xa; + xc = xc0; + carry = 0; + do { + z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; + carry = z >> 16; + z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; + carry = z2 >> 16; + Storeinc(xc, z2, z); + } while (x < xae); + *xc = (ULong)carry; + } + if ((y = *xb >> 16) != 0) { + x = xa; + xc = xc0; + carry = 0; + z2 = *xc; + do { + z = (*x & 0xffff) * y + (*xc >> 16) + carry; + carry = z >> 16; + Storeinc(xc, z, z2); + z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; + carry = z2 >> 16; + } while (x < xae); + *xc = z2; + } + } +#else + for (; xb < xbe; xc0++) { + if (y = *xb++) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * y + *xc + carry; + carry = z >> 16; + *xc++ = z & 0xffff; + } while (x < xae); + *xc = (ULong)carry; + } + } +#endif +#endif + for (xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; + c->wds = wc; + return c; +} + +static Bigint *p5s; + +static Bigint * +pow5mult(Bigint *b, int k) +{ + Bigint *b1, *p5, *p51; + Bigint *p5tmp; + int i; + static const int p05[3] = { 5, 25, 125 }; + + if ((i = k & 3) != 0) + b = multadd(b, p05[i-1], 0); + + if (!(k >>= 2)) + return b; + if (!(p5 = p5s)) { + /* first time */ + ACQUIRE_DTOA_LOCK(1); + if (!(p5 = p5s)) { + p5 = i2b(625); + p5->next = 0; + p5tmp = ATOMIC_PTR_CAS(p5s, NULL, p5); + if (UNLIKELY(p5tmp)) { + Bfree(p5); + p5 = p5tmp; + } + } + FREE_DTOA_LOCK(1); + } + for (;;) { + if (k & 1) { + b1 = mult(b, p5); + Bfree(b); + b = b1; + } + if (!(k >>= 1)) + break; + if (!(p51 = p5->next)) { + ACQUIRE_DTOA_LOCK(1); + if (!(p51 = p5->next)) { + p51 = mult(p5,p5); + p51->next = 0; + p5tmp = ATOMIC_PTR_CAS(p5->next, NULL, p51); + if (UNLIKELY(p5tmp)) { + Bfree(p51); + p51 = p5tmp; + } + } + FREE_DTOA_LOCK(1); + } + p5 = p51; + } + return b; +} + +static Bigint * +lshift(Bigint *b, int k) +{ + int i, k1, n, n1; + Bigint *b1; + ULong *x, *x1, *xe, z; + +#ifdef Pack_32 + n = k >> 5; +#else + n = k >> 4; +#endif + k1 = b->k; + n1 = n + b->wds + 1; + for (i = b->maxwds; n1 > i; i <<= 1) + k1++; + b1 = Balloc(k1); + x1 = b1->x; + for (i = 0; i < n; i++) + *x1++ = 0; + x = b->x; + xe = x + b->wds; +#ifdef Pack_32 + if (k &= 0x1f) { + k1 = 32 - k; + z = 0; + do { + *x1++ = *x << k | z; + z = *x++ >> k1; + } while (x < xe); + if ((*x1 = z) != 0) + ++n1; + } +#else + if (k &= 0xf) { + k1 = 16 - k; + z = 0; + do { + *x1++ = *x << k & 0xffff | z; + z = *x++ >> k1; + } while (x < xe); + if (*x1 = z) + ++n1; + } +#endif + else + do { + *x1++ = *x++; + } while (x < xe); + b1->wds = n1 - 1; + Bfree(b); + return b1; +} + +static int +cmp(Bigint *a, Bigint *b) +{ + ULong *xa, *xa0, *xb, *xb0; + int i, j; + + i = a->wds; + j = b->wds; +#ifdef DEBUG + if (i > 1 && !a->x[i-1]) + Bug("cmp called with a->x[a->wds-1] == 0"); + if (j > 1 && !b->x[j-1]) + Bug("cmp called with b->x[b->wds-1] == 0"); +#endif + if (i -= j) + return i; + xa0 = a->x; + xa = xa0 + j; + xb0 = b->x; + xb = xb0 + j; + for (;;) { + if (*--xa != *--xb) + return *xa < *xb ? -1 : 1; + if (xa <= xa0) + break; + } + return 0; +} + +NO_SANITIZE("unsigned-integer-overflow", static Bigint * diff(Bigint *a, Bigint *b)); +static Bigint * +diff(Bigint *a, Bigint *b) +{ + Bigint *c; + int i, wa, wb; + ULong *xa, *xae, *xb, *xbe, *xc; +#ifdef ULLong + ULLong borrow, y; +#else + ULong borrow, y; +#ifdef Pack_32 + ULong z; +#endif +#endif + + i = cmp(a,b); + if (!i) { + c = Balloc(0); + c->wds = 1; + c->x[0] = 0; + return c; + } + if (i < 0) { + c = a; + a = b; + b = c; + i = 1; + } + else + i = 0; + c = Balloc(a->k); + c->sign = i; + wa = a->wds; + xa = a->x; + xae = xa + wa; + wb = b->wds; + xb = b->x; + xbe = xb + wb; + xc = c->x; + borrow = 0; +#ifdef ULLong + do { + y = (ULLong)*xa++ - *xb++ - borrow; + borrow = y >> 32 & (ULong)1; + *xc++ = (ULong)(y & FFFFFFFF); + } while (xb < xbe); + while (xa < xae) { + y = *xa++ - borrow; + borrow = y >> 32 & (ULong)1; + *xc++ = (ULong)(y & FFFFFFFF); + } +#else +#ifdef Pack_32 + do { + y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } while (xb < xbe); + while (xa < xae) { + y = (*xa & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } +#else + do { + y = *xa++ - *xb++ - borrow; + borrow = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } while (xb < xbe); + while (xa < xae) { + y = *xa++ - borrow; + borrow = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } +#endif +#endif + while (!*--xc) + wa--; + c->wds = wa; + return c; +} + +static double +ulp(double x_) +{ + register Long L; + double_u x, a; + dval(x) = x_; + + L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; +#ifndef Avoid_Underflow +#ifndef Sudden_Underflow + if (L > 0) { +#endif +#endif +#ifdef IBM + L |= Exp_msk1 >> 4; +#endif + word0(a) = L; + word1(a) = 0; +#ifndef Avoid_Underflow +#ifndef Sudden_Underflow + } + else { + L = -L >> Exp_shift; + if (L < Exp_shift) { + word0(a) = 0x80000 >> L; + word1(a) = 0; + } + else { + word0(a) = 0; + L -= Exp_shift; + word1(a) = L >= 31 ? 1 : 1 << 31 - L; + } + } +#endif +#endif + return dval(a); +} + +static double +b2d(Bigint *a, int *e) +{ + ULong *xa, *xa0, w, y, z; + int k; + double_u d; +#ifdef VAX + ULong d0, d1; +#else +#define d0 word0(d) +#define d1 word1(d) +#endif + + xa0 = a->x; + xa = xa0 + a->wds; + y = *--xa; +#ifdef DEBUG + if (!y) Bug("zero y in b2d"); +#endif + k = hi0bits(y); + *e = 32 - k; +#ifdef Pack_32 + if (k < Ebits) { + d0 = Exp_1 | y >> (Ebits - k); + w = xa > xa0 ? *--xa : 0; + d1 = y << ((32-Ebits) + k) | w >> (Ebits - k); + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + if (k -= Ebits) { + d0 = Exp_1 | y << k | z >> (32 - k); + y = xa > xa0 ? *--xa : 0; + d1 = z << k | y >> (32 - k); + } + else { + d0 = Exp_1 | y; + d1 = z; + } +#else + if (k < Ebits + 16) { + z = xa > xa0 ? *--xa : 0; + d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; + w = xa > xa0 ? *--xa : 0; + y = xa > xa0 ? *--xa : 0; + d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + w = xa > xa0 ? *--xa : 0; + k -= Ebits + 16; + d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; + y = xa > xa0 ? *--xa : 0; + d1 = w << k + 16 | y << k; +#endif +ret_d: +#ifdef VAX + word0(d) = d0 >> 16 | d0 << 16; + word1(d) = d1 >> 16 | d1 << 16; +#else +#undef d0 +#undef d1 +#endif + return dval(d); +} + +static Bigint * +d2b(double d_, int *e, int *bits) +{ + double_u d; + Bigint *b; + int de, k; + ULong *x, y, z; +#ifndef Sudden_Underflow + int i; +#endif +#ifdef VAX + ULong d0, d1; +#endif + dval(d) = d_; +#ifdef VAX + d0 = word0(d) >> 16 | word0(d) << 16; + d1 = word1(d) >> 16 | word1(d) << 16; +#else +#define d0 word0(d) +#define d1 word1(d) +#endif + +#ifdef Pack_32 + b = Balloc(1); +#else + b = Balloc(2); +#endif + x = b->x; + + z = d0 & Frac_mask; + d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ +#ifdef Sudden_Underflow + de = (int)(d0 >> Exp_shift); +#ifndef IBM + z |= Exp_msk11; +#endif +#else + if ((de = (int)(d0 >> Exp_shift)) != 0) + z |= Exp_msk1; +#endif +#ifdef Pack_32 + if ((y = d1) != 0) { + if ((k = lo0bits(&y)) != 0) { + x[0] = y | z << (32 - k); + z >>= k; + } + else + x[0] = y; +#ifndef Sudden_Underflow + i = +#endif + b->wds = (x[1] = z) ? 2 : 1; + } + else { +#ifdef DEBUG + if (!z) + Bug("Zero passed to d2b"); +#endif + k = lo0bits(&z); + x[0] = z; +#ifndef Sudden_Underflow + i = +#endif + b->wds = 1; + k += 32; + } +#else + if (y = d1) { + if (k = lo0bits(&y)) + if (k >= 16) { + x[0] = y | z << 32 - k & 0xffff; + x[1] = z >> k - 16 & 0xffff; + x[2] = z >> k; + i = 2; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16 | z << 16 - k & 0xffff; + x[2] = z >> k & 0xffff; + x[3] = z >> k+16; + i = 3; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16; + x[2] = z & 0xffff; + x[3] = z >> 16; + i = 3; + } + } + else { +#ifdef DEBUG + if (!z) + Bug("Zero passed to d2b"); +#endif + k = lo0bits(&z); + if (k >= 16) { + x[0] = z; + i = 0; + } + else { + x[0] = z & 0xffff; + x[1] = z >> 16; + i = 1; + } + k += 32; + } + while (!x[i]) + --i; + b->wds = i + 1; +#endif +#ifndef Sudden_Underflow + if (de) { +#endif +#ifdef IBM + *e = (de - Bias - (P-1) << 2) + k; + *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); +#else + *e = de - Bias - (P-1) + k; + *bits = P - k; +#endif +#ifndef Sudden_Underflow + } + else { + *e = de - Bias - (P-1) + 1 + k; +#ifdef Pack_32 + *bits = 32*i - hi0bits(x[i-1]); +#else + *bits = (i+2)*16 - hi0bits(x[i]); +#endif + } +#endif + return b; +} +#undef d0 +#undef d1 + +static double +ratio(Bigint *a, Bigint *b) +{ + double_u da, db; + int k, ka, kb; + + dval(da) = b2d(a, &ka); + dval(db) = b2d(b, &kb); +#ifdef Pack_32 + k = ka - kb + 32*(a->wds - b->wds); +#else + k = ka - kb + 16*(a->wds - b->wds); +#endif +#ifdef IBM + if (k > 0) { + word0(da) += (k >> 2)*Exp_msk1; + if (k &= 3) + dval(da) *= 1 << k; + } + else { + k = -k; + word0(db) += (k >> 2)*Exp_msk1; + if (k &= 3) + dval(db) *= 1 << k; + } +#else + if (k > 0) + word0(da) += k*Exp_msk1; + else { + k = -k; + word0(db) += k*Exp_msk1; + } +#endif + return dval(da) / dval(db); +} + +static const double +tens[] = { + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22 +#ifdef VAX + , 1e23, 1e24 +#endif +}; + +static const double +#ifdef IEEE_Arith +bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; +static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, +#ifdef Avoid_Underflow + 9007199254740992.*9007199254740992.e-256 + /* = 2^106 * 1e-53 */ +#else + 1e-256 +#endif +}; +/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ +/* flag unnecessarily. It leads to a song and dance at the end of strtod. */ +#define Scale_Bit 0x10 +#define n_bigtens 5 +#else +#ifdef IBM +bigtens[] = { 1e16, 1e32, 1e64 }; +static const double tinytens[] = { 1e-16, 1e-32, 1e-64 }; +#define n_bigtens 3 +#else +bigtens[] = { 1e16, 1e32 }; +static const double tinytens[] = { 1e-16, 1e-32 }; +#define n_bigtens 2 +#endif +#endif + +#ifndef IEEE_Arith +#undef INFNAN_CHECK +#endif + +#ifdef INFNAN_CHECK + +#ifndef NAN_WORD0 +#define NAN_WORD0 0x7ff80000 +#endif + +#ifndef NAN_WORD1 +#define NAN_WORD1 0 +#endif + +static int +match(const char **sp, char *t) +{ + int c, d; + const char *s = *sp; + + while (d = *t++) { + if ((c = *++s) >= 'A' && c <= 'Z') + c += 'a' - 'A'; + if (c != d) + return 0; + } + *sp = s + 1; + return 1; +} + +#ifndef No_Hex_NaN +static void +hexnan(double *rvp, const char **sp) +{ + ULong c, x[2]; + const char *s; + int havedig, udx0, xshift; + + x[0] = x[1] = 0; + havedig = xshift = 0; + udx0 = 1; + s = *sp; + while (c = *(const unsigned char*)++s) { + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'a' && c <= 'f') + c += 10 - 'a'; + else if (c >= 'A' && c <= 'F') + c += 10 - 'A'; + else if (c <= ' ') { + if (udx0 && havedig) { + udx0 = 0; + xshift = 1; + } + continue; + } + else if (/*(*/ c == ')' && havedig) { + *sp = s + 1; + break; + } + else + return; /* invalid form: don't change *sp */ + havedig = 1; + if (xshift) { + xshift = 0; + x[0] = x[1]; + x[1] = 0; + } + if (udx0) + x[0] = (x[0] << 4) | (x[1] >> 28); + x[1] = (x[1] << 4) | c; + } + if ((x[0] &= 0xfffff) || x[1]) { + word0(*rvp) = Exp_mask | x[0]; + word1(*rvp) = x[1]; + } +} +#endif /*No_Hex_NaN*/ +#endif /* INFNAN_CHECK */ + +NO_SANITIZE("unsigned-integer-overflow", double strtod(const char *s00, char **se)); +double +strtod(const char *s00, char **se) +{ +#ifdef Avoid_Underflow + int scale; +#endif + int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, + e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; + const char *s, *s0, *s1; + double aadj, adj; + double_u aadj1, rv, rv0; + Long L; + ULong y, z; + Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; +#ifdef SET_INEXACT + int inexact, oldinexact; +#endif +#ifdef Honor_FLT_ROUNDS + int rounding; +#endif +#ifdef USE_LOCALE + const char *s2; +#endif + + errno = 0; + sign = nz0 = nz = 0; + dval(rv) = 0.; + for (s = s00;;s++) + switch (*s) { + case '-': + sign = 1; + /* no break */ + case '+': + if (*++s) + goto break2; + /* no break */ + case 0: + goto ret0; + case '\t': + case '\n': + case '\v': + case '\f': + case '\r': + case ' ': + continue; + default: + goto break2; + } +break2: + if (*s == '0') { + if (s[1] == 'x' || s[1] == 'X') { + s0 = ++s; + adj = 0; + aadj = 1.0; + nd0 = -4; + + if (!*++s || !(s1 = strchr(hexdigit, *s))) goto ret0; + if (*s == '0') { + while (*++s == '0'); + s1 = strchr(hexdigit, *s); + } + if (s1 != NULL) { + do { + adj += aadj * ((s1 - hexdigit) & 15); + nd0 += 4; + aadj /= 16; + } while (*++s && (s1 = strchr(hexdigit, *s))); + } + + if (*s == '.') { + dsign = 1; + if (!*++s || !(s1 = strchr(hexdigit, *s))) goto ret0; + if (nd0 < 0) { + while (*s == '0') { + s++; + nd0 -= 4; + } + } + for (; *s && (s1 = strchr(hexdigit, *s)); ++s) { + adj += aadj * ((s1 - hexdigit) & 15); + if ((aadj /= 16) == 0.0) { + while (strchr(hexdigit, *++s)); + break; + } + } + } + else { + dsign = 0; + } + + if (*s == 'P' || *s == 'p') { + dsign = 0x2C - *++s; /* +: 2B, -: 2D */ + if (abs(dsign) == 1) s++; + else dsign = 1; + + nd = 0; + c = *s; + if (c < '0' || '9' < c) goto ret0; + do { + nd *= 10; + nd += c; + nd -= '0'; + c = *++s; + /* Float("0x0."+("0"*267)+"1fp2095") */ + if (nd + dsign * nd0 > 2095) { + while ('0' <= c && c <= '9') c = *++s; + break; + } + } while ('0' <= c && c <= '9'); + nd0 += nd * dsign; + } + else { + if (dsign) goto ret0; + } + dval(rv) = ldexp(adj, nd0); + goto ret; + } + nz0 = 1; + while (*++s == '0') ; + if (!*s) + goto ret; + } + s0 = s; + y = z = 0; + for (nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) + if (nd < 9) + y = 10*y + c - '0'; + else if (nd < DBL_DIG + 2) + z = 10*z + c - '0'; + nd0 = nd; +#ifdef USE_LOCALE + s1 = localeconv()->decimal_point; + if (c == *s1) { + c = '.'; + if (*++s1) { + s2 = s; + for (;;) { + if (*++s2 != *s1) { + c = 0; + break; + } + if (!*++s1) { + s = s2; + break; + } + } + } + } +#endif + if (c == '.') { + if (!ISDIGIT(s[1])) + goto dig_done; + c = *++s; + if (!nd) { + for (; c == '0'; c = *++s) + nz++; + if (c > '0' && c <= '9') { + s0 = s; + nf += nz; + nz = 0; + goto have_dig; + } + goto dig_done; + } + for (; c >= '0' && c <= '9'; c = *++s) { +have_dig: + nz++; + if (nd > DBL_DIG * 4) { + continue; + } + if (c -= '0') { + nf += nz; + for (i = 1; i < nz; i++) + if (nd++ < 9) + y *= 10; + else if (nd <= DBL_DIG + 2) + z *= 10; + if (nd++ < 9) + y = 10*y + c; + else if (nd <= DBL_DIG + 2) + z = 10*z + c; + nz = 0; + } + } + } +dig_done: + e = 0; + if (c == 'e' || c == 'E') { + if (!nd && !nz && !nz0) { + goto ret0; + } + s00 = s; + esign = 0; + switch (c = *++s) { + case '-': + esign = 1; + case '+': + c = *++s; + } + if (c >= '0' && c <= '9') { + while (c == '0') + c = *++s; + if (c > '0' && c <= '9') { + L = c - '0'; + s1 = s; + while ((c = *++s) >= '0' && c <= '9') + L = 10*L + c - '0'; + if (s - s1 > 8 || L > 19999) + /* Avoid confusion from exponents + * so large that e might overflow. + */ + e = 19999; /* safe for 16 bit ints */ + else + e = (int)L; + if (esign) + e = -e; + } + else + e = 0; + } + else + s = s00; + } + if (!nd) { + if (!nz && !nz0) { +#ifdef INFNAN_CHECK + /* Check for Nan and Infinity */ + switch (c) { + case 'i': + case 'I': + if (match(&s,"nf")) { + --s; + if (!match(&s,"inity")) + ++s; + word0(rv) = 0x7ff00000; + word1(rv) = 0; + goto ret; + } + break; + case 'n': + case 'N': + if (match(&s, "an")) { + word0(rv) = NAN_WORD0; + word1(rv) = NAN_WORD1; +#ifndef No_Hex_NaN + if (*s == '(') /*)*/ + hexnan(&rv, &s); +#endif + goto ret; + } + } +#endif /* INFNAN_CHECK */ +ret0: + s = s00; + sign = 0; + } + goto ret; + } + e1 = e -= nf; + + /* Now we have nd0 digits, starting at s0, followed by a + * decimal point, followed by nd-nd0 digits. The number we're + * after is the integer represented by those digits times + * 10**e */ + + if (!nd0) + nd0 = nd; + k = nd < DBL_DIG + 2 ? nd : DBL_DIG + 2; + dval(rv) = y; + if (k > 9) { +#ifdef SET_INEXACT + if (k > DBL_DIG) + oldinexact = get_inexact(); +#endif + dval(rv) = tens[k - 9] * dval(rv) + z; + } + bd0 = bb = bd = bs = delta = 0; + if (nd <= DBL_DIG +#ifndef RND_PRODQUOT +#ifndef Honor_FLT_ROUNDS + && Flt_Rounds == 1 +#endif +#endif + ) { + if (!e) + goto ret; + if (e > 0) { + if (e <= Ten_pmax) { +#ifdef VAX + goto vax_ovfl_check; +#else +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + dval(rv) = -dval(rv); + sign = 0; + } +#endif + /* rv = */ rounded_product(dval(rv), tens[e]); + goto ret; +#endif + } + i = DBL_DIG - nd; + if (e <= Ten_pmax + i) { + /* A fancier test would sometimes let us do + * this for larger i values. + */ +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + dval(rv) = -dval(rv); + sign = 0; + } +#endif + e -= i; + dval(rv) *= tens[i]; +#ifdef VAX + /* VAX exponent range is so narrow we must + * worry about overflow here... + */ +vax_ovfl_check: + word0(rv) -= P*Exp_msk1; + /* rv = */ rounded_product(dval(rv), tens[e]); + if ((word0(rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) + goto ovfl; + word0(rv) += P*Exp_msk1; +#else + /* rv = */ rounded_product(dval(rv), tens[e]); +#endif + goto ret; + } + } +#ifndef Inaccurate_Divide + else if (e >= -Ten_pmax) { +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + dval(rv) = -dval(rv); + sign = 0; + } +#endif + /* rv = */ rounded_quotient(dval(rv), tens[-e]); + goto ret; + } +#endif + } + e1 += nd - k; + +#ifdef IEEE_Arith +#ifdef SET_INEXACT + inexact = 1; + if (k <= DBL_DIG) + oldinexact = get_inexact(); +#endif +#ifdef Avoid_Underflow + scale = 0; +#endif +#ifdef Honor_FLT_ROUNDS + if ((rounding = Flt_Rounds) >= 2) { + if (sign) + rounding = rounding == 2 ? 0 : 2; + else + if (rounding != 2) + rounding = 0; + } +#endif +#endif /*IEEE_Arith*/ + + /* Get starting approximation = rv * 10**e1 */ + + if (e1 > 0) { + if ((i = e1 & 15) != 0) + dval(rv) *= tens[i]; + if (e1 &= ~15) { + if (e1 > DBL_MAX_10_EXP) { +ovfl: +#ifndef NO_ERRNO + errno = ERANGE; +#endif + /* Can't trust HUGE_VAL */ +#ifdef IEEE_Arith +#ifdef Honor_FLT_ROUNDS + switch (rounding) { + case 0: /* toward 0 */ + case 3: /* toward -infinity */ + word0(rv) = Big0; + word1(rv) = Big1; + break; + default: + word0(rv) = Exp_mask; + word1(rv) = 0; + } +#else /*Honor_FLT_ROUNDS*/ + word0(rv) = Exp_mask; + word1(rv) = 0; +#endif /*Honor_FLT_ROUNDS*/ +#ifdef SET_INEXACT + /* set overflow bit */ + dval(rv0) = 1e300; + dval(rv0) *= dval(rv0); +#endif +#else /*IEEE_Arith*/ + word0(rv) = Big0; + word1(rv) = Big1; +#endif /*IEEE_Arith*/ + if (bd0) + goto retfree; + goto ret; + } + e1 >>= 4; + for (j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= bigtens[j]; + /* The last multiplication could overflow. */ + word0(rv) -= P*Exp_msk1; + dval(rv) *= bigtens[j]; + if ((z = word0(rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-P)) + goto ovfl; + if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { + /* set to largest number */ + /* (Can't trust DBL_MAX) */ + word0(rv) = Big0; + word1(rv) = Big1; + } + else + word0(rv) += P*Exp_msk1; + } + } + else if (e1 < 0) { + e1 = -e1; + if ((i = e1 & 15) != 0) + dval(rv) /= tens[i]; + if (e1 >>= 4) { + if (e1 >= 1 << n_bigtens) + goto undfl; +#ifdef Avoid_Underflow + if (e1 & Scale_Bit) + scale = 2*P; + for (j = 0; e1 > 0; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= tinytens[j]; + if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask) + >> Exp_shift)) > 0) { + /* scaled rv is denormal; zap j low bits */ + if (j >= 32) { + word1(rv) = 0; + if (j >= 53) + word0(rv) = (P+2)*Exp_msk1; + else + word0(rv) &= 0xffffffff << (j-32); + } + else + word1(rv) &= 0xffffffff << j; + } +#else + for (j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= tinytens[j]; + /* The last multiplication could underflow. */ + dval(rv0) = dval(rv); + dval(rv) *= tinytens[j]; + if (!dval(rv)) { + dval(rv) = 2.*dval(rv0); + dval(rv) *= tinytens[j]; +#endif + if (!dval(rv)) { +undfl: + dval(rv) = 0.; +#ifndef NO_ERRNO + errno = ERANGE; +#endif + if (bd0) + goto retfree; + goto ret; + } +#ifndef Avoid_Underflow + word0(rv) = Tiny0; + word1(rv) = Tiny1; + /* The refinement below will clean + * this approximation up. + */ + } +#endif + } + } + + /* Now the hard part -- adjusting rv to the correct value.*/ + + /* Put digits into bd: true value = bd * 10^e */ + + bd0 = s2b(s0, nd0, nd, y); + + for (;;) { + bd = Balloc(bd0->k); + Bcopy(bd, bd0); + bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ + bs = i2b(1); + + if (e >= 0) { + bb2 = bb5 = 0; + bd2 = bd5 = e; + } + else { + bb2 = bb5 = -e; + bd2 = bd5 = 0; + } + if (bbe >= 0) + bb2 += bbe; + else + bd2 -= bbe; + bs2 = bb2; +#ifdef Honor_FLT_ROUNDS + if (rounding != 1) + bs2++; +#endif +#ifdef Avoid_Underflow + j = bbe - scale; + i = j + bbbits - 1; /* logb(rv) */ + if (i < Emin) /* denormal */ + j += P - Emin; + else + j = P + 1 - bbbits; +#else /*Avoid_Underflow*/ +#ifdef Sudden_Underflow +#ifdef IBM + j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); +#else + j = P + 1 - bbbits; +#endif +#else /*Sudden_Underflow*/ + j = bbe; + i = j + bbbits - 1; /* logb(rv) */ + if (i < Emin) /* denormal */ + j += P - Emin; + else + j = P + 1 - bbbits; +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + bb2 += j; + bd2 += j; +#ifdef Avoid_Underflow + bd2 += scale; +#endif + i = bb2 < bd2 ? bb2 : bd2; + if (i > bs2) + i = bs2; + if (i > 0) { + bb2 -= i; + bd2 -= i; + bs2 -= i; + } + if (bb5 > 0) { + bs = pow5mult(bs, bb5); + bb1 = mult(bs, bb); + Bfree(bb); + bb = bb1; + } + if (bb2 > 0) + bb = lshift(bb, bb2); + if (bd5 > 0) + bd = pow5mult(bd, bd5); + if (bd2 > 0) + bd = lshift(bd, bd2); + if (bs2 > 0) + bs = lshift(bs, bs2); + delta = diff(bb, bd); + dsign = delta->sign; + delta->sign = 0; + i = cmp(delta, bs); +#ifdef Honor_FLT_ROUNDS + if (rounding != 1) { + if (i < 0) { + /* Error is less than an ulp */ + if (!delta->x[0] && delta->wds <= 1) { + /* exact */ +#ifdef SET_INEXACT + inexact = 0; +#endif + break; + } + if (rounding) { + if (dsign) { + adj = 1.; + goto apply_adj; + } + } + else if (!dsign) { + adj = -1.; + if (!word1(rv) + && !(word0(rv) & Frac_mask)) { + y = word0(rv) & Exp_mask; +#ifdef Avoid_Underflow + if (!scale || y > 2*P*Exp_msk1) +#else + if (y) +#endif + { + delta = lshift(delta,Log2P); + if (cmp(delta, bs) <= 0) + adj = -0.5; + } + } +apply_adj: +#ifdef Avoid_Underflow + if (scale && (y = word0(rv) & Exp_mask) + <= 2*P*Exp_msk1) + word0(adj) += (2*P+1)*Exp_msk1 - y; +#else +#ifdef Sudden_Underflow + if ((word0(rv) & Exp_mask) <= + P*Exp_msk1) { + word0(rv) += P*Exp_msk1; + dval(rv) += adj*ulp(dval(rv)); + word0(rv) -= P*Exp_msk1; + } + else +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + dval(rv) += adj*ulp(dval(rv)); + } + break; + } + adj = ratio(delta, bs); + if (adj < 1.) + adj = 1.; + if (adj <= 0x7ffffffe) { + /* adj = rounding ? ceil(adj) : floor(adj); */ + y = adj; + if (y != adj) { + if (!((rounding>>1) ^ dsign)) + y++; + adj = y; + } + } +#ifdef Avoid_Underflow + if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) + word0(adj) += (2*P+1)*Exp_msk1 - y; +#else +#ifdef Sudden_Underflow + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { + word0(rv) += P*Exp_msk1; + adj *= ulp(dval(rv)); + if (dsign) + dval(rv) += adj; + else + dval(rv) -= adj; + word0(rv) -= P*Exp_msk1; + goto cont; + } +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + adj *= ulp(dval(rv)); + if (dsign) + dval(rv) += adj; + else + dval(rv) -= adj; + goto cont; + } +#endif /*Honor_FLT_ROUNDS*/ + + if (i < 0) { + /* Error is less than half an ulp -- check for + * special case of mantissa a power of two. + */ + if (dsign || word1(rv) || word0(rv) & Bndry_mask +#ifdef IEEE_Arith +#ifdef Avoid_Underflow + || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1 +#else + || (word0(rv) & Exp_mask) <= Exp_msk1 +#endif +#endif + ) { +#ifdef SET_INEXACT + if (!delta->x[0] && delta->wds <= 1) + inexact = 0; +#endif + break; + } + if (!delta->x[0] && delta->wds <= 1) { + /* exact result */ +#ifdef SET_INEXACT + inexact = 0; +#endif + break; + } + delta = lshift(delta,Log2P); + if (cmp(delta, bs) > 0) + goto drop_down; + break; + } + if (i == 0) { + /* exactly half-way between */ + if (dsign) { + if ((word0(rv) & Bndry_mask1) == Bndry_mask1 + && word1(rv) == ( +#ifdef Avoid_Underflow + (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) + ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : +#endif + 0xffffffff)) { + /*boundary case -- increment exponent*/ + word0(rv) = (word0(rv) & Exp_mask) + + Exp_msk1 +#ifdef IBM + | Exp_msk1 >> 4 +#endif + ; + word1(rv) = 0; +#ifdef Avoid_Underflow + dsign = 0; +#endif + break; + } + } + else if (!(word0(rv) & Bndry_mask) && !word1(rv)) { +drop_down: + /* boundary case -- decrement exponent */ +#ifdef Sudden_Underflow /*{{*/ + L = word0(rv) & Exp_mask; +#ifdef IBM + if (L < Exp_msk1) +#else +#ifdef Avoid_Underflow + if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) +#else + if (L <= Exp_msk1) +#endif /*Avoid_Underflow*/ +#endif /*IBM*/ + goto undfl; + L -= Exp_msk1; +#else /*Sudden_Underflow}{*/ +#ifdef Avoid_Underflow + if (scale) { + L = word0(rv) & Exp_mask; + if (L <= (2*P+1)*Exp_msk1) { + if (L > (P+2)*Exp_msk1) + /* round even ==> */ + /* accept rv */ + break; + /* rv = smallest denormal */ + goto undfl; + } + } +#endif /*Avoid_Underflow*/ + L = (word0(rv) & Exp_mask) - Exp_msk1; +#endif /*Sudden_Underflow}}*/ + word0(rv) = L | Bndry_mask1; + word1(rv) = 0xffffffff; +#ifdef IBM + goto cont; +#else + break; +#endif + } +#ifndef ROUND_BIASED + if (!(word1(rv) & LSB)) + break; +#endif + if (dsign) + dval(rv) += ulp(dval(rv)); +#ifndef ROUND_BIASED + else { + dval(rv) -= ulp(dval(rv)); +#ifndef Sudden_Underflow + if (!dval(rv)) + goto undfl; +#endif + } +#ifdef Avoid_Underflow + dsign = 1 - dsign; +#endif +#endif + break; + } + if ((aadj = ratio(delta, bs)) <= 2.) { + if (dsign) + aadj = dval(aadj1) = 1.; + else if (word1(rv) || word0(rv) & Bndry_mask) { +#ifndef Sudden_Underflow + if (word1(rv) == Tiny1 && !word0(rv)) + goto undfl; +#endif + aadj = 1.; + dval(aadj1) = -1.; + } + else { + /* special case -- power of FLT_RADIX to be */ + /* rounded down... */ + + if (aadj < 2./FLT_RADIX) + aadj = 1./FLT_RADIX; + else + aadj *= 0.5; + dval(aadj1) = -aadj; + } + } + else { + aadj *= 0.5; + dval(aadj1) = dsign ? aadj : -aadj; +#ifdef Check_FLT_ROUNDS + switch (Rounding) { + case 2: /* towards +infinity */ + dval(aadj1) -= 0.5; + break; + case 0: /* towards 0 */ + case 3: /* towards -infinity */ + dval(aadj1) += 0.5; + } +#else + if (Flt_Rounds == 0) + dval(aadj1) += 0.5; +#endif /*Check_FLT_ROUNDS*/ + } + y = word0(rv) & Exp_mask; + + /* Check for overflow */ + + if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { + dval(rv0) = dval(rv); + word0(rv) -= P*Exp_msk1; + adj = dval(aadj1) * ulp(dval(rv)); + dval(rv) += adj; + if ((word0(rv) & Exp_mask) >= + Exp_msk1*(DBL_MAX_EXP+Bias-P)) { + if (word0(rv0) == Big0 && word1(rv0) == Big1) + goto ovfl; + word0(rv) = Big0; + word1(rv) = Big1; + goto cont; + } + else + word0(rv) += P*Exp_msk1; + } + else { +#ifdef Avoid_Underflow + if (scale && y <= 2*P*Exp_msk1) { + if (aadj <= 0x7fffffff) { + if ((z = (int)aadj) <= 0) + z = 1; + aadj = z; + dval(aadj1) = dsign ? aadj : -aadj; + } + word0(aadj1) += (2*P+1)*Exp_msk1 - y; + } + adj = dval(aadj1) * ulp(dval(rv)); + dval(rv) += adj; +#else +#ifdef Sudden_Underflow + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { + dval(rv0) = dval(rv); + word0(rv) += P*Exp_msk1; + adj = dval(aadj1) * ulp(dval(rv)); + dval(rv) += adj; +#ifdef IBM + if ((word0(rv) & Exp_mask) < P*Exp_msk1) +#else + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) +#endif + { + if (word0(rv0) == Tiny0 && word1(rv0) == Tiny1) + goto undfl; + word0(rv) = Tiny0; + word1(rv) = Tiny1; + goto cont; + } + else + word0(rv) -= P*Exp_msk1; + } + else { + adj = dval(aadj1) * ulp(dval(rv)); + dval(rv) += adj; + } +#else /*Sudden_Underflow*/ + /* Compute adj so that the IEEE rounding rules will + * correctly round rv + adj in some half-way cases. + * If rv * ulp(rv) is denormalized (i.e., + * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid + * trouble from bits lost to denormalization; + * example: 1.2e-307 . + */ + if (y <= (P-1)*Exp_msk1 && aadj > 1.) { + dval(aadj1) = (double)(int)(aadj + 0.5); + if (!dsign) + dval(aadj1) = -dval(aadj1); + } + adj = dval(aadj1) * ulp(dval(rv)); + dval(rv) += adj; +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + } + z = word0(rv) & Exp_mask; +#ifndef SET_INEXACT +#ifdef Avoid_Underflow + if (!scale) +#endif + if (y == z) { + /* Can we stop now? */ + L = (Long)aadj; + aadj -= L; + /* The tolerances below are conservative. */ + if (dsign || word1(rv) || word0(rv) & Bndry_mask) { + if (aadj < .4999999 || aadj > .5000001) + break; + } + else if (aadj < .4999999/FLT_RADIX) + break; + } +#endif +cont: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(delta); + } +#ifdef SET_INEXACT + if (inexact) { + if (!oldinexact) { + word0(rv0) = Exp_1 + (70 << Exp_shift); + word1(rv0) = 0; + dval(rv0) += 1.; + } + } + else if (!oldinexact) + clear_inexact(); +#endif +#ifdef Avoid_Underflow + if (scale) { + word0(rv0) = Exp_1 - 2*P*Exp_msk1; + word1(rv0) = 0; + dval(rv) *= dval(rv0); +#ifndef NO_ERRNO + /* try to avoid the bug of testing an 8087 register value */ + if (word0(rv) == 0 && word1(rv) == 0) + errno = ERANGE; +#endif + } +#endif /* Avoid_Underflow */ +#ifdef SET_INEXACT + if (inexact && !(word0(rv) & Exp_mask)) { + /* set underflow bit */ + dval(rv0) = 1e-300; + dval(rv0) *= dval(rv0); + } +#endif +retfree: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); +ret: + if (se) + *se = (char *)s; + return sign ? -dval(rv) : dval(rv); +} + +NO_SANITIZE("unsigned-integer-overflow", static int quorem(Bigint *b, Bigint *S)); +static int +quorem(Bigint *b, Bigint *S) +{ + int n; + ULong *bx, *bxe, q, *sx, *sxe; +#ifdef ULLong + ULLong borrow, carry, y, ys; +#else + ULong borrow, carry, y, ys; +#ifdef Pack_32 + ULong si, z, zs; +#endif +#endif + + n = S->wds; +#ifdef DEBUG + /*debug*/ if (b->wds > n) + /*debug*/ Bug("oversize b in quorem"); +#endif + if (b->wds < n) + return 0; + sx = S->x; + sxe = sx + --n; + bx = b->x; + bxe = bx + n; + q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ +#ifdef DEBUG + /*debug*/ if (q > 9) + /*debug*/ Bug("oversized quotient in quorem"); +#endif + if (q) { + borrow = 0; + carry = 0; + do { +#ifdef ULLong + ys = *sx++ * (ULLong)q + carry; + carry = ys >> 32; + y = *bx - (ys & FFFFFFFF) - borrow; + borrow = y >> 32 & (ULong)1; + *bx++ = (ULong)(y & FFFFFFFF); +#else +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) * q + carry; + zs = (si >> 16) * q + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#else + ys = *sx++ * q + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + *bx++ = y & 0xffff; +#endif +#endif + } while (sx <= sxe); + if (!*bxe) { + bx = b->x; + while (--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + if (cmp(b, S) >= 0) { + q++; + borrow = 0; + carry = 0; + bx = b->x; + sx = S->x; + do { +#ifdef ULLong + ys = *sx++ + carry; + carry = ys >> 32; + y = *bx - (ys & FFFFFFFF) - borrow; + borrow = y >> 32 & (ULong)1; + *bx++ = (ULong)(y & FFFFFFFF); +#else +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) + carry; + zs = (si >> 16) + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#else + ys = *sx++ + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + *bx++ = y & 0xffff; +#endif +#endif + } while (sx <= sxe); + bx = b->x; + bxe = bx + n; + if (!*bxe) { + while (--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + return q; +} + +#ifndef MULTIPLE_THREADS +static char *dtoa_result; +#endif + +#ifndef MULTIPLE_THREADS +static char * +rv_alloc(int i) +{ + return dtoa_result = MALLOC(i); +} +#else +#define rv_alloc(i) MALLOC(i) +#endif + +static char * +nrv_alloc(const char *s, char **rve, size_t n) +{ + char *rv, *t; + + t = rv = rv_alloc(n); + while ((*t = *s++) != 0) t++; + if (rve) + *rve = t; + return rv; +} + +#define rv_strdup(s, rve) nrv_alloc((s), (rve), strlen(s)+1) + +#ifndef MULTIPLE_THREADS +/* freedtoa(s) must be used to free values s returned by dtoa + * when MULTIPLE_THREADS is #defined. It should be used in all cases, + * but for consistency with earlier versions of dtoa, it is optional + * when MULTIPLE_THREADS is not defined. + */ + +static void +freedtoa(char *s) +{ + FREE(s); +} +#endif + +static const char INFSTR[] = "Infinity"; +static const char NANSTR[] = "NaN"; +static const char ZEROSTR[] = "0"; + +/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. + * + * Inspired by "How to Print Floating-Point Numbers Accurately" by + * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. + * + * Modifications: + * 1. Rather than iterating, we use a simple numeric overestimate + * to determine k = floor(log10(d)). We scale relevant + * quantities using O(log2(k)) rather than O(k) multiplications. + * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't + * try to generate digits strictly left to right. Instead, we + * compute with fewer bits and propagate the carry if necessary + * when rounding the final digit up. This is often faster. + * 3. Under the assumption that input will be rounded nearest, + * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. + * That is, we allow equality in stopping tests when the + * round-nearest rule will give the same floating-point value + * as would satisfaction of the stopping test with strict + * inequality. + * 4. We remove common factors of powers of 2 from relevant + * quantities. + * 5. When converting floating-point integers less than 1e16, + * we use floating-point arithmetic rather than resorting + * to multiple-precision integers. + * 6. When asked to produce fewer than 15 digits, we first try + * to get by with floating-point arithmetic; we resort to + * multiple-precision integer arithmetic only if we cannot + * guarantee that the floating-point calculation has given + * the correctly rounded result. For k requested digits and + * "uniformly" distributed input, the probability is + * something like 10^(k-15) that we must resort to the Long + * calculation. + */ + +char * +dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve) +{ + /* Arguments ndigits, decpt, sign are similar to those + of ecvt and fcvt; trailing zeros are suppressed from + the returned string. If not null, *rve is set to point + to the end of the return value. If d is +-Infinity or NaN, + then *decpt is set to 9999. + + mode: + 0 ==> shortest string that yields d when read in + and rounded to nearest. + 1 ==> like 0, but with Steele & White stopping rule; + e.g. with IEEE P754 arithmetic , mode 0 gives + 1e23 whereas mode 1 gives 9.999999999999999e22. + 2 ==> max(1,ndigits) significant digits. This gives a + return value similar to that of ecvt, except + that trailing zeros are suppressed. + 3 ==> through ndigits past the decimal point. This + gives a return value similar to that from fcvt, + except that trailing zeros are suppressed, and + ndigits can be negative. + 4,5 ==> similar to 2 and 3, respectively, but (in + round-nearest mode) with the tests of mode 0 to + possibly return a shorter string that rounds to d. + With IEEE arithmetic and compilation with + -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same + as modes 2 and 3 when FLT_ROUNDS != 1. + 6-9 ==> Debugging modes similar to mode - 4: don't try + fast floating-point estimate (if applicable). + + Values of mode other than 0-9 are treated as mode 0. + + Sufficient space is allocated to the return value + to hold the suppressed trailing zeros. + */ + + int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, + j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, + spec_case, try_quick, half = 0; + Long L; +#ifndef Sudden_Underflow + int denorm; + ULong x; +#endif + Bigint *b, *b1, *delta, *mlo = 0, *mhi = 0, *S; + double ds; + double_u d, d2, eps; + char *s, *s0; +#ifdef Honor_FLT_ROUNDS + int rounding; +#endif +#ifdef SET_INEXACT + int inexact, oldinexact; +#endif + + dval(d) = d_; + +#ifndef MULTIPLE_THREADS + if (dtoa_result) { + freedtoa(dtoa_result); + dtoa_result = 0; + } +#endif + + if (word0(d) & Sign_bit) { + /* set sign for everything, including 0's and NaNs */ + *sign = 1; + word0(d) &= ~Sign_bit; /* clear sign bit */ + } + else + *sign = 0; + +#if defined(IEEE_Arith) + defined(VAX) +#ifdef IEEE_Arith + if ((word0(d) & Exp_mask) == Exp_mask) +#else + if (word0(d) == 0x8000) +#endif + { + /* Infinity or NaN */ + *decpt = 9999; +#ifdef IEEE_Arith + if (!word1(d) && !(word0(d) & 0xfffff)) + return rv_strdup(INFSTR, rve); +#endif + return rv_strdup(NANSTR, rve); + } +#endif +#ifdef IBM + dval(d) += 0; /* normalize */ +#endif + if (!dval(d)) { + *decpt = 1; + return rv_strdup(ZEROSTR, rve); + } + +#ifdef SET_INEXACT + try_quick = oldinexact = get_inexact(); + inexact = 1; +#endif +#ifdef Honor_FLT_ROUNDS + if ((rounding = Flt_Rounds) >= 2) { + if (*sign) + rounding = rounding == 2 ? 0 : 2; + else + if (rounding != 2) + rounding = 0; + } +#endif + + b = d2b(dval(d), &be, &bbits); +#ifdef Sudden_Underflow + i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); +#else + if ((i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) { +#endif + dval(d2) = dval(d); + word0(d2) &= Frac_mask1; + word0(d2) |= Exp_11; +#ifdef IBM + if (j = 11 - hi0bits(word0(d2) & Frac_mask)) + dval(d2) /= 1 << j; +#endif + + /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 + * log10(x) = log(x) / log(10) + * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) + * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) + * + * This suggests computing an approximation k to log10(d) by + * + * k = (i - Bias)*0.301029995663981 + * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); + * + * We want k to be too large rather than too small. + * The error in the first-order Taylor series approximation + * is in our favor, so we just round up the constant enough + * to compensate for any error in the multiplication of + * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, + * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, + * adding 1e-13 to the constant term more than suffices. + * Hence we adjust the constant term to 0.1760912590558. + * (We could get a more accurate k by invoking log10, + * but this is probably not worthwhile.) + */ + + i -= Bias; +#ifdef IBM + i <<= 2; + i += j; +#endif +#ifndef Sudden_Underflow + denorm = 0; + } + else { + /* d is denormalized */ + + i = bbits + be + (Bias + (P-1) - 1); + x = i > 32 ? word0(d) << (64 - i) | word1(d) >> (i - 32) + : word1(d) << (32 - i); + dval(d2) = x; + word0(d2) -= 31*Exp_msk1; /* adjust exponent */ + i -= (Bias + (P-1) - 1) + 1; + denorm = 1; + } +#endif + ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; + k = (int)ds; + if (ds < 0. && ds != k) + k--; /* want k = floor(ds) */ + k_check = 1; + if (k >= 0 && k <= Ten_pmax) { + if (dval(d) < tens[k]) + k--; + k_check = 0; + } + j = bbits - i - 1; + if (j >= 0) { + b2 = 0; + s2 = j; + } + else { + b2 = -j; + s2 = 0; + } + if (k >= 0) { + b5 = 0; + s5 = k; + s2 += k; + } + else { + b2 -= k; + b5 = -k; + s5 = 0; + } + if (mode < 0 || mode > 9) + mode = 0; + +#ifndef SET_INEXACT +#ifdef Check_FLT_ROUNDS + try_quick = Rounding == 1; +#else + try_quick = 1; +#endif +#endif /*SET_INEXACT*/ + + if (mode > 5) { + mode -= 4; + try_quick = 0; + } + leftright = 1; + ilim = ilim1 = -1; + switch (mode) { + case 0: + case 1: + i = 18; + ndigits = 0; + break; + case 2: + leftright = 0; + /* no break */ + case 4: + if (ndigits <= 0) + ndigits = 1; + ilim = ilim1 = i = ndigits; + break; + case 3: + leftright = 0; + /* no break */ + case 5: + i = ndigits + k + 1; + ilim = i; + ilim1 = i - 1; + if (i <= 0) + i = 1; + } + s = s0 = rv_alloc(i+1); + +#ifdef Honor_FLT_ROUNDS + if (mode > 1 && rounding != 1) + leftright = 0; +#endif + + if (ilim >= 0 && ilim <= Quick_max && try_quick) { + + /* Try to get by with floating-point arithmetic. */ + + i = 0; + dval(d2) = dval(d); + k0 = k; + ilim0 = ilim; + ieps = 2; /* conservative */ + if (k > 0) { + ds = tens[k&0xf]; + j = k >> 4; + if (j & Bletch) { + /* prevent overflows */ + j &= Bletch - 1; + dval(d) /= bigtens[n_bigtens-1]; + ieps++; + } + for (; j; j >>= 1, i++) + if (j & 1) { + ieps++; + ds *= bigtens[i]; + } + dval(d) /= ds; + } + else if ((j1 = -k) != 0) { + dval(d) *= tens[j1 & 0xf]; + for (j = j1 >> 4; j; j >>= 1, i++) + if (j & 1) { + ieps++; + dval(d) *= bigtens[i]; + } + } + if (k_check && dval(d) < 1. && ilim > 0) { + if (ilim1 <= 0) + goto fast_failed; + ilim = ilim1; + k--; + dval(d) *= 10.; + ieps++; + } + dval(eps) = ieps*dval(d) + 7.; + word0(eps) -= (P-1)*Exp_msk1; + if (ilim == 0) { + S = mhi = 0; + dval(d) -= 5.; + if (dval(d) > dval(eps)) + goto one_digit; + if (dval(d) < -dval(eps)) + goto no_digits; + goto fast_failed; + } +#ifndef No_leftright + if (leftright) { + /* Use Steele & White method of only + * generating digits needed. + */ + dval(eps) = 0.5/tens[ilim-1] - dval(eps); + for (i = 0;;) { + L = (int)dval(d); + dval(d) -= L; + *s++ = '0' + (int)L; + if (dval(d) < dval(eps)) + goto ret1; + if (1. - dval(d) < dval(eps)) + goto bump_up; + if (++i >= ilim) + break; + dval(eps) *= 10.; + dval(d) *= 10.; + } + } + else { +#endif + /* Generate ilim digits, then fix them up. */ + dval(eps) *= tens[ilim-1]; + for (i = 1;; i++, dval(d) *= 10.) { + L = (Long)(dval(d)); + if (!(dval(d) -= L)) + ilim = i; + *s++ = '0' + (int)L; + if (i == ilim) { + if (dval(d) > 0.5 + dval(eps)) + goto bump_up; + else if (dval(d) < 0.5 - dval(eps)) { + while (*--s == '0') ; + s++; + goto ret1; + } + half = 1; + if ((*(s-1) - '0') & 1) { + goto bump_up; + } + break; + } + } +#ifndef No_leftright + } +#endif +fast_failed: + s = s0; + dval(d) = dval(d2); + k = k0; + ilim = ilim0; + } + + /* Do we have a "small" integer? */ + + if (be >= 0 && k <= Int_max) { + /* Yes. */ + ds = tens[k]; + if (ndigits < 0 && ilim <= 0) { + S = mhi = 0; + if (ilim < 0 || dval(d) <= 5*ds) + goto no_digits; + goto one_digit; + } + for (i = 1;; i++, dval(d) *= 10.) { + L = (Long)(dval(d) / ds); + dval(d) -= L*ds; +#ifdef Check_FLT_ROUNDS + /* If FLT_ROUNDS == 2, L will usually be high by 1 */ + if (dval(d) < 0) { + L--; + dval(d) += ds; + } +#endif + *s++ = '0' + (int)L; + if (!dval(d)) { +#ifdef SET_INEXACT + inexact = 0; +#endif + break; + } + if (i == ilim) { +#ifdef Honor_FLT_ROUNDS + if (mode > 1) + switch (rounding) { + case 0: goto ret1; + case 2: goto bump_up; + } +#endif + dval(d) += dval(d); + if (dval(d) > ds || (dval(d) == ds && (L & 1))) { +bump_up: + while (*--s == '9') + if (s == s0) { + k++; + *s = '0'; + break; + } + ++*s++; + } + break; + } + } + goto ret1; + } + + m2 = b2; + m5 = b5; + if (leftright) { + i = +#ifndef Sudden_Underflow + denorm ? be + (Bias + (P-1) - 1 + 1) : +#endif +#ifdef IBM + 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); +#else + 1 + P - bbits; +#endif + b2 += i; + s2 += i; + mhi = i2b(1); + } + if (m2 > 0 && s2 > 0) { + i = m2 < s2 ? m2 : s2; + b2 -= i; + m2 -= i; + s2 -= i; + } + if (b5 > 0) { + if (leftright) { + if (m5 > 0) { + mhi = pow5mult(mhi, m5); + b1 = mult(mhi, b); + Bfree(b); + b = b1; + } + if ((j = b5 - m5) != 0) + b = pow5mult(b, j); + } + else + b = pow5mult(b, b5); + } + S = i2b(1); + if (s5 > 0) + S = pow5mult(S, s5); + + /* Check for special case that d is a normalized power of 2. */ + + spec_case = 0; + if ((mode < 2 || leftright) +#ifdef Honor_FLT_ROUNDS + && rounding == 1 +#endif + ) { + if (!word1(d) && !(word0(d) & Bndry_mask) +#ifndef Sudden_Underflow + && word0(d) & (Exp_mask & ~Exp_msk1) +#endif + ) { + /* The special case */ + b2 += Log2P; + s2 += Log2P; + spec_case = 1; + } + } + + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + * + * Perhaps we should just compute leading 28 bits of S once + * and for all and pass them and a shift to quorem, so it + * can do shifts and ors to compute the numerator for q. + */ +#ifdef Pack_32 + if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0) + i = 32 - i; +#else + if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) != 0) + i = 16 - i; +#endif + if (i > 4) { + i -= 4; + b2 += i; + m2 += i; + s2 += i; + } + else if (i < 4) { + i += 28; + b2 += i; + m2 += i; + s2 += i; + } + if (b2 > 0) + b = lshift(b, b2); + if (s2 > 0) + S = lshift(S, s2); + if (k_check) { + if (cmp(b,S) < 0) { + k--; + b = multadd(b, 10, 0); /* we botched the k estimate */ + if (leftright) + mhi = multadd(mhi, 10, 0); + ilim = ilim1; + } + } + if (ilim <= 0 && (mode == 3 || mode == 5)) { + if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { + /* no digits, fcvt style */ +no_digits: + k = -1 - ndigits; + goto ret; + } +one_digit: + *s++ = '1'; + k++; + goto ret; + } + if (leftright) { + if (m2 > 0) + mhi = lshift(mhi, m2); + + /* Compute mlo -- check for special case + * that d is a normalized power of 2. + */ + + mlo = mhi; + if (spec_case) { + mhi = Balloc(mhi->k); + Bcopy(mhi, mlo); + mhi = lshift(mhi, Log2P); + } + + for (i = 1;;i++) { + dig = quorem(b,S) + '0'; + /* Do we yet have the shortest decimal string + * that will round to d? + */ + j = cmp(b, mlo); + delta = diff(S, mhi); + j1 = delta->sign ? 1 : cmp(b, delta); + Bfree(delta); +#ifndef ROUND_BIASED + if (j1 == 0 && mode != 1 && !(word1(d) & 1) +#ifdef Honor_FLT_ROUNDS + && rounding >= 1 +#endif + ) { + if (dig == '9') + goto round_9_up; + if (j > 0) + dig++; +#ifdef SET_INEXACT + else if (!b->x[0] && b->wds <= 1) + inexact = 0; +#endif + *s++ = dig; + goto ret; + } +#endif + if (j < 0 || (j == 0 && mode != 1 +#ifndef ROUND_BIASED + && !(word1(d) & 1) +#endif + )) { + if (!b->x[0] && b->wds <= 1) { +#ifdef SET_INEXACT + inexact = 0; +#endif + goto accept_dig; + } +#ifdef Honor_FLT_ROUNDS + if (mode > 1) + switch (rounding) { + case 0: goto accept_dig; + case 2: goto keep_dig; + } +#endif /*Honor_FLT_ROUNDS*/ + if (j1 > 0) { + b = lshift(b, 1); + j1 = cmp(b, S); + if ((j1 > 0 || (j1 == 0 && (dig & 1))) && dig++ == '9') + goto round_9_up; + } +accept_dig: + *s++ = dig; + goto ret; + } + if (j1 > 0) { +#ifdef Honor_FLT_ROUNDS + if (!rounding) + goto accept_dig; +#endif + if (dig == '9') { /* possible if i == 1 */ +round_9_up: + *s++ = '9'; + goto roundoff; + } + *s++ = dig + 1; + goto ret; + } +#ifdef Honor_FLT_ROUNDS +keep_dig: +#endif + *s++ = dig; + if (i == ilim) + break; + b = multadd(b, 10, 0); + if (mlo == mhi) + mlo = mhi = multadd(mhi, 10, 0); + else { + mlo = multadd(mlo, 10, 0); + mhi = multadd(mhi, 10, 0); + } + } + } + else + for (i = 1;; i++) { + *s++ = dig = quorem(b,S) + '0'; + if (!b->x[0] && b->wds <= 1) { +#ifdef SET_INEXACT + inexact = 0; +#endif + goto ret; + } + if (i >= ilim) + break; + b = multadd(b, 10, 0); + } + + /* Round off last digit */ + +#ifdef Honor_FLT_ROUNDS + switch (rounding) { + case 0: goto trimzeros; + case 2: goto roundoff; + } +#endif + b = lshift(b, 1); + j = cmp(b, S); + if (j > 0 || (j == 0 && (dig & 1))) { + roundoff: + while (*--s == '9') + if (s == s0) { + k++; + *s++ = '1'; + goto ret; + } + if (!half || (*s - '0') & 1) + ++*s; + } + else { + while (*--s == '0') ; + } + s++; +ret: + Bfree(S); + if (mhi) { + if (mlo && mlo != mhi) + Bfree(mlo); + Bfree(mhi); + } +ret1: +#ifdef SET_INEXACT + if (inexact) { + if (!oldinexact) { + word0(d) = Exp_1 + (70 << Exp_shift); + word1(d) = 0; + dval(d) += 1.; + } + } + else if (!oldinexact) + clear_inexact(); +#endif + Bfree(b); + *s = 0; + *decpt = k + 1; + if (rve) + *rve = s; + return s0; +} + +/*- + * Copyright (c) 2004-2008 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#define DBL_MANH_SIZE 20 +#define DBL_MANL_SIZE 32 +#define DBL_ADJ (DBL_MAX_EXP - 2) +#define SIGFIGS ((DBL_MANT_DIG + 3) / 4 + 1) +#define dexp_get(u) ((int)(word0(u) >> Exp_shift) & ~Exp_msk1) +#define dexp_set(u,v) (word0(u) = (((int)(word0(u)) & ~Exp_mask) | ((v) << Exp_shift))) +#define dmanh_get(u) ((uint32_t)(word0(u) & Frac_mask)) +#define dmanl_get(u) ((uint32_t)word1(u)) + + +/* + * This procedure converts a double-precision number in IEEE format + * into a string of hexadecimal digits and an exponent of 2. Its + * behavior is bug-for-bug compatible with dtoa() in mode 2, with the + * following exceptions: + * + * - An ndigits < 0 causes it to use as many digits as necessary to + * represent the number exactly. + * - The additional xdigs argument should point to either the string + * "0123456789ABCDEF" or the string "0123456789abcdef", depending on + * which case is desired. + * - This routine does not repeat dtoa's mistake of setting decpt + * to 9999 in the case of an infinity or NaN. INT_MAX is used + * for this purpose instead. + * + * Note that the C99 standard does not specify what the leading digit + * should be for non-zero numbers. For instance, 0x1.3p3 is the same + * as 0x2.6p2 is the same as 0x4.cp3. This implementation always makes + * the leading digit a 1. This ensures that the exponent printed is the + * actual base-2 exponent, i.e., ilogb(d). + * + * Inputs: d, xdigs, ndigits + * Outputs: decpt, sign, rve + */ +char * +hdtoa(double d, const char *xdigs, int ndigits, int *decpt, int *sign, char **rve) +{ + U u; + char *s, *s0; + int bufsize; + uint32_t manh, manl; + + u.d = d; + if (word0(u) & Sign_bit) { + /* set sign for everything, including 0's and NaNs */ + *sign = 1; + word0(u) &= ~Sign_bit; /* clear sign bit */ + } + else + *sign = 0; + + if (isinf(d)) { /* FP_INFINITE */ + *decpt = INT_MAX; + return rv_strdup(INFSTR, rve); + } + else if (isnan(d)) { /* FP_NAN */ + *decpt = INT_MAX; + return rv_strdup(NANSTR, rve); + } + else if (d == 0.0) { /* FP_ZERO */ + *decpt = 1; + return rv_strdup(ZEROSTR, rve); + } + else if (dexp_get(u)) { /* FP_NORMAL */ + *decpt = dexp_get(u) - DBL_ADJ; + } + else { /* FP_SUBNORMAL */ + u.d *= 5.363123171977039e+154 /* 0x1p514 */; + *decpt = dexp_get(u) - (514 + DBL_ADJ); + } + + if (ndigits == 0) /* dtoa() compatibility */ + ndigits = 1; + + /* + * If ndigits < 0, we are expected to auto-size, so we allocate + * enough space for all the digits. + */ + bufsize = (ndigits > 0) ? ndigits : SIGFIGS; + s0 = rv_alloc(bufsize+1); + + /* Round to the desired number of digits. */ + if (SIGFIGS > ndigits && ndigits > 0) { + float redux = 1.0f; + int offset = 4 * ndigits + DBL_MAX_EXP - 4 - DBL_MANT_DIG; + dexp_set(u, offset); + u.d += redux; + u.d -= redux; + *decpt += dexp_get(u) - offset; + } + + manh = dmanh_get(u); + manl = dmanl_get(u); + *s0 = '1'; + for (s = s0 + 1; s < s0 + bufsize; s++) { + *s = xdigs[(manh >> (DBL_MANH_SIZE - 4)) & 0xf]; + manh = (manh << 4) | (manl >> (DBL_MANL_SIZE - 4)); + manl <<= 4; + } + + /* If ndigits < 0, we are expected to auto-size the precision. */ + if (ndigits < 0) { + for (ndigits = SIGFIGS; s0[ndigits - 1] == '0'; ndigits--) + ; + } + + s = s0 + ndigits; + *s = '\0'; + if (rve != NULL) + *rve = s; + return (s0); +} + +#ifdef __cplusplus +#if 0 +{ /* satisfy cc-mode */ +#endif +} +#endif diff --git a/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/static_assert.h b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/static_assert.h new file mode 100644 index 0000000..9295729 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/ext/bigdecimal/static_assert.h @@ -0,0 +1,54 @@ +#ifndef BIGDECIMAL_STATIC_ASSERT_H +#define BIGDECIMAL_STATIC_ASSERT_H + +#include "feature.h" + +#ifdef HAVE_RUBY_INTERNAL_STATIC_ASSERT_H +# include +#endif + +#ifdef RBIMPL_STATIC_ASSERT +# define STATIC_ASSERT RBIMPL_STATIC_ASSERT +#endif + +#ifndef STATIC_ASSERT +# /* The following section is copied from CRuby's static_assert.h */ + +# if defined(__cplusplus) && defined(__cpp_static_assert) +# /* https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations */ +# define BIGDECIMAL_STATIC_ASSERT0 static_assert + +# elif defined(__cplusplus) && defined(_MSC_VER) && _MSC_VER >= 1600 +# define BIGDECIMAL_STATIC_ASSERT0 static_assert + +# elif defined(__INTEL_CXX11_MODE__) +# define BIGDECIMAL_STATIC_ASSERT0 static_assert + +# elif defined(__cplusplus) && __cplusplus >= 201103L +# define BIGDECIMAL_STATIC_ASSERT0 static_assert + +# elif defined(__cplusplus) && __has_extension(cxx_static_assert) +# define BIGDECIMAL_STATIC_ASSERT0 __extension__ static_assert + +# elif defined(__STDC_VERSION__) && __has_extension(c_static_assert) +# define BIGDECIMAL_STATIC_ASSERT0 __extension__ _Static_assert + +# elif defined(__STDC_VERSION__) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +# define BIGDECIMAL_STATIC_ASSERT0 __extension__ _Static_assert +#endif + +# if defined(__DOXYGEN__) +# define STATIC_ASSERT static_assert + +# elif defined(BIGDECIMAL_STATIC_ASSERT0) +# define STATIC_ASSERT(name, expr) \ + BIGDECIMAL_STATIC_ASSERT0(expr, #name ": " #expr) + +# else +# define STATIC_ASSERT(name, expr) \ + typedef int static_assert_ ## name ## _check[1 - 2 * !(expr)] +# endif +#endif /* STATIC_ASSERT */ + + +#endif /* BIGDECIMAL_STATIC_ASSERT_H */ diff --git a/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/lib/bigdecimal.rb b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/lib/bigdecimal.rb new file mode 100644 index 0000000..db03a17 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/lib/bigdecimal.rb @@ -0,0 +1,356 @@ +if RUBY_ENGINE == 'jruby' + JRuby::Util.load_ext("org.jruby.ext.bigdecimal.BigDecimalLibrary") + + class BigDecimal + def _decimal_shift(i) # :nodoc: + to_java.move_point_right(i).to_d + end + end +else + require 'bigdecimal.so' +end + +class BigDecimal + module Internal # :nodoc: + + # Coerce x to BigDecimal with the specified precision. + # TODO: some methods (example: BigMath.exp) require more precision than specified to coerce. + def self.coerce_to_bigdecimal(x, prec, method_name) # :nodoc: + case x + when BigDecimal + return x + when Integer, Float + return BigDecimal(x, 0) + when Rational + return BigDecimal(x, [prec, 2 * BigDecimal.double_fig].max) + end + raise ArgumentError, "#{x.inspect} can't be coerced into BigDecimal" + end + + def self.coerce_validate_prec(prec, method_name, accept_zero: false) # :nodoc: + unless Integer === prec + original = prec + # Emulate Integer.try_convert for ruby < 3.1 + if prec.respond_to?(:to_int) + prec = prec.to_int + else + raise TypeError, "no implicit conversion of #{original.class} into Integer" + end + raise TypeError, "can't convert #{original.class} to Integer" unless Integer === prec + end + + if accept_zero + raise ArgumentError, "Negative precision for #{method_name}" if prec < 0 + else + raise ArgumentError, "Zero or negative precision for #{method_name}" if prec <= 0 + end + prec + end + + def self.infinity_computation_result # :nodoc: + if BigDecimal.mode(BigDecimal::EXCEPTION_ALL).anybits?(BigDecimal::EXCEPTION_INFINITY) + raise FloatDomainError, "Computation results in 'Infinity'" + end + BigDecimal::INFINITY + end + + def self.nan_computation_result # :nodoc: + if BigDecimal.mode(BigDecimal::EXCEPTION_ALL).anybits?(BigDecimal::EXCEPTION_NaN) + raise FloatDomainError, "Computation results to 'NaN'" + end + BigDecimal::NAN + end + end + + # call-seq: + # self ** other -> bigdecimal + # + # Returns the \BigDecimal value of +self+ raised to power +other+: + # + # b = BigDecimal('3.14') + # b ** 2 # => 0.98596e1 + # b ** 2.0 # => 0.98596e1 + # b ** Rational(2, 1) # => 0.98596e1 + # + # Related: BigDecimal#power. + # + def **(y) + case y + when BigDecimal, Integer, Float, Rational + power(y) + when nil + raise TypeError, 'wrong argument type NilClass' + else + x, y = y.coerce(self) + x**y + end + end + + # call-seq: + # power(n) + # power(n, prec) + # + # Returns the value raised to the power of n. + # + # Also available as the operator **. + # + def power(y, prec = 0) + prec = Internal.coerce_validate_prec(prec, :power, accept_zero: true) + x = self + y = Internal.coerce_to_bigdecimal(y, prec.nonzero? || n_significant_digits, :power) + + return Internal.nan_computation_result if x.nan? || y.nan? + return BigDecimal(1) if y.zero? + + if y.infinite? + if x < 0 + return BigDecimal(0) if x < -1 && y.negative? + return BigDecimal(0) if x > -1 && y.positive? + raise Math::DomainError, 'Result undefined for negative base raised to infinite power' + elsif x < 1 + return y.positive? ? BigDecimal(0) : BigDecimal::Internal.infinity_computation_result + elsif x == 1 + return BigDecimal(1) + else + return y.positive? ? BigDecimal::Internal.infinity_computation_result : BigDecimal(0) + end + end + + if x.infinite? && y < 0 + # Computation result will be +0 or -0. Avoid overflow. + neg = x < 0 && y.frac.zero? && y % 2 == 1 + return neg ? -BigDecimal(0) : BigDecimal(0) + end + + if x.zero? + return BigDecimal(1) if y.zero? + return BigDecimal(0) if y > 0 + if y.frac.zero? && y % 2 == 1 && x.sign == -1 + return -BigDecimal::Internal.infinity_computation_result + else + return BigDecimal::Internal.infinity_computation_result + end + elsif x < 0 + if y.frac.zero? + if y % 2 == 0 + return (-x).power(y, prec) + else + return -(-x).power(y, prec) + end + else + raise Math::DomainError, 'Computation results in complex number' + end + elsif x == 1 + return BigDecimal(1) + end + + prec = BigDecimal.limit if prec.zero? + frac_part = y.frac + + if frac_part.zero? && prec.zero? + # Infinite precision calculation for `x ** int` and `x.power(int)` + int_part = y.fix.to_i + int_part = -int_part if (neg = int_part < 0) + ans = BigDecimal(1) + n = 1 + xn = x + while true + ans *= xn if int_part.allbits?(n) + n <<= 1 + break if n > int_part + xn *= xn + # Detect overflow/underflow before consuming infinite memory + if (xn.exponent.abs - 1) * int_part / n >= 0x7FFFFFFFFFFFFFFF + return ((xn.exponent > 0) ^ neg ? BigDecimal::Internal.infinity_computation_result : BigDecimal(0)) * (int_part.even? || x > 0 ? 1 : -1) + end + end + return neg ? BigDecimal(1) / ans : ans + end + + prec = [x.n_significant_digits, y.n_significant_digits, BigDecimal.double_fig].max + BigDecimal.double_fig if prec.zero? + + if y < 0 + inv = x.power(-y, prec) + return BigDecimal(0) if inv.infinite? + return BigDecimal::Internal.infinity_computation_result if inv.zero? + return BigDecimal(1).div(inv, prec) + end + + prec2 = prec + BigDecimal.double_fig + + if frac_part.zero? && y.exponent < Math.log(prec) * 5 + 20 + # Use exponentiation by squaring if y is an integer and not too large + pow_prec = prec2 + y.exponent + n = 1 + xn = x + ans = BigDecimal(1) + int_part = y.fix.to_i + while true + ans = ans.mult(xn, pow_prec) if int_part.allbits?(n) + n <<= 1 + break if n > int_part + xn = xn.mult(xn, pow_prec) + end + ans.mult(1, prec) + else + if x > 1 + # To calculate exp(z, prec), z needs prec+max(z.exponent, 0) precision if z > 0. + # Estimate (y*log(x)).exponent + logx_exponent = x < 2 ? (x - 1).exponent : Math.log10(x.exponent).round + ylogx_exponent = y.exponent + logx_exponent + prec2 += [ylogx_exponent, 0].max + end + BigMath.exp(BigMath.log(x, prec2).mult(y, prec2), prec) + end + end + + # Returns the square root of the value. + # + # Result has at least prec significant digits. + # + def sqrt(prec) + prec = Internal.coerce_validate_prec(prec, :sqrt, accept_zero: true) + return Internal.infinity_computation_result if infinite? == 1 + + raise FloatDomainError, 'sqrt of negative value' if self < 0 + raise FloatDomainError, "sqrt of 'NaN'(Not a Number)" if nan? + return self if zero? + + if prec == 0 + prec = BigDecimal.limit.nonzero? || n_significant_digits + BigDecimal.double_fig + end + + ex = exponent / 2 + x = _decimal_shift(-2 * ex) + y = BigDecimal(Math.sqrt(x.to_f), 0) + precs = [prec + BigDecimal.double_fig] + precs << 2 + precs.last / 2 while precs.last > BigDecimal.double_fig + precs.reverse_each do |p| + y = y.add(x.div(y, p), p).div(2, p) + end + y._decimal_shift(ex).mult(1, prec) + end +end + +# Core BigMath methods for BigDecimal (log, exp) are defined here. +# Other methods (sin, cos, atan) are defined in 'bigdecimal/math.rb'. +module BigMath + + # call-seq: + # BigMath.log(decimal, numeric) -> BigDecimal + # + # Computes the natural logarithm of +decimal+ to the specified number of + # digits of precision, +numeric+. + # + # If +decimal+ is zero or negative, raises Math::DomainError. + # + # If +decimal+ is positive infinity, returns Infinity. + # + # If +decimal+ is NaN, returns NaN. + # + def self.log(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :log) + raise Math::DomainError, 'Complex argument for BigMath.log' if Complex === x + + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :log) + return BigDecimal::Internal.nan_computation_result if x.nan? + raise Math::DomainError, 'Negative argument for log' if x < 0 + return -BigDecimal::Internal.infinity_computation_result if x.zero? + return BigDecimal::Internal.infinity_computation_result if x.infinite? + return BigDecimal(0) if x == 1 + + prec2 = prec + BigDecimal.double_fig + BigDecimal.save_limit do + BigDecimal.limit(0) + if x > 10 || x < 0.1 + log10 = log(BigDecimal(10), prec2) + exponent = x.exponent + x = x._decimal_shift(-exponent) + if x < 0.3 + x *= 10 + exponent -= 1 + end + return (log10 * exponent).add(log(x, prec2), prec) + end + + x_minus_one_exponent = (x - 1).exponent + + # log(x) = log(sqrt(sqrt(sqrt(sqrt(x))))) * 2**sqrt_steps + sqrt_steps = [Integer.sqrt(prec2) + 3 * x_minus_one_exponent, 0].max + + lg2 = 0.3010299956639812 + sqrt_prec = prec2 + [-x_minus_one_exponent, 0].max + (sqrt_steps * lg2).ceil + + sqrt_steps.times do + x = x.sqrt(sqrt_prec) + end + + # Taylor series for log(x) around 1 + # log(x) = -log((1 + X) / (1 - X)) where X = (x - 1) / (x + 1) + # log(x) = 2 * (X + X**3 / 3 + X**5 / 5 + X**7 / 7 + ...) + x = (x - 1).div(x + 1, sqrt_prec) + y = x + x2 = x.mult(x, prec2) + 1.step do |i| + n = prec2 + x.exponent - y.exponent + x2.exponent + break if n <= 0 || x.zero? + x = x.mult(x2.round(n - x2.exponent), n) + y = y.add(x.div(2 * i + 1, n), prec2) + end + + y.mult(2 ** (sqrt_steps + 1), prec) + end + end + + # Taylor series for exp(x) around 0 + private_class_method def self._exp_taylor(x, prec) # :nodoc: + xn = BigDecimal(1) + y = BigDecimal(1) + 1.step do |i| + n = prec + xn.exponent + break if n <= 0 || xn.zero? + xn = xn.mult(x, n).div(i, n) + y = y.add(xn, prec) + end + y + end + + # call-seq: + # BigMath.exp(decimal, numeric) -> BigDecimal + # + # Computes the value of e (the base of natural logarithms) raised to the + # power of +decimal+, to the specified number of digits of precision. + # + # If +decimal+ is infinity, returns Infinity. + # + # If +decimal+ is NaN, returns NaN. + # + def self.exp(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :exp) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :exp) + return BigDecimal::Internal.nan_computation_result if x.nan? + return x.positive? ? BigDecimal::Internal.infinity_computation_result : BigDecimal(0) if x.infinite? + return BigDecimal(1) if x.zero? + + # exp(x * 10**cnt) = exp(x)**(10**cnt) + cnt = x < -1 || x > 1 ? x.exponent : 0 + prec2 = prec + BigDecimal.double_fig + cnt + x = x._decimal_shift(-cnt) + + # Calculation of exp(small_prec) is fast because calculation of x**n is fast + # Calculation of exp(small_abs) converges fast. + # exp(x) = exp(small_prec_part + small_abs_part) = exp(small_prec_part) * exp(small_abs_part) + x_small_prec = x.round(Integer.sqrt(prec2)) + y = _exp_taylor(x_small_prec, prec2).mult(_exp_taylor(x.sub(x_small_prec, prec2), prec2), prec2) + + # calculate exp(x * 10**cnt) from exp(x) + # exp(x * 10**k) = exp(x * 10**(k - 1)) ** 10 + cnt.times do + y2 = y.mult(y, prec2) + y5 = y2.mult(y2, prec2).mult(y, prec2) + y = y5.mult(y5, prec2) + end + + y.mult(1, prec) + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/lib/bigdecimal.so b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/lib/bigdecimal.so new file mode 100755 index 0000000..78e8578 Binary files /dev/null and b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/lib/bigdecimal.so differ diff --git a/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/lib/bigdecimal/jacobian.rb b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/lib/bigdecimal/jacobian.rb new file mode 100644 index 0000000..4448024 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/lib/bigdecimal/jacobian.rb @@ -0,0 +1,90 @@ +# frozen_string_literal: false + +require 'bigdecimal' + +# require 'bigdecimal/jacobian' +# +# Provides methods to compute the Jacobian matrix of a set of equations at a +# point x. In the methods below: +# +# f is an Object which is used to compute the Jacobian matrix of the equations. +# It must provide the following methods: +# +# f.values(x):: returns the values of all functions at x +# +# f.zero:: returns 0.0 +# f.one:: returns 1.0 +# f.two:: returns 2.0 +# f.ten:: returns 10.0 +# +# f.eps:: returns the convergence criterion (epsilon value) used to determine whether two values are considered equal. If |a-b| < epsilon, the two values are considered equal. +# +# x is the point at which to compute the Jacobian. +# +# fx is f.values(x). +# +module Jacobian + module_function + + # Determines the equality of two numbers by comparing to zero, or using the epsilon value + def isEqual(a,b,zero=0.0,e=1.0e-8) + aa = a.abs + bb = b.abs + if aa == zero && bb == zero then + true + else + if ((a-b)/(aa+bb)).abs < e then + true + else + false + end + end + end + + + # Computes the derivative of +f[i]+ at +x[i]+. + # +fx+ is the value of +f+ at +x+. + def dfdxi(f,fx,x,i) + nRetry = 0 + n = x.size + xSave = x[i] + ok = 0 + ratio = f.ten*f.ten*f.ten + dx = x[i].abs/ratio + dx = fx[i].abs/ratio if isEqual(dx,f.zero,f.zero,f.eps) + dx = f.one/f.ten if isEqual(dx,f.zero,f.zero,f.eps) + until ok>0 do + deriv = [] + nRetry += 1 + if nRetry > 100 + raise "Singular Jacobian matrix. No change at x[" + i.to_s + "]" + end + dx = dx*f.two + x[i] += dx + fxNew = f.values(x) + for j in 0...n do + if !isEqual(fxNew[j],fx[j],f.zero,f.eps) then + ok += 1 + deriv <<= (fxNew[j]-fx[j])/dx + else + deriv <<= f.zero + end + end + x[i] = xSave + end + deriv + end + + # Computes the Jacobian of +f+ at +x+. +fx+ is the value of +f+ at +x+. + def jacobian(f,fx,x) + n = x.size + dfdx = Array.new(n*n) + for i in 0...n do + df = dfdxi(f,fx,x,i) + for j in 0...n do + dfdx[j*n+i] = df[j] + end + end + dfdx + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/lib/bigdecimal/ludcmp.rb b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/lib/bigdecimal/ludcmp.rb new file mode 100644 index 0000000..dd265e4 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/lib/bigdecimal/ludcmp.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: false +require 'bigdecimal' + +# +# Solves a*x = b for x, using LU decomposition. +# +module LUSolve + module_function + + # Performs LU decomposition of the n by n matrix a. + def ludecomp(a,n,zero=0,one=1) + prec = BigDecimal.limit(nil) + ps = [] + scales = [] + for i in 0...n do # pick up largest(abs. val.) element in each row. + ps <<= i + nrmrow = zero + ixn = i*n + for j in 0...n do + biggst = a[ixn+j].abs + nrmrow = biggst if biggst>nrmrow + end + if nrmrow>zero then + scales <<= one.div(nrmrow,prec) + else + raise "Singular matrix" + end + end + n1 = n - 1 + for k in 0...n1 do # Gaussian elimination with partial pivoting. + biggst = zero; + for i in k...n do + size = a[ps[i]*n+k].abs*scales[ps[i]] + if size>biggst then + biggst = size + pividx = i + end + end + raise "Singular matrix" if biggst<=zero + if pividx!=k then + j = ps[k] + ps[k] = ps[pividx] + ps[pividx] = j + end + pivot = a[ps[k]*n+k] + for i in (k+1)...n do + psin = ps[i]*n + a[psin+k] = mult = a[psin+k].div(pivot,prec) + if mult!=zero then + pskn = ps[k]*n + for j in (k+1)...n do + a[psin+j] -= mult.mult(a[pskn+j],prec) + end + end + end + end + raise "Singular matrix" if a[ps[n1]*n+n1] == zero + ps + end + + # Solves a*x = b for x, using LU decomposition. + # + # a is a matrix, b is a constant vector, x is the solution vector. + # + # ps is the pivot, a vector which indicates the permutation of rows performed + # during LU decomposition. + def lusolve(a,b,ps,zero=0.0) + prec = BigDecimal.limit(nil) + n = ps.size + x = [] + for i in 0...n do + dot = zero + psin = ps[i]*n + for j in 0...i do + dot = a[psin+j].mult(x[j],prec) + dot + end + x <<= b[ps[i]] - dot + end + (n-1).downto(0) do |i| + dot = zero + psin = ps[i]*n + for j in (i+1)...n do + dot = a[psin+j].mult(x[j],prec) + dot + end + x[i] = (x[i]-dot).div(a[psin+i],prec) + end + x + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/lib/bigdecimal/math.rb b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/lib/bigdecimal/math.rb new file mode 100644 index 0000000..d2d2e68 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/lib/bigdecimal/math.rb @@ -0,0 +1,249 @@ +# frozen_string_literal: false +require 'bigdecimal' + +# +#-- +# Contents: +# sqrt(x, prec) +# sin (x, prec) +# cos (x, prec) +# tan (x, prec) +# atan(x, prec) +# PI (prec) +# E (prec) == exp(1.0,prec) +# +# where: +# x ... BigDecimal number to be computed. +# prec ... Number of digits to be obtained. +#++ +# +# Provides mathematical functions. +# +# Example: +# +# require "bigdecimal/math" +# +# include BigMath +# +# a = BigDecimal((PI(49)/2).to_s) +# puts sin(a,100) # => 0.9999999999...9999999986e0 +# +module BigMath + module_function + + # call-seq: + # sqrt(decimal, numeric) -> BigDecimal + # + # Computes the square root of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # BigMath.sqrt(BigDecimal('2'), 32).to_s + # #=> "0.14142135623730950488016887242097e1" + # + def sqrt(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :sqrt) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :sqrt) + x.sqrt(prec) + end + + + # Returns [sign, reduced_x] where reduced_x is in -pi/2..pi/2 + # and satisfies sin(x) = sign * sin(reduced_x) + # If add_half_pi is true, adds pi/2 to x before reduction. + # Precision of pi is adjusted to ensure reduced_x has the required precision. + private_class_method def _sin_periodic_reduction(x, prec, add_half_pi: false) # :nodoc: + return [1, x] if -Math::PI/2 <= x && x <= Math::PI/2 && !add_half_pi + + mod_prec = prec + BigDecimal.double_fig + pi_extra_prec = [x.exponent, 0].max + BigDecimal.double_fig + while true + pi = PI(mod_prec + pi_extra_prec) + half_pi = pi / 2 + div, mod = (add_half_pi ? x + pi : x + half_pi).divmod(pi) + mod -= half_pi + if mod.zero? || mod_prec + mod.exponent <= 0 + # mod is too small to estimate required pi precision + mod_prec = mod_prec * 3 / 2 + BigDecimal.double_fig + elsif mod_prec + mod.exponent < prec + # Estimate required precision of pi + mod_prec = prec - mod.exponent + BigDecimal.double_fig + else + return [div % 2 == 0 ? 1 : -1, mod.mult(1, prec)] + end + end + end + + # call-seq: + # sin(decimal, numeric) -> BigDecimal + # + # Computes the sine of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # If +decimal+ is Infinity or NaN, returns NaN. + # + # BigMath.sin(BigMath.PI(5)/4, 32).to_s + # #=> "0.70710807985947359435812921837984e0" + # + def sin(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :sin) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :sin) + return BigDecimal::Internal.nan_computation_result if x.infinite? || x.nan? + n = prec + BigDecimal.double_fig + one = BigDecimal("1") + two = BigDecimal("2") + sign, x = _sin_periodic_reduction(x, n) + x1 = x + x2 = x.mult(x,n) + y = x + d = y + i = one + z = one + while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0) + m = BigDecimal.double_fig if m < BigDecimal.double_fig + x1 = -x2.mult(x1,n) + i += two + z *= (i-one) * i + d = x1.div(z,m) + y += d + end + y = BigDecimal("1") if y > 1 + y.mult(sign, prec) + end + + # call-seq: + # cos(decimal, numeric) -> BigDecimal + # + # Computes the cosine of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # If +decimal+ is Infinity or NaN, returns NaN. + # + # BigMath.cos(BigMath.PI(16), 32).to_s + # #=> "-0.99999999999999999999999999999997e0" + # + def cos(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :cos) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :cos) + return BigDecimal::Internal.nan_computation_result if x.infinite? || x.nan? + sign, x = _sin_periodic_reduction(x, prec + BigDecimal.double_fig, add_half_pi: true) + sign * sin(x, prec) + end + + # call-seq: + # tan(decimal, numeric) -> BigDecimal + # + # Computes the tangent of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # If +decimal+ is Infinity or NaN, returns NaN. + # + # BigMath.tan(BigDecimal("0.0"), 4).to_s + # #=> "0.0" + # + # BigMath.tan(BigMath.PI(24) / 4, 32).to_s + # #=> "0.99999999999999999999999830836025e0" + # + def tan(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :tan) + sin(x, prec + BigDecimal.double_fig).div(cos(x, prec + BigDecimal.double_fig), prec) + end + + # call-seq: + # atan(decimal, numeric) -> BigDecimal + # + # Computes the arctangent of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # If +decimal+ is NaN, returns NaN. + # + # BigMath.atan(BigDecimal('-1'), 32).to_s + # #=> "-0.78539816339744830961566084581988e0" + # + def atan(x, prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :atan) + x = BigDecimal::Internal.coerce_to_bigdecimal(x, prec, :atan) + return BigDecimal::Internal.nan_computation_result if x.nan? + n = prec + BigDecimal.double_fig + pi = PI(n) + x = -x if neg = x < 0 + return pi.div(neg ? -2 : 2, prec) if x.infinite? + return pi.div(neg ? -4 : 4, prec) if x.round(prec) == 1 + x = BigDecimal("1").div(x, n) if inv = x > 1 + x = (-1 + sqrt(1 + x.mult(x, n), n)).div(x, n) if dbl = x > 0.5 + y = x + d = y + t = x + r = BigDecimal("3") + x2 = x.mult(x,n) + while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0) + m = BigDecimal.double_fig if m < BigDecimal.double_fig + t = -t.mult(x2,n) + d = t.div(r,m) + y += d + r += 2 + end + y *= 2 if dbl + y = pi / 2 - y if inv + y = -y if neg + y.mult(1, prec) + end + + # call-seq: + # PI(numeric) -> BigDecimal + # + # Computes the value of pi to the specified number of digits of precision, + # +numeric+. + # + # BigMath.PI(32).to_s + # #=> "0.31415926535897932384626433832795e1" + # + def PI(prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :PI) + n = prec + BigDecimal.double_fig + zero = BigDecimal("0") + one = BigDecimal("1") + two = BigDecimal("2") + + m25 = BigDecimal("-0.04") + m57121 = BigDecimal("-57121") + + pi = zero + + d = one + k = one + t = BigDecimal("-80") + while d.nonzero? && ((m = n - (pi.exponent - d.exponent).abs) > 0) + m = BigDecimal.double_fig if m < BigDecimal.double_fig + t = t*m25 + d = t.div(k,m) + k = k+two + pi = pi + d + end + + d = one + k = one + t = BigDecimal("956") + while d.nonzero? && ((m = n - (pi.exponent - d.exponent).abs) > 0) + m = BigDecimal.double_fig if m < BigDecimal.double_fig + t = t.div(m57121,n) + d = t.div(k,m) + pi = pi + d + k = k+two + end + pi.mult(1, prec) + end + + # call-seq: + # E(numeric) -> BigDecimal + # + # Computes e (the base of natural logarithms) to the specified number of + # digits of precision, +numeric+. + # + # BigMath.E(32).to_s + # #=> "0.27182818284590452353602874713527e1" + # + def E(prec) + prec = BigDecimal::Internal.coerce_validate_prec(prec, :E) + BigMath.exp(1, prec) + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/lib/bigdecimal/newton.rb b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/lib/bigdecimal/newton.rb new file mode 100644 index 0000000..85bacb7 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/lib/bigdecimal/newton.rb @@ -0,0 +1,80 @@ +# frozen_string_literal: false +require "bigdecimal/ludcmp" +require "bigdecimal/jacobian" + +# +# newton.rb +# +# Solves the nonlinear algebraic equation system f = 0 by Newton's method. +# This program is not dependent on BigDecimal. +# +# To call: +# n = nlsolve(f,x) +# where n is the number of iterations required, +# x is the initial value vector +# f is an Object which is used to compute the values of the equations to be solved. +# It must provide the following methods: +# +# f.values(x):: returns the values of all functions at x +# +# f.zero:: returns 0.0 +# f.one:: returns 1.0 +# f.two:: returns 2.0 +# f.ten:: returns 10.0 +# +# f.eps:: returns the convergence criterion (epsilon value) used to determine whether two values are considered equal. If |a-b| < epsilon, the two values are considered equal. +# +# On exit, x is the solution vector. +# +module Newton + include LUSolve + include Jacobian + module_function + + def norm(fv,zero=0.0) # :nodoc: + s = zero + n = fv.size + for i in 0...n do + s += fv[i]*fv[i] + end + s + end + + # See also Newton + def nlsolve(f,x) + nRetry = 0 + n = x.size + + f0 = f.values(x) + zero = f.zero + one = f.one + two = f.two + p5 = one/two + d = norm(f0,zero) + minfact = f.ten*f.ten*f.ten + minfact = one/minfact + e = f.eps + while d >= e do + nRetry += 1 + # Not yet converged. => Compute Jacobian matrix + dfdx = jacobian(f,f0,x) + # Solve dfdx*dx = -f0 to estimate dx + dx = lusolve(dfdx,f0,ludecomp(dfdx,n,zero,one),zero) + fact = two + xs = x.dup + begin + fact *= p5 + if fact < minfact then + raise "Failed to reduce function values." + end + for i in 0...n do + x[i] = xs[i] - dx[i]*fact + end + f0 = f.values(x) + dn = norm(f0,zero) + end while(dn>=d) + d = dn + end + nRetry + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/lib/bigdecimal/util.rb b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/lib/bigdecimal/util.rb new file mode 100644 index 0000000..7c5f32e --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/lib/bigdecimal/util.rb @@ -0,0 +1,186 @@ +# frozen_string_literal: false +# +#-- +# bigdecimal/util extends various native classes to provide the #to_d method, +# and provides BigDecimal#to_d and BigDecimal#to_digits. +#++ + +require 'bigdecimal' + +class Integer < Numeric + # call-seq: + # int.to_d -> bigdecimal + # + # Returns the value of +int+ as a BigDecimal. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # 42.to_d # => 0.42e2 + # + # See also Kernel.BigDecimal. + # + def to_d + BigDecimal(self) + end +end + + +class Float < Numeric + # call-seq: + # float.to_d -> bigdecimal + # float.to_d(precision) -> bigdecimal + # + # Returns the value of +float+ as a BigDecimal. + # The +precision+ parameter is used to determine the number of + # significant digits for the result. When +precision+ is set to +0+, + # the number of digits to represent the float being converted is determined + # automatically. + # The default +precision+ is +0+. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # 0.5.to_d # => 0.5e0 + # 1.234.to_d # => 0.1234e1 + # 1.234.to_d(2) # => 0.12e1 + # + # See also Kernel.BigDecimal. + # + def to_d(precision=0) + BigDecimal(self, precision) + end +end + + +class String + # call-seq: + # str.to_d -> bigdecimal + # + # Returns the result of interpreting leading characters in +str+ + # as a BigDecimal. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # "0.5".to_d # => 0.5e0 + # "123.45e1".to_d # => 0.12345e4 + # "45.67 degrees".to_d # => 0.4567e2 + # + # See also Kernel.BigDecimal. + # + def to_d + BigDecimal.interpret_loosely(self) + end +end + + +class BigDecimal < Numeric + # call-seq: + # a.to_digits -> string + # + # Converts a BigDecimal to a String of the form "nnnnnn.mmm". + # This method is deprecated; use BigDecimal#to_s("F") instead. + # + # require 'bigdecimal/util' + # + # d = BigDecimal("3.14") + # d.to_digits # => "3.14" + # + def to_digits + if self.nan? || self.infinite? || self.zero? + self.to_s + else + i = self.to_i.to_s + _,f,_,z = self.frac.split + i + "." + ("0"*(-z)) + f + end + end + + # call-seq: + # a.to_d -> bigdecimal + # + # Returns self. + # + # require 'bigdecimal/util' + # + # d = BigDecimal("3.14") + # d.to_d # => 0.314e1 + # + def to_d + self + end +end + + +class Rational < Numeric + # call-seq: + # rat.to_d(precision) -> bigdecimal + # + # Returns the value as a BigDecimal. + # + # The +precision+ parameter is used to determine the number of + # significant digits for the result. When +precision+ is set to +0+, + # the number of digits to represent the float being converted is determined + # automatically. + # The default +precision+ is +0+. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # Rational(22, 7).to_d(3) # => 0.314e1 + # + # See also Kernel.BigDecimal. + # + def to_d(precision=0) + BigDecimal(self, precision) + end +end + + +class Complex < Numeric + # call-seq: + # cmp.to_d -> bigdecimal + # cmp.to_d(precision) -> bigdecimal + # + # Returns the value as a BigDecimal. + # If the imaginary part is not +0+, an error is raised + # + # The +precision+ parameter is used to determine the number of + # significant digits for the result. When +precision+ is set to +0+, + # the number of digits to represent the float being converted is determined + # automatically. + # The default +precision+ is +0+. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # Complex(0.1234567, 0).to_d(4) # => 0.1235e0 + # Complex(Rational(22, 7), 0).to_d(3) # => 0.314e1 + # Complex(1, 1).to_d # raises ArgumentError + # + # See also Kernel.BigDecimal. + # + def to_d(precision=0) + BigDecimal(self) unless self.imag.zero? # to raise error + + BigDecimal(self.real, precision) + end +end + + +class NilClass + # call-seq: + # nil.to_d -> bigdecimal + # + # Returns nil represented as a BigDecimal. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # nil.to_d # => 0.0 + # + def to_d + BigDecimal(0) + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/sample/linear.rb b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/sample/linear.rb new file mode 100644 index 0000000..516c247 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/sample/linear.rb @@ -0,0 +1,74 @@ +#!/usr/local/bin/ruby +# frozen_string_literal: false + +# +# linear.rb +# +# Solves linear equation system(A*x = b) by LU decomposition method. +# where A is a coefficient matrix,x is an answer vector,b is a constant vector. +# +# USAGE: +# ruby linear.rb [input file solved] +# + +# :stopdoc: +require "bigdecimal" +require "bigdecimal/ludcmp" + +# +# NOTE: +# Change following BigDecimal.limit() if needed. +BigDecimal.limit(100) +# + +include LUSolve +def rd_order(na) + printf("Number of equations ?") if(na <= 0) + n = ARGF.gets().to_i +end + +na = ARGV.size +zero = BigDecimal("0.0") +one = BigDecimal("1.0") + +while (n=rd_order(na))>0 + a = [] + as= [] + b = [] + if na <= 0 + # Read data from console. + printf("\nEnter coefficient matrix element A[i,j]\n") + for i in 0...n do + for j in 0...n do + printf("A[%d,%d]? ",i,j); s = ARGF.gets + a << BigDecimal(s) + as << BigDecimal(s) + end + printf("Contatant vector element b[%d] ? ",i) + b << BigDecimal(ARGF.gets) + end + else + # Read data from specified file. + printf("Coefficient matrix and constant vector.\n") + for i in 0...n do + s = ARGF.gets + printf("%d) %s",i,s) + s = s.split + for j in 0...n do + a << BigDecimal(s[j]) + as << BigDecimal(s[j]) + end + b << BigDecimal(s[n]) + end + end + x = lusolve(a,b,ludecomp(a,n,zero,one),zero) + printf("Answer(x[i] & (A*x-b)[i]) follows\n") + for i in 0...n do + printf("x[%d]=%s ",i,x[i].to_s) + s = zero + for j in 0...n do + s = s + as[i*n+j]*x[j] + end + printf(" & %s\n",(s-b[i]).to_s) + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/sample/nlsolve.rb b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/sample/nlsolve.rb new file mode 100644 index 0000000..c2227da --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/sample/nlsolve.rb @@ -0,0 +1,40 @@ +#!/usr/local/bin/ruby +# frozen_string_literal: false + +# +# nlsolve.rb +# An example for solving nonlinear algebraic equation system. +# + +require "bigdecimal" +require "bigdecimal/newton" +include Newton + +class Function # :nodoc: all + def initialize() + @zero = BigDecimal("0.0") + @one = BigDecimal("1.0") + @two = BigDecimal("2.0") + @ten = BigDecimal("10.0") + @eps = BigDecimal("1.0e-16") + end + def zero;@zero;end + def one ;@one ;end + def two ;@two ;end + def ten ;@ten ;end + def eps ;@eps ;end + def values(x) # <= defines functions solved + f = [] + f1 = x[0]*x[0] + x[1]*x[1] - @two # f1 = x**2 + y**2 - 2 => 0 + f2 = x[0] - x[1] # f2 = x - y => 0 + f <<= f1 + f <<= f2 + f + end +end + +f = BigDecimal.limit(100) +f = Function.new +x = [f.zero,f.zero] # Initial values +n = nlsolve(f,x) +p x diff --git a/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/sample/pi.rb b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/sample/pi.rb new file mode 100644 index 0000000..ea96638 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/bigdecimal-3.3.1/sample/pi.rb @@ -0,0 +1,21 @@ +#!/usr/local/bin/ruby +# frozen_string_literal: false + +# +# pi.rb +# +# Calculates 3.1415.... (the number of times that a circle's diameter +# will fit around the circle) using J. Machin's formula. +# + +require "bigdecimal" +require "bigdecimal/math.rb" + +include BigMath + +if ARGV.size == 1 + print "PI("+ARGV[0]+"):\n" + p PI(ARGV[0].to_i) +else + print "TRY: ruby pi.rb 1000 \n" +end diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/LICENSE.txt b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/LICENSE.txt new file mode 100644 index 0000000..07b1b7f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/LICENSE.txt @@ -0,0 +1,33 @@ +Copyright (C) 2005-2016 James Edward Gray II. All rights reserved. +Copyright (C) 2007-2017 Yukihiro Matsumoto. All rights reserved. +Copyright (C) 2017 SHIBATA Hiroshi. All rights reserved. +Copyright (C) 2017 Olivier Lacan. All rights reserved. +Copyright (C) 2017 Espartaco Palma. All rights reserved. +Copyright (C) 2017 Marcus Stollsteimer. All rights reserved. +Copyright (C) 2017 pavel. All rights reserved. +Copyright (C) 2017-2018 Steven Daniels. All rights reserved. +Copyright (C) 2018 Tomohiro Ogoke. All rights reserved. +Copyright (C) 2018 Kouhei Sutou. All rights reserved. +Copyright (C) 2018 Mitsutaka Mimura. All rights reserved. +Copyright (C) 2018 Vladislav. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/NEWS.md b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/NEWS.md new file mode 100644 index 0000000..58e4432 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/NEWS.md @@ -0,0 +1,1009 @@ +# News + +## 3.3.5 - 2025-06-01 + +### Improvements + + * docs: Fixed `StringScanner` document URL. + * GH-343 + * Patch by Petrik de Heus + +### Thanks + + * Petrik de Heus + +## 3.3.4 - 2025-04-13 + +### Improvements + + * `csv-filter`: Removed an experimental command line tool. + * GH-341 + +## 3.3.3 - 2025-03-20 + +### Improvements + + * `csv-filter`: Added an experimental command line tool to filter a CSV. + * Patch by Burdette Lamar + +### Fixes + + * Fixed wrong EOF detection for `ARGF` + * GH-328 + * Reported by Takeshi Nishimatsu + + * Fixed a regression bug that `CSV.open` rejects integer mode. + * GH-336 + * Reported by Dave Burgess + +### Thanks + + * Takeshi Nishimatsu + + * Burdette Lamar + + * Dave Burgess + +## 3.3.2 - 2024-12-21 + +### Fixes + + * Fixed a parse bug with a quoted line with `col_sep` and an empty + line. This was introduced in 3.3.1. + * GH-324 + * Reported by stoodfarback + +### Thanks + + * stoodfarback + +## 3.3.1 - 2024-12-15 + +### Improvements + + * `CSV.open`: Changed to detect BOM by default. Note that this isn't + enabled on Windows because Ruby may have a bug. See also: + https://bugs.ruby-lang.org/issues/20526 + * GH-301 + * Reported by Junichi Ito + + * Improved performance. + * GH-311 + * GH-312 + * Patch by Vladimir Kochnev + + * `CSV.open`: Added support for `StringIO` as an input. + * GH-300 + * GH-302 + * Patch by Marcelo + + * Added a built-in time converter. You can use it by `converters: + :time`. + * GH-313 + * Patch by Bart de Water + + * Added `CSV::TSV` for tab-separated values. + * GH-272 + * GH-319 + * Reported by kojix2 + * Patch by Jas + +### Thanks + + * Junichi Ito + + * Vladimir Kochnev + + * Marcelo + + * Bart de Water + + * kojix2 + + * Jas + +## 3.3.0 - 2024-03-22 + +### Fixes + + * Fixed a regression parse bug in 3.2.9 that parsing with + `:skip_lines` may cause wrong result. + +## 3.2.9 - 2024-03-22 + +### Fixes + + * Fixed a parse bug that wrong result may be happen when: + + * `:skip_lines` is used + * `:row_separator` is `"\r\n"` + * There is a line that includes `\n` as a column value + + Reported by Ryo Tsukamoto. + + GH-296 + +### Thanks + + * Ryo Tsukamoto + +## 3.2.8 - 2023-11-08 + +### Improvements + + * Added `CSV::InvalidEncodingError`. + + Patch by Kosuke Shibata. + + GH-287 + +### Thanks + + * Kosuke Shibata + +## 3.2.7 - 2023-06-26 + +### Improvements + + * Removed an unused internal variable. + [GH-273](https://github.com/ruby/csv/issues/273) + [Patch by Mau Magnaguagno] + + * Changed to use `https://` instead of `http://` in documents. + [GH-274](https://github.com/ruby/csv/issues/274) + [Patch by Vivek Bharath Akupatni] + + * Added prefix to a helper module in test. + [GH-278](https://github.com/ruby/csv/issues/278) + [Patch by Luke Gruber] + + * Added a documentation for `liberal_parsing: {backslash_quotes: true}`. + [GH-280](https://github.com/ruby/csv/issues/280) + [Patch by Mark Schneider] + +### Fixes + + * Fixed a wrong execution result in documents. + [GH-276](https://github.com/ruby/csv/issues/276) + [Patch by Yuki Tsujimoto] + + * Fixed a bug that the same line is used multiple times. + [GH-279](https://github.com/ruby/csv/issues/279) + [Reported by Gabriel Nagy] + +### Thanks + + * Mau Magnaguagno + + * Vivek Bharath Akupatni + + * Yuki Tsujimoto + + * Luke Gruber + + * Mark Schneider + + * Gabriel Nagy + +## 3.2.6 - 2022-12-08 + +### Improvements + + * `CSV#read` consumes the same lines with other methods like + `CSV#shift`. + [[GitHub#258](https://github.com/ruby/csv/issues/258)] + [Reported by Lhoussaine Ghallou] + + * All `Enumerable` based methods consume the same lines with other + methods. This may have a performance penalty. + [[GitHub#260](https://github.com/ruby/csv/issues/260)] + [Reported by Lhoussaine Ghallou] + + * Simplify some implementations. + [[GitHub#262](https://github.com/ruby/csv/pull/262)] + [[GitHub#263](https://github.com/ruby/csv/pull/263)] + [Patch by Mau Magnaguagno] + +### Fixes + + * Fixed `CSV.generate_lines` document. + [[GitHub#257](https://github.com/ruby/csv/pull/257)] + [Patch by Sampat Badhe] + +### Thanks + + * Sampat Badhe + + * Lhoussaine Ghallou + + * Mau Magnaguagno + +## 3.2.5 - 2022-08-26 + +### Improvements + + * Added `CSV.generate_lines`. + [[GitHub#255](https://github.com/ruby/csv/issues/255)] + [Reported by OKURA Masafumi] + [[GitHub#256](https://github.com/ruby/csv/pull/256)] + [Patch by Eriko Sugiyama] + +### Thanks + + * OKURA Masafumi + + * Eriko Sugiyama + +## 3.2.4 - 2022-08-22 + +### Improvements + + * Cleaned up internal implementations. + [[GitHub#249](https://github.com/ruby/csv/pull/249)] + [[GitHub#250](https://github.com/ruby/csv/pull/250)] + [[GitHub#251](https://github.com/ruby/csv/pull/251)] + [Patch by Mau Magnaguagno] + + * Added support for RFC 3339 style time. + [[GitHub#248](https://github.com/ruby/csv/pull/248)] + [Patch by Thierry Lambert] + + * Added support for transcoding String CSV. Syntax is + `from-encoding:to-encoding`. + [[GitHub#254](https://github.com/ruby/csv/issues/254)] + [Reported by Richard Stueven] + + * Added quoted information to `CSV::FieldInfo`. + [[GitHub#254](https://github.com/ruby/csv/pull/253)] + [Reported by Hirokazu SUZUKI] + +### Fixes + + * Fixed a link in documents. + [[GitHub#244](https://github.com/ruby/csv/pull/244)] + [Patch by Peter Zhu] + +### Thanks + + * Peter Zhu + + * Mau Magnaguagno + + * Thierry Lambert + + * Richard Stueven + + * Hirokazu SUZUKI + +## 3.2.3 - 2022-04-09 + +### Improvements + + * Added contents summary to `CSV::Table#inspect`. + [GitHub#229][Patch by Eriko Sugiyama] + [GitHub#235][Patch by Sampat Badhe] + + * Suppressed `$INPUT_RECORD_SEPARATOR` deprecation warning by + `Warning.warn`. + [GitHub#233][Reported by Jean byroot Boussier] + + * Improved error message for liberal parsing with quoted values. + [GitHub#231][Patch by Nikolay Rys] + + * Fixed typos in documentation. + [GitHub#236][Patch by Sampat Badhe] + + * Added `:max_field_size` option and deprecated `:field_size_limit` option. + [GitHub#238][Reported by Dan Buettner] + + * Added `:symbol_raw` to built-in header converters. + [GitHub#237][Reported by taki] + [GitHub#239][Patch by Eriko Sugiyama] + +### Fixes + + * Fixed a bug that some texts may be dropped unexpectedly. + [Bug #18245][ruby-core:105587][Reported by Hassan Abdul Rehman] + + * Fixed a bug that `:field_size_limit` doesn't work with not complex row. + [GitHub#238][Reported by Dan Buettner] + +### Thanks + + * Hassan Abdul Rehman + + * Eriko Sugiyama + + * Jean byroot Boussier + + * Nikolay Rys + + * Sampat Badhe + + * Dan Buettner + + * taki + +## 3.2.2 - 2021-12-24 + +### Improvements + + * Added a validation for invalid option combination. + [GitHub#225][Patch by adamroyjones] + + * Improved documentation for developers. + [GitHub#227][Patch by Eriko Sugiyama] + +### Fixes + + * Fixed a bug that all of `ARGF` contents may not be consumed. + [GitHub#228][Reported by Rafael Navaza] + +### Thanks + + * adamroyjones + + * Eriko Sugiyama + + * Rafael Navaza + +## 3.2.1 - 2021-10-23 + +### Improvements + + * doc: Fixed wrong class name. + [GitHub#217][Patch by Vince] + + * Changed to always use `"\n"` for the default row separator on Ruby + 3.0 or later because `$INPUT_RECORD_SEPARATOR` was deprecated + since Ruby 3.0. + + * Added support for Ractor. + [GitHub#218][Patch by rm155] + + * Users who want to use the built-in converters in non-main + Ractors need to call `Ractor.make_shareable(CSV::Converters)` + and/or `Ractor.make_shareable(CSV::HeaderConverters)` before + creating non-main Ractors. + +### Thanks + + * Vince + + * Joakim Antman + + * rm155 + +## 3.2.0 - 2021-06-06 + +### Improvements + + * `CSV.open`: Added support for `:newline` option. + [GitHub#198][Patch by Nobuyoshi Nakada] + + * `CSV::Table#each`: Added support for column mode with duplicated + headers. + [GitHub#206][Reported by Yaroslav Berezovskiy] + + * `Object#CSV`: Added support for Ruby 3.0. + + * `CSV::Row`: Added support for pattern matching. + [GitHub#207][Patch by Kevin Newton] + +### Fixes + + * Fixed typos in documentation. + [GitHub#196][GitHub#205][Patch by Sampat Badhe] + +### Thanks + + * Sampat Badhe + + * Nobuyoshi Nakada + + * Yaroslav Berezovskiy + + * Kevin Newton + +## 3.1.9 - 2020-11-23 + +### Fixes + + * Fixed a compatibility bug that the line to be processed by + `skip_lines:` has a row separator. + [GitHub#194][Reported by Josef Šimánek] + +### Thanks + + * Josef Šimánek + +## 3.1.8 - 2020-11-18 + +### Improvements + + * Improved documentation. + [Patch by Burdette Lamar] + +### Thanks + + * Burdette Lamar + +## 3.1.7 - 2020-08-04 + +### Improvements + + * Improved document. + [GitHub#158][GitHub#160][GitHub#161] + [Patch by Burdette Lamar] + + * Updated required Ruby version to 2.5.0 or later. + [GitHub#159] + [Patch by Gabriel Nagy] + + * Removed stringio 0.1.3 or later dependency. + +### Thanks + + * Burdette Lamar + + * Gabriel Nagy + +## 3.1.6 - 2020-07-20 + +### Improvements + + * Improved document. + [GitHub#127][GitHub#135][GitHub#136][GitHub#137][GitHub#139][GitHub#140] + [GitHub#141][GitHub#142][GitHub#143][GitHub#145][GitHub#146][GitHub#148] + [GitHub#148][GitHub#151][GitHub#152][GitHub#154][GitHub#155][GitHub#157] + [Patch by Burdette Lamar] + + * `CSV.open`: Added support for `undef: :replace`. + [GitHub#129][Patch by Koichi ITO] + + * `CSV.open`: Added support for `invalid: :replace`. + [GitHub#129][Patch by Koichi ITO] + + * Don't run quotable check for invalid encoding field values. + [GitHub#131][Patch by Koichi ITO] + + * Added support for specifying the target indexes and names to + `force_quotes:`. + [GitHub#153][Reported by Aleksandr] + + * `CSV.generate`: Changed to use the encoding of the first non-ASCII + field rather than the encoding of ASCII only field. + + * Changed to require the stringio gem 0.1.3 or later. + +### Thanks + + * Burdette Lamar + + * Koichi ITO + + * Aleksandr + +## 3.1.5 - 2020-05-18 + +### Improvements + + * Improved document. + [GitHub#124][Patch by Burdette Lamar] + +### Fixes + + * Added missing document files. + [GitHub#125][Reported by joast] + +### Thanks + + * Burdette Lamar + + * joast + +## 3.1.4 - 2020-05-17 + +### Improvements + + * Improved document. + [GitHub#122][Patch by Burdette Lamar] + + * Stopped to dropping stack trace for exception caused by + `CSV.parse_line`. + [GitHub#120][Reported by Kyle d'Oliveira] + +### Fixes + + * Fixed a bug that `:write_nil_value` or `:write_empty_value` don't + work with non `String` objects. + [GitHub#123][Reported by asm256] + +### Thanks + + * Burdette Lamar + + * asm256 + + * Kyle d'Oliveira + +## 3.1.3 - 2020-05-09 + +### Improvements + + * `CSV::Row#dup`: Copied deeply. + [GitHub#108][Patch by Jim Kane] + +### Fixes + + * Fixed a infinite loop bug for zero length match `skip_lines`. + [GitHub#110][Patch by Mike MacDonald] + + * `CSV.generate`: Fixed a bug that encoding isn't set correctly. + [GitHub#110][Patch by Seiei Miyagi] + + * Fixed document for the `:strip` option. + [GitHub#114][Patch by TOMITA Masahiro] + + * Fixed a parse bug when split charcter exists in middle of column + value. + [GitHub#115][Reported by TOMITA Masahiro] + +### Thanks + + * Jim Kane + + * Mike MacDonald + + * Seiei Miyagi + + * TOMITA Masahiro + +## 3.1.2 - 2019-10-12 + +### Improvements + + * Added `:col_sep` check. + [GitHub#94][Reported by Florent Beaurain] + + * Suppressed warnings. + [GitHub#96][Patch by Nobuyoshi Nakada] + + * Improved documentation. + [GitHub#101][GitHub#102][Patch by Vitor Oliveira] + +### Fixes + + * Fixed a typo in documentation. + [GitHub#95][Patch by Yuji Yaginuma] + + * Fixed a multibyte character handling bug. + [GitHub#97][Patch by koshigoe] + + * Fixed typos in documentation. + [GitHub#100][Patch by Vitor Oliveira] + + * Fixed a bug that seeked `StringIO` isn't accepted. + [GitHub#98][Patch by MATSUMOTO Katsuyoshi] + + * Fixed a bug that `CSV.generate_line` doesn't work with + `Encoding.default_internal`. + [GitHub#105][Reported by David Rodríguez] + +### Thanks + + * Florent Beaurain + + * Yuji Yaginuma + + * Nobuyoshi Nakada + + * koshigoe + + * Vitor Oliveira + + * MATSUMOTO Katsuyoshi + + * David Rodríguez + +## 3.1.1 - 2019-04-26 + +### Improvements + + * Added documentation for `strip` option. + [GitHub#88][Patch by hayashiyoshino] + + * Added documentation for `write_converters`, `write_nil_value` and + `write_empty_value` options. + [GitHub#87][Patch by Masafumi Koba] + + * Added documentation for `quote_empty` option. + [GitHub#89][Patch by kawa\_tech] + +### Fixes + + * Fixed a bug that `strip; true` removes a newline. + +### Thanks + + * hayashiyoshino + + * Masafumi Koba + + * kawa\_tech + +## 3.1.0 - 2019-04-17 + +### Fixes + + * Fixed a backward incompatibility bug that `CSV#eof?` may raises an + error. + [GitHub#86][Reported by krororo] + +### Thanks + + * krororo + +## 3.0.9 - 2019-04-15 + +### Fixes + + * Fixed a test for Windows. + +## 3.0.8 - 2019-04-11 + +### Fixes + + * Fixed a bug that `strip: String` doesn't work. + +## 3.0.7 - 2019-04-08 + +### Improvements + + * Improve parse performance 1.5x by introducing loose parser. + +### Fixes + + * Fix performance regression in 3.0.5. + + * Fix a bug that `CSV#line` returns wrong value when you + use `quote_char: nil`. + +## 3.0.6 - 2019-03-30 + +### Improvements + + * `CSV.foreach`: Added support for `mode`. + +## 3.0.5 - 2019-03-24 + +### Improvements + + * Added `:liberal_parsing => {backslash_quote: true}` option. + [GitHub#74][Patch by 284km] + + * Added `:write_converters` option. + [GitHub#73][Patch by Danillo Souza] + + * Added `:write_nil_value` option. + + * Added `:write_empty_value` option. + + * Improved invalid byte line number detection. + [GitHub#78][Patch by Alyssa Ross] + + * Added `quote_char: nil` optimization. + [GitHub#79][Patch by 284km] + + * Improved error message. + [GitHub#81][Patch by Andrés Torres] + + * Improved IO-like implementation for `StringIO` data. + [GitHub#80][Patch by Genadi Samokovarov] + + * Added `:strip` option. + [GitHub#58] + +### Fixes + + * Fixed a compatibility bug that `CSV#each` doesn't care `CSV#shift`. + [GitHub#76][Patch by Alyssa Ross] + + * Fixed a compatibility bug that `CSV#eof?` doesn't care `CSV#each` + and `CSV#shift`. + [GitHub#77][Reported by Chi Leung] + + * Fixed a compatibility bug that invalid line isn't ignored. + [GitHub#82][Reported by krororo] + + * Fixed a bug that `:skip_lines` doesn't work with multibyte characters data. + [GitHub#83][Reported by ff2248] + +### Thanks + + * Alyssa Ross + + * 284km + + * Chi Leung + + * Danillo Souza + + * Andrés Torres + + * Genadi Samokovarov + + * krororo + + * ff2248 + +## 3.0.4 - 2019-01-25 + +### Improvements + + * Removed duplicated `CSV::Row#include?` implementations. + [GitHub#69][Patch by Max Schwenk] + + * Removed duplicated `CSV::Row#header?` implementations. + [GitHub#70][Patch by Max Schwenk] + +### Fixes + + * Fixed a typo in document. + [GitHub#72][Patch by Artur Beljajev] + + * Fixed a compatibility bug when row headers are changed. + [GitHub#71][Reported by tomoyuki kosaka] + +### Thanks + + * Max Schwenk + + * Artur Beljajev + + * tomoyuki kosaka + +## 3.0.3 - 2019-01-12 + +### Improvements + + * Migrated benchmark tool to benchmark-driver from benchmark-ips. + [GitHub#57][Patch by 284km] + + * Added `liberal_parsing: {double_quote_outside_quote: true}` parse + option. + [GitHub#66][Reported by Watson] + + * Added `quote_empty:` write option. + [GitHub#35][Reported by Dave Myron] + +### Fixes + + * Fixed a compatibility bug that `CSV.generate` always return + `ASCII-8BIT` encoding string. + [GitHub#63][Patch by Watson] + + * Fixed a compatibility bug that `CSV.parse("", headers: true)` + doesn't return `CSV::Table`. + [GitHub#64][Reported by Watson][Patch by 284km] + + * Fixed a compatibility bug that multiple-characters column + separator doesn't work. + [GitHub#67][Reported by Jesse Reiss] + + * Fixed a compatibility bug that double `#each` parse twice. + [GitHub#68][Reported by Max Schwenk] + +### Thanks + + * Watson + + * 284km + + * Jesse Reiss + + * Dave Myron + + * Max Schwenk + +## 3.0.2 - 2018-12-23 + +### Improvements + + * Changed to use strscan in parser. + [GitHub#52][Patch by 284km] + + * Improves CSV write performance. + 3.0.2 will be about 2 times faster than 3.0.1. + + * Improves CSV parse performance for complex case. + 3.0.2 will be about 2 times faster than 3.0.1. + +### Fixes + + * Fixed a parse error bug for new line only input with `headers` option. + [GitHub#53][Reported by Chris Beer] + + * Fixed some typos in document. + [GitHub#54][Patch by Victor Shepelev] + +### Thanks + + * 284km + + * Chris Beer + + * Victor Shepelev + +## 3.0.1 - 2018-12-07 + +### Improvements + + * Added a test. + [GitHub#38][Patch by 284km] + + * `CSV::Row#dup`: Changed to duplicate internal data. + [GitHub#39][Reported by André Guimarães Sakata] + + * Documented `:nil_value` and `:empty_value` options. + [GitHub#41][Patch by OwlWorks] + + * Added support for separator detection for non-seekable inputs. + [GitHub#45][Patch by Ilmari Karonen] + + * Removed needless code. + [GitHub#48][Patch by Espartaco Palma] + + * Added support for parsing header only CSV with `headers: true`. + [GitHub#47][Patch by Kazuma Shibasaka] + + * Added support for coverage report in CI. + [GitHub#48][Patch by Espartaco Palma] + + * Improved auto CR row separator detection. + [GitHub#51][Reported by Yuki Kurihara] + +### Fixes + + * Fixed a typo in document. + [GitHub#40][Patch by Marcus Stollsteimer] + +### Thanks + + * 284km + + * André Guimarães Sakata + + * Marcus Stollsteimer + + * OwlWorks + + * Ilmari Karonen + + * Espartaco Palma + + * Kazuma Shibasaka + + * Yuki Kurihara + +## 3.0.0 - 2018-06-06 + +### Fixes + + * Fixed a bug that header isn't returned for empty row. + [GitHub#37][Patch by Grace Lee] + +### Thanks + + * Grace Lee + +## 1.0.2 - 2018-05-03 + +### Improvements + + * Split file for CSV::VERSION + + * Code cleanup: Split csv.rb into a more manageable structure + [GitHub#19][Patch by Espartaco Palma] + [GitHub#20][Patch by Steven Daniels] + + * Use CSV::MalformedCSVError for invalid encoding line + [GitHub#26][Reported by deepj] + + * Support implicit Row <-> Array conversion + [Bug #10013][ruby-core:63582][Reported by Dawid Janczak] + + * Update class docs + [GitHub#32][Patch by zverok] + + * Add `Row#each_pair` + [GitHub#33][Patch by zverok] + + * Improve CSV performance + [GitHub#30][Patch by Watson] + + * Add :nil_value and :empty_value option + +### Fixes + + * Fix a bug that "bom|utf-8" doesn't work + [GitHub#23][Reported by Pavel Lobashov] + + * `CSV::Row#to_h`, `#to_hash`: uses the same value as `Row#[]` + [Bug #14482][Reported by tomoya ishida] + + * Make row separator detection more robust + [GitHub#25][Reported by deepj] + + * Fix a bug that too much separator when col_sep is `" "` + [Bug #8784][ruby-core:63582][Reported by Sylvain Laperche] + +### Thanks + + * Espartaco Palma + + * Steven Daniels + + * deepj + + * Dawid Janczak + + * zverok + + * Watson + + * Pavel Lobashov + + * tomoya ishida + + * Sylvain Laperche + + * Ryunosuke Sato + +## 1.0.1 - 2018-02-09 + +### Improvements + + * `CSV::Table#delete`: Added bulk delete support. You can delete + multiple rows and columns at once. + [GitHub#4][Patch by Vladislav] + + * Updated Gem description. + [GitHub#11][Patch by Marcus Stollsteimer] + + * Code cleanup. + [GitHub#12][Patch by Marcus Stollsteimer] + [GitHub#14][Patch by Steven Daniels] + [GitHub#18][Patch by takkanm] + + * `CSV::Table#dig`: Added. + [GitHub#15][Patch by Tomohiro Ogoke] + + * `CSV::Row#dig`: Added. + [GitHub#15][Patch by Tomohiro Ogoke] + + * Added ISO 8601 support to date time converter. + [GitHub#16] + +### Fixes + + * Fixed wrong `CSV::VERSION`. + [GitHub#10][Reported by Marcus Stollsteimer] + + * `CSV.generate`: Fixed a regression bug that `String` argument is + ignored. + [GitHub#13][Patch by pavel] + +### Thanks + + * Vladislav + + * Marcus Stollsteimer + + * Steven Daniels + + * takkanm + + * Tomohiro Ogoke + + * pavel diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/README.md b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/README.md new file mode 100644 index 0000000..cf61a35 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/README.md @@ -0,0 +1,55 @@ +# CSV + +This library provides a complete interface to CSV files and data. It offers tools to enable you to read and write to and from Strings or IO objects, as needed. + +## Installation + +Add this line to your application's Gemfile: + +```ruby +gem 'csv' +``` + +And then execute: + + $ bundle + +Or install it yourself as: + + $ gem install csv + +## Usage + +```ruby +require "csv" + +CSV.foreach("path/to/file.csv") do |row| + # use row here... +end +``` + +## Documentation + +- [API](https://ruby.github.io/csv/): all classes, methods, and constants. +- [Recipes](https://ruby.github.io/csv/doc/csv/recipes/recipes_rdoc.html): specific code for specific tasks. + +## Development + +After checking out the repo, run `ruby run-test.rb` to check if your changes can pass the test. + +To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). + +## Contributing + +Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/csv. + +### NOTE: About RuboCop + +We don't use RuboCop because we can manage our coding style by ourselves. We want to accept small fluctuations in our coding style because we use Ruby. +Please do not submit issues and PRs that aim to introduce RuboCop in this repository. + +## License + +The gem is available as open source under the terms of the [2-Clause BSD License](https://opensource.org/licenses/BSD-2-Clause). + +See LICENSE.txt for details. diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/arguments/io.rdoc b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/arguments/io.rdoc new file mode 100644 index 0000000..f5fe1d1 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/arguments/io.rdoc @@ -0,0 +1,5 @@ +* Argument +io+ should be an IO object that is: + * Open for reading; on return, the IO object will be closed. + * Positioned at the beginning. + To position at the end, for appending, use method CSV.generate. + For any other positioning, pass a preset \StringIO object instead. diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/common/col_sep.rdoc b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/common/col_sep.rdoc new file mode 100644 index 0000000..b8be869 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/common/col_sep.rdoc @@ -0,0 +1,57 @@ +====== Option +col_sep+ + +Specifies the \String column separator to be used +for both parsing and generating. +The \String will be transcoded into the data's \Encoding before use. + +Default value: + CSV::DEFAULT_OPTIONS.fetch(:col_sep) # => "," (comma) + +Using the default (comma): + str = CSV.generate do |csv| + csv << [:foo, 0] + csv << [:bar, 1] + csv << [:baz, 2] + end + str # => "foo,0\nbar,1\nbaz,2\n" + ary = CSV.parse(str) + ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] + +Using +:+ (colon): + col_sep = ':' + str = CSV.generate(col_sep: col_sep) do |csv| + csv << [:foo, 0] + csv << [:bar, 1] + csv << [:baz, 2] + end + str # => "foo:0\nbar:1\nbaz:2\n" + ary = CSV.parse(str, col_sep: col_sep) + ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] + +Using +::+ (two colons): + col_sep = '::' + str = CSV.generate(col_sep: col_sep) do |csv| + csv << [:foo, 0] + csv << [:bar, 1] + csv << [:baz, 2] + end + str # => "foo::0\nbar::1\nbaz::2\n" + ary = CSV.parse(str, col_sep: col_sep) + ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] + +Using '' (empty string): + col_sep = '' + str = CSV.generate(col_sep: col_sep) do |csv| + csv << [:foo, 0] + csv << [:bar, 1] + csv << [:baz, 2] + end + str # => "foo0\nbar1\nbaz2\n" + +--- + +Raises an exception if parsing with the empty \String: + col_sep = '' + # Raises ArgumentError (:col_sep must be 1 or more characters: "") + CSV.parse("foo0\nbar1\nbaz2\n", col_sep: col_sep) + diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/common/quote_char.rdoc b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/common/quote_char.rdoc new file mode 100644 index 0000000..67fd3af --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/common/quote_char.rdoc @@ -0,0 +1,42 @@ +====== Option +quote_char+ + +Specifies the character (\String of length 1) used used to quote fields +in both parsing and generating. +This String will be transcoded into the data's \Encoding before use. + +Default value: + CSV::DEFAULT_OPTIONS.fetch(:quote_char) # => "\"" (double quote) + +This is useful for an application that incorrectly uses ' (single-quote) +to quote fields, instead of the correct " (double-quote). + +Using the default (double quote): + str = CSV.generate do |csv| + csv << ['foo', 0] + csv << ["'bar'", 1] + csv << ['"baz"', 2] + end + str # => "foo,0\n'bar',1\n\"\"\"baz\"\"\",2\n" + ary = CSV.parse(str) + ary # => [["foo", "0"], ["'bar'", "1"], ["\"baz\"", "2"]] + +Using ' (single-quote): + quote_char = "'" + str = CSV.generate(quote_char: quote_char) do |csv| + csv << ['foo', 0] + csv << ["'bar'", 1] + csv << ['"baz"', 2] + end + str # => "foo,0\n'''bar''',1\n\"baz\",2\n" + ary = CSV.parse(str, quote_char: quote_char) + ary # => [["foo", "0"], ["'bar'", "1"], ["\"baz\"", "2"]] + +--- + +Raises an exception if the \String length is greater than 1: + # Raises ArgumentError (:quote_char has to be nil or a single character String) + CSV.new('', quote_char: 'xx') + +Raises an exception if the value is not a \String: + # Raises ArgumentError (:quote_char has to be nil or a single character String) + CSV.new('', quote_char: :foo) diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/common/row_sep.rdoc b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/common/row_sep.rdoc new file mode 100644 index 0000000..eae15b4 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/common/row_sep.rdoc @@ -0,0 +1,91 @@ +====== Option +row_sep+ + +Specifies the row separator, a \String or the \Symbol :auto (see below), +to be used for both parsing and generating. + +Default value: + CSV::DEFAULT_OPTIONS.fetch(:row_sep) # => :auto + +--- + +When +row_sep+ is a \String, that \String becomes the row separator. +The String will be transcoded into the data's Encoding before use. + +Using "\n": + row_sep = "\n" + str = CSV.generate(row_sep: row_sep) do |csv| + csv << [:foo, 0] + csv << [:bar, 1] + csv << [:baz, 2] + end + str # => "foo,0\nbar,1\nbaz,2\n" + ary = CSV.parse(str) + ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] + +Using | (pipe): + row_sep = '|' + str = CSV.generate(row_sep: row_sep) do |csv| + csv << [:foo, 0] + csv << [:bar, 1] + csv << [:baz, 2] + end + str # => "foo,0|bar,1|baz,2|" + ary = CSV.parse(str, row_sep: row_sep) + ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] + +Using -- (two hyphens): + row_sep = '--' + str = CSV.generate(row_sep: row_sep) do |csv| + csv << [:foo, 0] + csv << [:bar, 1] + csv << [:baz, 2] + end + str # => "foo,0--bar,1--baz,2--" + ary = CSV.parse(str, row_sep: row_sep) + ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] + +Using '' (empty string): + row_sep = '' + str = CSV.generate(row_sep: row_sep) do |csv| + csv << [:foo, 0] + csv << [:bar, 1] + csv << [:baz, 2] + end + str # => "foo,0bar,1baz,2" + ary = CSV.parse(str, row_sep: row_sep) + ary # => [["foo", "0bar", "1baz", "2"]] + +--- + +When +row_sep+ is the \Symbol +:auto+ (the default), +generating uses "\n" as the row separator: + str = CSV.generate do |csv| + csv << [:foo, 0] + csv << [:bar, 1] + csv << [:baz, 2] + end + str # => "foo,0\nbar,1\nbaz,2\n" + +Parsing, on the other hand, invokes auto-discovery of the row separator. + +Auto-discovery reads ahead in the data looking for the next \r\n, +\n+, or +\r+ sequence. +The sequence will be selected even if it occurs in a quoted field, +assuming that you would have the same line endings there. + +Example: + str = CSV.generate do |csv| + csv << [:foo, 0] + csv << [:bar, 1] + csv << [:baz, 2] + end + str # => "foo,0\nbar,1\nbaz,2\n" + ary = CSV.parse(str) + ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] + +The default $INPUT_RECORD_SEPARATOR ($/) is used +if any of the following is true: +* None of those sequences is found. +* Data is +ARGF+, +STDIN+, +STDOUT+, or +STDERR+. +* The stream is only available for output. + +Obviously, discovery takes a little time. Set manually if speed is important. Also note that IO objects should be opened in binary mode on Windows if this feature will be used as the line-ending translation can cause problems with resetting the document position to where it was before the read ahead. diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/generating/force_quotes.rdoc b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/generating/force_quotes.rdoc new file mode 100644 index 0000000..11afd1a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/generating/force_quotes.rdoc @@ -0,0 +1,17 @@ +====== Option +force_quotes+ + +Specifies the boolean that determines whether each output field is to be double-quoted. + +Default value: + CSV::DEFAULT_OPTIONS.fetch(:force_quotes) # => false + +For examples in this section: + ary = ['foo', 0, nil] + +Using the default, +false+: + str = CSV.generate_line(ary) + str # => "foo,0,\n" + +Using +true+: + str = CSV.generate_line(ary, force_quotes: true) + str # => "\"foo\",\"0\",\"\"\n" diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/generating/quote_empty.rdoc b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/generating/quote_empty.rdoc new file mode 100644 index 0000000..4c5645c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/generating/quote_empty.rdoc @@ -0,0 +1,12 @@ +====== Option +quote_empty+ + +Specifies the boolean that determines whether an empty value is to be double-quoted. + +Default value: + CSV::DEFAULT_OPTIONS.fetch(:quote_empty) # => true + +With the default +true+: + CSV.generate_line(['"', ""]) # => "\"\"\"\",\"\"\n" + +With +false+: + CSV.generate_line(['"', ""], quote_empty: false) # => "\"\"\"\",\n" diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/generating/write_converters.rdoc b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/generating/write_converters.rdoc new file mode 100644 index 0000000..d1a9cc7 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/generating/write_converters.rdoc @@ -0,0 +1,25 @@ +====== Option +write_converters+ + +Specifies converters to be used in generating fields. +See {Write Converters}[#class-CSV-label-Write+Converters] + +Default value: + CSV::DEFAULT_OPTIONS.fetch(:write_converters) # => nil + +With no write converter: + str = CSV.generate_line(["\na\n", "\tb\t", " c "]) + str # => "\"\na\n\",\tb\t, c \n" + +With a write converter: + strip_converter = proc {|field| field.strip } + str = CSV.generate_line(["\na\n", "\tb\t", " c "], write_converters: strip_converter) + str # => "a,b,c\n" + +With two write converters (called in order): + upcase_converter = proc {|field| field.upcase } + downcase_converter = proc {|field| field.downcase } + write_converters = [upcase_converter, downcase_converter] + str = CSV.generate_line(['a', 'b', 'c'], write_converters: write_converters) + str # => "a,b,c\n" + +See also {Write Converters}[#class-CSV-label-Write+Converters] diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/generating/write_empty_value.rdoc b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/generating/write_empty_value.rdoc new file mode 100644 index 0000000..67be566 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/generating/write_empty_value.rdoc @@ -0,0 +1,15 @@ +====== Option +write_empty_value+ + +Specifies the object that is to be substituted for each field +that has an empty \String. + +Default value: + CSV::DEFAULT_OPTIONS.fetch(:write_empty_value) # => "" + +Without the option: + str = CSV.generate_line(['a', '', 'c', '']) + str # => "a,\"\",c,\"\"\n" + +With the option: + str = CSV.generate_line(['a', '', 'c', ''], write_empty_value: "x") + str # => "a,x,c,x\n" diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/generating/write_headers.rdoc b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/generating/write_headers.rdoc new file mode 100644 index 0000000..c56aa48 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/generating/write_headers.rdoc @@ -0,0 +1,29 @@ +====== Option +write_headers+ + +Specifies the boolean that determines whether a header row is included in the output; +ignored if there are no headers. + +Default value: + CSV::DEFAULT_OPTIONS.fetch(:write_headers) # => nil + +Without +write_headers+: + file_path = 't.csv' + CSV.open(file_path,'w', + :headers => ['Name','Value'] + ) do |csv| + csv << ['foo', '0'] + end + CSV.open(file_path) do |csv| + csv.shift + end # => ["foo", "0"] + +With +write_headers+": + CSV.open(file_path,'w', + :write_headers => true, + :headers => ['Name','Value'] + ) do |csv| + csv << ['foo', '0'] + end + CSV.open(file_path) do |csv| + csv.shift + end # => ["Name", "Value"] diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/generating/write_nil_value.rdoc b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/generating/write_nil_value.rdoc new file mode 100644 index 0000000..65d33ff --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/generating/write_nil_value.rdoc @@ -0,0 +1,14 @@ +====== Option +write_nil_value+ + +Specifies the object that is to be substituted for each +nil+-valued field. + +Default value: + CSV::DEFAULT_OPTIONS.fetch(:write_nil_value) # => nil + +Without the option: + str = CSV.generate_line(['a', nil, 'c', nil]) + str # => "a,,c,\n" + +With the option: + str = CSV.generate_line(['a', nil, 'c', nil], write_nil_value: "x") + str # => "a,x,c,x\n" diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/converters.rdoc b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/converters.rdoc new file mode 100644 index 0000000..211fa48 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/converters.rdoc @@ -0,0 +1,46 @@ +====== Option +converters+ + +Specifies converters to be used in parsing fields. +See {Field Converters}[#class-CSV-label-Field+Converters] + +Default value: + CSV::DEFAULT_OPTIONS.fetch(:converters) # => nil + +The value may be a field converter name +(see {Stored Converters}[#class-CSV-label-Stored+Converters]): + str = '1,2,3' + # Without a converter + array = CSV.parse_line(str) + array # => ["1", "2", "3"] + # With built-in converter :integer + array = CSV.parse_line(str, converters: :integer) + array # => [1, 2, 3] + +The value may be a converter list +(see {Converter Lists}[#class-CSV-label-Converter+Lists]): + str = '1,3.14159' + # Without converters + array = CSV.parse_line(str) + array # => ["1", "3.14159"] + # With built-in converters + array = CSV.parse_line(str, converters: [:integer, :float]) + array # => [1, 3.14159] + +The value may be a \Proc custom converter: +(see {Custom Field Converters}[#class-CSV-label-Custom+Field+Converters]): + str = ' foo , bar , baz ' + # Without a converter + array = CSV.parse_line(str) + array # => [" foo ", " bar ", " baz "] + # With a custom converter + array = CSV.parse_line(str, converters: proc {|field| field.strip }) + array # => ["foo", "bar", "baz"] + +See also {Custom Field Converters}[#class-CSV-label-Custom+Field+Converters] + +--- + +Raises an exception if the converter is not a converter name or a \Proc: + str = 'foo,0' + # Raises NoMethodError (undefined method `arity' for nil:NilClass) + CSV.parse(str, converters: :foo) diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/empty_value.rdoc b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/empty_value.rdoc new file mode 100644 index 0000000..7d3bcc0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/empty_value.rdoc @@ -0,0 +1,13 @@ +====== Option +empty_value+ + +Specifies the object that is to be substituted +for each field that has an empty \String. + +Default value: + CSV::DEFAULT_OPTIONS.fetch(:empty_value) # => "" (empty string) + +With the default, "": + CSV.parse_line('a,"",b,"",c') # => ["a", "", "b", "", "c"] + +With a different object: + CSV.parse_line('a,"",b,"",c', empty_value: 'x') # => ["a", "x", "b", "x", "c"] diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/field_size_limit.rdoc b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/field_size_limit.rdoc new file mode 100644 index 0000000..797c577 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/field_size_limit.rdoc @@ -0,0 +1,39 @@ +====== Option +field_size_limit+ + +Specifies the \Integer field size limit. + +Default value: + CSV::DEFAULT_OPTIONS.fetch(:field_size_limit) # => nil + +This is a maximum size CSV will read ahead looking for the closing quote for a field. +(In truth, it reads to the first line ending beyond this size.) +If a quote cannot be found within the limit CSV will raise a MalformedCSVError, +assuming the data is faulty. +You can use this limit to prevent what are effectively DoS attacks on the parser. +However, this limit can cause a legitimate parse to fail; +therefore the default value is +nil+ (no limit). + +For the examples in this section: + str = <<~EOT + "a","b" + " + 2345 + ","" + EOT + str # => "\"a\",\"b\"\n\"\n2345\n\",\"\"\n" + +Using the default +nil+: + ary = CSV.parse(str) + ary # => [["a", "b"], ["\n2345\n", ""]] + +Using 50: + field_size_limit = 50 + ary = CSV.parse(str, field_size_limit: field_size_limit) + ary # => [["a", "b"], ["\n2345\n", ""]] + +--- + +Raises an exception if a field is too long: + big_str = "123456789\n" * 1024 + # Raises CSV::MalformedCSVError (Field size exceeded in line 1.) + CSV.parse('valid,fields,"' + big_str + '"', field_size_limit: 2048) diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/header_converters.rdoc b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/header_converters.rdoc new file mode 100644 index 0000000..3091808 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/header_converters.rdoc @@ -0,0 +1,43 @@ +====== Option +header_converters+ + +Specifies converters to be used in parsing headers. +See {Header Converters}[#class-CSV-label-Header+Converters] + +Default value: + CSV::DEFAULT_OPTIONS.fetch(:header_converters) # => nil + +Identical in functionality to option {converters}[#class-CSV-label-Option+converters] +except that: +- The converters apply only to the header row. +- The built-in header converters are +:downcase+ and +:symbol+. + +This section assumes prior execution of: + str = <<-EOT + Name,Value + foo,0 + bar,1 + baz,2 + EOT + # With no header converter + table = CSV.parse(str, headers: true) + table.headers # => ["Name", "Value"] + +The value may be a header converter name +(see {Stored Converters}[#class-CSV-label-Stored+Converters]): + table = CSV.parse(str, headers: true, header_converters: :downcase) + table.headers # => ["name", "value"] + +The value may be a converter list +(see {Converter Lists}[#class-CSV-label-Converter+Lists]): + header_converters = [:downcase, :symbol] + table = CSV.parse(str, headers: true, header_converters: header_converters) + table.headers # => [:name, :value] + +The value may be a \Proc custom converter +(see {Custom Header Converters}[#class-CSV-label-Custom+Header+Converters]): + upcase_converter = proc {|field| field.upcase } + table = CSV.parse(str, headers: true, header_converters: upcase_converter) + table.headers # => ["NAME", "VALUE"] + +See also {Custom Header Converters}[#class-CSV-label-Custom+Header+Converters] + diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/headers.rdoc b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/headers.rdoc new file mode 100644 index 0000000..0ea151f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/headers.rdoc @@ -0,0 +1,63 @@ +====== Option +headers+ + +Specifies a boolean, \Symbol, \Array, or \String to be used +to define column headers. + +Default value: + CSV::DEFAULT_OPTIONS.fetch(:headers) # => false + +--- + +Without +headers+: + str = <<-EOT + Name,Count + foo,0 + bar,1 + bax,2 + EOT + csv = CSV.new(str) + csv # => # + csv.headers # => nil + csv.shift # => ["Name", "Count"] + +--- + +If set to +true+ or the \Symbol +:first_row+, +the first row of the data is treated as a row of headers: + str = <<-EOT + Name,Count + foo,0 + bar,1 + bax,2 + EOT + csv = CSV.new(str, headers: true) + csv # => # + csv.headers # => ["Name", "Count"] + csv.shift # => # + +--- + +If set to an \Array, the \Array elements are treated as headers: + str = <<-EOT + foo,0 + bar,1 + bax,2 + EOT + csv = CSV.new(str, headers: ['Name', 'Count']) + csv + csv.headers # => ["Name", "Count"] + csv.shift # => # + +--- + +If set to a \String +str+, method CSV::parse_line(str, options) is called +with the current +options+, and the returned \Array is treated as headers: + str = <<-EOT + foo,0 + bar,1 + bax,2 + EOT + csv = CSV.new(str, headers: 'Name,Count') + csv + csv.headers # => ["Name", "Count"] + csv.shift # => # diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/liberal_parsing.rdoc b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/liberal_parsing.rdoc new file mode 100644 index 0000000..603de28 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/liberal_parsing.rdoc @@ -0,0 +1,38 @@ +====== Option +liberal_parsing+ + +Specifies the boolean or hash value that determines whether +CSV will attempt to parse input not conformant with RFC 4180, +such as double quotes in unquoted fields. + +Default value: + CSV::DEFAULT_OPTIONS.fetch(:liberal_parsing) # => false + +For the next two examples: + str = 'is,this "three, or four",fields' + +Without +liberal_parsing+: + # Raises CSV::MalformedCSVError (Illegal quoting in str 1.) + CSV.parse_line(str) + +With +liberal_parsing+: + ary = CSV.parse_line(str, liberal_parsing: true) + ary # => ["is", "this \"three", " or four\"", "fields"] + +Use the +backslash_quote+ sub-option to parse values that use +a backslash to escape a double-quote character. This +causes the parser to treat \" as if it were +"". + +For the next two examples: + str = 'Show,"Harry \"Handcuff\" Houdini, the one and only","Tampa Theater"' + +With +liberal_parsing+, but without the +backslash_quote+ sub-option: + # Incorrect interpretation of backslash; incorrectly interprets the quoted comma as a field separator. + ary = CSV.parse_line(str, liberal_parsing: true) + ary # => ["Show", "\"Harry \\\"Handcuff\\\" Houdini", " the one and only\"", "Tampa Theater"] + puts ary[1] # => "Harry \"Handcuff\" Houdini + +With +liberal_parsing+ and its +backslash_quote+ sub-option: + ary = CSV.parse_line(str, liberal_parsing: { backslash_quote: true }) + ary # => ["Show", "Harry \"Handcuff\" Houdini, the one and only", "Tampa Theater"] + puts ary[1] # => Harry "Handcuff" Houdini, the one and only diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/nil_value.rdoc b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/nil_value.rdoc new file mode 100644 index 0000000..412e879 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/nil_value.rdoc @@ -0,0 +1,12 @@ +====== Option +nil_value+ + +Specifies the object that is to be substituted for each null (no-text) field. + +Default value: + CSV::DEFAULT_OPTIONS.fetch(:nil_value) # => nil + +With the default, +nil+: + CSV.parse_line('a,,b,,c') # => ["a", nil, "b", nil, "c"] + +With a different object: + CSV.parse_line('a,,b,,c', nil_value: 0) # => ["a", 0, "b", 0, "c"] diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/return_headers.rdoc b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/return_headers.rdoc new file mode 100644 index 0000000..45d2e3f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/return_headers.rdoc @@ -0,0 +1,22 @@ +====== Option +return_headers+ + +Specifies the boolean that determines whether method #shift +returns or ignores the header row. + +Default value: + CSV::DEFAULT_OPTIONS.fetch(:return_headers) # => false + +Examples: + str = <<-EOT + Name,Count + foo,0 + bar,1 + bax,2 + EOT + # Without return_headers first row is str. + csv = CSV.new(str, headers: true) + csv.shift # => # + # With return_headers first row is headers. + csv = CSV.new(str, headers: true, return_headers: true) + csv.shift # => # + diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/skip_blanks.rdoc b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/skip_blanks.rdoc new file mode 100644 index 0000000..2c8f7b7 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/skip_blanks.rdoc @@ -0,0 +1,31 @@ +====== Option +skip_blanks+ + +Specifies a boolean that determines whether blank lines in the input will be ignored; +a line that contains a column separator is not considered to be blank. + +Default value: + CSV::DEFAULT_OPTIONS.fetch(:skip_blanks) # => false + +See also option {skiplines}[#class-CSV-label-Option+skip_lines]. + +For examples in this section: + str = <<-EOT + foo,0 + + bar,1 + baz,2 + + , + EOT + +Using the default, +false+: + ary = CSV.parse(str) + ary # => [["foo", "0"], [], ["bar", "1"], ["baz", "2"], [], [nil, nil]] + +Using +true+: + ary = CSV.parse(str, skip_blanks: true) + ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"], [nil, nil]] + +Using a truthy value: + ary = CSV.parse(str, skip_blanks: :foo) + ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"], [nil, nil]] diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/skip_lines.rdoc b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/skip_lines.rdoc new file mode 100644 index 0000000..1481c40 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/skip_lines.rdoc @@ -0,0 +1,37 @@ +====== Option +skip_lines+ + +Specifies an object to use in identifying comment lines in the input that are to be ignored: +* If a \Regexp, ignores lines that match it. +* If a \String, converts it to a \Regexp, ignores lines that match it. +* If +nil+, no lines are considered to be comments. + +Default value: + CSV::DEFAULT_OPTIONS.fetch(:skip_lines) # => nil + +For examples in this section: + str = <<-EOT + # Comment + foo,0 + bar,1 + baz,2 + # Another comment + EOT + str # => "# Comment\nfoo,0\nbar,1\nbaz,2\n# Another comment\n" + +Using the default, +nil+: + ary = CSV.parse(str) + ary # => [["# Comment"], ["foo", "0"], ["bar", "1"], ["baz", "2"], ["# Another comment"]] + +Using a \Regexp: + ary = CSV.parse(str, skip_lines: /^#/) + ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] + +Using a \String: + ary = CSV.parse(str, skip_lines: '#') + ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] + +--- + +Raises an exception if given an object that is not a \Regexp, a \String, or +nil+: + # Raises ArgumentError (:skip_lines has to respond to #match: 0) + CSV.parse(str, skip_lines: 0) diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/strip.rdoc b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/strip.rdoc new file mode 100644 index 0000000..56ae431 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/strip.rdoc @@ -0,0 +1,15 @@ +====== Option +strip+ + +Specifies the boolean value that determines whether +whitespace is stripped from each input field. + +Default value: + CSV::DEFAULT_OPTIONS.fetch(:strip) # => false + +With default value +false+: + ary = CSV.parse_line(' a , b ') + ary # => [" a ", " b "] + +With value +true+: + ary = CSV.parse_line(' a , b ', strip: true) + ary # => ["a", "b"] diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/unconverted_fields.rdoc b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/unconverted_fields.rdoc new file mode 100644 index 0000000..3e7f839 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/options/parsing/unconverted_fields.rdoc @@ -0,0 +1,27 @@ +====== Option +unconverted_fields+ + +Specifies the boolean that determines whether unconverted field values are to be available. + +Default value: + CSV::DEFAULT_OPTIONS.fetch(:unconverted_fields) # => nil + +The unconverted field values are those found in the source data, +prior to any conversions performed via option +converters+. + +When option +unconverted_fields+ is +true+, +each returned row (\Array or \CSV::Row) has an added method, ++unconverted_fields+, that returns the unconverted field values: + str = <<-EOT + foo,0 + bar,1 + baz,2 + EOT + # Without unconverted_fields + csv = CSV.parse(str, converters: :integer) + csv # => [["foo", 0], ["bar", 1], ["baz", 2]] + csv.first.respond_to?(:unconverted_fields) # => false + # With unconverted_fields + csv = CSV.parse(str, converters: :integer, unconverted_fields: true) + csv # => [["foo", 0], ["bar", 1], ["baz", 2]] + csv.first.respond_to?(:unconverted_fields) # => true + csv.first.unconverted_fields # => ["foo", "0"] diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/recipes/filtering.rdoc b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/recipes/filtering.rdoc new file mode 100644 index 0000000..d92afb7 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/recipes/filtering.rdoc @@ -0,0 +1,226 @@ +== Recipes for Filtering \CSV + +These recipes are specific code examples for specific \CSV filtering tasks. + +For other recipes, see {Recipes for CSV}[./recipes_rdoc.html]. + +All code snippets on this page assume that the following has been executed: + require 'csv' + +=== Contents + +- {Source and Output Formats}[#label-Source+and+Output+Formats] + - {Filtering String to String}[#label-Filtering+String+to+String] + - {Recipe: Filter String to String parsing Headers}[#label-Recipe-3A+Filter+String+to+String+parsing+Headers] + - {Recipe: Filter String to String parsing and writing Headers}[#label-Recipe-3A+Filter+String+to+String+parsing+and+writing+Headers] + - {Recipe: Filter String to String Without Headers}[#label-Recipe-3A+Filter+String+to+String+Without+Headers] + - {Filtering String to IO Stream}[#label-Filtering+String+to+IO+Stream] + - {Recipe: Filter String to IO Stream parsing Headers}[#label-Recipe-3A+Filter+String+to+IO+Stream+parsing+Headers] + - {Recipe: Filter String to IO Stream parsing and writing Headers}[#label-Recipe-3A+Filter+String+to+IO+Stream+parsing+and+writing+Headers] + - {Recipe: Filter String to IO Stream Without Headers}[#label-Recipe-3A+Filter+String+to+IO+Stream+Without+Headers] + - {Filtering IO Stream to String}[#label-Filtering+IO+Stream+to+String] + - {Recipe: Filter IO Stream to String parsing Headers}[#label-Recipe-3A+Filter+IO+Stream+to+String+parsing+Headers] + - {Recipe: Filter IO Stream to String parsing and writing Headers}[#label-Recipe-3A+Filter+IO+Stream+to+String+parsing+and+writing+Headers] + - {Recipe: Filter IO Stream to String Without Headers}[#label-Recipe-3A+Filter+IO+Stream+to+String+Without+Headers] + - {Filtering IO Stream to IO Stream}[#label-Filtering+IO+Stream+to+IO+Stream] + - {Recipe: Filter IO Stream to IO Stream parsing Headers}[#label-Recipe-3A+Filter+IO+Stream+to+IO+Stream+parsing+Headers] + - {Recipe: Filter IO Stream to IO Stream parsing and writing Headers}[#label-Recipe-3A+Filter+IO+Stream+to+IO+Stream+parsing+and+writing+Headers] + - {Recipe: Filter IO Stream to IO Stream Without Headers}[#label-Recipe-3A+Filter+IO+Stream+to+IO+Stream+Without+Headers] + +=== Source and Output Formats + +You can use a Unix-style "filter" for \CSV data. +The filter reads source \CSV data and writes output \CSV data as modified by the filter. +The input and output \CSV data may be any mixture of \Strings and \IO streams. + +==== Filtering \String to \String + +You can filter one \String to another, with or without headers. + +===== Recipe: Filter \String to \String parsing Headers + +Use class method CSV.filter with option +headers+ to filter a \String to another \String: + in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + out_string = '' + CSV.filter(in_string, out_string, headers: true) do |row| + row['Name'] = row['Name'].upcase + row['Value'] *= 4 + end + out_string # => "FOO,0000\nBAR,1111\nBAZ,2222\n" + +===== Recipe: Filter \String to \String parsing and writing Headers + +Use class method CSV.filter with option +headers+ and +out_write_headers+ to filter a \String to another \String including header row: + in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + out_string = '' + CSV.filter(in_string, out_string, headers: true, out_write_headers: true) do |row| + unless row.is_a?(Array) + row['Name'] = row['Name'].upcase + row['Value'] *= 4 + end + end + out_string # => "Name,Value\nFOO,0000\nBAR,1111\nBAZ,2222\n" + +===== Recipe: Filter \String to \String Without Headers + +Use class method CSV.filter without option +headers+ to filter a \String to another \String: + in_string = "foo,0\nbar,1\nbaz,2\n" + out_string = '' + CSV.filter(in_string, out_string) do |row| + row[0] = row[0].upcase + row[1] *= 4 + end + out_string # => "FOO,0000\nBAR,1111\nBAZ,2222\n" + +==== Filtering \String to \IO Stream + +You can filter a \String to an \IO stream, with or without headers. + +===== Recipe: Filter \String to \IO Stream parsing Headers + +Use class method CSV.filter with option +headers+ to filter a \String to an \IO stream: + in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + path = 't.csv' + File.open(path, 'w') do |out_io| + CSV.filter(in_string, out_io, headers: true) do |row| + row['Name'] = row['Name'].upcase + row['Value'] *= 4 + end + end + p File.read(path) # => "FOO,0000\nBAR,1111\nBAZ,2222\n" + +===== Recipe: Filter \String to \IO Stream parsing and writing Headers + +Use class method CSV.filter with option +headers+ and +out_write_headers+ to filter a \String to an \IO stream including header row: + in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + path = 't.csv' + File.open(path, 'w') do |out_io| + CSV.filter(in_string, out_io, headers: true, out_write_headers: true ) do |row| + unless row.is_a?(Array) + row['Name'] = row['Name'].upcase + row['Value'] *= 4 + end + end + end + p File.read(path) # => "Name,Value\nFOO,0000\nBAR,1111\nBAZ,2222\n" + +===== Recipe: Filter \String to \IO Stream Without Headers + +Use class method CSV.filter without option +headers+ to filter a \String to an \IO stream: + in_string = "foo,0\nbar,1\nbaz,2\n" + path = 't.csv' + File.open(path, 'w') do |out_io| + CSV.filter(in_string, out_io) do |row| + row[0] = row[0].upcase + row[1] *= 4 + end + end + p File.read(path) # => "FOO,0000\nBAR,1111\nBAZ,2222\n" + +==== Filtering \IO Stream to \String + +You can filter an \IO stream to a \String, with or without headers. + +===== Recipe: Filter \IO Stream to \String parsing Headers + +Use class method CSV.filter with option +headers+ to filter an \IO stream to a \String: + in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + path = 't.csv' + File.write(path, in_string) + out_string = '' + File.open(path) do |in_io| + CSV.filter(in_io, out_string, headers: true) do |row| + row['Name'] = row['Name'].upcase + row['Value'] *= 4 + end + end + out_string # => "FOO,0000\nBAR,1111\nBAZ,2222\n" + +===== Recipe: Filter \IO Stream to \String parsing and writing Headers + +Use class method CSV.filter with option +headers+ and +out_write_headers+ to filter an \IO stream to a \String including header row: + in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + path = 't.csv' + File.write(path, in_string) + out_string = '' + File.open(path) do |in_io| + CSV.filter(in_io, out_string, headers: true, out_write_headers: true) do |row| + unless row.is_a?(Array) + row['Name'] = row['Name'].upcase + row['Value'] *= 4 + end + end + end + out_string # => "Name,Value\nFOO,0000\nBAR,1111\nBAZ,2222\n" + +===== Recipe: Filter \IO Stream to \String Without Headers + +Use class method CSV.filter without option +headers+ to filter an \IO stream to a \String: + in_string = "foo,0\nbar,1\nbaz,2\n" + path = 't.csv' + File.write(path, in_string) + out_string = '' + File.open(path) do |in_io| + CSV.filter(in_io, out_string) do |row| + row[0] = row[0].upcase + row[1] *= 4 + end + end + out_string # => "FOO,0000\nBAR,1111\nBAZ,2222\n" + +==== Filtering \IO Stream to \IO Stream + +You can filter an \IO stream to another \IO stream, with or without headers. + +===== Recipe: Filter \IO Stream to \IO Stream parsing Headers + +Use class method CSV.filter with option +headers+ to filter an \IO stream to another \IO stream: + in_path = 't.csv' + in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + File.write(in_path, in_string) + out_path = 'u.csv' + File.open(in_path) do |in_io| + File.open(out_path, 'w') do |out_io| + CSV.filter(in_io, out_io, headers: true) do |row| + row['Name'] = row['Name'].upcase + row['Value'] *= 4 + end + end + end + p File.read(out_path) # => "FOO,0000\nBAR,1111\nBAZ,2222\n" + +===== Recipe: Filter \IO Stream to \IO Stream parsing and writing Headers + +Use class method CSV.filter with option +headers+ and +out_write_headers+ to filter an \IO stream to another \IO stream including header row: + in_path = 't.csv' + in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + File.write(in_path, in_string) + out_path = 'u.csv' + File.open(in_path) do |in_io| + File.open(out_path, 'w') do |out_io| + CSV.filter(in_io, out_io, headers: true, out_write_headers: true) do |row| + unless row.is_a?(Array) + row['Name'] = row['Name'].upcase + row['Value'] *= 4 + end + end + end + end + p File.read(out_path) # => "Name,Value\nFOO,0000\nBAR,1111\nBAZ,2222\n" + +===== Recipe: Filter \IO Stream to \IO Stream Without Headers + +Use class method CSV.filter without option +headers+ to filter an \IO stream to another \IO stream: + in_path = 't.csv' + in_string = "foo,0\nbar,1\nbaz,2\n" + File.write(in_path, in_string) + out_path = 'u.csv' + File.open(in_path) do |in_io| + File.open(out_path, 'w') do |out_io| + CSV.filter(in_io, out_io) do |row| + row[0] = row[0].upcase + row[1] *= 4 + end + end + end + p File.read(out_path) # => "FOO,0000\nBAR,1111\nBAZ,2222\n" diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/recipes/generating.rdoc b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/recipes/generating.rdoc new file mode 100644 index 0000000..d96ff85 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/recipes/generating.rdoc @@ -0,0 +1,298 @@ +== Recipes for Generating \CSV + +These recipes are specific code examples for specific \CSV generating tasks. + +For other recipes, see {Recipes for CSV}[./recipes_rdoc.html]. + +All code snippets on this page assume that the following has been executed: + require 'csv' + +=== Contents + +- {Output Formats}[#label-Output+Formats] + - {Generating to a String}[#label-Generating+to+a+String] + - {Recipe: Generate to String with Headers}[#label-Recipe-3A+Generate+to+String+with+Headers] + - {Recipe: Generate to String Without Headers}[#label-Recipe-3A+Generate+to+String+Without+Headers] + - {Generating to a File}[#label-Generating+to+a+File] + - {Recipe: Generate to File with Headers}[#label-Recipe-3A+Generate+to+File+with+Headers] + - {Recipe: Generate to File Without Headers}[#label-Recipe-3A+Generate+to+File+Without+Headers] + - {Generating to IO an Stream}[#label-Generating+to+an+IO+Stream] + - {Recipe: Generate to IO Stream with Headers}[#label-Recipe-3A+Generate+to+IO+Stream+with+Headers] + - {Recipe: Generate to IO Stream Without Headers}[#label-Recipe-3A+Generate+to+IO+Stream+Without+Headers] +- {Converting Fields}[#label-Converting+Fields] + - {Recipe: Filter Generated Field Strings}[#label-Recipe-3A+Filter+Generated+Field+Strings] + - {Recipe: Specify Multiple Write Converters}[#label-Recipe-3A+Specify+Multiple+Write+Converters] +- {RFC 4180 Compliance}[#label-RFC+4180+Compliance] + - {Row Separator}[#label-Row+Separator] + - {Recipe: Generate Compliant Row Separator}[#label-Recipe-3A+Generate+Compliant+Row+Separator] + - {Recipe: Generate Non-Compliant Row Separator}[#label-Recipe-3A+Generate+Non-Compliant+Row+Separator] + - {Column Separator}[#label-Column+Separator] + - {Recipe: Generate Compliant Column Separator}[#label-Recipe-3A+Generate+Compliant+Column+Separator] + - {Recipe: Generate Non-Compliant Column Separator}[#label-Recipe-3A+Generate+Non-Compliant+Column+Separator] + - {Quotes}[#label-Quotes] + - {Recipe: Quote All Fields}[#label-Recipe-3A+Quote+All+Fields] + - {Recipe: Quote Empty Fields}[#label-Recipe-3A+Quote+Empty+Fields] + - {Recipe: Generate Compliant Quote Character}[#label-Recipe-3A+Generate+Compliant+Quote+Character] + - {Recipe: Generate Non-Compliant Quote Character}[#label-Recipe-3A+Generate+Non-Compliant+Quote+Character] + +=== Output Formats + +You can generate \CSV output to a \String, to a \File (via its path), or to an \IO stream. + +==== Generating to a \String + +You can generate \CSV output to a \String, with or without headers. + +===== Recipe: Generate to \String with Headers + +Use class method CSV.generate with option +headers+ to generate to a \String. + +This example uses method CSV#<< to append the rows +that are to be generated: + output_string = CSV.generate('', headers: ['Name', 'Value'], write_headers: true) do |csv| + csv << ['Foo', 0] + csv << ['Bar', 1] + csv << ['Baz', 2] + end + output_string # => "Name,Value\nFoo,0\nBar,1\nBaz,2\n" + +===== Recipe: Generate to \String Without Headers + +Use class method CSV.generate without option +headers+ to generate to a \String. + +This example uses method CSV#<< to append the rows +that are to be generated: + output_string = CSV.generate do |csv| + csv << ['Foo', 0] + csv << ['Bar', 1] + csv << ['Baz', 2] + end + output_string # => "Foo,0\nBar,1\nBaz,2\n" + +==== Generating to a \File + +You can generate /CSV data to a \File, with or without headers. + +===== Recipe: Generate to \File with Headers + +Use class method CSV.open with option +headers+ generate to a \File. + +This example uses method CSV#<< to append the rows +that are to be generated: + path = 't.csv' + CSV.open(path, 'w', headers: ['Name', 'Value'], write_headers: true) do |csv| + csv << ['Foo', 0] + csv << ['Bar', 1] + csv << ['Baz', 2] + end + p File.read(path) # => "Name,Value\nFoo,0\nBar,1\nBaz,2\n" + +===== Recipe: Generate to \File Without Headers + +Use class method CSV.open without option +headers+ to generate to a \File. + +This example uses method CSV#<< to append the rows +that are to be generated: + path = 't.csv' + CSV.open(path, 'w') do |csv| + csv << ['Foo', 0] + csv << ['Bar', 1] + csv << ['Baz', 2] + end + p File.read(path) # => "Foo,0\nBar,1\nBaz,2\n" + +==== Generating to an \IO Stream + +You can generate \CSV data to an \IO stream, with or without headers. + +==== Recipe: Generate to \IO Stream with Headers + +Use class method CSV.new with option +headers+ to generate \CSV data to an \IO stream: + path = 't.csv' + File.open(path, 'w') do |file| + csv = CSV.new(file, headers: ['Name', 'Value'], write_headers: true) + csv << ['Foo', 0] + csv << ['Bar', 1] + csv << ['Baz', 2] + end + p File.read(path) # => "Name,Value\nFoo,0\nBar,1\nBaz,2\n" + +===== Recipe: Generate to \IO Stream Without Headers + +Use class method CSV.new without option +headers+ to generate \CSV data to an \IO stream: + path = 't.csv' + File.open(path, 'w') do |file| + csv = CSV.new(file) + csv << ['Foo', 0] + csv << ['Bar', 1] + csv << ['Baz', 2] + end + p File.read(path) # => "Foo,0\nBar,1\nBaz,2\n" + +=== Converting Fields + +You can use _write_ _converters_ to convert fields when generating \CSV. + +==== Recipe: Filter Generated Field Strings + +Use option :write_converters and a custom converter to convert field values when generating \CSV. + +This example defines and uses a custom write converter to strip whitespace from generated fields: + strip_converter = proc {|field| field.respond_to?(:strip) ? field.strip : field } + output_string = CSV.generate(write_converters: strip_converter) do |csv| + csv << [' foo ', 0] + csv << [' bar ', 1] + csv << [' baz ', 2] + end + output_string # => "foo,0\nbar,1\nbaz,2\n" + +==== Recipe: Specify Multiple Write Converters + +Use option :write_converters and multiple custom converters +to convert field values when generating \CSV. + +This example defines and uses two custom write converters to strip and upcase generated fields: + strip_converter = proc {|field| field.respond_to?(:strip) ? field.strip : field } + upcase_converter = proc {|field| field.respond_to?(:upcase) ? field.upcase : field } + converters = [strip_converter, upcase_converter] + output_string = CSV.generate(write_converters: converters) do |csv| + csv << [' foo ', 0] + csv << [' bar ', 1] + csv << [' baz ', 2] + end + output_string # => "FOO,0\nBAR,1\nBAZ,2\n" + +=== RFC 4180 Compliance + +By default, \CSV generates data that is compliant with +{RFC 4180}[https://www.rfc-editor.org/rfc/rfc4180] +with respect to: +- Column separator. +- Quote character. + +==== Row Separator + +RFC 4180 specifies the row separator CRLF (Ruby "\r\n"). + +===== Recipe: Generate Compliant Row Separator + +For strict compliance, use option +:row_sep+ to specify row separator "\r\n": + output_string = CSV.generate('', row_sep: "\r\n") do |csv| + csv << ['Foo', 0] + csv << ['Bar', 1] + csv << ['Baz', 2] + end + output_string # => "Foo,0\r\nBar,1\r\nBaz,2\r\n" + +===== Recipe: Generate Non-Compliant Row Separator + +For data with non-compliant row separators, use option +:row_sep+ with a different value: +This example source uses semicolon (";') as its row separator: + output_string = CSV.generate('', row_sep: ";") do |csv| + csv << ['Foo', 0] + csv << ['Bar', 1] + csv << ['Baz', 2] + end + output_string # => "Foo,0;Bar,1;Baz,2;" + +==== Column Separator + +RFC 4180 specifies column separator COMMA (Ruby ","). + +===== Recipe: Generate Compliant Column Separator + +Because the \CSV default comma separator is ",", +you need not specify option +:col_sep+ for compliant data: + output_string = CSV.generate('') do |csv| + csv << ['Foo', 0] + csv << ['Bar', 1] + csv << ['Baz', 2] + end + output_string # => "Foo,0\nBar,1\nBaz,2\n" + +===== Recipe: Generate Non-Compliant Column Separator + +For data with non-compliant column separators, use option +:col_sep+. +This example source uses TAB ("\t") as its column separator: + output_string = CSV.generate('', col_sep: "\t") do |csv| + csv << ['Foo', 0] + csv << ['Bar', 1] + csv << ['Baz', 2] + end + output_string # => "Foo\t0\nBar\t1\nBaz\t2\n" + +==== Quotes + +IFC 4180 allows most fields to be quoted or not. +By default, \CSV does not quote most fields. + +However, a field containing the current row separator, column separator, +or quote character is automatically quoted, producing IFC 4180 compliance: + # Field contains row separator. + output_string = CSV.generate('') do |csv| + row_sep = csv.row_sep + csv << ["Foo#{row_sep}Foo", 0] + csv << ['Bar', 1] + csv << ['Baz', 2] + end + output_string # => "\"Foo\nFoo\",0\nBar,1\nBaz,2\n" + # Field contains column separator. + output_string = CSV.generate('') do |csv| + col_sep = csv.col_sep + csv << ["Foo#{col_sep}Foo", 0] + csv << ['Bar', 1] + csv << ['Baz', 2] + end + output_string # => "\"Foo,Foo\",0\nBar,1\nBaz,2\n" + # Field contains quote character. + output_string = CSV.generate('') do |csv| + quote_char = csv.quote_char + csv << ["Foo#{quote_char}Foo", 0] + csv << ['Bar', 1] + csv << ['Baz', 2] + end + output_string # => "\"Foo\"\"Foo\",0\nBar,1\nBaz,2\n" + +===== Recipe: Quote All Fields + +Use option +:force_quotes+ to force quoted fields: + output_string = CSV.generate('', force_quotes: true) do |csv| + csv << ['Foo', 0] + csv << ['Bar', 1] + csv << ['Baz', 2] + end + output_string # => "\"Foo\",\"0\"\n\"Bar\",\"1\"\n\"Baz\",\"2\"\n" + +===== Recipe: Quote Empty Fields + +Use option +:quote_empty+ to force quoting for empty fields: + output_string = CSV.generate('', quote_empty: true) do |csv| + csv << ['Foo', 0] + csv << ['Bar', 1] + csv << ['', 2] + end + output_string # => "Foo,0\nBar,1\n\"\",2\n" + +===== Recipe: Generate Compliant Quote Character + +RFC 4180 specifies quote character DQUOTE (Ruby "\""). + +Because the \CSV default quote character is also "\"", +you need not specify option +:quote_char+ for compliant data: + output_string = CSV.generate('', force_quotes: true) do |csv| + csv << ['Foo', 0] + csv << ['Bar', 1] + csv << ['Baz', 2] + end + output_string # => "\"Foo\",\"0\"\n\"Bar\",\"1\"\n\"Baz\",\"2\"\n" + +===== Recipe: Generate Non-Compliant Quote Character + +For data with non-compliant quote characters, use option +:quote_char+. +This example source uses SQUOTE ("'") as its quote character: + output_string = CSV.generate('', quote_char: "'", force_quotes: true) do |csv| + csv << ['Foo', 0] + csv << ['Bar', 1] + csv << ['Baz', 2] + end + output_string # => "'Foo','0'\n'Bar','1'\n'Baz','2'\n" diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/recipes/parsing.rdoc b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/recipes/parsing.rdoc new file mode 100644 index 0000000..6367307 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/recipes/parsing.rdoc @@ -0,0 +1,554 @@ +== Recipes for Parsing \CSV + +These recipes are specific code examples for specific \CSV parsing tasks. + +For other recipes, see {Recipes for CSV}[./recipes_rdoc.html]. + +All code snippets on this page assume that the following has been executed: + require 'csv' + +=== Contents + +- {Source Formats}[#label-Source+Formats] + - {Parsing from a String}[#label-Parsing+from+a+String] + - {Recipe: Parse from String with Headers}[#label-Recipe-3A+Parse+from+String+with+Headers] + - {Recipe: Parse from String Without Headers}[#label-Recipe-3A+Parse+from+String+Without+Headers] + - {Parsing from a File}[#label-Parsing+from+a+File] + - {Recipe: Parse from File with Headers}[#label-Recipe-3A+Parse+from+File+with+Headers] + - {Recipe: Parse from File Without Headers}[#label-Recipe-3A+Parse+from+File+Without+Headers] + - {Parsing from an IO Stream}[#label-Parsing+from+an+IO+Stream] + - {Recipe: Parse from IO Stream with Headers}[#label-Recipe-3A+Parse+from+IO+Stream+with+Headers] + - {Recipe: Parse from IO Stream Without Headers}[#label-Recipe-3A+Parse+from+IO+Stream+Without+Headers] +- {RFC 4180 Compliance}[#label-RFC+4180+Compliance] + - {Row Separator}[#label-Row+Separator] + - {Recipe: Handle Compliant Row Separator}[#label-Recipe-3A+Handle+Compliant+Row+Separator] + - {Recipe: Handle Non-Compliant Row Separator}[#label-Recipe-3A+Handle+Non-Compliant+Row+Separator] + - {Column Separator}[#label-Column+Separator] + - {Recipe: Handle Compliant Column Separator}[#label-Recipe-3A+Handle+Compliant+Column+Separator] + - {Recipe: Handle Non-Compliant Column Separator}[#label-Recipe-3A+Handle+Non-Compliant+Column+Separator] + - {Quote Character}[#label-Quote+Character] + - {Recipe: Handle Compliant Quote Character}[#label-Recipe-3A+Handle+Compliant+Quote+Character] + - {Recipe: Handle Non-Compliant Quote Character}[#label-Recipe-3A+Handle+Non-Compliant+Quote+Character] + - {Recipe: Allow Liberal Parsing}[#label-Recipe-3A+Allow+Liberal+Parsing] +- {Special Handling}[#label-Special+Handling] + - {Special Line Handling}[#label-Special+Line+Handling] + - {Recipe: Ignore Blank Lines}[#label-Recipe-3A+Ignore+Blank+Lines] + - {Recipe: Ignore Selected Lines}[#label-Recipe-3A+Ignore+Selected+Lines] + - {Special Field Handling}[#label-Special+Field+Handling] + - {Recipe: Strip Fields}[#label-Recipe-3A+Strip+Fields] + - {Recipe: Handle Null Fields}[#label-Recipe-3A+Handle+Null+Fields] + - {Recipe: Handle Empty Fields}[#label-Recipe-3A+Handle+Empty+Fields] +- {Converting Fields}[#label-Converting+Fields] + - {Converting Fields to Objects}[#label-Converting+Fields+to+Objects] + - {Recipe: Convert Fields to Integers}[#label-Recipe-3A+Convert+Fields+to+Integers] + - {Recipe: Convert Fields to Floats}[#label-Recipe-3A+Convert+Fields+to+Floats] + - {Recipe: Convert Fields to Numerics}[#label-Recipe-3A+Convert+Fields+to+Numerics] + - {Recipe: Convert Fields to Dates}[#label-Recipe-3A+Convert+Fields+to+Dates] + - {Recipe: Convert Fields to DateTimes}[#label-Recipe-3A+Convert+Fields+to+DateTimes] + - {Recipe: Convert Fields to Times}[#label-Recipe-3A+Convert+Fields+to+Times] + - {Recipe: Convert Assorted Fields to Objects}[#label-Recipe-3A+Convert+Assorted+Fields+to+Objects] + - {Recipe: Convert Fields to Other Objects}[#label-Recipe-3A+Convert+Fields+to+Other+Objects] + - {Recipe: Filter Field Strings}[#label-Recipe-3A+Filter+Field+Strings] + - {Recipe: Register Field Converters}[#label-Recipe-3A+Register+Field+Converters] + - {Using Multiple Field Converters}[#label-Using+Multiple+Field+Converters] + - {Recipe: Specify Multiple Field Converters in Option :converters}[#label-Recipe-3A+Specify+Multiple+Field+Converters+in+Option+-3Aconverters] + - {Recipe: Specify Multiple Field Converters in a Custom Converter List}[#label-Recipe-3A+Specify+Multiple+Field+Converters+in+a+Custom+Converter+List] +- {Converting Headers}[#label-Converting+Headers] + - {Recipe: Convert Headers to Lowercase}[#label-Recipe-3A+Convert+Headers+to+Lowercase] + - {Recipe: Convert Headers to Symbols}[#label-Recipe-3A+Convert+Headers+to+Symbols] + - {Recipe: Filter Header Strings}[#label-Recipe-3A+Filter+Header+Strings] + - {Recipe: Register Header Converters}[#label-Recipe-3A+Register+Header+Converters] + - {Using Multiple Header Converters}[#label-Using+Multiple+Header+Converters] + - {Recipe: Specify Multiple Header Converters in Option :header_converters}[#label-Recipe-3A+Specify+Multiple+Header+Converters+in+Option+-3Aheader_converters] + - {Recipe: Specify Multiple Header Converters in a Custom Header Converter List}[#label-Recipe-3A+Specify+Multiple+Header+Converters+in+a+Custom+Header+Converter+List] +- {Diagnostics}[#label-Diagnostics] + - {Recipe: Capture Unconverted Fields}[#label-Recipe-3A+Capture+Unconverted+Fields] + - {Recipe: Capture Field Info}[#label-Recipe-3A+Capture+Field+Info] + +=== Source Formats + +You can parse \CSV data from a \String, from a \File (via its path), or from an \IO stream. + +==== Parsing from a \String + +You can parse \CSV data from a \String, with or without headers. + +===== Recipe: Parse from \String with Headers + +Use class method CSV.parse with option +headers+ to read a source \String all at once +(may have memory resource implications): + string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + CSV.parse(string, headers: true) # => # + +Use instance method CSV#each with option +headers+ to read a source \String one row at a time: + CSV.new(string, headers: true).each do |row| + p row + end +Output: + # + # + # + +===== Recipe: Parse from \String Without Headers + +Use class method CSV.parse without option +headers+ to read a source \String all at once +(may have memory resource implications): + string = "foo,0\nbar,1\nbaz,2\n" + CSV.parse(string) # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] + +Use instance method CSV#each without option +headers+ to read a source \String one row at a time: + CSV.new(string).each do |row| + p row + end +Output: + ["foo", "0"] + ["bar", "1"] + ["baz", "2"] + +==== Parsing from a \File + +You can parse \CSV data from a \File, with or without headers. + +===== Recipe: Parse from \File with Headers + +Use class method CSV.read with option +headers+ to read a file all at once: + string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + path = 't.csv' + File.write(path, string) + CSV.read(path, headers: true) # => # + +Use class method CSV.foreach with option +headers+ to read one row at a time: + CSV.foreach(path, headers: true) do |row| + p row + end +Output: + # + # + # + +===== Recipe: Parse from \File Without Headers + +Use class method CSV.read without option +headers+ to read a file all at once: + string = "foo,0\nbar,1\nbaz,2\n" + path = 't.csv' + File.write(path, string) + CSV.read(path) # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] + +Use class method CSV.foreach without option +headers+ to read one row at a time: + CSV.foreach(path) do |row| + p row + end +Output: + ["foo", "0"] + ["bar", "1"] + ["baz", "2"] + +==== Parsing from an \IO Stream + +You can parse \CSV data from an \IO stream, with or without headers. + +===== Recipe: Parse from \IO Stream with Headers + +Use class method CSV.parse with option +headers+ to read an \IO stream all at once: + string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + path = 't.csv' + File.write(path, string) + File.open(path) do |file| + CSV.parse(file, headers: true) + end # => # + +Use class method CSV.foreach with option +headers+ to read one row at a time: + File.open(path) do |file| + CSV.foreach(file, headers: true) do |row| + p row + end + end +Output: + # + # + # + +===== Recipe: Parse from \IO Stream Without Headers + +Use class method CSV.parse without option +headers+ to read an \IO stream all at once: + string = "foo,0\nbar,1\nbaz,2\n" + path = 't.csv' + File.write(path, string) + File.open(path) do |file| + CSV.parse(file) + end # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] + +Use class method CSV.foreach without option +headers+ to read one row at a time: + File.open(path) do |file| + CSV.foreach(file) do |row| + p row + end + end +Output: + ["foo", "0"] + ["bar", "1"] + ["baz", "2"] + +=== RFC 4180 Compliance + +By default, \CSV parses data that is compliant with +{RFC 4180}[https://www.rfc-editor.org/rfc/rfc4180] +with respect to: +- Row separator. +- Column separator. +- Quote character. + +==== Row Separator + +RFC 4180 specifies the row separator CRLF (Ruby "\r\n"). + +Although the \CSV default row separator is "\n", +the parser also by default handles row separator "\r" and the RFC-compliant "\r\n". + +===== Recipe: Handle Compliant Row Separator + +For strict compliance, use option +:row_sep+ to specify row separator "\r\n", +which allows the compliant row separator: + source = "foo,1\r\nbar,1\r\nbaz,2\r\n" + CSV.parse(source, row_sep: "\r\n") # => [["foo", "1"], ["bar", "1"], ["baz", "2"]] +But rejects other row separators: + source = "foo,1\nbar,1\nbaz,2\n" + CSV.parse(source, row_sep: "\r\n") # Raised MalformedCSVError + source = "foo,1\rbar,1\rbaz,2\r" + CSV.parse(source, row_sep: "\r\n") # Raised MalformedCSVError + source = "foo,1\n\rbar,1\n\rbaz,2\n\r" + CSV.parse(source, row_sep: "\r\n") # Raised MalformedCSVError + +===== Recipe: Handle Non-Compliant Row Separator + +For data with non-compliant row separators, use option +:row_sep+. +This example source uses semicolon (";") as its row separator: + source = "foo,1;bar,1;baz,2;" + CSV.parse(source, row_sep: ';') # => [["foo", "1"], ["bar", "1"], ["baz", "2"]] + +==== Column Separator + +RFC 4180 specifies column separator COMMA (Ruby ","). + +===== Recipe: Handle Compliant Column Separator + +Because the \CSV default comma separator is ',', +you need not specify option +:col_sep+ for compliant data: + source = "foo,1\nbar,1\nbaz,2\n" + CSV.parse(source) # => [["foo", "1"], ["bar", "1"], ["baz", "2"]] + +===== Recipe: Handle Non-Compliant Column Separator + +For data with non-compliant column separators, use option +:col_sep+. +This example source uses TAB ("\t") as its column separator: + source = "foo,1\tbar,1\tbaz,2" + CSV.parse(source, col_sep: "\t") # => [["foo", "1"], ["bar", "1"], ["baz", "2"]] + +==== Quote Character + +RFC 4180 specifies quote character DQUOTE (Ruby "\""). + +===== Recipe: Handle Compliant Quote Character + +Because the \CSV default quote character is "\"", +you need not specify option +:quote_char+ for compliant data: + source = "\"foo\",\"1\"\n\"bar\",\"1\"\n\"baz\",\"2\"\n" + CSV.parse(source) # => [["foo", "1"], ["bar", "1"], ["baz", "2"]] + +===== Recipe: Handle Non-Compliant Quote Character + +For data with non-compliant quote characters, use option +:quote_char+. +This example source uses SQUOTE ("'") as its quote character: + source = "'foo','1'\n'bar','1'\n'baz','2'\n" + CSV.parse(source, quote_char: "'") # => [["foo", "1"], ["bar", "1"], ["baz", "2"]] + +==== Recipe: Allow Liberal Parsing + +Use option +:liberal_parsing+ to specify that \CSV should +attempt to parse input not conformant with RFC 4180, such as double quotes in unquoted fields: + source = 'is,this "three, or four",fields' + CSV.parse(source) # Raises MalformedCSVError + CSV.parse(source, liberal_parsing: true) # => [["is", "this \"three", " or four\"", "fields"]] + +=== Special Handling + +You can use parsing options to specify special handling for certain lines and fields. + +==== Special Line Handling + +Use parsing options to specify special handling for blank lines, or for other selected lines. + +===== Recipe: Ignore Blank Lines + +Use option +:skip_blanks+ to ignore blank lines: + source = <<-EOT + foo,0 + + bar,1 + baz,2 + + , + EOT + parsed = CSV.parse(source, skip_blanks: true) + parsed # => [["foo", "0"], ["bar", "1"], ["baz", "2"], [nil, nil]] + +===== Recipe: Ignore Selected Lines + +Use option +:skip_lines+ to ignore selected lines. + source = <<-EOT + # Comment + foo,0 + bar,1 + baz,2 + # Another comment + EOT + parsed = CSV.parse(source, skip_lines: /^#/) + parsed # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] + +==== Special Field Handling + +Use parsing options to specify special handling for certain field values. + +===== Recipe: Strip Fields + +Use option +:strip+ to strip parsed field values: + CSV.parse_line(' a , b ', strip: true) # => ["a", "b"] + +===== Recipe: Handle Null Fields + +Use option +:nil_value+ to specify a value that will replace each field +that is null (no text): + CSV.parse_line('a,,b,,c', nil_value: 0) # => ["a", 0, "b", 0, "c"] + +===== Recipe: Handle Empty Fields + +Use option +:empty_value+ to specify a value that will replace each field +that is empty (\String of length 0); + CSV.parse_line('a,"",b,"",c', empty_value: 'x') # => ["a", "x", "b", "x", "c"] + +=== Converting Fields + +You can use field converters to change parsed \String fields into other objects, +or to otherwise modify the \String fields. + +==== Converting Fields to Objects + +Use field converters to change parsed \String objects into other, more specific, objects. + +There are built-in field converters for converting to objects of certain classes: +- \Float +- \Integer +- \Date +- \DateTime +- \Time + +Other built-in field converters include: +- +:numeric+: converts to \Integer and \Float. +- +:all+: converts to \DateTime, \Integer, \Float. + +You can also define field converters to convert to objects of other classes. + +===== Recipe: Convert Fields to Integers + +Convert fields to \Integer objects using built-in converter +:integer+: + source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + parsed = CSV.parse(source, headers: true, converters: :integer) + parsed.map {|row| row['Value'].class} # => [Integer, Integer, Integer] + +===== Recipe: Convert Fields to Floats + +Convert fields to \Float objects using built-in converter +:float+: + source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + parsed = CSV.parse(source, headers: true, converters: :float) + parsed.map {|row| row['Value'].class} # => [Float, Float, Float] + +===== Recipe: Convert Fields to Numerics + +Convert fields to \Integer and \Float objects using built-in converter +:numeric+: + source = "Name,Value\nfoo,0\nbar,1.1\nbaz,2.2\n" + parsed = CSV.parse(source, headers: true, converters: :numeric) + parsed.map {|row| row['Value'].class} # => [Integer, Float, Float] + +===== Recipe: Convert Fields to Dates + +Convert fields to \Date objects using built-in converter +:date+: + source = "Name,Date\nfoo,2001-02-03\nbar,2001-02-04\nbaz,2001-02-03\n" + parsed = CSV.parse(source, headers: true, converters: :date) + parsed.map {|row| row['Date'].class} # => [Date, Date, Date] + +===== Recipe: Convert Fields to DateTimes + +Convert fields to \DateTime objects using built-in converter +:date_time+: + source = "Name,DateTime\nfoo,2001-02-03\nbar,2001-02-04\nbaz,2020-05-07T14:59:00-05:00\n" + parsed = CSV.parse(source, headers: true, converters: :date_time) + parsed.map {|row| row['DateTime'].class} # => [DateTime, DateTime, DateTime] + +===== Recipe: Convert Fields to Times + +Convert fields to \Time objects using built-in converter +:time+: + source = "Name,Time\nfoo,2001-02-03\nbar,2001-02-04\nbaz,2020-05-07T14:59:00-05:00\n" + parsed = CSV.parse(source, headers: true, converters: :time) + parsed.map {|row| row['Time'].class} # => [Time, Time, Time] + +===== Recipe: Convert Assorted Fields to Objects + +Convert assorted fields to objects using built-in converter +:all+: + source = "Type,Value\nInteger,0\nFloat,1.0\nDateTime,2001-02-04\n" + parsed = CSV.parse(source, headers: true, converters: :all) + parsed.map {|row| row['Value'].class} # => [Integer, Float, DateTime] + +===== Recipe: Convert Fields to Other Objects + +Define a custom field converter to convert \String fields into other objects. +This example defines and uses a custom field converter +that converts each column-1 value to a \Rational object: + rational_converter = proc do |field, field_context| + field_context.index == 1 ? field.to_r : field + end + source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + parsed = CSV.parse(source, headers: true, converters: rational_converter) + parsed.map {|row| row['Value'].class} # => [Rational, Rational, Rational] + +==== Recipe: Filter Field Strings + +Define a custom field converter to modify \String fields. +This example defines and uses a custom field converter +that strips whitespace from each field value: + strip_converter = proc {|field| field.strip } + source = "Name,Value\n foo , 0 \n bar , 1 \n baz , 2 \n" + parsed = CSV.parse(source, headers: true, converters: strip_converter) + parsed['Name'] # => ["foo", "bar", "baz"] + parsed['Value'] # => ["0", "1", "2"] + +==== Recipe: Register Field Converters + +Register a custom field converter, assigning it a name; +then refer to the converter by its name: + rational_converter = proc do |field, field_context| + field_context.index == 1 ? field.to_r : field + end + CSV::Converters[:rational] = rational_converter + source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + parsed = CSV.parse(source, headers: true, converters: :rational) + parsed['Value'] # => [(0/1), (1/1), (2/1)] + +==== Using Multiple Field Converters + +You can use multiple field converters in either of these ways: +- Specify converters in option +:converters+. +- Specify converters in a custom converter list. + +===== Recipe: Specify Multiple Field Converters in Option +:converters+ + +Apply multiple field converters by specifying them in option +:converters+: + source = "Name,Value\nfoo,0\nbar,1.0\nbaz,2.0\n" + parsed = CSV.parse(source, headers: true, converters: [:integer, :float]) + parsed['Value'] # => [0, 1.0, 2.0] + +===== Recipe: Specify Multiple Field Converters in a Custom Converter List + +Apply multiple field converters by defining and registering a custom converter list: + strip_converter = proc {|field| field.strip } + CSV::Converters[:strip] = strip_converter + CSV::Converters[:my_converters] = [:integer, :float, :strip] + source = "Name,Value\n foo , 0 \n bar , 1.0 \n baz , 2.0 \n" + parsed = CSV.parse(source, headers: true, converters: :my_converters) + parsed['Name'] # => ["foo", "bar", "baz"] + parsed['Value'] # => [0, 1.0, 2.0] + +=== Converting Headers + +You can use header converters to modify parsed \String headers. + +Built-in header converters include: +- +:symbol+: converts \String header to \Symbol. +- +:downcase+: converts \String header to lowercase. + +You can also define header converters to otherwise modify header \Strings. + +==== Recipe: Convert Headers to Lowercase + +Convert headers to lowercase using built-in converter +:downcase+: + source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + parsed = CSV.parse(source, headers: true, header_converters: :downcase) + parsed.headers # => ["name", "value"] + +==== Recipe: Convert Headers to Symbols + +Convert headers to downcased Symbols using built-in converter +:symbol+: + source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + parsed = CSV.parse(source, headers: true, header_converters: :symbol) + parsed.headers # => [:name, :value] + parsed.headers.map {|header| header.class} # => [Symbol, Symbol] + +==== Recipe: Filter Header Strings + +Define a custom header converter to modify \String fields. +This example defines and uses a custom header converter +that capitalizes each header \String: + capitalize_converter = proc {|header| header.capitalize } + source = "NAME,VALUE\nfoo,0\nbar,1\nbaz,2\n" + parsed = CSV.parse(source, headers: true, header_converters: capitalize_converter) + parsed.headers # => ["Name", "Value"] + +==== Recipe: Register Header Converters + +Register a custom header converter, assigning it a name; +then refer to the converter by its name: + capitalize_converter = proc {|header| header.capitalize } + CSV::HeaderConverters[:capitalize] = capitalize_converter + source = "NAME,VALUE\nfoo,0\nbar,1\nbaz,2\n" + parsed = CSV.parse(source, headers: true, header_converters: :capitalize) + parsed.headers # => ["Name", "Value"] + +==== Using Multiple Header Converters + +You can use multiple header converters in either of these ways: +- Specify header converters in option +:header_converters+. +- Specify header converters in a custom header converter list. + +===== Recipe: Specify Multiple Header Converters in Option :header_converters + +Apply multiple header converters by specifying them in option +:header_converters+: + source = "Name,Value\nfoo,0\nbar,1.0\nbaz,2.0\n" + parsed = CSV.parse(source, headers: true, header_converters: [:downcase, :symbol]) + parsed.headers # => [:name, :value] + +===== Recipe: Specify Multiple Header Converters in a Custom Header Converter List + +Apply multiple header converters by defining and registering a custom header converter list: + CSV::HeaderConverters[:my_header_converters] = [:symbol, :downcase] + source = "NAME,VALUE\nfoo,0\nbar,1.0\nbaz,2.0\n" + parsed = CSV.parse(source, headers: true, header_converters: :my_header_converters) + parsed.headers # => [:name, :value] + +=== Diagnostics + +==== Recipe: Capture Unconverted Fields + +To capture unconverted field values, use option +:unconverted_fields+: + source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + parsed = CSV.parse(source, converters: :integer, unconverted_fields: true) + parsed # => [["Name", "Value"], ["foo", 0], ["bar", 1], ["baz", 2]] + parsed.each {|row| p row.unconverted_fields } +Output: + ["Name", "Value"] + ["foo", "0"] + ["bar", "1"] + ["baz", "2"] + +==== Recipe: Capture Field Info + +To capture field info in a custom converter, accept two block arguments. +The first is the field value; the second is a +CSV::FieldInfo+ object: + strip_converter = proc {|field, field_info| p field_info; field.strip } + source = " foo , 0 \n bar , 1 \n baz , 2 \n" + parsed = CSV.parse(source, converters: strip_converter) + parsed # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] +Output: + # + # + # + # + # + # diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/recipes/recipes.rdoc b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/recipes/recipes.rdoc new file mode 100644 index 0000000..9bf7885 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/doc/csv/recipes/recipes.rdoc @@ -0,0 +1,6 @@ +== Recipes for \CSV + +The recipes are specific code examples for specific tasks. See: +- {Recipes for Parsing CSV}[./parsing_rdoc.html] +- {Recipes for Generating CSV}[./generating_rdoc.html] +- {Recipes for Filtering CSV}[./filtering_rdoc.html] diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv.rb b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv.rb new file mode 100644 index 0000000..aef96ac --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv.rb @@ -0,0 +1,3017 @@ +# encoding: US-ASCII +# frozen_string_literal: true +# = csv.rb -- CSV Reading and Writing +# +# Created by James Edward Gray II on 2005-10-31. +# +# See CSV for documentation. +# +# == Description +# +# Welcome to the new and improved CSV. +# +# This version of the CSV library began its life as FasterCSV. FasterCSV was +# intended as a replacement to Ruby's then standard CSV library. It was +# designed to address concerns users of that library had and it had three +# primary goals: +# +# 1. Be significantly faster than CSV while remaining a pure Ruby library. +# 2. Use a smaller and easier to maintain code base. (FasterCSV eventually +# grew larger, was also but considerably richer in features. The parsing +# core remains quite small.) +# 3. Improve on the CSV interface. +# +# Obviously, the last one is subjective. I did try to defer to the original +# interface whenever I didn't have a compelling reason to change it though, so +# hopefully this won't be too radically different. +# +# We must have met our goals because FasterCSV was renamed to CSV and replaced +# the original library as of Ruby 1.9. If you are migrating code from 1.8 or +# earlier, you may have to change your code to comply with the new interface. +# +# == What's the Different From the Old CSV? +# +# I'm sure I'll miss something, but I'll try to mention most of the major +# differences I am aware of, to help others quickly get up to speed: +# +# === \CSV Parsing +# +# * This parser is m17n aware. See CSV for full details. +# * This library has a stricter parser and will throw MalformedCSVErrors on +# problematic data. +# * This library has a less liberal idea of a line ending than CSV. What you +# set as the :row_sep is law. It can auto-detect your line endings +# though. +# * The old library returned empty lines as [nil]. This library calls +# them []. +# * This library has a much faster parser. +# +# === Interface +# +# * CSV now uses keyword parameters to set options. +# * CSV no longer has generate_row() or parse_row(). +# * The old CSV's Reader and Writer classes have been dropped. +# * CSV::open() is now more like Ruby's open(). +# * CSV objects now support most standard IO methods. +# * CSV now has a new() method used to wrap objects like String and IO for +# reading and writing. +# * CSV::generate() is different from the old method. +# * CSV no longer supports partial reads. It works line-by-line. +# * CSV no longer allows the instance methods to override the separators for +# performance reasons. They must be set in the constructor. +# +# If you use this library and find yourself missing any functionality I have +# trimmed, please {let me know}[mailto:james@grayproductions.net]. +# +# == Documentation +# +# See CSV for documentation. +# +# == What is CSV, really? +# +# CSV maintains a pretty strict definition of CSV taken directly from +# {the RFC}[https://www.ietf.org/rfc/rfc4180.txt]. I relax the rules in only one +# place and that is to make using this library easier. CSV will parse all valid +# CSV. +# +# What you don't want to do is to feed CSV invalid data. Because of the way the +# CSV format works, it's common for a parser to need to read until the end of +# the file to be sure a field is invalid. This consumes a lot of time and memory. +# +# Luckily, when working with invalid CSV, Ruby's built-in methods will almost +# always be superior in every way. For example, parsing non-quoted fields is as +# easy as: +# +# data.split(",") +# +# == Questions and/or Comments +# +# Feel free to email {James Edward Gray II}[mailto:james@grayproductions.net] +# with any questions. + +require "forwardable" +require "date" +require "time" +require "stringio" + +require_relative "csv/fields_converter" +require_relative "csv/input_record_separator" +require_relative "csv/parser" +require_relative "csv/row" +require_relative "csv/table" +require_relative "csv/writer" + +# == \CSV +# +# === \CSV Data +# +# \CSV (comma-separated values) data is a text representation of a table: +# - A _row_ _separator_ delimits table rows. +# A common row separator is the newline character "\n". +# - A _column_ _separator_ delimits fields in a row. +# A common column separator is the comma character ",". +# +# This \CSV \String, with row separator "\n" +# and column separator ",", +# has three rows and two columns: +# "foo,0\nbar,1\nbaz,2\n" +# +# Despite the name \CSV, a \CSV representation can use different separators. +# +# For more about tables, see the Wikipedia article +# "{Table (information)}[https://en.wikipedia.org/wiki/Table_(information)]", +# especially its section +# "{Simple table}[https://en.wikipedia.org/wiki/Table_(information)#Simple_table]" +# +# == \Class \CSV +# +# Class \CSV provides methods for: +# - Parsing \CSV data from a \String object, a \File (via its file path), or an \IO object. +# - Generating \CSV data to a \String object. +# +# To make \CSV available: +# require 'csv' +# +# All examples here assume that this has been done. +# +# == Keeping It Simple +# +# A \CSV object has dozens of instance methods that offer fine-grained control +# of parsing and generating \CSV data. +# For many needs, though, simpler approaches will do. +# +# This section summarizes the singleton methods in \CSV +# that allow you to parse and generate without explicitly +# creating \CSV objects. +# For details, follow the links. +# +# === Simple Parsing +# +# Parsing methods commonly return either of: +# - An \Array of Arrays of Strings: +# - The outer \Array is the entire "table". +# - Each inner \Array is a row. +# - Each \String is a field. +# - A CSV::Table object. For details, see +# {\CSV with Headers}[#class-CSV-label-CSV+with+Headers]. +# +# ==== Parsing a \String +# +# The input to be parsed can be a string: +# string = "foo,0\nbar,1\nbaz,2\n" +# +# \Method CSV.parse returns the entire \CSV data: +# CSV.parse(string) # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] +# +# \Method CSV.parse_line returns only the first row: +# CSV.parse_line(string) # => ["foo", "0"] +# +# \CSV extends class \String with instance method String#parse_csv, +# which also returns only the first row: +# string.parse_csv # => ["foo", "0"] +# +# ==== Parsing Via a \File Path +# +# The input to be parsed can be in a file: +# string = "foo,0\nbar,1\nbaz,2\n" +# path = 't.csv' +# File.write(path, string) +# +# \Method CSV.read returns the entire \CSV data: +# CSV.read(path) # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] +# +# \Method CSV.foreach iterates, passing each row to the given block: +# CSV.foreach(path) do |row| +# p row +# end +# Output: +# ["foo", "0"] +# ["bar", "1"] +# ["baz", "2"] +# +# \Method CSV.table returns the entire \CSV data as a CSV::Table object: +# CSV.table(path) # => # +# +# ==== Parsing from an Open \IO Stream +# +# The input to be parsed can be in an open \IO stream: +# +# \Method CSV.read returns the entire \CSV data: +# File.open(path) do |file| +# CSV.read(file) +# end # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] +# +# As does method CSV.parse: +# File.open(path) do |file| +# CSV.parse(file) +# end # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] +# +# \Method CSV.parse_line returns only the first row: +# File.open(path) do |file| +# CSV.parse_line(file) +# end # => ["foo", "0"] +# +# \Method CSV.foreach iterates, passing each row to the given block: +# File.open(path) do |file| +# CSV.foreach(file) do |row| +# p row +# end +# end +# Output: +# ["foo", "0"] +# ["bar", "1"] +# ["baz", "2"] +# +# \Method CSV.table returns the entire \CSV data as a CSV::Table object: +# File.open(path) do |file| +# CSV.table(file) +# end # => # +# +# === Simple Generating +# +# \Method CSV.generate returns a \String; +# this example uses method CSV#<< to append the rows +# that are to be generated: +# output_string = CSV.generate do |csv| +# csv << ['foo', 0] +# csv << ['bar', 1] +# csv << ['baz', 2] +# end +# output_string # => "foo,0\nbar,1\nbaz,2\n" +# +# \Method CSV.generate_line returns a \String containing the single row +# constructed from an \Array: +# CSV.generate_line(['foo', '0']) # => "foo,0\n" +# +# \CSV extends class \Array with instance method Array#to_csv, +# which forms an \Array into a \String: +# ['foo', '0'].to_csv # => "foo,0\n" +# +# === "Filtering" \CSV +# +# \Method CSV.filter provides a Unix-style filter for \CSV data. +# The input data is processed to form the output data: +# in_string = "foo,0\nbar,1\nbaz,2\n" +# out_string = '' +# CSV.filter(in_string, out_string) do |row| +# row[0] = row[0].upcase +# row[1] *= 4 +# end +# out_string # => "FOO,0000\nBAR,1111\nBAZ,2222\n" +# +# == \CSV Objects +# +# There are three ways to create a \CSV object: +# - \Method CSV.new returns a new \CSV object. +# - \Method CSV.instance returns a new or cached \CSV object. +# - \Method \CSV() also returns a new or cached \CSV object. +# +# === Instance Methods +# +# \CSV has three groups of instance methods: +# - Its own internally defined instance methods. +# - Methods included by module Enumerable. +# - Methods delegated to class IO. See below. +# +# ==== Delegated Methods +# +# For convenience, a CSV object will delegate to many methods in class IO. +# (A few have wrapper "guard code" in \CSV.) You may call: +# * IO#binmode +# * #binmode? +# * IO#close +# * IO#close_read +# * IO#close_write +# * IO#closed? +# * #eof +# * #eof? +# * IO#external_encoding +# * IO#fcntl +# * IO#fileno +# * #flock +# * IO#flush +# * IO#fsync +# * IO#internal_encoding +# * #ioctl +# * IO#isatty +# * #path +# * IO#pid +# * IO#pos +# * IO#pos= +# * IO#reopen +# * #rewind +# * IO#seek +# * #stat +# * IO#string +# * IO#sync +# * IO#sync= +# * IO#tell +# * #to_i +# * #to_io +# * IO#truncate +# * IO#tty? +# +# === Options +# +# The default values for options are: +# DEFAULT_OPTIONS = { +# # For both parsing and generating. +# col_sep: ",", +# row_sep: :auto, +# quote_char: '"', +# # For parsing. +# field_size_limit: nil, +# converters: nil, +# unconverted_fields: nil, +# headers: false, +# return_headers: false, +# header_converters: nil, +# skip_blanks: false, +# skip_lines: nil, +# liberal_parsing: false, +# nil_value: nil, +# empty_value: "", +# strip: false, +# # For generating. +# write_headers: nil, +# quote_empty: true, +# force_quotes: false, +# write_converters: nil, +# write_nil_value: nil, +# write_empty_value: "", +# } +# +# ==== Options for Parsing +# +# Options for parsing, described in detail below, include: +# - +row_sep+: Specifies the row separator; used to delimit rows. +# - +col_sep+: Specifies the column separator; used to delimit fields. +# - +quote_char+: Specifies the quote character; used to quote fields. +# - +field_size_limit+: Specifies the maximum field size + 1 allowed. +# Deprecated since 3.2.3. Use +max_field_size+ instead. +# - +max_field_size+: Specifies the maximum field size allowed. +# - +converters+: Specifies the field converters to be used. +# - +unconverted_fields+: Specifies whether unconverted fields are to be available. +# - +headers+: Specifies whether data contains headers, +# or specifies the headers themselves. +# - +return_headers+: Specifies whether headers are to be returned. +# - +header_converters+: Specifies the header converters to be used. +# - +skip_blanks+: Specifies whether blanks lines are to be ignored. +# - +skip_lines+: Specifies how comments lines are to be recognized. +# - +strip+: Specifies whether leading and trailing whitespace are to be +# stripped from fields. This must be compatible with +col_sep+; if it is not, +# then an +ArgumentError+ exception will be raised. +# - +liberal_parsing+: Specifies whether \CSV should attempt to parse +# non-compliant data. +# - +nil_value+: Specifies the object that is to be substituted for each null (no-text) field. +# - +empty_value+: Specifies the object that is to be substituted for each empty field. +# +# :include: ../doc/csv/options/common/row_sep.rdoc +# +# :include: ../doc/csv/options/common/col_sep.rdoc +# +# :include: ../doc/csv/options/common/quote_char.rdoc +# +# :include: ../doc/csv/options/parsing/field_size_limit.rdoc +# +# :include: ../doc/csv/options/parsing/converters.rdoc +# +# :include: ../doc/csv/options/parsing/unconverted_fields.rdoc +# +# :include: ../doc/csv/options/parsing/headers.rdoc +# +# :include: ../doc/csv/options/parsing/return_headers.rdoc +# +# :include: ../doc/csv/options/parsing/header_converters.rdoc +# +# :include: ../doc/csv/options/parsing/skip_blanks.rdoc +# +# :include: ../doc/csv/options/parsing/skip_lines.rdoc +# +# :include: ../doc/csv/options/parsing/strip.rdoc +# +# :include: ../doc/csv/options/parsing/liberal_parsing.rdoc +# +# :include: ../doc/csv/options/parsing/nil_value.rdoc +# +# :include: ../doc/csv/options/parsing/empty_value.rdoc +# +# ==== Options for Generating +# +# Options for generating, described in detail below, include: +# - +row_sep+: Specifies the row separator; used to delimit rows. +# - +col_sep+: Specifies the column separator; used to delimit fields. +# - +quote_char+: Specifies the quote character; used to quote fields. +# - +write_headers+: Specifies whether headers are to be written. +# - +force_quotes+: Specifies whether each output field is to be quoted. +# - +quote_empty+: Specifies whether each empty output field is to be quoted. +# - +write_converters+: Specifies the field converters to be used in writing. +# - +write_nil_value+: Specifies the object that is to be substituted for each +nil+-valued field. +# - +write_empty_value+: Specifies the object that is to be substituted for each empty field. +# +# :include: ../doc/csv/options/common/row_sep.rdoc +# +# :include: ../doc/csv/options/common/col_sep.rdoc +# +# :include: ../doc/csv/options/common/quote_char.rdoc +# +# :include: ../doc/csv/options/generating/write_headers.rdoc +# +# :include: ../doc/csv/options/generating/force_quotes.rdoc +# +# :include: ../doc/csv/options/generating/quote_empty.rdoc +# +# :include: ../doc/csv/options/generating/write_converters.rdoc +# +# :include: ../doc/csv/options/generating/write_nil_value.rdoc +# +# :include: ../doc/csv/options/generating/write_empty_value.rdoc +# +# === \CSV with Headers +# +# CSV allows to specify column names of CSV file, whether they are in data, or +# provided separately. If headers are specified, reading methods return an instance +# of CSV::Table, consisting of CSV::Row. +# +# # Headers are part of data +# data = CSV.parse(<<~ROWS, headers: true) +# Name,Department,Salary +# Bob,Engineering,1000 +# Jane,Sales,2000 +# John,Management,5000 +# ROWS +# +# data.class #=> CSV::Table +# data.first #=> # +# data.first.to_h #=> {"Name"=>"Bob", "Department"=>"Engineering", "Salary"=>"1000"} +# +# # Headers provided by developer +# data = CSV.parse('Bob,Engineering,1000', headers: %i[name department salary]) +# data.first #=> # +# +# === \Converters +# +# By default, each value (field or header) parsed by \CSV is formed into a \String. +# You can use a _field_ _converter_ or _header_ _converter_ +# to intercept and modify the parsed values: +# - See {Field Converters}[#class-CSV-label-Field+Converters]. +# - See {Header Converters}[#class-CSV-label-Header+Converters]. +# +# Also by default, each value to be written during generation is written 'as-is'. +# You can use a _write_ _converter_ to modify values before writing. +# - See {Write Converters}[#class-CSV-label-Write+Converters]. +# +# ==== Specifying \Converters +# +# You can specify converters for parsing or generating in the +options+ +# argument to various \CSV methods: +# - Option +converters+ for converting parsed field values. +# - Option +header_converters+ for converting parsed header values. +# - Option +write_converters+ for converting values to be written (generated). +# +# There are three forms for specifying converters: +# - A converter proc: executable code to be used for conversion. +# - A converter name: the name of a stored converter. +# - A converter list: an array of converter procs, converter names, and converter lists. +# +# ===== Converter Procs +# +# This converter proc, +strip_converter+, accepts a value +field+ +# and returns field.strip: +# strip_converter = proc {|field| field.strip } +# In this call to CSV.parse, +# the keyword argument converters: string_converter +# specifies that: +# - \Proc +string_converter+ is to be called for each parsed field. +# - The converter's return value is to replace the +field+ value. +# Example: +# string = " foo , 0 \n bar , 1 \n baz , 2 \n" +# array = CSV.parse(string, converters: strip_converter) +# array # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] +# +# A converter proc can receive a second argument, +field_info+, +# that contains details about the field. +# This modified +strip_converter+ displays its arguments: +# strip_converter = proc do |field, field_info| +# p [field, field_info] +# field.strip +# end +# string = " foo , 0 \n bar , 1 \n baz , 2 \n" +# array = CSV.parse(string, converters: strip_converter) +# array # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] +# Output: +# [" foo ", #] +# [" 0 ", #] +# [" bar ", #] +# [" 1 ", #] +# [" baz ", #] +# [" 2 ", #] +# Each CSV::FieldInfo object shows: +# - The 0-based field index. +# - The 1-based line index. +# - The field header, if any. +# +# ===== Stored \Converters +# +# A converter may be given a name and stored in a structure where +# the parsing methods can find it by name. +# +# The storage structure for field converters is the \Hash CSV::Converters. +# It has several built-in converter procs: +# - :integer: converts each \String-embedded integer into a true \Integer. +# - :float: converts each \String-embedded float into a true \Float. +# - :date: converts each \String-embedded date into a true \Date. +# - :date_time: converts each \String-embedded date-time into a true \DateTime +# - :time: converts each \String-embedded time into a true \Time +# . +# This example creates a converter proc, then stores it: +# strip_converter = proc {|field| field.strip } +# CSV::Converters[:strip] = strip_converter +# Then the parsing method call can refer to the converter +# by its name, :strip: +# string = " foo , 0 \n bar , 1 \n baz , 2 \n" +# array = CSV.parse(string, converters: :strip) +# array # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] +# +# The storage structure for header converters is the \Hash CSV::HeaderConverters, +# which works in the same way. +# It also has built-in converter procs: +# - :downcase: Downcases each header. +# - :symbol: Converts each header to a \Symbol. +# +# There is no such storage structure for write headers. +# +# In order for the parsing methods to access stored converters in non-main-Ractors, the +# storage structure must be made shareable first. +# Therefore, Ractor.make_shareable(CSV::Converters) and +# Ractor.make_shareable(CSV::HeaderConverters) must be called before the creation +# of Ractors that use the converters stored in these structures. (Since making the storage +# structures shareable involves freezing them, any custom converters that are to be used +# must be added first.) +# +# ===== Converter Lists +# +# A _converter_ _list_ is an \Array that may include any assortment of: +# - Converter procs. +# - Names of stored converters. +# - Nested converter lists. +# +# Examples: +# numeric_converters = [:integer, :float] +# date_converters = [:date, :date_time] +# [numeric_converters, strip_converter] +# [strip_converter, date_converters, :float] +# +# Like a converter proc, a converter list may be named and stored in either +# \CSV::Converters or CSV::HeaderConverters: +# CSV::Converters[:custom] = [strip_converter, date_converters, :float] +# CSV::HeaderConverters[:custom] = [:downcase, :symbol] +# +# There are two built-in converter lists: +# CSV::Converters[:numeric] # => [:integer, :float] +# CSV::Converters[:all] # => [:date_time, :numeric] +# +# ==== Field \Converters +# +# With no conversion, all parsed fields in all rows become Strings: +# string = "foo,0\nbar,1\nbaz,2\n" +# ary = CSV.parse(string) +# ary # => # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] +# +# When you specify a field converter, each parsed field is passed to the converter; +# its return value becomes the stored value for the field. +# A converter might, for example, convert an integer embedded in a \String +# into a true \Integer. +# (In fact, that's what built-in field converter +:integer+ does.) +# +# There are three ways to use field \converters. +# +# - Using option {converters}[#class-CSV-label-Option+converters] with a parsing method: +# ary = CSV.parse(string, converters: :integer) +# ary # => [0, 1, 2] # => [["foo", 0], ["bar", 1], ["baz", 2]] +# - Using option {converters}[#class-CSV-label-Option+converters] with a new \CSV instance: +# csv = CSV.new(string, converters: :integer) +# # Field converters in effect: +# csv.converters # => [:integer] +# csv.read # => [["foo", 0], ["bar", 1], ["baz", 2]] +# - Using method #convert to add a field converter to a \CSV instance: +# csv = CSV.new(string) +# # Add a converter. +# csv.convert(:integer) +# csv.converters # => [:integer] +# csv.read # => [["foo", 0], ["bar", 1], ["baz", 2]] +# +# Installing a field converter does not affect already-read rows: +# csv = CSV.new(string) +# csv.shift # => ["foo", "0"] +# # Add a converter. +# csv.convert(:integer) +# csv.converters # => [:integer] +# csv.read # => [["bar", 1], ["baz", 2]] +# +# There are additional built-in \converters, and custom \converters are also supported. +# +# ===== Built-In Field \Converters +# +# The built-in field converters are in \Hash CSV::Converters: +# - Each key is a field converter name. +# - Each value is one of: +# - A \Proc field converter. +# - An \Array of field converter names. +# +# Display: +# CSV::Converters.each_pair do |name, value| +# if value.kind_of?(Proc) +# p [name, value.class] +# else +# p [name, value] +# end +# end +# Output: +# [:integer, Proc] +# [:float, Proc] +# [:numeric, [:integer, :float]] +# [:date, Proc] +# [:date_time, Proc] +# [:time, Proc] +# [:all, [:date_time, :numeric]] +# +# Each of these converters transcodes values to UTF-8 before attempting conversion. +# If a value cannot be transcoded to UTF-8 the conversion will +# fail and the value will remain unconverted. +# +# Converter +:integer+ converts each field that Integer() accepts: +# data = '0,1,2,x' +# # Without the converter +# csv = CSV.parse_line(data) +# csv # => ["0", "1", "2", "x"] +# # With the converter +# csv = CSV.parse_line(data, converters: :integer) +# csv # => [0, 1, 2, "x"] +# +# Converter +:float+ converts each field that Float() accepts: +# data = '1.0,3.14159,x' +# # Without the converter +# csv = CSV.parse_line(data) +# csv # => ["1.0", "3.14159", "x"] +# # With the converter +# csv = CSV.parse_line(data, converters: :float) +# csv # => [1.0, 3.14159, "x"] +# +# Converter +:numeric+ converts with both +:integer+ and +:float+.. +# +# Converter +:date+ converts each field that Date::parse accepts: +# data = '2001-02-03,x' +# # Without the converter +# csv = CSV.parse_line(data) +# csv # => ["2001-02-03", "x"] +# # With the converter +# csv = CSV.parse_line(data, converters: :date) +# csv # => [#, "x"] +# +# Converter +:date_time+ converts each field that DateTime::parse accepts: +# data = '2020-05-07T14:59:00-05:00,x' +# # Without the converter +# csv = CSV.parse_line(data) +# csv # => ["2020-05-07T14:59:00-05:00", "x"] +# # With the converter +# csv = CSV.parse_line(data, converters: :date_time) +# csv # => [#, "x"] +# +# Converter +time+ converts each field that Time::parse accepts: +# data = '2020-05-07T14:59:00-05:00,x' +# # Without the converter +# csv = CSV.parse_line(data) +# csv # => ["2020-05-07T14:59:00-05:00", "x"] +# # With the converter +# csv = CSV.parse_line(data, converters: :time) +# csv # => [2020-05-07 14:59:00 -0500, "x"] +# +# Converter +:numeric+ converts with both +:date_time+ and +:numeric+.. +# +# As seen above, method #convert adds \converters to a \CSV instance, +# and method #converters returns an \Array of the \converters in effect: +# csv = CSV.new('0,1,2') +# csv.converters # => [] +# csv.convert(:integer) +# csv.converters # => [:integer] +# csv.convert(:date) +# csv.converters # => [:integer, :date] +# +# ===== Custom Field \Converters +# +# You can define a custom field converter: +# strip_converter = proc {|field| field.strip } +# string = " foo , 0 \n bar , 1 \n baz , 2 \n" +# array = CSV.parse(string, converters: strip_converter) +# array # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] +# You can register the converter in \Converters \Hash, +# which allows you to refer to it by name: +# CSV::Converters[:strip] = strip_converter +# string = " foo , 0 \n bar , 1 \n baz , 2 \n" +# array = CSV.parse(string, converters: :strip) +# array # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] +# +# ==== Header \Converters +# +# Header converters operate only on headers (and not on other rows). +# +# There are three ways to use header \converters; +# these examples use built-in header converter +:downcase+, +# which downcases each parsed header. +# +# - Option +header_converters+ with a singleton parsing method: +# string = "Name,Count\nFoo,0\n,Bar,1\nBaz,2" +# tbl = CSV.parse(string, headers: true, header_converters: :downcase) +# tbl.class # => CSV::Table +# tbl.headers # => ["name", "count"] +# +# - Option +header_converters+ with a new \CSV instance: +# csv = CSV.new(string, header_converters: :downcase) +# # Header converters in effect: +# csv.header_converters # => [:downcase] +# tbl = CSV.parse(string, headers: true) +# tbl.headers # => ["Name", "Count"] +# +# - Method #header_convert adds a header converter to a \CSV instance: +# csv = CSV.new(string) +# # Add a header converter. +# csv.header_convert(:downcase) +# csv.header_converters # => [:downcase] +# tbl = CSV.parse(string, headers: true) +# tbl.headers # => ["Name", "Count"] +# +# ===== Built-In Header \Converters +# +# The built-in header \converters are in \Hash CSV::HeaderConverters. +# The keys there are the names of the \converters: +# CSV::HeaderConverters.keys # => [:downcase, :symbol] +# +# Converter +:downcase+ converts each header by downcasing it: +# string = "Name,Count\nFoo,0\n,Bar,1\nBaz,2" +# tbl = CSV.parse(string, headers: true, header_converters: :downcase) +# tbl.class # => CSV::Table +# tbl.headers # => ["name", "count"] +# +# Converter +:symbol+ converts each header by making it into a \Symbol: +# string = "Name,Count\nFoo,0\n,Bar,1\nBaz,2" +# tbl = CSV.parse(string, headers: true, header_converters: :symbol) +# tbl.headers # => [:name, :count] +# Details: +# - Strips leading and trailing whitespace. +# - Downcases the header. +# - Replaces embedded spaces with underscores. +# - Removes non-word characters. +# - Makes the string into a \Symbol. +# +# ===== Custom Header \Converters +# +# You can define a custom header converter: +# upcase_converter = proc {|header| header.upcase } +# string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" +# table = CSV.parse(string, headers: true, header_converters: upcase_converter) +# table # => # +# table.headers # => ["NAME", "VALUE"] +# You can register the converter in \HeaderConverters \Hash, +# which allows you to refer to it by name: +# CSV::HeaderConverters[:upcase] = upcase_converter +# table = CSV.parse(string, headers: true, header_converters: :upcase) +# table # => # +# table.headers # => ["NAME", "VALUE"] +# +# ===== Write \Converters +# +# When you specify a write converter for generating \CSV, +# each field to be written is passed to the converter; +# its return value becomes the new value for the field. +# A converter might, for example, strip whitespace from a field. +# +# Using no write converter (all fields unmodified): +# output_string = CSV.generate do |csv| +# csv << [' foo ', 0] +# csv << [' bar ', 1] +# csv << [' baz ', 2] +# end +# output_string # => " foo ,0\n bar ,1\n baz ,2\n" +# Using option +write_converters+ with two custom write converters: +# strip_converter = proc {|field| field.respond_to?(:strip) ? field.strip : field } +# upcase_converter = proc {|field| field.respond_to?(:upcase) ? field.upcase : field } +# write_converters = [strip_converter, upcase_converter] +# output_string = CSV.generate(write_converters: write_converters) do |csv| +# csv << [' foo ', 0] +# csv << [' bar ', 1] +# csv << [' baz ', 2] +# end +# output_string # => "FOO,0\nBAR,1\nBAZ,2\n" +# +# === Character Encodings (M17n or Multilingualization) +# +# This new CSV parser is m17n savvy. The parser works in the Encoding of the IO +# or String object being read from or written to. Your data is never transcoded +# (unless you ask Ruby to transcode it for you) and will literally be parsed in +# the Encoding it is in. Thus CSV will return Arrays or Rows of Strings in the +# Encoding of your data. This is accomplished by transcoding the parser itself +# into your Encoding. +# +# Some transcoding must take place, of course, to accomplish this multiencoding +# support. For example, :col_sep, :row_sep, and +# :quote_char must be transcoded to match your data. Hopefully this +# makes the entire process feel transparent, since CSV's defaults should just +# magically work for your data. However, you can set these values manually in +# the target Encoding to avoid the translation. +# +# It's also important to note that while all of CSV's core parser is now +# Encoding agnostic, some features are not. For example, the built-in +# converters will try to transcode data to UTF-8 before making conversions. +# Again, you can provide custom converters that are aware of your Encodings to +# avoid this translation. It's just too hard for me to support native +# conversions in all of Ruby's Encodings. +# +# Anyway, the practical side of this is simple: make sure IO and String objects +# passed into CSV have the proper Encoding set and everything should just work. +# CSV methods that allow you to open IO objects (CSV::foreach(), CSV::open(), +# CSV::read(), and CSV::readlines()) do allow you to specify the Encoding. +# +# One minor exception comes when generating CSV into a String with an Encoding +# that is not ASCII compatible. There's no existing data for CSV to use to +# prepare itself and thus you will probably need to manually specify the desired +# Encoding for most of those cases. It will try to guess using the fields in a +# row of output though, when using CSV::generate_line() or Array#to_csv(). +# +# I try to point out any other Encoding issues in the documentation of methods +# as they come up. +# +# This has been tested to the best of my ability with all non-"dummy" Encodings +# Ruby ships with. However, it is brave new code and may have some bugs. +# Please feel free to {report}[mailto:james@grayproductions.net] any issues you +# find with it. +# +class CSV + + # The error thrown when the parser encounters illegal CSV formatting. + class MalformedCSVError < RuntimeError + attr_reader :line_number + alias_method :lineno, :line_number + def initialize(message, line_number) + @line_number = line_number + super("#{message} in line #{line_number}.") + end + end + + # The error thrown when the parser encounters invalid encoding in CSV. + class InvalidEncodingError < MalformedCSVError + attr_reader :encoding + def initialize(encoding, line_number) + @encoding = encoding + super("Invalid byte sequence in #{encoding}", line_number) + end + end + + # + # A FieldInfo Struct contains details about a field's position in the data + # source it was read from. CSV will pass this Struct to some blocks that make + # decisions based on field structure. See CSV.convert_fields() for an + # example. + # + # index:: The zero-based index of the field in its row. + # line:: The line of the data source this row is from. + # header:: The header for the column, when available. + # quoted?:: True or false, whether the original value is quoted or not. + # + FieldInfo = Struct.new(:index, :line, :header, :quoted?) + + # A Regexp used to find and convert some common Date formats. + DateMatcher = / \A(?: (\w+,?\s+)?\w+\s+\d{1,2},?\s+\d{2,4} | + \d{4}-\d{2}-\d{2} )\z /x + # A Regexp used to find and convert some common (Date)Time formats. + DateTimeMatcher = + / \A(?: (\w+,?\s+)?\w+\s+\d{1,2}\s+\d{1,2}:\d{1,2}:\d{1,2},?\s+\d{2,4} | + # ISO-8601 and RFC-3339 (space instead of T) recognized by (Date)Time.parse + \d{4}-\d{2}-\d{2} + (?:[T\s]\d{2}:\d{2}(?::\d{2}(?:\.\d+)?(?:[+-]\d{2}(?::\d{2})|Z)?)?)? + )\z /x + + # The encoding used by all converters. + ConverterEncoding = Encoding.find("UTF-8") + + # A \Hash containing the names and \Procs for the built-in field converters. + # See {Built-In Field Converters}[#class-CSV-label-Built-In+Field+Converters]. + # + # This \Hash is intentionally left unfrozen, and may be extended with + # custom field converters. + # See {Custom Field Converters}[#class-CSV-label-Custom+Field+Converters]. + Converters = { + integer: lambda { |f| + Integer(f.encode(ConverterEncoding)) rescue f + }, + float: lambda { |f| + Float(f.encode(ConverterEncoding)) rescue f + }, + numeric: [:integer, :float], + date: lambda { |f| + begin + e = f.encode(ConverterEncoding) + e.match?(DateMatcher) ? Date.parse(e) : f + rescue # encoding conversion or date parse errors + f + end + }, + date_time: lambda { |f| + begin + e = f.encode(ConverterEncoding) + e.match?(DateTimeMatcher) ? DateTime.parse(e) : f + rescue # encoding conversion or date parse errors + f + end + }, + time: lambda { |f| + begin + e = f.encode(ConverterEncoding) + e.match?(DateTimeMatcher) ? Time.parse(e) : f + rescue # encoding conversion or parse errors + f + end + }, + all: [:date_time, :numeric], + } + + # A \Hash containing the names and \Procs for the built-in header converters. + # See {Built-In Header Converters}[#class-CSV-label-Built-In+Header+Converters]. + # + # This \Hash is intentionally left unfrozen, and may be extended with + # custom field converters. + # See {Custom Header Converters}[#class-CSV-label-Custom+Header+Converters]. + HeaderConverters = { + downcase: lambda { |h| h.encode(ConverterEncoding).downcase }, + symbol: lambda { |h| + h.encode(ConverterEncoding).downcase.gsub(/[^\s\w]+/, "").strip. + gsub(/\s+/, "_").to_sym + }, + symbol_raw: lambda { |h| h.encode(ConverterEncoding).to_sym } + } + + # Default values for method options. + DEFAULT_OPTIONS = { + # For both parsing and generating. + col_sep: ",", + row_sep: :auto, + quote_char: '"', + # For parsing. + field_size_limit: nil, + max_field_size: nil, + converters: nil, + unconverted_fields: nil, + headers: false, + return_headers: false, + header_converters: nil, + skip_blanks: false, + skip_lines: nil, + liberal_parsing: false, + nil_value: nil, + empty_value: "", + strip: false, + # For generating. + write_headers: nil, + quote_empty: true, + force_quotes: false, + write_converters: nil, + write_nil_value: nil, + write_empty_value: "", + }.freeze + + class << self + # :call-seq: + # instance(string, **options) + # instance(io = $stdout, **options) + # instance(string, **options) {|csv| ... } + # instance(io = $stdout, **options) {|csv| ... } + # + # Creates or retrieves cached \CSV objects. + # For arguments and options, see CSV.new. + # + # This API is not Ractor-safe. + # + # --- + # + # With no block given, returns a \CSV object. + # + # The first call to +instance+ creates and caches a \CSV object: + # s0 = 's0' + # csv0 = CSV.instance(s0) + # csv0.class # => CSV + # + # Subsequent calls to +instance+ with that _same_ +string+ or +io+ + # retrieve that same cached object: + # csv1 = CSV.instance(s0) + # csv1.class # => CSV + # csv1.equal?(csv0) # => true # Same CSV object + # + # A subsequent call to +instance+ with a _different_ +string+ or +io+ + # creates and caches a _different_ \CSV object. + # s1 = 's1' + # csv2 = CSV.instance(s1) + # csv2.equal?(csv0) # => false # Different CSV object + # + # All the cached objects remains available: + # csv3 = CSV.instance(s0) + # csv3.equal?(csv0) # true # Same CSV object + # csv4 = CSV.instance(s1) + # csv4.equal?(csv2) # true # Same CSV object + # + # --- + # + # When a block is given, calls the block with the created or retrieved + # \CSV object; returns the block's return value: + # CSV.instance(s0) {|csv| :foo } # => :foo + def instance(data = $stdout, **options) + # create a _signature_ for this method call, data object and options + sig = [data.object_id] + + options.values_at(*DEFAULT_OPTIONS.keys) + + # fetch or create the instance for this signature + @@instances ||= Hash.new + instance = (@@instances[sig] ||= new(data, **options)) + + if block_given? + yield instance # run block, if given, returning result + else + instance # or return the instance + end + end + + # :call-seq: + # filter(in_string_or_io, **options) {|row| ... } -> array_of_arrays or csv_table + # filter(in_string_or_io, out_string_or_io, **options) {|row| ... } -> array_of_arrays or csv_table + # filter(**options) {|row| ... } -> array_of_arrays or csv_table + # + # - Parses \CSV from a source (\String, \IO stream, or ARGF). + # - Calls the given block with each parsed row: + # - Without headers, each row is an \Array. + # - With headers, each row is a CSV::Row. + # - Generates \CSV to an output (\String, \IO stream, or STDOUT). + # - Returns the parsed source: + # - Without headers, an \Array of \Arrays. + # - With headers, a CSV::Table. + # + # When +in_string_or_io+ is given, but not +out_string_or_io+, + # parses from the given +in_string_or_io+ + # and generates to STDOUT. + # + # \String input without headers: + # + # in_string = "foo,0\nbar,1\nbaz,2" + # CSV.filter(in_string) do |row| + # row[0].upcase! + # row[1] = - row[1].to_i + # end # => [["FOO", 0], ["BAR", -1], ["BAZ", -2]] + # + # Output (to STDOUT): + # + # FOO,0 + # BAR,-1 + # BAZ,-2 + # + # \String input with headers: + # + # in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2" + # CSV.filter(in_string, headers: true) do |row| + # row[0].upcase! + # row[1] = - row[1].to_i + # end # => # + # + # Output (to STDOUT): + # + # Name,Value + # FOO,0 + # BAR,-1 + # BAZ,-2 + # + # \IO stream input without headers: + # + # File.write('t.csv', "foo,0\nbar,1\nbaz,2") + # File.open('t.csv') do |in_io| + # CSV.filter(in_io) do |row| + # row[0].upcase! + # row[1] = - row[1].to_i + # end + # end # => [["FOO", 0], ["BAR", -1], ["BAZ", -2]] + # + # Output (to STDOUT): + # + # FOO,0 + # BAR,-1 + # BAZ,-2 + # + # \IO stream input with headers: + # + # File.write('t.csv', "Name,Value\nfoo,0\nbar,1\nbaz,2") + # File.open('t.csv') do |in_io| + # CSV.filter(in_io, headers: true) do |row| + # row[0].upcase! + # row[1] = - row[1].to_i + # end + # end # => # + # + # Output (to STDOUT): + # + # Name,Value + # FOO,0 + # BAR,-1 + # BAZ,-2 + # + # When both +in_string_or_io+ and +out_string_or_io+ are given, + # parses from +in_string_or_io+ and generates to +out_string_or_io+. + # + # \String output without headers: + # + # in_string = "foo,0\nbar,1\nbaz,2" + # out_string = '' + # CSV.filter(in_string, out_string) do |row| + # row[0].upcase! + # row[1] = - row[1].to_i + # end # => [["FOO", 0], ["BAR", -1], ["BAZ", -2]] + # out_string # => "FOO,0\nBAR,-1\nBAZ,-2\n" + # + # \String output with headers: + # + # in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2" + # out_string = '' + # CSV.filter(in_string, out_string, headers: true) do |row| + # row[0].upcase! + # row[1] = - row[1].to_i + # end # => # + # out_string # => "Name,Value\nFOO,0\nBAR,-1\nBAZ,-2\n" + # + # \IO stream output without headers: + # + # in_string = "foo,0\nbar,1\nbaz,2" + # File.open('t.csv', 'w') do |out_io| + # CSV.filter(in_string, out_io) do |row| + # row[0].upcase! + # row[1] = - row[1].to_i + # end + # end # => [["FOO", 0], ["BAR", -1], ["BAZ", -2]] + # File.read('t.csv') # => "FOO,0\nBAR,-1\nBAZ,-2\n" + # + # \IO stream output with headers: + # + # in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2" + # File.open('t.csv', 'w') do |out_io| + # CSV.filter(in_string, out_io, headers: true) do |row| + # row[0].upcase! + # row[1] = - row[1].to_i + # end + # end # => # + # File.read('t.csv') # => "Name,Value\nFOO,0\nBAR,-1\nBAZ,-2\n" + # + # When neither +in_string_or_io+ nor +out_string_or_io+ given, + # parses from {ARGF}[rdoc-ref:ARGF] + # and generates to STDOUT. + # + # Without headers: + # + # # Put Ruby code into a file. + # ruby = <<-EOT + # require 'csv' + # CSV.filter do |row| + # row[0].upcase! + # row[1] = - row[1].to_i + # end + # EOT + # File.write('t.rb', ruby) + # # Put some CSV into a file. + # File.write('t.csv', "foo,0\nbar,1\nbaz,2") + # # Run the Ruby code with CSV filename as argument. + # system(Gem.ruby, "t.rb", "t.csv") + # + # Output (to STDOUT): + # + # FOO,0 + # BAR,-1 + # BAZ,-2 + # + # With headers: + # + # # Put Ruby code into a file. + # ruby = <<-EOT + # require 'csv' + # CSV.filter(headers: true) do |row| + # row[0].upcase! + # row[1] = - row[1].to_i + # end + # EOT + # File.write('t.rb', ruby) + # # Put some CSV into a file. + # File.write('t.csv', "Name,Value\nfoo,0\nbar,1\nbaz,2") + # # Run the Ruby code with CSV filename as argument. + # system(Gem.ruby, "t.rb", "t.csv") + # + # Output (to STDOUT): + # + # Name,Value + # FOO,0 + # BAR,-1 + # BAZ,-2 + # + # Arguments: + # + # * Argument +in_string_or_io+ must be a \String or an \IO stream. + # * Argument +out_string_or_io+ must be a \String or an \IO stream. + # * Arguments **options must be keyword options. + # + # - Each option defined as an {option for parsing}[#class-CSV-label-Options+for+Parsing] + # is used for parsing the filter input. + # - Each option defined as an {option for generating}[#class-CSV-label-Options+for+Generating] + # is used for generator the filter input. + # + # However, there are three options that may be used for both parsing and generating: + # +col_sep+, +quote_char+, and +row_sep+. + # + # Therefore for method +filter+ (and method +filter+ only), + # there are special options that allow these parsing and generating options + # to be specified separately: + # + # - Options +input_col_sep+ and +output_col_sep+ + # (and their aliases +in_col_sep+ and +out_col_sep+) + # specify the column separators for parsing and generating. + # - Options +input_quote_char+ and +output_quote_char+ + # (and their aliases +in_quote_char+ and +out_quote_char+) + # specify the quote characters for parsing and generting. + # - Options +input_row_sep+ and +output_row_sep+ + # (and their aliases +in_row_sep+ and +out_row_sep+) + # specify the row separators for parsing and generating. + # + # Example options (for column separators): + # + # CSV.filter # Default for both parsing and generating. + # CSV.filter(in_col_sep: ';') # ';' for parsing, default for generating. + # CSV.filter(out_col_sep: '|') # Default for parsing, '|' for generating. + # CSV.filter(in_col_sep: ';', out_col_sep: '|') # ';' for parsing, '|' for generating. + # + # Note that for a special option (e.g., +input_col_sep+) + # and its corresponding "regular" option (e.g., +col_sep+), + # the two are mutually overriding. + # + # Another example (possibly surprising): + # + # CSV.filter(in_col_sep: ';', col_sep: '|') # '|' for both parsing(!) and generating. + # + def filter(input=nil, output=nil, **options) + # parse options for input, output, or both + in_options, out_options = Hash.new, {row_sep: InputRecordSeparator.value} + options.each do |key, value| + case key + when /\Ain(?:put)?_(.+)\Z/ + in_options[$1.to_sym] = value + when /\Aout(?:put)?_(.+)\Z/ + out_options[$1.to_sym] = value + else + in_options[key] = value + out_options[key] = value + end + end + + # build input and output wrappers + input = new(input || ARGF, **in_options) + output = new(output || $stdout, **out_options) + + # process headers + need_manual_header_output = + (in_options[:headers] and + out_options[:headers] == true and + out_options[:write_headers]) + if need_manual_header_output + first_row = input.shift + if first_row + if first_row.is_a?(Row) + headers = first_row.headers + yield headers + output << headers + end + yield first_row + output << first_row + end + end + + # read, yield, write + input.each do |row| + yield row + output << row + end + end + + # + # :call-seq: + # foreach(path_or_io, mode='r', **options) {|row| ... ) + # foreach(path_or_io, mode='r', **options) -> new_enumerator + # + # Calls the block with each row read from source +path_or_io+. + # + # \Path input without headers: + # + # string = "foo,0\nbar,1\nbaz,2\n" + # in_path = 't.csv' + # File.write(in_path, string) + # CSV.foreach(in_path) {|row| p row } + # + # Output: + # + # ["foo", "0"] + # ["bar", "1"] + # ["baz", "2"] + # + # \Path input with headers: + # + # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # in_path = 't.csv' + # File.write(in_path, string) + # CSV.foreach(in_path, headers: true) {|row| p row } + # + # Output: + # + # + # + # + # + # \IO stream input without headers: + # + # string = "foo,0\nbar,1\nbaz,2\n" + # path = 't.csv' + # File.write(path, string) + # File.open('t.csv') do |in_io| + # CSV.foreach(in_io) {|row| p row } + # end + # + # Output: + # + # ["foo", "0"] + # ["bar", "1"] + # ["baz", "2"] + # + # \IO stream input with headers: + # + # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # path = 't.csv' + # File.write(path, string) + # File.open('t.csv') do |in_io| + # CSV.foreach(in_io, headers: true) {|row| p row } + # end + # + # Output: + # + # + # + # + # + # With no block given, returns an \Enumerator: + # + # string = "foo,0\nbar,1\nbaz,2\n" + # path = 't.csv' + # File.write(path, string) + # CSV.foreach(path) # => # + # + # Arguments: + # * Argument +path_or_io+ must be a file path or an \IO stream. + # * Argument +mode+, if given, must be a \File mode. + # See {Access Modes}[https://docs.ruby-lang.org/en/master/File.html#class-File-label-Access+Modes]. + # * Arguments **options must be keyword options. + # See {Options for Parsing}[#class-CSV-label-Options+for+Parsing]. + # * This method optionally accepts an additional :encoding option + # that you can use to specify the Encoding of the data read from +path+ or +io+. + # You must provide this unless your data is in the encoding + # given by Encoding::default_external. + # Parsing will use this to determine how to parse the data. + # You may provide a second Encoding to + # have the data transcoded as it is read. For example, + # encoding: 'UTF-32BE:UTF-8' + # would read +UTF-32BE+ data from the file + # but transcode it to +UTF-8+ before parsing. + def foreach(path, mode="r", **options, &block) + return to_enum(__method__, path, mode, **options) unless block_given? + open(path, mode, **options) do |csv| + csv.each(&block) + end + end + + # + # :call-seq: + # generate(csv_string, **options) {|csv| ... } + # generate(**options) {|csv| ... } + # + # * Argument +csv_string+, if given, must be a \String object; + # defaults to a new empty \String. + # * Arguments +options+, if given, should be generating options. + # See {Options for Generating}[#class-CSV-label-Options+for+Generating]. + # + # --- + # + # Creates a new \CSV object via CSV.new(csv_string, **options); + # calls the block with the \CSV object, which the block may modify; + # returns the \String generated from the \CSV object. + # + # Note that a passed \String *is* modified by this method. + # Pass csv_string.dup if the \String must be preserved. + # + # This method has one additional option: :encoding, + # which sets the base Encoding for the output if no no +str+ is specified. + # CSV needs this hint if you plan to output non-ASCII compatible data. + # + # --- + # + # Add lines: + # input_string = "foo,0\nbar,1\nbaz,2\n" + # output_string = CSV.generate(input_string) do |csv| + # csv << ['bat', 3] + # csv << ['bam', 4] + # end + # output_string # => "foo,0\nbar,1\nbaz,2\nbat,3\nbam,4\n" + # input_string # => "foo,0\nbar,1\nbaz,2\nbat,3\nbam,4\n" + # output_string.equal?(input_string) # => true # Same string, modified + # + # Add lines into new string, preserving old string: + # input_string = "foo,0\nbar,1\nbaz,2\n" + # output_string = CSV.generate(input_string.dup) do |csv| + # csv << ['bat', 3] + # csv << ['bam', 4] + # end + # output_string # => "foo,0\nbar,1\nbaz,2\nbat,3\nbam,4\n" + # input_string # => "foo,0\nbar,1\nbaz,2\n" + # output_string.equal?(input_string) # => false # Different strings + # + # Create lines from nothing: + # output_string = CSV.generate do |csv| + # csv << ['foo', 0] + # csv << ['bar', 1] + # csv << ['baz', 2] + # end + # output_string # => "foo,0\nbar,1\nbaz,2\n" + # + # --- + # + # Raises an exception if +csv_string+ is not a \String object: + # # Raises TypeError (no implicit conversion of Integer into String) + # CSV.generate(0) + # + def generate(str=nil, **options) + encoding = options[:encoding] + # add a default empty String, if none was given + if str + str = StringIO.new(str) + str.seek(0, IO::SEEK_END) + str.set_encoding(encoding) if encoding + else + str = +"" + str.force_encoding(encoding) if encoding + end + csv = new(str, **options) # wrap + yield csv # yield for appending + csv.string # return final String + end + + # :call-seq: + # CSV.generate_line(ary) + # CSV.generate_line(ary, **options) + # + # Returns the \String created by generating \CSV from +ary+ + # using the specified +options+. + # + # Argument +ary+ must be an \Array. + # + # Special options: + # * Option :row_sep defaults to "\n"> on Ruby 3.0 or later + # and $INPUT_RECORD_SEPARATOR ($/) otherwise.: + # $INPUT_RECORD_SEPARATOR # => "\n" + # * This method accepts an additional option, :encoding, which sets the base + # Encoding for the output. This method will try to guess your Encoding from + # the first non-+nil+ field in +row+, if possible, but you may need to use + # this parameter as a backup plan. + # + # For other +options+, + # see {Options for Generating}[#class-CSV-label-Options+for+Generating]. + # + # --- + # + # Returns the \String generated from an \Array: + # CSV.generate_line(['foo', '0']) # => "foo,0\n" + # + # --- + # + # Raises an exception if +ary+ is not an \Array: + # # Raises NoMethodError (undefined method `find' for :foo:Symbol) + # CSV.generate_line(:foo) + # + def generate_line(row, **options) + options = {row_sep: InputRecordSeparator.value}.merge(options) + str = +"" + if options[:encoding] + str.force_encoding(options[:encoding]) + else + fallback_encoding = nil + output_encoding = nil + row.each do |field| + next unless field.is_a?(String) + fallback_encoding ||= field.encoding + next if field.ascii_only? + output_encoding = field.encoding + break + end + output_encoding ||= fallback_encoding + if output_encoding + str.force_encoding(output_encoding) + end + end + (new(str, **options) << row).string + end + + # :call-seq: + # CSV.generate_lines(rows) + # CSV.generate_lines(rows, **options) + # + # Returns the \String created by generating \CSV from + # using the specified +options+. + # + # Argument +rows+ must be an \Array of row. Row is \Array of \String or \CSV::Row. + # + # Special options: + # * Option :row_sep defaults to "\n" on Ruby 3.0 or later + # and $INPUT_RECORD_SEPARATOR ($/) otherwise.: + # $INPUT_RECORD_SEPARATOR # => "\n" + # * This method accepts an additional option, :encoding, which sets the base + # Encoding for the output. This method will try to guess your Encoding from + # the first non-+nil+ field in +row+, if possible, but you may need to use + # this parameter as a backup plan. + # + # For other +options+, + # see {Options for Generating}[#class-CSV-label-Options+for+Generating]. + # + # --- + # + # Returns the \String generated from an + # CSV.generate_lines([['foo', '0'], ['bar', '1'], ['baz', '2']]) # => "foo,0\nbar,1\nbaz,2\n" + # + # --- + # + # Raises an exception + # # Raises NoMethodError (undefined method `each' for :foo:Symbol) + # CSV.generate_lines(:foo) + # + def generate_lines(rows, **options) + self.generate(**options) do |csv| + rows.each do |row| + csv << row + end + end + end + + # + # :call-seq: + # open(path_or_io, mode = "rb", **options ) -> new_csv + # open(path_or_io, mode = "rb", **options ) { |csv| ... } -> object + # + # possible options elements: + # keyword form: + # :invalid => nil # raise error on invalid byte sequence (default) + # :invalid => :replace # replace invalid byte sequence + # :undef => :replace # replace undefined conversion + # :replace => string # replacement string ("?" or "\uFFFD" if not specified) + # + # * Argument +path_or_io+, must be a file path or an \IO stream. + # :include: ../doc/csv/arguments/io.rdoc + # * Argument +mode+, if given, must be a \File mode. + # See {Access Modes}[https://docs.ruby-lang.org/en/master/File.html#class-File-label-Access+Modes]. + # * Arguments **options must be keyword options. + # See {Options for Generating}[#class-CSV-label-Options+for+Generating]. + # * This method optionally accepts an additional :encoding option + # that you can use to specify the Encoding of the data read from +path+ or +io+. + # You must provide this unless your data is in the encoding + # given by Encoding::default_external. + # Parsing will use this to determine how to parse the data. + # You may provide a second Encoding to + # have the data transcoded as it is read. For example, + # encoding: 'UTF-32BE:UTF-8' + # would read +UTF-32BE+ data from the file + # but transcode it to +UTF-8+ before parsing. + # + # --- + # + # These examples assume prior execution of: + # string = "foo,0\nbar,1\nbaz,2\n" + # path = 't.csv' + # File.write(path, string) + # + # string_io = StringIO.new + # string_io << "foo,0\nbar,1\nbaz,2\n" + # + # --- + # + # With no block given, returns a new \CSV object. + # + # Create a \CSV object using a file path: + # csv = CSV.open(path) + # csv # => # + # + # Create a \CSV object using an open \File: + # csv = CSV.open(File.open(path)) + # csv # => # + # + # Create a \CSV object using a \StringIO: + # csv = CSV.open(string_io) + # csv # => # + # --- + # + # With a block given, calls the block with the created \CSV object; + # returns the block's return value: + # + # Using a file path: + # csv = CSV.open(path) {|csv| p csv} + # csv # => # + # Output: + # # + # + # Using an open \File: + # csv = CSV.open(File.open(path)) {|csv| p csv} + # csv # => # + # Output: + # # + # + # Using a \StringIO: + # csv = CSV.open(string_io) {|csv| p csv} + # csv # => # + # Output: + # # + # --- + # + # Raises an exception if the argument is not a \String object or \IO object: + # # Raises TypeError (no implicit conversion of Symbol into String) + # CSV.open(:foo) + def open(filename_or_io, mode="r", **options) + # wrap a File opened with the remaining +args+ with no newline + # decorator + file_opts = {} + may_enable_bom_detection_automatically(filename_or_io, + mode, + options, + file_opts) + file_opts.merge!(options) + unless file_opts.key?(:newline) + file_opts[:universal_newline] ||= false + end + options.delete(:invalid) + options.delete(:undef) + options.delete(:replace) + options.delete_if {|k, _| /newline\z/.match?(k)} + + if filename_or_io.is_a?(StringIO) + f = create_stringio(filename_or_io.string, mode, **file_opts) + else + begin + f = File.open(filename_or_io, mode, **file_opts) + rescue ArgumentError => e + raise unless /needs binmode/.match?(e.message) and mode == "r" + mode = "rb" + file_opts = {encoding: Encoding.default_external}.merge(file_opts) + retry + end + end + + begin + csv = new(f, **options) + rescue Exception + f.close + raise + end + + # handle blocks like Ruby's open(), not like the CSV library + if block_given? + begin + yield csv + ensure + csv.close + end + else + csv + end + end + + # + # :call-seq: + # parse(string) -> array_of_arrays + # parse(io) -> array_of_arrays + # parse(string, headers: ..., **options) -> csv_table + # parse(io, headers: ..., **options) -> csv_table + # parse(string, **options) {|row| ... } + # parse(io, **options) {|row| ... } + # + # Parses +string+ or +io+ using the specified +options+. + # + # - Argument +string+ should be a \String object; + # it will be put into a new StringIO object positioned at the beginning. + # :include: ../doc/csv/arguments/io.rdoc + # - Argument +options+: see {Options for Parsing}[#class-CSV-label-Options+for+Parsing] + # + # ====== Without Option +headers+ + # + # Without {option +headers+}[#class-CSV-label-Option+headers] case. + # + # These examples assume prior execution of: + # string = "foo,0\nbar,1\nbaz,2\n" + # path = 't.csv' + # File.write(path, string) + # + # --- + # + # With no block given, returns an \Array of Arrays formed from the source. + # + # Parse a \String: + # a_of_a = CSV.parse(string) + # a_of_a # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] + # + # Parse an open \File: + # a_of_a = File.open(path) do |file| + # CSV.parse(file) + # end + # a_of_a # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] + # + # --- + # + # With a block given, calls the block with each parsed row: + # + # Parse a \String: + # CSV.parse(string) {|row| p row } + # + # Output: + # ["foo", "0"] + # ["bar", "1"] + # ["baz", "2"] + # + # Parse an open \File: + # File.open(path) do |file| + # CSV.parse(file) {|row| p row } + # end + # + # Output: + # ["foo", "0"] + # ["bar", "1"] + # ["baz", "2"] + # + # ====== With Option +headers+ + # + # With {option +headers+}[#class-CSV-label-Option+headers] case. + # + # These examples assume prior execution of: + # string = "Name,Count\nfoo,0\nbar,1\nbaz,2\n" + # path = 't.csv' + # File.write(path, string) + # + # --- + # + # With no block given, returns a CSV::Table object formed from the source. + # + # Parse a \String: + # csv_table = CSV.parse(string, headers: ['Name', 'Count']) + # csv_table # => # + # + # Parse an open \File: + # csv_table = File.open(path) do |file| + # CSV.parse(file, headers: ['Name', 'Count']) + # end + # csv_table # => # + # + # --- + # + # With a block given, calls the block with each parsed row, + # which has been formed into a CSV::Row object: + # + # Parse a \String: + # CSV.parse(string, headers: ['Name', 'Count']) {|row| p row } + # + # Output: + # # + # # + # # + # + # Parse an open \File: + # File.open(path) do |file| + # CSV.parse(file, headers: ['Name', 'Count']) {|row| p row } + # end + # + # Output: + # # + # # + # # + # + # --- + # + # Raises an exception if the argument is not a \String object or \IO object: + # # Raises NoMethodError (undefined method `close' for :foo:Symbol) + # CSV.parse(:foo) + # + # --- + # + # Please make sure if your text contains \BOM or not. CSV.parse will not remove + # \BOM automatically. You might want to remove \BOM before calling CSV.parse : + # # remove BOM on calling File.open + # File.open(path, encoding: 'bom|utf-8') do |file| + # CSV.parse(file, headers: true) do |row| + # # you can get value by column name because BOM is removed + # p row['Name'] + # end + # end + # + # Output: + # # "foo" + # # "bar" + # # "baz" + def parse(str, **options, &block) + csv = new(str, **options) + + return csv.each(&block) if block_given? + + # slurp contents, if no block is given + begin + csv.read + ensure + csv.close + end + end + + # :call-seq: + # CSV.parse_line(string) -> new_array or nil + # CSV.parse_line(io) -> new_array or nil + # CSV.parse_line(string, **options) -> new_array or nil + # CSV.parse_line(io, **options) -> new_array or nil + # CSV.parse_line(string, headers: true, **options) -> csv_row or nil + # CSV.parse_line(io, headers: true, **options) -> csv_row or nil + # + # Returns the data created by parsing the first line of +string+ or +io+ + # using the specified +options+. + # + # - Argument +string+ should be a \String object; + # it will be put into a new StringIO object positioned at the beginning. + # :include: ../doc/csv/arguments/io.rdoc + # - Argument +options+: see {Options for Parsing}[#class-CSV-label-Options+for+Parsing] + # + # ====== Without Option +headers+ + # + # Without option +headers+, returns the first row as a new \Array. + # + # These examples assume prior execution of: + # string = "foo,0\nbar,1\nbaz,2\n" + # path = 't.csv' + # File.write(path, string) + # + # Parse the first line from a \String object: + # CSV.parse_line(string) # => ["foo", "0"] + # + # Parse the first line from a File object: + # File.open(path) do |file| + # CSV.parse_line(file) # => ["foo", "0"] + # end # => ["foo", "0"] + # + # Returns +nil+ if the argument is an empty \String: + # CSV.parse_line('') # => nil + # + # ====== With Option +headers+ + # + # With {option +headers+}[#class-CSV-label-Option+headers], + # returns the first row as a CSV::Row object. + # + # These examples assume prior execution of: + # string = "Name,Count\nfoo,0\nbar,1\nbaz,2\n" + # path = 't.csv' + # File.write(path, string) + # + # Parse the first line from a \String object: + # CSV.parse_line(string, headers: true) # => # + # + # Parse the first line from a File object: + # File.open(path) do |file| + # CSV.parse_line(file, headers: true) + # end # => # + # + # --- + # + # Raises an exception if the argument is +nil+: + # # Raises ArgumentError (Cannot parse nil as CSV): + # CSV.parse_line(nil) + # + def parse_line(line, **options) + new(line, **options).each.first + end + + # + # :call-seq: + # read(source, **options) -> array_of_arrays + # read(source, headers: true, **options) -> csv_table + # + # Opens the given +source+ with the given +options+ (see CSV.open), + # reads the source (see CSV#read), and returns the result, + # which will be either an \Array of Arrays or a CSV::Table. + # + # Without headers: + # string = "foo,0\nbar,1\nbaz,2\n" + # path = 't.csv' + # File.write(path, string) + # CSV.read(path) # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] + # + # With headers: + # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # path = 't.csv' + # File.write(path, string) + # CSV.read(path, headers: true) # => # + def read(path, **options) + open(path, **options) { |csv| csv.read } + end + + # :call-seq: + # CSV.readlines(source, **options) + # + # Alias for CSV.read. + def readlines(path, **options) + read(path, **options) + end + + # :call-seq: + # CSV.table(source, **options) + # + # Calls CSV.read with +source+, +options+, and certain default options: + # - +headers+: +true+ + # - +converters+: +:numeric+ + # - +header_converters+: +:symbol+ + # + # Returns a CSV::Table object. + # + # Example: + # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # path = 't.csv' + # File.write(path, string) + # CSV.table(path) # => # + def table(path, **options) + default_options = { + headers: true, + converters: :numeric, + header_converters: :symbol, + } + options = default_options.merge(options) + read(path, **options) + end + + ON_WINDOWS = /mingw|mswin/.match?(RUBY_PLATFORM) + private_constant :ON_WINDOWS + + private + def may_enable_bom_detection_automatically(filename_or_io, + mode, + options, + file_opts) + if filename_or_io.is_a?(StringIO) + # Support to StringIO was dropped for Ruby 2.6 and earlier without BOM support: + # https://github.com/ruby/stringio/pull/47 + return if RUBY_VERSION < "2.7" + else + # "bom|utf-8" may be buggy on Windows: + # https://bugs.ruby-lang.org/issues/20526 + return if ON_WINDOWS + end + return unless Encoding.default_external == Encoding::UTF_8 + return if options.key?(:encoding) + return if options.key?(:external_encoding) + return if mode.is_a?(String) and mode.include?(":") + file_opts[:encoding] = "bom|utf-8" + end + + if RUBY_VERSION < "2.7" + def create_stringio(str, mode, opts) + opts.delete_if {|k, _| k == :universal_newline or DEFAULT_OPTIONS.key?(k)} + raise ArgumentError, "Unsupported options parsing StringIO: #{opts.keys}" unless opts.empty? + StringIO.new(str, mode) + end + else + def create_stringio(str, mode, opts) + StringIO.new(str, mode, **opts) + end + end + end + + # :call-seq: + # CSV.new(string) + # CSV.new(io) + # CSV.new(string, **options) + # CSV.new(io, **options) + # + # Returns the new \CSV object created using +string+ or +io+ + # and the specified +options+. + # + # - Argument +string+ should be a \String object; + # it will be put into a new StringIO object positioned at the beginning. + # :include: ../doc/csv/arguments/io.rdoc + # - Argument +options+: See: + # * {Options for Parsing}[#class-CSV-label-Options+for+Parsing] + # * {Options for Generating}[#class-CSV-label-Options+for+Generating] + # For performance reasons, the options cannot be overridden + # in a \CSV object, so those specified here will endure. + # + # In addition to the \CSV instance methods, several \IO methods are delegated. + # See {Delegated Methods}[#class-CSV-label-Delegated+Methods]. + # + # --- + # + # Create a \CSV object from a \String object: + # csv = CSV.new('foo,0') + # csv # => # + # + # Create a \CSV object from a \File object: + # File.write('t.csv', 'foo,0') + # csv = CSV.new(File.open('t.csv')) + # csv # => # + # + # --- + # + # Raises an exception if the argument is +nil+: + # # Raises ArgumentError (Cannot parse nil as CSV): + # CSV.new(nil) + # + def initialize(data, + col_sep: ",", + row_sep: :auto, + quote_char: '"', + field_size_limit: nil, + max_field_size: nil, + converters: nil, + unconverted_fields: nil, + headers: false, + return_headers: false, + write_headers: nil, + header_converters: nil, + skip_blanks: false, + force_quotes: false, + skip_lines: nil, + liberal_parsing: false, + internal_encoding: nil, + external_encoding: nil, + encoding: nil, + nil_value: nil, + empty_value: "", + strip: false, + quote_empty: true, + write_converters: nil, + write_nil_value: nil, + write_empty_value: "") + raise ArgumentError.new("Cannot parse nil as CSV") if data.nil? + + if data.is_a?(String) + if encoding + if encoding.is_a?(String) + data_external_encoding, data_internal_encoding = encoding.split(":", 2) + if data_internal_encoding + data = data.encode(data_internal_encoding, data_external_encoding) + else + data = data.dup.force_encoding(data_external_encoding) + end + else + data = data.dup.force_encoding(encoding) + end + end + @io = StringIO.new(data) + else + @io = data + end + @encoding = determine_encoding(encoding, internal_encoding) + + @base_fields_converter_options = { + nil_value: nil_value, + empty_value: empty_value, + } + @write_fields_converter_options = { + nil_value: write_nil_value, + empty_value: write_empty_value, + } + @initial_converters = converters + @initial_header_converters = header_converters + @initial_write_converters = write_converters + + if max_field_size.nil? and field_size_limit + max_field_size = field_size_limit - 1 + end + @parser_options = { + column_separator: col_sep, + row_separator: row_sep, + quote_character: quote_char, + max_field_size: max_field_size, + unconverted_fields: unconverted_fields, + headers: headers, + return_headers: return_headers, + skip_blanks: skip_blanks, + skip_lines: skip_lines, + liberal_parsing: liberal_parsing, + encoding: @encoding, + nil_value: nil_value, + empty_value: empty_value, + strip: strip, + } + @parser = nil + @parser_enumerator = nil + @eof_error = nil + + @writer_options = { + encoding: @encoding, + force_encoding: (not encoding.nil?), + force_quotes: force_quotes, + headers: headers, + write_headers: write_headers, + column_separator: col_sep, + row_separator: row_sep, + quote_character: quote_char, + quote_empty: quote_empty, + } + + @writer = nil + writer if @writer_options[:write_headers] + end + + class TSV < CSV + def initialize(data, **options) + super(data, **({col_sep: "\t"}.merge(options))) + end + end + + # :call-seq: + # csv.col_sep -> string + # + # Returns the encoded column separator; used for parsing and writing; + # see {Option +col_sep+}[#class-CSV-label-Option+col_sep]: + # CSV.new('').col_sep # => "," + def col_sep + parser.column_separator + end + + # :call-seq: + # csv.row_sep -> string + # + # Returns the encoded row separator; used for parsing and writing; + # see {Option +row_sep+}[#class-CSV-label-Option+row_sep]: + # CSV.new('').row_sep # => "\n" + def row_sep + parser.row_separator + end + + # :call-seq: + # csv.quote_char -> character + # + # Returns the encoded quote character; used for parsing and writing; + # see {Option +quote_char+}[#class-CSV-label-Option+quote_char]: + # CSV.new('').quote_char # => "\"" + def quote_char + parser.quote_character + end + + # :call-seq: + # csv.field_size_limit -> integer or nil + # + # Returns the limit for field size; used for parsing; + # see {Option +field_size_limit+}[#class-CSV-label-Option+field_size_limit]: + # CSV.new('').field_size_limit # => nil + # + # Deprecated since 3.2.3. Use +max_field_size+ instead. + def field_size_limit + parser.field_size_limit + end + + # :call-seq: + # csv.max_field_size -> integer or nil + # + # Returns the limit for field size; used for parsing; + # see {Option +max_field_size+}[#class-CSV-label-Option+max_field_size]: + # CSV.new('').max_field_size # => nil + # + # Since 3.2.3. + def max_field_size + parser.max_field_size + end + + # :call-seq: + # csv.skip_lines -> regexp or nil + # + # Returns the \Regexp used to identify comment lines; used for parsing; + # see {Option +skip_lines+}[#class-CSV-label-Option+skip_lines]: + # CSV.new('').skip_lines # => nil + def skip_lines + parser.skip_lines + end + + # :call-seq: + # csv.converters -> array + # + # Returns an \Array containing field converters; + # see {Field Converters}[#class-CSV-label-Field+Converters]: + # csv = CSV.new('') + # csv.converters # => [] + # csv.convert(:integer) + # csv.converters # => [:integer] + # csv.convert(proc {|x| x.to_s }) + # csv.converters + # + # Notes that you need to call + # +Ractor.make_shareable(CSV::Converters)+ on the main Ractor to use + # this method. + def converters + parser_fields_converter.map do |converter| + name = Converters.rassoc(converter) + name ? name.first : converter + end + end + + # :call-seq: + # csv.unconverted_fields? -> object + # + # Returns the value that determines whether unconverted fields are to be + # available; used for parsing; + # see {Option +unconverted_fields+}[#class-CSV-label-Option+unconverted_fields]: + # CSV.new('').unconverted_fields? # => nil + def unconverted_fields? + parser.unconverted_fields? + end + + # :call-seq: + # csv.headers -> object + # + # Returns the value that determines whether headers are used; used for parsing; + # see {Option +headers+}[#class-CSV-label-Option+headers]: + # CSV.new('').headers # => nil + def headers + if @writer + @writer.headers + else + parsed_headers = parser.headers + return parsed_headers if parsed_headers + raw_headers = @parser_options[:headers] + raw_headers = nil if raw_headers == false + raw_headers + end + end + + # :call-seq: + # csv.return_headers? -> true or false + # + # Returns the value that determines whether headers are to be returned; used for parsing; + # see {Option +return_headers+}[#class-CSV-label-Option+return_headers]: + # CSV.new('').return_headers? # => false + def return_headers? + parser.return_headers? + end + + # :call-seq: + # csv.write_headers? -> true or false + # + # Returns the value that determines whether headers are to be written; used for generating; + # see {Option +write_headers+}[#class-CSV-label-Option+write_headers]: + # CSV.new('').write_headers? # => nil + def write_headers? + @writer_options[:write_headers] + end + + # :call-seq: + # csv.header_converters -> array + # + # Returns an \Array containing header converters; used for parsing; + # see {Header Converters}[#class-CSV-label-Header+Converters]: + # CSV.new('').header_converters # => [] + # + # Notes that you need to call + # +Ractor.make_shareable(CSV::HeaderConverters)+ on the main Ractor + # to use this method. + def header_converters + header_fields_converter.map do |converter| + name = HeaderConverters.rassoc(converter) + name ? name.first : converter + end + end + + # :call-seq: + # csv.skip_blanks? -> true or false + # + # Returns the value that determines whether blank lines are to be ignored; used for parsing; + # see {Option +skip_blanks+}[#class-CSV-label-Option+skip_blanks]: + # CSV.new('').skip_blanks? # => false + def skip_blanks? + parser.skip_blanks? + end + + # :call-seq: + # csv.force_quotes? -> true or false + # + # Returns the value that determines whether all output fields are to be quoted; + # used for generating; + # see {Option +force_quotes+}[#class-CSV-label-Option+force_quotes]: + # CSV.new('').force_quotes? # => false + def force_quotes? + @writer_options[:force_quotes] + end + + # :call-seq: + # csv.liberal_parsing? -> true or false + # + # Returns the value that determines whether illegal input is to be handled; used for parsing; + # see {Option +liberal_parsing+}[#class-CSV-label-Option+liberal_parsing]: + # CSV.new('').liberal_parsing? # => false + def liberal_parsing? + parser.liberal_parsing? + end + + # :call-seq: + # csv.encoding -> encoding + # + # Returns the encoding used for parsing and generating; + # see {Character Encodings (M17n or Multilingualization)}[#class-CSV-label-Character+Encodings+-28M17n+or+Multilingualization-29]: + # CSV.new('').encoding # => # + attr_reader :encoding + + # :call-seq: + # csv.line_no -> integer + # + # Returns the count of the rows parsed or generated. + # + # Parsing: + # string = "foo,0\nbar,1\nbaz,2\n" + # path = 't.csv' + # File.write(path, string) + # CSV.open(path) do |csv| + # csv.each do |row| + # p [csv.lineno, row] + # end + # end + # Output: + # [1, ["foo", "0"]] + # [2, ["bar", "1"]] + # [3, ["baz", "2"]] + # + # Generating: + # CSV.generate do |csv| + # p csv.lineno; csv << ['foo', 0] + # p csv.lineno; csv << ['bar', 1] + # p csv.lineno; csv << ['baz', 2] + # end + # Output: + # 0 + # 1 + # 2 + def lineno + if @writer + @writer.lineno + else + parser.lineno + end + end + + # :call-seq: + # csv.line -> array + # + # Returns the line most recently read: + # string = "foo,0\nbar,1\nbaz,2\n" + # path = 't.csv' + # File.write(path, string) + # CSV.open(path) do |csv| + # csv.each do |row| + # p [csv.lineno, csv.line] + # end + # end + # Output: + # [1, "foo,0\n"] + # [2, "bar,1\n"] + # [3, "baz,2\n"] + def line + parser.line + end + + ### IO and StringIO Delegation ### + + extend Forwardable + def_delegators :@io, :binmode, :close, :close_read, :close_write, + :closed?, :external_encoding, :fcntl, + :fileno, :flush, :fsync, :internal_encoding, + :isatty, :pid, :pos, :pos=, :reopen, + :seek, :string, :sync, :sync=, :tell, + :truncate, :tty? + + def binmode? + if @io.respond_to?(:binmode?) + @io.binmode? + else + false + end + end + + def flock(*args) + raise NotImplementedError unless @io.respond_to?(:flock) + @io.flock(*args) + end + + def ioctl(*args) + raise NotImplementedError unless @io.respond_to?(:ioctl) + @io.ioctl(*args) + end + + def path + @io.path if @io.respond_to?(:path) + end + + def stat(*args) + raise NotImplementedError unless @io.respond_to?(:stat) + @io.stat(*args) + end + + def to_i + raise NotImplementedError unless @io.respond_to?(:to_i) + @io.to_i + end + + def to_io + @io.respond_to?(:to_io) ? @io.to_io : @io + end + + def eof? + return false if @eof_error + begin + parser_enumerator.peek + false + rescue MalformedCSVError => error + @eof_error = error + false + rescue StopIteration + true + end + end + alias_method :eof, :eof? + + # Rewinds the underlying IO object and resets CSV's lineno() counter. + def rewind + @parser = nil + @parser_enumerator = nil + @eof_error = nil + @writer.rewind if @writer + @io.rewind + end + + ### End Delegation ### + + # :call-seq: + # csv << row -> self + # + # Appends a row to +self+. + # + # - Argument +row+ must be an \Array object or a CSV::Row object. + # - The output stream must be open for writing. + # + # --- + # + # Append Arrays: + # CSV.generate do |csv| + # csv << ['foo', 0] + # csv << ['bar', 1] + # csv << ['baz', 2] + # end # => "foo,0\nbar,1\nbaz,2\n" + # + # Append CSV::Rows: + # headers = [] + # CSV.generate do |csv| + # csv << CSV::Row.new(headers, ['foo', 0]) + # csv << CSV::Row.new(headers, ['bar', 1]) + # csv << CSV::Row.new(headers, ['baz', 2]) + # end # => "foo,0\nbar,1\nbaz,2\n" + # + # Headers in CSV::Row objects are not appended: + # headers = ['Name', 'Count'] + # CSV.generate do |csv| + # csv << CSV::Row.new(headers, ['foo', 0]) + # csv << CSV::Row.new(headers, ['bar', 1]) + # csv << CSV::Row.new(headers, ['baz', 2]) + # end # => "foo,0\nbar,1\nbaz,2\n" + # + # --- + # + # Raises an exception if +row+ is not an \Array or \CSV::Row: + # CSV.generate do |csv| + # # Raises NoMethodError (undefined method `collect' for :foo:Symbol) + # csv << :foo + # end + # + # Raises an exception if the output stream is not opened for writing: + # path = 't.csv' + # File.write(path, '') + # File.open(path) do |file| + # CSV.open(file) do |csv| + # # Raises IOError (not opened for writing) + # csv << ['foo', 0] + # end + # end + def <<(row) + writer << row + self + end + alias_method :add_row, :<< + alias_method :puts, :<< + + # :call-seq: + # convert(converter_name) -> array_of_procs + # convert {|field, field_info| ... } -> array_of_procs + # + # - With no block, installs a field converter (a \Proc). + # - With a block, defines and installs a custom field converter. + # - Returns the \Array of installed field converters. + # + # - Argument +converter_name+, if given, should be the name + # of an existing field converter. + # + # See {Field Converters}[#class-CSV-label-Field+Converters]. + # --- + # + # With no block, installs a field converter: + # csv = CSV.new('') + # csv.convert(:integer) + # csv.convert(:float) + # csv.convert(:date) + # csv.converters # => [:integer, :float, :date] + # + # --- + # + # The block, if given, is called for each field: + # - Argument +field+ is the field value. + # - Argument +field_info+ is a CSV::FieldInfo object + # containing details about the field. + # + # The examples here assume the prior execution of: + # string = "foo,0\nbar,1\nbaz,2\n" + # path = 't.csv' + # File.write(path, string) + # + # Example giving a block: + # csv = CSV.open(path) + # csv.convert {|field, field_info| p [field, field_info]; field.upcase } + # csv.read # => [["FOO", "0"], ["BAR", "1"], ["BAZ", "2"]] + # + # Output: + # ["foo", #] + # ["0", #] + # ["bar", #] + # ["1", #] + # ["baz", #] + # ["2", #] + # + # The block need not return a \String object: + # csv = CSV.open(path) + # csv.convert {|field, field_info| field.to_sym } + # csv.read # => [[:foo, :"0"], [:bar, :"1"], [:baz, :"2"]] + # + # If +converter_name+ is given, the block is not called: + # csv = CSV.open(path) + # csv.convert(:integer) {|field, field_info| fail 'Cannot happen' } + # csv.read # => [["foo", 0], ["bar", 1], ["baz", 2]] + # + # --- + # + # Raises a parse-time exception if +converter_name+ is not the name of a built-in + # field converter: + # csv = CSV.open(path) + # csv.convert(:nosuch) => [nil] + # # Raises NoMethodError (undefined method `arity' for nil:NilClass) + # csv.read + def convert(name = nil, &converter) + parser_fields_converter.add_converter(name, &converter) + end + + # :call-seq: + # header_convert(converter_name) -> array_of_procs + # header_convert {|header, field_info| ... } -> array_of_procs + # + # - With no block, installs a header converter (a \Proc). + # - With a block, defines and installs a custom header converter. + # - Returns the \Array of installed header converters. + # + # - Argument +converter_name+, if given, should be the name + # of an existing header converter. + # + # See {Header Converters}[#class-CSV-label-Header+Converters]. + # --- + # + # With no block, installs a header converter: + # csv = CSV.new('') + # csv.header_convert(:symbol) + # csv.header_convert(:downcase) + # csv.header_converters # => [:symbol, :downcase] + # + # --- + # + # The block, if given, is called for each header: + # - Argument +header+ is the header value. + # - Argument +field_info+ is a CSV::FieldInfo object + # containing details about the header. + # + # The examples here assume the prior execution of: + # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # path = 't.csv' + # File.write(path, string) + # + # Example giving a block: + # csv = CSV.open(path, headers: true) + # csv.header_convert {|header, field_info| p [header, field_info]; header.upcase } + # table = csv.read + # table # => # + # table.headers # => ["NAME", "VALUE"] + # + # Output: + # ["Name", #] + # ["Value", #] + + # The block need not return a \String object: + # csv = CSV.open(path, headers: true) + # csv.header_convert {|header, field_info| header.to_sym } + # table = csv.read + # table.headers # => [:Name, :Value] + # + # If +converter_name+ is given, the block is not called: + # csv = CSV.open(path, headers: true) + # csv.header_convert(:downcase) {|header, field_info| fail 'Cannot happen' } + # table = csv.read + # table.headers # => ["name", "value"] + # --- + # + # Raises a parse-time exception if +converter_name+ is not the name of a built-in + # field converter: + # csv = CSV.open(path, headers: true) + # csv.header_convert(:nosuch) + # # Raises NoMethodError (undefined method `arity' for nil:NilClass) + # csv.read + def header_convert(name = nil, &converter) + header_fields_converter.add_converter(name, &converter) + end + + include Enumerable + + # :call-seq: + # csv.each -> enumerator + # csv.each {|row| ...} + # + # Calls the block with each successive row. + # The data source must be opened for reading. + # + # Without headers: + # string = "foo,0\nbar,1\nbaz,2\n" + # csv = CSV.new(string) + # csv.each do |row| + # p row + # end + # Output: + # ["foo", "0"] + # ["bar", "1"] + # ["baz", "2"] + # + # With headers: + # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # csv = CSV.new(string, headers: true) + # csv.each do |row| + # p row + # end + # Output: + # + # + # + # + # --- + # + # Raises an exception if the source is not opened for reading: + # string = "foo,0\nbar,1\nbaz,2\n" + # csv = CSV.new(string) + # csv.close + # # Raises IOError (not opened for reading) + # csv.each do |row| + # p row + # end + def each(&block) + return to_enum(__method__) unless block_given? + begin + while true + yield(parser_enumerator.next) + end + rescue StopIteration + end + end + + # :call-seq: + # csv.read -> array or csv_table + # + # Forms the remaining rows from +self+ into: + # - A CSV::Table object, if headers are in use. + # - An \Array of Arrays, otherwise. + # + # The data source must be opened for reading. + # + # Without headers: + # string = "foo,0\nbar,1\nbaz,2\n" + # path = 't.csv' + # File.write(path, string) + # csv = CSV.open(path) + # csv.read # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] + # + # With headers: + # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # path = 't.csv' + # File.write(path, string) + # csv = CSV.open(path, headers: true) + # csv.read # => # + # + # --- + # + # Raises an exception if the source is not opened for reading: + # string = "foo,0\nbar,1\nbaz,2\n" + # csv = CSV.new(string) + # csv.close + # # Raises IOError (not opened for reading) + # csv.read + def read + rows = to_a + if parser.use_headers? + Table.new(rows, headers: parser.headers) + else + rows + end + end + alias_method :readlines, :read + + # :call-seq: + # csv.header_row? -> true or false + # + # Returns +true+ if the next row to be read is a header row\; + # +false+ otherwise. + # + # Without headers: + # string = "foo,0\nbar,1\nbaz,2\n" + # csv = CSV.new(string) + # csv.header_row? # => false + # + # With headers: + # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # csv = CSV.new(string, headers: true) + # csv.header_row? # => true + # csv.shift # => # + # csv.header_row? # => false + # + # --- + # + # Raises an exception if the source is not opened for reading: + # string = "foo,0\nbar,1\nbaz,2\n" + # csv = CSV.new(string) + # csv.close + # # Raises IOError (not opened for reading) + # csv.header_row? + def header_row? + parser.header_row? + end + + # :call-seq: + # csv.shift -> array, csv_row, or nil + # + # Returns the next row of data as: + # - An \Array if no headers are used. + # - A CSV::Row object if headers are used. + # + # The data source must be opened for reading. + # + # Without headers: + # string = "foo,0\nbar,1\nbaz,2\n" + # csv = CSV.new(string) + # csv.shift # => ["foo", "0"] + # csv.shift # => ["bar", "1"] + # csv.shift # => ["baz", "2"] + # csv.shift # => nil + # + # With headers: + # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # csv = CSV.new(string, headers: true) + # csv.shift # => # + # csv.shift # => # + # csv.shift # => # + # csv.shift # => nil + # + # --- + # + # Raises an exception if the source is not opened for reading: + # string = "foo,0\nbar,1\nbaz,2\n" + # csv = CSV.new(string) + # csv.close + # # Raises IOError (not opened for reading) + # csv.shift + def shift + if @eof_error + eof_error, @eof_error = @eof_error, nil + raise eof_error + end + begin + parser_enumerator.next + rescue StopIteration + nil + end + end + alias_method :gets, :shift + alias_method :readline, :shift + + # :call-seq: + # csv.inspect -> string + # + # Returns a \String showing certain properties of +self+: + # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # csv = CSV.new(string, headers: true) + # s = csv.inspect + # s # => "#" + def inspect + str = ["#<", self.class.to_s, " io_type:"] + # show type of wrapped IO + if @io == $stdout then str << "$stdout" + elsif @io == $stdin then str << "$stdin" + elsif @io == $stderr then str << "$stderr" + else str << @io.class.to_s + end + # show IO.path(), if available + if @io.respond_to?(:path) and (p = @io.path) + str << " io_path:" << p.inspect + end + # show encoding + str << " encoding:" << @encoding.name + # show other attributes + ["lineno", "col_sep", "row_sep", "quote_char"].each do |attr_name| + if a = __send__(attr_name) + str << " " << attr_name << ":" << a.inspect + end + end + ["skip_blanks", "liberal_parsing"].each do |attr_name| + if a = __send__("#{attr_name}?") + str << " " << attr_name << ":" << a.inspect + end + end + _headers = headers + str << " headers:" << _headers.inspect if _headers + str << ">" + begin + str.join('') + rescue # any encoding error + str.map do |s| + e = Encoding::Converter.asciicompat_encoding(s.encoding) + e ? s.encode(e) : s.force_encoding("ASCII-8BIT") + end.join('') + end + end + + private + + def determine_encoding(encoding, internal_encoding) + # honor the IO encoding if we can, otherwise default to ASCII-8BIT + io_encoding = raw_encoding + return io_encoding if io_encoding + + return Encoding.find(internal_encoding) if internal_encoding + + if encoding + encoding, = encoding.split(":", 2) if encoding.is_a?(String) + return Encoding.find(encoding) + end + + Encoding.default_internal || Encoding.default_external + end + + def normalize_converters(converters) + converters ||= [] + unless converters.is_a?(Array) + converters = [converters] + end + converters.collect do |converter| + case converter + when Proc # custom code block + [nil, converter] + else # by name + [converter, nil] + end + end + end + + # + # Processes +fields+ with @converters, or @header_converters + # if +headers+ is passed as +true+, returning the converted field set. Any + # converter that changes the field into something other than a String halts + # the pipeline of conversion for that field. This is primarily an efficiency + # shortcut. + # + def convert_fields(fields, headers = false) + if headers + header_fields_converter.convert(fields, nil, 0) + else + parser_fields_converter.convert(fields, @headers, lineno) + end + end + + # + # Returns the encoding of the internal IO object. + # + def raw_encoding + if @io.respond_to? :internal_encoding + @io.internal_encoding || @io.external_encoding + elsif @io.respond_to? :encoding + @io.encoding + else + nil + end + end + + def parser_fields_converter + @parser_fields_converter ||= build_parser_fields_converter + end + + def build_parser_fields_converter + specific_options = { + builtin_converters_name: :Converters, + } + options = @base_fields_converter_options.merge(specific_options) + build_fields_converter(@initial_converters, options) + end + + def header_fields_converter + @header_fields_converter ||= build_header_fields_converter + end + + def build_header_fields_converter + specific_options = { + builtin_converters_name: :HeaderConverters, + accept_nil: true, + } + options = @base_fields_converter_options.merge(specific_options) + build_fields_converter(@initial_header_converters, options) + end + + def writer_fields_converter + @writer_fields_converter ||= build_writer_fields_converter + end + + def build_writer_fields_converter + build_fields_converter(@initial_write_converters, + @write_fields_converter_options) + end + + def build_fields_converter(initial_converters, options) + fields_converter = FieldsConverter.new(options) + normalize_converters(initial_converters).each do |name, converter| + fields_converter.add_converter(name, &converter) + end + fields_converter + end + + def parser + @parser ||= Parser.new(@io, parser_options) + end + + def parser_options + @parser_options.merge(header_fields_converter: header_fields_converter, + fields_converter: parser_fields_converter) + end + + def parser_enumerator + @parser_enumerator ||= parser.parse + end + + def writer + @writer ||= Writer.new(@io, writer_options) + end + + def writer_options + @writer_options.merge(header_fields_converter: header_fields_converter, + fields_converter: writer_fields_converter) + end +end + +# Passes +args+ to CSV::instance. +# +# CSV("CSV,data").read +# #=> [["CSV", "data"]] +# +# If a block is given, the instance is passed the block and the return value +# becomes the return value of the block. +# +# CSV("CSV,data") { |c| +# c.read.any? { |a| a.include?("data") } +# } #=> true +# +# CSV("CSV,data") { |c| +# c.read.any? { |a| a.include?("zombies") } +# } #=> false +# +# CSV options may also be given. +# +# io = StringIO.new +# CSV(io, col_sep: ";") { |csv| csv << ["a", "b", "c"] } +# +# This API is not Ractor-safe. +# +def CSV(*args, **options, &block) + CSV.instance(*args, **options, &block) +end + +require_relative "csv/version" +require_relative "csv/core_ext/array" +require_relative "csv/core_ext/string" diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv/core_ext/array.rb b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv/core_ext/array.rb new file mode 100644 index 0000000..ad1b881 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv/core_ext/array.rb @@ -0,0 +1,9 @@ +class Array + # Equivalent to CSV::generate_line(self, options) + # + # ["CSV", "data"].to_csv + # #=> "CSV,data\n" + def to_csv(**options) + CSV.generate_line(self, **options) + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv/core_ext/string.rb b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv/core_ext/string.rb new file mode 100644 index 0000000..61286d0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv/core_ext/string.rb @@ -0,0 +1,9 @@ +class String + # Equivalent to CSV::parse_line(self, options) + # + # "CSV,data".parse_csv + # #=> ["CSV", "data"] + def parse_csv(**options) + CSV.parse_line(self, **options) + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv/fields_converter.rb b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv/fields_converter.rb new file mode 100644 index 0000000..8ea1340 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv/fields_converter.rb @@ -0,0 +1,96 @@ +# frozen_string_literal: true + +class CSV + # Note: Don't use this class directly. This is an internal class. + class FieldsConverter + include Enumerable + + NO_QUOTED_FIELDS = [] # :nodoc: + def NO_QUOTED_FIELDS.[](_index) + false + end + NO_QUOTED_FIELDS.freeze + + # + # A CSV::FieldsConverter is a data structure for storing the + # fields converter properties to be passed as a parameter + # when parsing a new file (e.g. CSV::Parser.new(@io, parser_options)) + # + + def initialize(options={}) + @converters = [] + @nil_value = options[:nil_value] + @empty_value = options[:empty_value] + @empty_value_is_empty_string = (@empty_value == "") + @accept_nil = options[:accept_nil] + @builtin_converters_name = options[:builtin_converters_name] + @need_static_convert = need_static_convert? + end + + def add_converter(name=nil, &converter) + if name.nil? # custom converter + @converters << converter + else # named converter + combo = builtin_converters[name] + case combo + when Array # combo converter + combo.each do |sub_name| + add_converter(sub_name) + end + else # individual named converter + @converters << combo + end + end + end + + def each(&block) + @converters.each(&block) + end + + def empty? + @converters.empty? + end + + def convert(fields, headers, lineno, quoted_fields=NO_QUOTED_FIELDS) + return fields unless need_convert? + + fields.collect.with_index do |field, index| + if field.nil? + field = @nil_value + elsif field.is_a?(String) and field.empty? + field = @empty_value unless @empty_value_is_empty_string + end + @converters.each do |converter| + break if field.nil? and @accept_nil + if converter.arity == 1 # straight field converter + field = converter[field] + else # FieldInfo converter + if headers + header = headers[index] + else + header = nil + end + quoted = quoted_fields[index] + field = converter[field, FieldInfo.new(index, lineno, header, quoted)] + end + break unless field.is_a?(String) # short-circuit pipeline for speed + end + field # final state of each field, converted or original + end + end + + private + def need_static_convert? + not (@nil_value.nil? and @empty_value_is_empty_string) + end + + def need_convert? + @need_static_convert or + (not @converters.empty?) + end + + def builtin_converters + @builtin_converters ||= ::CSV.const_get(@builtin_converters_name) + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv/input_record_separator.rb b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv/input_record_separator.rb new file mode 100644 index 0000000..7a99343 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv/input_record_separator.rb @@ -0,0 +1,18 @@ +require "English" +require "stringio" + +class CSV + module InputRecordSeparator + class << self + if RUBY_VERSION >= "3.0.0" + def value + "\n" + end + else + def value + $INPUT_RECORD_SEPARATOR + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv/parser.rb b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv/parser.rb new file mode 100644 index 0000000..4a74e40 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv/parser.rb @@ -0,0 +1,1302 @@ +# frozen_string_literal: true + +require "strscan" + +require_relative "input_record_separator" +require_relative "row" +require_relative "table" + +class CSV + # Note: Don't use this class directly. This is an internal class. + class Parser + # + # A CSV::Parser is m17n aware. The parser works in the Encoding of the IO + # or String object being read from or written to. Your data is never transcoded + # (unless you ask Ruby to transcode it for you) and will literally be parsed in + # the Encoding it is in. Thus CSV will return Arrays or Rows of Strings in the + # Encoding of your data. This is accomplished by transcoding the parser itself + # into your Encoding. + # + + class << self + ARGF_OBJECT_ID = ARGF.object_id + # Convenient method to check whether the give input reached EOF + # or not. + def eof?(input) + # We can't use input != ARGF in Ractor. Because ARGF isn't a + # shareable object. + input.object_id != ARGF_OBJECT_ID and + input.respond_to?(:eof) and + input.eof? + end + end + + # Raised when encoding is invalid. + class InvalidEncoding < StandardError + end + + # Raised when unexpected case is happen. + class UnexpectedError < StandardError + end + + # + # CSV::Scanner receives a CSV output, scans it and return the content. + # It also controls the life cycle of the object with its methods +keep_start+, + # +keep_end+, +keep_back+, +keep_drop+. + # + # Uses StringScanner (the official strscan gem). Strscan provides lexical + # scanning operations on a String. We inherit its object and take advantage + # on the methods. For more information, please visit: + # https://docs.ruby-lang.org/en/master/StringScanner.html + # + class Scanner < StringScanner + alias_method :scan_all, :scan + + def initialize(*args) + super + @keeps = [] + end + + def each_line(row_separator) + position = pos + rest.each_line(row_separator) do |line| + position += line.bytesize + self.pos = position + yield(line) + end + end + + def keep_start + @keeps.push(pos) + end + + def keep_end + start = @keeps.pop + string.byteslice(start, pos - start) + end + + def keep_back + self.pos = @keeps.pop + end + + def keep_drop + @keeps.pop + end + end + + # + # CSV::InputsScanner receives IO inputs, encoding and the chunk_size. + # It also controls the life cycle of the object with its methods +keep_start+, + # +keep_end+, +keep_back+, +keep_drop+. + # + # CSV::InputsScanner.scan() tries to match with pattern at the current position. + # If there's a match, the scanner advances the "scan pointer" and returns the matched string. + # Otherwise, the scanner returns nil. + # + # CSV::InputsScanner.rest() returns the "rest" of the string (i.e. everything after the scan pointer). + # If there is no more data (eos? = true), it returns "". + # + class InputsScanner + def initialize(inputs, encoding, row_separator, chunk_size: 8192) + @inputs = inputs.dup + @encoding = encoding + @row_separator = row_separator + @chunk_size = chunk_size + @last_scanner = @inputs.empty? + @keeps = [] + read_chunk + end + + def each_line(row_separator) + return enum_for(__method__, row_separator) unless block_given? + buffer = nil + input = @scanner.rest + position = @scanner.pos + offset = 0 + n_row_separator_chars = row_separator.size + # trace(__method__, :start, input) + while true + input.each_line(row_separator) do |line| + @scanner.pos += line.bytesize + if buffer + if n_row_separator_chars == 2 and + buffer.end_with?(row_separator[0]) and + line.start_with?(row_separator[1]) + buffer << line[0] + line = line[1..-1] + position += buffer.bytesize + offset + @scanner.pos = position + offset = 0 + yield(buffer) + buffer = nil + next if line.empty? + else + buffer << line + line = buffer + buffer = nil + end + end + if line.end_with?(row_separator) + position += line.bytesize + offset + @scanner.pos = position + offset = 0 + yield(line) + else + buffer = line + end + end + break unless read_chunk + input = @scanner.rest + position = @scanner.pos + offset = -buffer.bytesize if buffer + end + yield(buffer) if buffer + end + + def scan(pattern) + # trace(__method__, pattern, :start) + value = @scanner.scan(pattern) + # trace(__method__, pattern, :done, :last, value) if @last_scanner + return value if @last_scanner + + read_chunk if value and @scanner.eos? + # trace(__method__, pattern, :done, value) + value + end + + def scan_all(pattern) + # trace(__method__, pattern, :start) + value = @scanner.scan(pattern) + # trace(__method__, pattern, :done, :last, value) if @last_scanner + return value if @last_scanner + + # trace(__method__, pattern, :done, :nil) if value.nil? + return nil if value.nil? + while @scanner.eos? and read_chunk and (sub_value = @scanner.scan(pattern)) + # trace(__method__, pattern, :sub, sub_value) + value << sub_value + end + # trace(__method__, pattern, :done, value) + value + end + + def eos? + @scanner.eos? + end + + def keep_start + # trace(__method__, :start) + adjust_last_keep + @keeps.push([@scanner, @scanner.pos, nil]) + # trace(__method__, :done) + end + + def keep_end + # trace(__method__, :start) + scanner, start, buffer = @keeps.pop + if scanner == @scanner + keep = @scanner.string.byteslice(start, @scanner.pos - start) + else + keep = @scanner.string.byteslice(0, @scanner.pos) + end + if buffer + buffer << keep + keep = buffer + end + # trace(__method__, :done, keep) + keep + end + + def keep_back + # trace(__method__, :start) + scanner, start, buffer = @keeps.pop + if buffer + # trace(__method__, :rescan, start, buffer) + string = @scanner.string + if scanner == @scanner + keep = string.byteslice(start, + string.bytesize - @scanner.pos - start) + else + keep = string + end + if keep and not keep.empty? + @inputs.unshift(StringIO.new(keep)) + @last_scanner = false + end + @scanner = StringScanner.new(buffer) + else + if @scanner != scanner + message = "scanners are different but no buffer: " + message += "#{@scanner.inspect}(#{@scanner.object_id}): " + message += "#{scanner.inspect}(#{scanner.object_id})" + raise UnexpectedError, message + end + # trace(__method__, :repos, start, buffer) + @scanner.pos = start + last_scanner, last_start, last_buffer = @keeps.last + # Drop the last buffer when the last buffer is the same data + # in the last keep. If we keep it, we have duplicated data + # by the next keep_back. + if last_scanner == @scanner and + last_buffer and + last_buffer == last_scanner.string.byteslice(last_start, start) + @keeps.last[2] = nil + end + end + read_chunk if @scanner.eos? + end + + def keep_drop + _, _, buffer = @keeps.pop + # trace(__method__, :done, :empty) unless buffer + return unless buffer + + last_keep = @keeps.last + # trace(__method__, :done, :no_last_keep) unless last_keep + return unless last_keep + + if last_keep[2] + last_keep[2] << buffer + else + last_keep[2] = buffer + end + # trace(__method__, :done) + end + + def rest + @scanner.rest + end + + def check(pattern) + @scanner.check(pattern) + end + + private + def trace(*args) + pp([*args, @scanner, @scanner&.string, @scanner&.pos, @keeps]) + end + + def adjust_last_keep + # trace(__method__, :start) + + keep = @keeps.last + # trace(__method__, :done, :empty) if keep.nil? + return if keep.nil? + + scanner, start, buffer = keep + string = @scanner.string + if @scanner != scanner + start = 0 + end + if start == 0 and @scanner.eos? + keep_data = string + else + keep_data = string.byteslice(start, @scanner.pos - start) + end + if keep_data + if buffer + buffer << keep_data + else + keep[2] = keep_data.dup + end + end + + # trace(__method__, :done) + end + + def read_chunk + return false if @last_scanner + + adjust_last_keep + + input = @inputs.first + case input + when StringIO + string = input.read + raise InvalidEncoding unless string.valid_encoding? + # trace(__method__, :stringio, string) + @scanner = StringScanner.new(string) + @inputs.shift + @last_scanner = @inputs.empty? + true + else + chunk = input.gets(@row_separator, @chunk_size) + if chunk + raise InvalidEncoding unless chunk.valid_encoding? + # trace(__method__, :chunk, chunk) + @scanner = StringScanner.new(chunk) + if Parser.eof?(input) + @inputs.shift + @last_scanner = @inputs.empty? + end + true + else + # trace(__method__, :no_chunk) + @scanner = StringScanner.new("".encode(@encoding)) + @inputs.shift + @last_scanner = @inputs.empty? + if @last_scanner + false + else + read_chunk + end + end + end + end + end + + def initialize(input, options) + @input = input + @options = options + @samples = [] + + prepare + end + + def column_separator + @column_separator + end + + def row_separator + @row_separator + end + + def quote_character + @quote_character + end + + def field_size_limit + @max_field_size&.succ + end + + def max_field_size + @max_field_size + end + + def skip_lines + @skip_lines + end + + def unconverted_fields? + @unconverted_fields + end + + def headers + @headers + end + + def header_row? + @use_headers and @headers.nil? + end + + def return_headers? + @return_headers + end + + def skip_blanks? + @skip_blanks + end + + def liberal_parsing? + @liberal_parsing + end + + def lineno + @lineno + end + + def line + last_line + end + + def parse(&block) + return to_enum(__method__) unless block_given? + + if @return_headers and @headers and @raw_headers + headers = Row.new(@headers, @raw_headers, true) + if @unconverted_fields + headers = add_unconverted_fields(headers, []) + end + yield headers + end + + begin + @scanner ||= build_scanner + __send__(@parse_method, &block) + rescue InvalidEncoding + if @scanner + ignore_broken_line + lineno = @lineno + else + lineno = @lineno + 1 + end + raise InvalidEncodingError.new(@encoding, lineno) + rescue UnexpectedError => error + if @scanner + ignore_broken_line + lineno = @lineno + else + lineno = @lineno + 1 + end + message = "This should not be happen: #{error.message}: " + message += "Please report this to https://github.com/ruby/csv/issues" + raise MalformedCSVError.new(message, lineno) + end + end + + def use_headers? + @use_headers + end + + private + # A set of tasks to prepare the file in order to parse it + def prepare + prepare_variable + prepare_quote_character + prepare_backslash + prepare_skip_lines + prepare_strip + prepare_separators + validate_strip_and_col_sep_options + prepare_quoted + prepare_unquoted + prepare_line + prepare_header + prepare_parser + end + + def prepare_variable + @encoding = @options[:encoding] + liberal_parsing = @options[:liberal_parsing] + if liberal_parsing + @liberal_parsing = true + if liberal_parsing.is_a?(Hash) + @double_quote_outside_quote = + liberal_parsing[:double_quote_outside_quote] + @backslash_quote = liberal_parsing[:backslash_quote] + else + @double_quote_outside_quote = false + @backslash_quote = false + end + else + @liberal_parsing = false + @backslash_quote = false + end + @unconverted_fields = @options[:unconverted_fields] + @max_field_size = @options[:max_field_size] + @skip_blanks = @options[:skip_blanks] + @fields_converter = @options[:fields_converter] + @header_fields_converter = @options[:header_fields_converter] + end + + def prepare_quote_character + @quote_character = @options[:quote_character] + if @quote_character.nil? + @escaped_quote_character = nil + @escaped_quote = nil + else + @quote_character = @quote_character.to_s.encode(@encoding) + if @quote_character.length != 1 + message = ":quote_char has to be nil or a single character String" + raise ArgumentError, message + end + @escaped_quote_character = Regexp.escape(@quote_character) + @escaped_quote = Regexp.new(@escaped_quote_character) + end + end + + def prepare_backslash + return unless @backslash_quote + + @backslash_character = "\\".encode(@encoding) + + @escaped_backslash_character = Regexp.escape(@backslash_character) + @escaped_backslash = Regexp.new(@escaped_backslash_character) + if @quote_character.nil? + @backslash_quote_character = nil + else + @backslash_quote_character = + @backslash_character + @escaped_quote_character + end + end + + def prepare_skip_lines + skip_lines = @options[:skip_lines] + case skip_lines + when String + @skip_lines = skip_lines.encode(@encoding) + when Regexp, nil + @skip_lines = skip_lines + else + unless skip_lines.respond_to?(:match) + message = + ":skip_lines has to respond to \#match: #{skip_lines.inspect}" + raise ArgumentError, message + end + @skip_lines = skip_lines + end + end + + def prepare_strip + @strip = @options[:strip] + @escaped_strip = nil + @strip_value = nil + @rstrip_value = nil + if @strip.is_a?(String) + case @strip.length + when 0 + raise ArgumentError, ":strip must not be an empty String" + when 1 + # ok + else + raise ArgumentError, ":strip doesn't support 2 or more characters yet" + end + @strip = @strip.encode(@encoding) + @escaped_strip = Regexp.escape(@strip) + if @quote_character + @strip_value = Regexp.new(@escaped_strip + + "+".encode(@encoding)) + @rstrip_value = Regexp.new(@escaped_strip + + "+\\z".encode(@encoding)) + end + elsif @strip + strip_values = " \t\f\v" + @escaped_strip = strip_values.encode(@encoding) + if @quote_character + @strip_value = Regexp.new("[#{strip_values}]+".encode(@encoding)) + @rstrip_value = Regexp.new("[#{strip_values}]+\\z".encode(@encoding)) + end + end + end + + begin + StringScanner.new("x").scan("x") + rescue TypeError + STRING_SCANNER_SCAN_ACCEPT_STRING = false + else + STRING_SCANNER_SCAN_ACCEPT_STRING = true + end + + def prepare_separators + column_separator = @options[:column_separator] + @column_separator = column_separator.to_s.encode(@encoding) + if @column_separator.size < 1 + message = ":col_sep must be 1 or more characters: " + message += column_separator.inspect + raise ArgumentError, message + end + @row_separator = + resolve_row_separator(@options[:row_separator]).encode(@encoding) + + @escaped_column_separator = Regexp.escape(@column_separator) + @escaped_first_column_separator = Regexp.escape(@column_separator[0]) + if @column_separator.size > 1 + @column_end = Regexp.new(@escaped_column_separator) + @column_ends = @column_separator.each_char.collect do |char| + Regexp.new(Regexp.escape(char)) + end + @first_column_separators = Regexp.new(@escaped_first_column_separator + + "+".encode(@encoding)) + else + if STRING_SCANNER_SCAN_ACCEPT_STRING + @column_end = @column_separator + else + @column_end = Regexp.new(@escaped_column_separator) + end + @column_ends = nil + @first_column_separators = nil + end + + escaped_row_separator = Regexp.escape(@row_separator) + @row_end = Regexp.new(escaped_row_separator) + if @row_separator.size > 1 + @row_ends = @row_separator.each_char.collect do |char| + Regexp.new(Regexp.escape(char)) + end + else + @row_ends = nil + end + + @cr = "\r".encode(@encoding) + @lf = "\n".encode(@encoding) + @line_end = Regexp.new("\r\n|\n|\r".encode(@encoding)) + @not_line_end = Regexp.new("[^\r\n]+".encode(@encoding)) + end + + # This method verifies that there are no (obvious) ambiguities with the + # provided +col_sep+ and +strip+ parsing options. For example, if +col_sep+ + # and +strip+ were both equal to +\t+, then there would be no clear way to + # parse the input. + def validate_strip_and_col_sep_options + return unless @strip + + if @strip.is_a?(String) + if @column_separator.start_with?(@strip) || @column_separator.end_with?(@strip) + raise ArgumentError, + "The provided strip (#{@escaped_strip}) and " \ + "col_sep (#{@escaped_column_separator}) options are incompatible." + end + else + if Regexp.new("\\A[#{@escaped_strip}]|[#{@escaped_strip}]\\z").match?(@column_separator) + raise ArgumentError, + "The provided strip (true) and " \ + "col_sep (#{@escaped_column_separator}) options are incompatible." + end + end + end + + def prepare_quoted + if @quote_character + @quotes = Regexp.new(@escaped_quote_character + + "+".encode(@encoding)) + no_quoted_values = @escaped_quote_character.dup + if @backslash_quote + no_quoted_values << @escaped_backslash_character + end + @quoted_value = Regexp.new("[^".encode(@encoding) + + no_quoted_values + + "]+".encode(@encoding)) + end + if @escaped_strip + @split_column_separator = Regexp.new(@escaped_strip + + "*".encode(@encoding) + + @escaped_column_separator + + @escaped_strip + + "*".encode(@encoding)) + else + if @column_separator == " ".encode(@encoding) + @split_column_separator = Regexp.new(@escaped_column_separator) + else + @split_column_separator = @column_separator + end + end + end + + def prepare_unquoted + return if @quote_character.nil? + + no_unquoted_values = "\r\n".encode(@encoding) + no_unquoted_values << @escaped_first_column_separator + unless @liberal_parsing + no_unquoted_values << @escaped_quote_character + end + @unquoted_value = Regexp.new("[^".encode(@encoding) + + no_unquoted_values + + "]+".encode(@encoding)) + end + + def resolve_row_separator(separator) + if separator == :auto + cr = "\r".encode(@encoding) + lf = "\n".encode(@encoding) + if @input.is_a?(StringIO) + pos = @input.pos + separator = detect_row_separator(@input.read, cr, lf) + @input.seek(pos) + elsif @input.respond_to?(:gets) + if @input.is_a?(File) + chunk_size = 32 * 1024 + else + chunk_size = 1024 + end + begin + while separator == :auto + # + # if we run out of data, it's probably a single line + # (ensure will set default value) + # + break unless sample = @input.gets(nil, chunk_size) + + # extend sample if we're unsure of the line ending + if sample.end_with?(cr) + sample << (@input.gets(nil, 1) || "") + end + + @samples << sample + + separator = detect_row_separator(sample, cr, lf) + end + rescue IOError + # do nothing: ensure will set default + end + end + separator = InputRecordSeparator.value if separator == :auto + end + separator.to_s.encode(@encoding) + end + + def detect_row_separator(sample, cr, lf) + lf_index = sample.index(lf) + if lf_index + cr_index = sample[0, lf_index].index(cr) + else + cr_index = sample.index(cr) + end + if cr_index and lf_index + if cr_index + 1 == lf_index + cr + lf + elsif cr_index < lf_index + cr + else + lf + end + elsif cr_index + cr + elsif lf_index + lf + else + :auto + end + end + + def prepare_line + @lineno = 0 + @last_line = nil + @scanner = nil + end + + def last_line + if @scanner + @last_line ||= @scanner.keep_end + else + @last_line + end + end + + def prepare_header + @return_headers = @options[:return_headers] + + headers = @options[:headers] + case headers + when Array + @raw_headers = headers + quoted_fields = FieldsConverter::NO_QUOTED_FIELDS + @use_headers = true + when String + @raw_headers, quoted_fields = parse_headers(headers) + @use_headers = true + when nil, false + @raw_headers = nil + @use_headers = false + else + @raw_headers = nil + @use_headers = true + end + if @raw_headers + @headers = adjust_headers(@raw_headers, quoted_fields) + else + @headers = nil + end + end + + def parse_headers(row) + quoted_fields = [] + converter = lambda do |field, info| + quoted_fields << info.quoted? + field + end + headers = CSV.parse_line(row, + col_sep: @column_separator, + row_sep: @row_separator, + quote_char: @quote_character, + converters: [converter]) + [headers, quoted_fields] + end + + def adjust_headers(headers, quoted_fields) + adjusted_headers = @header_fields_converter.convert(headers, nil, @lineno, quoted_fields) + adjusted_headers.each {|h| h.freeze if h.is_a? String} + adjusted_headers + end + + def prepare_parser + @may_quoted = may_quoted? + if @quote_character.nil? + @parse_method = :parse_no_quote + elsif @liberal_parsing or @strip + @parse_method = :parse_quotable_robust + else + @parse_method = :parse_quotable_loose + end + end + + def may_quoted? + return false if @quote_character.nil? + + if @input.is_a?(StringIO) + pos = @input.pos + sample = @input.read + @input.seek(pos) + else + return false if @samples.empty? + sample = @samples.first + end + sample[0, 128].index(@quote_character) + end + + class UnoptimizedStringIO # :nodoc: + def initialize(string) + @io = StringIO.new(string, "rb:#{string.encoding}") + end + + def gets(*args) + @io.gets(*args) + end + + def each_line(*args, &block) + @io.each_line(*args, &block) + end + + def eof? + @io.eof? + end + end + + SCANNER_TEST = (ENV["CSV_PARSER_SCANNER_TEST"] == "yes") + if SCANNER_TEST + SCANNER_TEST_CHUNK_SIZE_NAME = "CSV_PARSER_SCANNER_TEST_CHUNK_SIZE" + SCANNER_TEST_CHUNK_SIZE_VALUE = ENV[SCANNER_TEST_CHUNK_SIZE_NAME] + def build_scanner + inputs = @samples.collect do |sample| + UnoptimizedStringIO.new(sample) + end + if @input.is_a?(StringIO) + inputs << UnoptimizedStringIO.new(@input.read) + else + inputs << @input + end + begin + chunk_size_value = ENV[SCANNER_TEST_CHUNK_SIZE_NAME] + rescue # Ractor::IsolationError + # Ractor on Ruby 3.0 can't read ENV value. + chunk_size_value = SCANNER_TEST_CHUNK_SIZE_VALUE + end + chunk_size = Integer((chunk_size_value || "1"), 10) + InputsScanner.new(inputs, + @encoding, + @row_separator, + chunk_size: chunk_size) + end + else + def build_scanner + string = nil + if @samples.empty? and @input.is_a?(StringIO) + string = @input.read + elsif @samples.size == 1 and Parser.eof?(@input) + string = @samples[0] + end + if string + unless string.valid_encoding? + index = string.lines(@row_separator).index do |line| + !line.valid_encoding? + end + if index + raise InvalidEncodingError.new(@encoding, @lineno + index + 1) + end + end + Scanner.new(string) + else + inputs = @samples.collect do |sample| + StringIO.new(sample) + end + inputs << @input + InputsScanner.new(inputs, @encoding, @row_separator) + end + end + end + + def skip_needless_lines + return unless @skip_lines + + until @scanner.eos? + @scanner.keep_start + line = @scanner.scan_all(@not_line_end) || "".encode(@encoding) + line << @row_separator if parse_row_end + if skip_line?(line) + @lineno += 1 + @scanner.keep_drop + else + @scanner.keep_back + return + end + end + end + + def skip_line?(line) + line = line.delete_suffix(@row_separator) + case @skip_lines + when String + line.include?(@skip_lines) + when Regexp + @skip_lines.match?(line) + else + @skip_lines.match(line) + end + end + + def validate_field_size(field) + return unless @max_field_size + return if field.size <= @max_field_size + ignore_broken_line + message = "Field size exceeded: #{field.size} > #{@max_field_size}" + raise MalformedCSVError.new(message, @lineno) + end + + def parse_no_quote(&block) + @scanner.each_line(@row_separator) do |line| + next if @skip_lines and skip_line?(line) + original_line = line + line = line.delete_suffix(@row_separator) + + if line.empty? + next if @skip_blanks + row = [] + else + line = strip_value(line) + row = line.split(@split_column_separator, -1) + if @max_field_size + row.each do |column| + validate_field_size(column) + end + end + n_columns = row.size + i = 0 + while i < n_columns + row[i] = nil if row[i].empty? + i += 1 + end + end + @last_line = original_line + emit_row(row, &block) + end + end + + def parse_quotable_loose(&block) + @scanner.keep_start + @scanner.each_line(@row_separator) do |line| + if @skip_lines and skip_line?(line) + @scanner.keep_drop + @scanner.keep_start + next + end + original_line = line + line = line.delete_suffix(@row_separator) + + if line.empty? + if @skip_blanks + @scanner.keep_drop + @scanner.keep_start + next + end + row = [] + quoted_fields = FieldsConverter::NO_QUOTED_FIELDS + elsif line.include?(@cr) or line.include?(@lf) + @scanner.keep_back + @parse_method = :parse_quotable_robust + return parse_quotable_robust(&block) + else + row = line.split(@split_column_separator, -1) + quoted_fields = [] + n_columns = row.size + i = 0 + while i < n_columns + column = row[i] + if column.empty? + quoted_fields << false + row[i] = nil + else + n_quotes = column.count(@quote_character) + if n_quotes.zero? + quoted_fields << false + # no quote + elsif n_quotes == 2 and + column.start_with?(@quote_character) and + column.end_with?(@quote_character) + quoted_fields << true + row[i] = column[1..-2] + else + @scanner.keep_back + @parse_method = :parse_quotable_robust + return parse_quotable_robust(&block) + end + validate_field_size(row[i]) + end + i += 1 + end + end + @scanner.keep_drop + @scanner.keep_start + @last_line = original_line + emit_row(row, quoted_fields, &block) + end + @scanner.keep_drop + end + + def parse_quotable_robust(&block) + row = [] + quoted_fields = [] + skip_needless_lines + start_row + while true + @quoted_column_value = false + @unquoted_column_value = false + @scanner.scan_all(@strip_value) if @strip_value + value = parse_column_value + if value + @scanner.scan_all(@strip_value) if @strip_value + validate_field_size(value) + end + if parse_column_end + row << value + quoted_fields << @quoted_column_value + elsif parse_row_end + if row.empty? and value.nil? + emit_row([], &block) unless @skip_blanks + else + row << value + quoted_fields << @quoted_column_value + emit_row(row, quoted_fields, &block) + row = [] + quoted_fields.clear + end + skip_needless_lines + start_row + elsif @scanner.eos? + break if row.empty? and value.nil? + row << value + quoted_fields << @quoted_column_value + emit_row(row, quoted_fields, &block) + break + else + if @quoted_column_value + if liberal_parsing? and (new_line = @scanner.check(@line_end)) + message = + "Illegal end-of-line sequence outside of a quoted field " + + "<#{new_line.inspect}>" + else + message = "Any value after quoted field isn't allowed" + end + ignore_broken_line + raise MalformedCSVError.new(message, @lineno) + elsif @unquoted_column_value and + (new_line = @scanner.scan(@line_end)) + ignore_broken_line + message = "Unquoted fields do not allow new line " + + "<#{new_line.inspect}>" + raise MalformedCSVError.new(message, @lineno) + elsif @scanner.rest.start_with?(@quote_character) + ignore_broken_line + message = "Illegal quoting" + raise MalformedCSVError.new(message, @lineno) + elsif (new_line = @scanner.scan(@line_end)) + ignore_broken_line + message = "New line must be <#{@row_separator.inspect}> " + + "not <#{new_line.inspect}>" + raise MalformedCSVError.new(message, @lineno) + else + ignore_broken_line + raise MalformedCSVError.new("TODO: Meaningful message", + @lineno) + end + end + end + end + + def parse_column_value + if @liberal_parsing + quoted_value = parse_quoted_column_value + if quoted_value + @scanner.scan_all(@strip_value) if @strip_value + unquoted_value = parse_unquoted_column_value + if unquoted_value + if @double_quote_outside_quote + unquoted_value = unquoted_value.gsub(@quote_character * 2, + @quote_character) + if quoted_value.empty? # %Q{""...} case + return @quote_character + unquoted_value + end + end + @quote_character + quoted_value + @quote_character + unquoted_value + else + quoted_value + end + else + parse_unquoted_column_value + end + elsif @may_quoted + parse_quoted_column_value || + parse_unquoted_column_value + else + parse_unquoted_column_value || + parse_quoted_column_value + end + end + + def parse_unquoted_column_value + value = @scanner.scan_all(@unquoted_value) + return nil unless value + + @unquoted_column_value = true + if @first_column_separators + while true + @scanner.keep_start + is_column_end = @column_ends.all? do |column_end| + @scanner.scan(column_end) + end + @scanner.keep_back + break if is_column_end + sub_separator = @scanner.scan_all(@first_column_separators) + break if sub_separator.nil? + value << sub_separator + sub_value = @scanner.scan_all(@unquoted_value) + break if sub_value.nil? + value << sub_value + end + end + value.gsub!(@backslash_quote_character, @quote_character) if @backslash_quote + if @rstrip_value + value.gsub!(@rstrip_value, "") + end + value + end + + def parse_quoted_column_value + quotes = @scanner.scan_all(@quotes) + return nil unless quotes + + @quoted_column_value = true + n_quotes = quotes.size + if (n_quotes % 2).zero? + quotes[0, (n_quotes - 2) / 2] + else + value = quotes[0, n_quotes / 2] + while true + quoted_value = @scanner.scan_all(@quoted_value) + value << quoted_value if quoted_value + if @backslash_quote + if @scanner.scan(@escaped_backslash) + if @scanner.scan(@escaped_quote) + value << @quote_character + else + value << @backslash_character + end + next + end + end + + quotes = @scanner.scan_all(@quotes) + unless quotes + ignore_broken_line + message = "Unclosed quoted field" + raise MalformedCSVError.new(message, @lineno) + end + n_quotes = quotes.size + if n_quotes == 1 + break + else + value << quotes[0, n_quotes / 2] + break if (n_quotes % 2) == 1 + end + end + value + end + end + + def parse_column_end + return true if @scanner.scan(@column_end) + return false unless @column_ends + + @scanner.keep_start + if @column_ends.all? {|column_end| @scanner.scan(column_end)} + @scanner.keep_drop + true + else + @scanner.keep_back + false + end + end + + def parse_row_end + return true if @scanner.scan(@row_end) + return false unless @row_ends + @scanner.keep_start + if @row_ends.all? {|row_end| @scanner.scan(row_end)} + @scanner.keep_drop + true + else + @scanner.keep_back + false + end + end + + def strip_value(value) + return value unless @strip + return value if value.nil? + + case @strip + when String + while value.delete_prefix!(@strip) + # do nothing + end + while value.delete_suffix!(@strip) + # do nothing + end + else + value.strip! + end + value + end + + def ignore_broken_line + @scanner.scan_all(@not_line_end) + @scanner.scan_all(@line_end) + @lineno += 1 + end + + def start_row + if @last_line + @last_line = nil + else + @scanner.keep_drop + end + @scanner.keep_start + end + + def emit_row(row, quoted_fields=FieldsConverter::NO_QUOTED_FIELDS, &block) + @lineno += 1 + + raw_row = row + if @use_headers + if @headers.nil? + @headers = adjust_headers(row, quoted_fields) + return unless @return_headers + row = Row.new(@headers, row, true) + else + row = Row.new(@headers, + @fields_converter.convert(raw_row, @headers, @lineno, quoted_fields)) + end + else + # convert fields, if needed... + row = @fields_converter.convert(raw_row, nil, @lineno, quoted_fields) + end + + # inject unconverted fields and accessor, if requested... + if @unconverted_fields and not row.respond_to?(:unconverted_fields) + add_unconverted_fields(row, raw_row) + end + + yield(row) + end + + # This method injects an instance variable unconverted_fields into + # +row+ and an accessor method for +row+ called unconverted_fields(). The + # variable is set to the contents of +fields+. + def add_unconverted_fields(row, fields) + class << row + attr_reader :unconverted_fields + end + row.instance_variable_set(:@unconverted_fields, fields) + row + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv/row.rb b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv/row.rb new file mode 100644 index 0000000..86323f7 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv/row.rb @@ -0,0 +1,757 @@ +# frozen_string_literal: true + +require "forwardable" + +class CSV + # = \CSV::Row + # A \CSV::Row instance represents a \CSV table row. + # (see {class CSV}[../CSV.html]). + # + # The instance may have: + # - Fields: each is an object, not necessarily a \String. + # - Headers: each serves a key, and also need not be a \String. + # + # === Instance Methods + # + # \CSV::Row has three groups of instance methods: + # - Its own internally defined instance methods. + # - Methods included by module Enumerable. + # - Methods delegated to class Array.: + # * Array#empty? + # * Array#length + # * Array#size + # + # == Creating a \CSV::Row Instance + # + # Commonly, a new \CSV::Row instance is created by parsing \CSV source + # that has headers: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # table.each {|row| p row } + # Output: + # # + # # + # # + # + # You can also create a row directly. See ::new. + # + # == Headers + # + # Like a \CSV::Table, a \CSV::Row has headers. + # + # A \CSV::Row that was created by parsing \CSV source + # inherits its headers from the table: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # row = table.first + # row.headers # => ["Name", "Value"] + # + # You can also create a new row with headers; + # like the keys in a \Hash, the headers need not be Strings: + # row = CSV::Row.new([:name, :value], ['foo', 0]) + # row.headers # => [:name, :value] + # + # The new row retains its headers even if added to a table + # that has headers: + # table << row # => # + # row.headers # => [:name, :value] + # row[:name] # => "foo" + # row['Name'] # => nil + # + # + # + # == Accessing Fields + # + # You may access a field in a \CSV::Row with either its \Integer index + # (\Array-style) or its header (\Hash-style). + # + # Fetch a field using method #[]: + # row = CSV::Row.new(['Name', 'Value'], ['foo', 0]) + # row[1] # => 0 + # row['Value'] # => 0 + # + # Set a field using method #[]=: + # row = CSV::Row.new(['Name', 'Value'], ['foo', 0]) + # row # => # + # row[0] = 'bar' + # row['Value'] = 1 + # row # => # + # + class Row + # :call-seq: + # CSV::Row.new(headers, fields, header_row = false) -> csv_row + # + # Returns the new \CSV::Row instance constructed from + # arguments +headers+ and +fields+; both should be Arrays; + # note that the fields need not be Strings: + # row = CSV::Row.new(['Name', 'Value'], ['foo', 0]) + # row # => # + # + # If the \Array lengths are different, the shorter is +nil+-filled: + # row = CSV::Row.new(['Name', 'Value', 'Date', 'Size'], ['foo', 0]) + # row # => # + # + # Each \CSV::Row object is either a field row or a header row; + # by default, a new row is a field row; for the row created above: + # row.field_row? # => true + # row.header_row? # => false + # + # If the optional argument +header_row+ is given as +true+, + # the created row is a header row: + # row = CSV::Row.new(['Name', 'Value'], ['foo', 0], header_row = true) + # row # => # + # row.field_row? # => false + # row.header_row? # => true + def initialize(headers, fields, header_row = false) + @header_row = header_row + headers.each { |h| h.freeze if h.is_a? String } + + # handle extra headers or fields + @row = if headers.size >= fields.size + headers.zip(fields) + else + fields.zip(headers).each(&:reverse!) + end + end + + # Internal data format used to compare equality. + attr_reader :row + protected :row + + ### Array Delegation ### + + extend Forwardable + def_delegators :@row, :empty?, :length, :size + + # :call-seq: + # row.initialize_copy(other_row) -> self + # + # Calls superclass method. + def initialize_copy(other) + super_return_value = super + @row = @row.collect(&:dup) + super_return_value + end + + # :call-seq: + # row.header_row? -> true or false + # + # Returns +true+ if this is a header row, +false+ otherwise. + def header_row? + @header_row + end + + # :call-seq: + # row.field_row? -> true or false + # + # Returns +true+ if this is a field row, +false+ otherwise. + def field_row? + not header_row? + end + + # :call-seq: + # row.headers -> array_of_headers + # + # Returns the headers for this row: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # row = table.first + # row.headers # => ["Name", "Value"] + def headers + @row.map(&:first) + end + + # :call-seq: + # field(index) -> value + # field(header) -> value + # field(header, offset) -> value + # + # Returns the field value for the given +index+ or +header+. + # + # --- + # + # Fetch field value by \Integer index: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row.field(0) # => "foo" + # row.field(1) # => "bar" + # + # Counts backward from the last column if +index+ is negative: + # row.field(-1) # => "0" + # row.field(-2) # => "foo" + # + # Returns +nil+ if +index+ is out of range: + # row.field(2) # => nil + # row.field(-3) # => nil + # + # --- + # + # Fetch field value by header (first found): + # source = "Name,Name,Name\nFoo,Bar,Baz\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row.field('Name') # => "Foo" + # + # Fetch field value by header, ignoring +offset+ leading fields: + # source = "Name,Name,Name\nFoo,Bar,Baz\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row.field('Name', 2) # => "Baz" + # + # Returns +nil+ if the header does not exist. + def field(header_or_index, minimum_index = 0) + # locate the pair + finder = (header_or_index.is_a?(Integer) || header_or_index.is_a?(Range)) ? :[] : :assoc + pair = @row[minimum_index..-1].public_send(finder, header_or_index) + + # return the field if we have a pair + if pair.nil? + nil + else + header_or_index.is_a?(Range) ? pair.map(&:last) : pair.last + end + end + alias_method :[], :field + + # + # :call-seq: + # fetch(header) -> value + # fetch(header, default) -> value + # fetch(header) {|row| ... } -> value + # + # Returns the field value as specified by +header+. + # + # --- + # + # With the single argument +header+, returns the field value + # for that header (first found): + # source = "Name,Name,Name\nFoo,Bar,Baz\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row.fetch('Name') # => "Foo" + # + # Raises exception +KeyError+ if the header does not exist. + # + # --- + # + # With arguments +header+ and +default+ given, + # returns the field value for the header (first found) + # if the header exists, otherwise returns +default+: + # source = "Name,Name,Name\nFoo,Bar,Baz\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row.fetch('Name', '') # => "Foo" + # row.fetch(:nosuch, '') # => "" + # + # --- + # + # With argument +header+ and a block given, + # returns the field value for the header (first found) + # if the header exists; otherwise calls the block + # and returns its return value: + # source = "Name,Name,Name\nFoo,Bar,Baz\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row.fetch('Name') {|header| fail 'Cannot happen' } # => "Foo" + # row.fetch(:nosuch) {|header| "Header '#{header} not found'" } # => "Header 'nosuch not found'" + def fetch(header, *varargs) + raise ArgumentError, "Too many arguments" if varargs.length > 1 + pair = @row.assoc(header) + if pair + pair.last + else + if block_given? + yield header + elsif varargs.empty? + raise KeyError, "key not found: #{header}" + else + varargs.first + end + end + end + + # :call-seq: + # row.has_key?(header) -> true or false + # + # Returns +true+ if there is a field with the given +header+, + # +false+ otherwise. + def has_key?(header) + !!@row.assoc(header) + end + alias_method :include?, :has_key? + alias_method :key?, :has_key? + alias_method :member?, :has_key? + alias_method :header?, :has_key? + + # + # :call-seq: + # row[index] = value -> value + # row[header, offset] = value -> value + # row[header] = value -> value + # + # Assigns the field value for the given +index+ or +header+; + # returns +value+. + # + # --- + # + # Assign field value by \Integer index: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row[0] = 'Bat' + # row[1] = 3 + # row # => # + # + # Counts backward from the last column if +index+ is negative: + # row[-1] = 4 + # row[-2] = 'Bam' + # row # => # + # + # Extends the row with nil:nil if positive +index+ is not in the row: + # row[4] = 5 + # row # => # + # + # Raises IndexError if negative +index+ is too small (too far from zero). + # + # --- + # + # Assign field value by header (first found): + # source = "Name,Name,Name\nFoo,Bar,Baz\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row['Name'] = 'Bat' + # row # => # + # + # Assign field value by header, ignoring +offset+ leading fields: + # source = "Name,Name,Name\nFoo,Bar,Baz\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row['Name', 2] = 4 + # row # => # + # + # Append new field by (new) header: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row['New'] = 6 + # row# => # + def []=(*args) + value = args.pop + + if args.first.is_a? Integer + if @row[args.first].nil? # extending past the end with index + @row[args.first] = [nil, value] + @row.map! { |pair| pair.nil? ? [nil, nil] : pair } + else # normal index assignment + @row[args.first][1] = value + end + else + index = index(*args) + if index.nil? # appending a field + self << [args.first, value] + else # normal header assignment + @row[index][1] = value + end + end + end + + # + # :call-seq: + # row << [header, value] -> self + # row << hash -> self + # row << value -> self + # + # Adds a field to +self+; returns +self+: + # + # If the argument is a 2-element \Array [header, value], + # a field is added with the given +header+ and +value+: + # source = "Name,Name,Name\nFoo,Bar,Baz\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row << ['NAME', 'Bat'] + # row # => # + # + # If the argument is a \Hash, each key-value pair is added + # as a field with header +key+ and value +value+. + # source = "Name,Name,Name\nFoo,Bar,Baz\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row << {NAME: 'Bat', name: 'Bam'} + # row # => # + # + # Otherwise, the given +value+ is added as a field with no header. + # source = "Name,Name,Name\nFoo,Bar,Baz\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row << 'Bag' + # row # => # + def <<(arg) + if arg.is_a?(Array) and arg.size == 2 # appending a header and name + @row << arg + elsif arg.is_a?(Hash) # append header and name pairs + arg.each { |pair| @row << pair } + else # append field value + @row << [nil, arg] + end + + self # for chaining + end + + # :call-seq: + # row.push(*values) -> self + # + # Appends each of the given +values+ to +self+ as a field; returns +self+: + # source = "Name,Name,Name\nFoo,Bar,Baz\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row.push('Bat', 'Bam') + # row # => # + def push(*args) + args.each { |arg| self << arg } + + self # for chaining + end + + # + # :call-seq: + # delete(index) -> [header, value] or nil + # delete(header) -> [header, value] or empty_array + # delete(header, offset) -> [header, value] or empty_array + # + # Removes a specified field from +self+; returns the 2-element \Array + # [header, value] if the field exists. + # + # If an \Integer argument +index+ is given, + # removes and returns the field at offset +index+, + # or returns +nil+ if the field does not exist: + # source = "Name,Name,Name\nFoo,Bar,Baz\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row.delete(1) # => ["Name", "Bar"] + # row.delete(50) # => nil + # + # Otherwise, if the single argument +header+ is given, + # removes and returns the first-found field with the given header, + # of returns a new empty \Array if the field does not exist: + # source = "Name,Name,Name\nFoo,Bar,Baz\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row.delete('Name') # => ["Name", "Foo"] + # row.delete('NAME') # => [] + # + # If argument +header+ and \Integer argument +offset+ are given, + # removes and returns the first-found field with the given header + # whose +index+ is at least as large as +offset+: + # source = "Name,Name,Name\nFoo,Bar,Baz\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row.delete('Name', 1) # => ["Name", "Bar"] + # row.delete('NAME', 1) # => [] + def delete(header_or_index, minimum_index = 0) + if header_or_index.is_a? Integer # by index + @row.delete_at(header_or_index) + elsif i = index(header_or_index, minimum_index) # by header + @row.delete_at(i) + else + [ ] + end + end + + # :call-seq: + # row.delete_if {|header, value| ... } -> self + # + # Removes fields from +self+ as selected by the block; returns +self+. + # + # Removes each field for which the block returns a truthy value: + # source = "Name,Name,Name\nFoo,Bar,Baz\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row.delete_if {|header, value| value.start_with?('B') } # => true + # row # => # + # row.delete_if {|header, value| header.start_with?('B') } # => false + # + # If no block is given, returns a new Enumerator: + # row.delete_if # => #:delete_if> + def delete_if(&block) + return enum_for(__method__) { size } unless block_given? + + @row.delete_if(&block) + + self # for chaining + end + + # :call-seq: + # self.fields(*specifiers) -> array_of_fields + # + # Returns field values per the given +specifiers+, which may be any mixture of: + # - \Integer index. + # - \Range of \Integer indexes. + # - 2-element \Array containing a header and offset. + # - Header. + # - \Range of headers. + # + # For +specifier+ in one of the first four cases above, + # returns the result of self.field(specifier); see #field. + # + # Although there may be any number of +specifiers+, + # the examples here will illustrate one at a time. + # + # When the specifier is an \Integer +index+, + # returns self.field(index)L + # source = "Name,Name,Name\nFoo,Bar,Baz\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row.fields(1) # => ["Bar"] + # + # When the specifier is a \Range of \Integers +range+, + # returns self.field(range): + # row.fields(1..2) # => ["Bar", "Baz"] + # + # When the specifier is a 2-element \Array +array+, + # returns self.field(array)L + # row.fields('Name', 1) # => ["Foo", "Bar"] + # + # When the specifier is a header +header+, + # returns self.field(header)L + # row.fields('Name') # => ["Foo"] + # + # When the specifier is a \Range of headers +range+, + # forms a new \Range +new_range+ from the indexes of + # range.start and range.end, + # and returns self.field(new_range): + # source = "Name,NAME,name\nFoo,Bar,Baz\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row.fields('Name'..'NAME') # => ["Foo", "Bar"] + # + # Returns all fields if no argument given: + # row.fields # => ["Foo", "Bar", "Baz"] + def fields(*headers_and_or_indices) + if headers_and_or_indices.empty? # return all fields--no arguments + @row.map(&:last) + else # or work like values_at() + all = [] + headers_and_or_indices.each do |h_or_i| + if h_or_i.is_a? Range + index_begin = h_or_i.begin.is_a?(Integer) ? h_or_i.begin : + index(h_or_i.begin) + index_end = h_or_i.end.is_a?(Integer) ? h_or_i.end : + index(h_or_i.end) + new_range = h_or_i.exclude_end? ? (index_begin...index_end) : + (index_begin..index_end) + all.concat(fields.values_at(new_range)) + else + all << field(*Array(h_or_i)) + end + end + return all + end + end + alias_method :values_at, :fields + + # :call-seq: + # index(header) -> index + # index(header, offset) -> index + # + # Returns the index for the given header, if it exists; + # otherwise returns +nil+. + # + # With the single argument +header+, returns the index + # of the first-found field with the given +header+: + # source = "Name,Name,Name\nFoo,Bar,Baz\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row.index('Name') # => 0 + # row.index('NAME') # => nil + # + # With arguments +header+ and +offset+, + # returns the index of the first-found field with given +header+, + # but ignoring the first +offset+ fields: + # row.index('Name', 1) # => 1 + # row.index('Name', 3) # => nil + def index(header, minimum_index = 0) + # find the pair + index = headers[minimum_index..-1].index(header) + # return the index at the right offset, if we found one + index.nil? ? nil : index + minimum_index + end + + # :call-seq: + # row.field?(value) -> true or false + # + # Returns +true+ if +value+ is a field in this row, +false+ otherwise: + # source = "Name,Name,Name\nFoo,Bar,Baz\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row.field?('Bar') # => true + # row.field?('BAR') # => false + def field?(data) + fields.include? data + end + + include Enumerable + + # :call-seq: + # row.each {|header, value| ... } -> self + # + # Calls the block with each header-value pair; returns +self+: + # source = "Name,Name,Name\nFoo,Bar,Baz\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row.each {|header, value| p [header, value] } + # Output: + # ["Name", "Foo"] + # ["Name", "Bar"] + # ["Name", "Baz"] + # + # If no block is given, returns a new Enumerator: + # row.each # => #:each> + def each(&block) + return enum_for(__method__) { size } unless block_given? + + @row.each(&block) + + self # for chaining + end + + alias_method :each_pair, :each + + # :call-seq: + # row == other -> true or false + # + # Returns +true+ if +other+ is a /CSV::Row that has the same + # fields (headers and values) in the same order as +self+; + # otherwise returns +false+: + # source = "Name,Name,Name\nFoo,Bar,Baz\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # other_row = table[0] + # row == other_row # => true + # other_row = table[1] + # row == other_row # => false + def ==(other) + return @row == other.row if other.is_a? CSV::Row + @row == other + end + + # :call-seq: + # row.to_h -> hash + # + # Returns the new \Hash formed by adding each header-value pair in +self+ + # as a key-value pair in the \Hash. + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row.to_h # => {"Name"=>"foo", "Value"=>"0"} + # + # Header order is preserved, but repeated headers are ignored: + # source = "Name,Name,Name\nFoo,Bar,Baz\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row.to_h # => {"Name"=>"Foo"} + def to_h + hash = {} + each do |key, _value| + hash[key] = self[key] unless hash.key?(key) + end + hash + end + alias_method :to_hash, :to_h + + # :call-seq: + # row.deconstruct_keys(keys) -> hash + # + # Returns the new \Hash suitable for pattern matching containing only the + # keys specified as an argument. + def deconstruct_keys(keys) + if keys.nil? + to_h + else + keys.to_h { |key| [key, self[key]] } + end + end + + alias_method :to_ary, :to_a + + # :call-seq: + # row.deconstruct -> array + # + # Returns the new \Array suitable for pattern matching containing the values + # of the row. + def deconstruct + fields + end + + # :call-seq: + # row.to_csv -> csv_string + # + # Returns the row as a \CSV String. Headers are not included: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row.to_csv # => "foo,0\n" + def to_csv(**options) + fields.to_csv(**options) + end + alias_method :to_s, :to_csv + + # :call-seq: + # row.dig(index_or_header, *identifiers) -> object + # + # Finds and returns the object in nested object that is specified + # by +index_or_header+ and +specifiers+. + # + # The nested objects may be instances of various classes. + # See {Dig Methods}[rdoc-ref:dig_methods.rdoc]. + # + # Examples: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row.dig(1) # => "0" + # row.dig('Value') # => "0" + # row.dig(5) # => nil + def dig(index_or_header, *indexes) + value = field(index_or_header) + if value.nil? + nil + elsif indexes.empty? + value + else + unless value.respond_to?(:dig) + raise TypeError, "#{value.class} does not have \#dig method" + end + value.dig(*indexes) + end + end + + # :call-seq: + # row.inspect -> string + # + # Returns an ASCII-compatible \String showing: + # - Class \CSV::Row. + # - Header-value pairs. + # Example: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # row = table[0] + # row.inspect # => "#" + def inspect + str = ["#<", self.class.to_s] + each do |header, field| + str << " " << (header.is_a?(Symbol) ? header.to_s : header.inspect) << + ":" << field.inspect + end + str << ">" + begin + str.join('') + rescue # any encoding error + str.map do |s| + e = Encoding::Converter.asciicompat_encoding(s.encoding) + e ? s.encode(e) : s.force_encoding("ASCII-8BIT") + end.join('') + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv/table.rb b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv/table.rb new file mode 100644 index 0000000..fb19f54 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv/table.rb @@ -0,0 +1,1055 @@ +# frozen_string_literal: true + +require "forwardable" + +class CSV + # = \CSV::Table + # A \CSV::Table instance represents \CSV data. + # (see {class CSV}[../CSV.html]). + # + # The instance may have: + # - Rows: each is a Table::Row object. + # - Headers: names for the columns. + # + # === Instance Methods + # + # \CSV::Table has three groups of instance methods: + # - Its own internally defined instance methods. + # - Methods included by module Enumerable. + # - Methods delegated to class Array.: + # * Array#empty? + # * Array#length + # * Array#size + # + # == Creating a \CSV::Table Instance + # + # Commonly, a new \CSV::Table instance is created by parsing \CSV source + # using headers: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # table.class # => CSV::Table + # + # You can also create an instance directly. See ::new. + # + # == Headers + # + # If a table has headers, the headers serve as labels for the columns of data. + # Each header serves as the label for its column. + # + # The headers for a \CSV::Table object are stored as an \Array of Strings. + # + # Commonly, headers are defined in the first row of \CSV source: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # table.headers # => ["Name", "Value"] + # + # If no headers are defined, the \Array is empty: + # table = CSV::Table.new([]) + # table.headers # => [] + # + # == Access Modes + # + # \CSV::Table provides three modes for accessing table data: + # - \Row mode. + # - Column mode. + # - Mixed mode (the default for a new table). + # + # The access mode for a\CSV::Table instance affects the behavior + # of some of its instance methods: + # - #[] + # - #[]= + # - #delete + # - #delete_if + # - #each + # - #values_at + # + # === \Row Mode + # + # Set a table to row mode with method #by_row!: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # table.by_row! # => # + # + # Specify a single row by an \Integer index: + # # Get a row. + # table[1] # => # + # # Set a row, then get it. + # table[1] = CSV::Row.new(['Name', 'Value'], ['bam', 3]) + # table[1] # => # + # + # Specify a sequence of rows by a \Range: + # # Get rows. + # table[1..2] # => [#, #] + # # Set rows, then get them. + # table[1..2] = [ + # CSV::Row.new(['Name', 'Value'], ['bat', 4]), + # CSV::Row.new(['Name', 'Value'], ['bad', 5]), + # ] + # table[1..2] # => [["Name", #], ["Value", #]] + # + # === Column Mode + # + # Set a table to column mode with method #by_col!: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # table.by_col! # => # + # + # Specify a column by an \Integer index: + # # Get a column. + # table[0] + # # Set a column, then get it. + # table[0] = ['FOO', 'BAR', 'BAZ'] + # table[0] # => ["FOO", "BAR", "BAZ"] + # + # Specify a column by its \String header: + # # Get a column. + # table['Name'] # => ["FOO", "BAR", "BAZ"] + # # Set a column, then get it. + # table['Name'] = ['Foo', 'Bar', 'Baz'] + # table['Name'] # => ["Foo", "Bar", "Baz"] + # + # === Mixed Mode + # + # In mixed mode, you can refer to either rows or columns: + # - An \Integer index refers to a row. + # - A \Range index refers to multiple rows. + # - A \String index refers to a column. + # + # Set a table to mixed mode with method #by_col_or_row!: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # table.by_col_or_row! # => # + # + # Specify a single row by an \Integer index: + # # Get a row. + # table[1] # => # + # # Set a row, then get it. + # table[1] = CSV::Row.new(['Name', 'Value'], ['bam', 3]) + # table[1] # => # + # + # Specify a sequence of rows by a \Range: + # # Get rows. + # table[1..2] # => [#, #] + # # Set rows, then get them. + # table[1] = CSV::Row.new(['Name', 'Value'], ['bat', 4]) + # table[2] = CSV::Row.new(['Name', 'Value'], ['bad', 5]) + # table[1..2] # => [["Name", #], ["Value", #]] + # + # Specify a column by its \String header: + # # Get a column. + # table['Name'] # => ["foo", "bat", "bad"] + # # Set a column, then get it. + # table['Name'] = ['Foo', 'Bar', 'Baz'] + # table['Name'] # => ["Foo", "Bar", "Baz"] + class Table + # :call-seq: + # CSV::Table.new(array_of_rows, headers = nil) -> csv_table + # + # Returns a new \CSV::Table object. + # + # - Argument +array_of_rows+ must be an \Array of CSV::Row objects. + # - Argument +headers+, if given, may be an \Array of Strings. + # + # --- + # + # Create an empty \CSV::Table object: + # table = CSV::Table.new([]) + # table # => # + # + # Create a non-empty \CSV::Table object: + # rows = [ + # CSV::Row.new([], []), + # CSV::Row.new([], []), + # CSV::Row.new([], []), + # ] + # table = CSV::Table.new(rows) + # table # => # + # + # --- + # + # If argument +headers+ is an \Array of Strings, + # those Strings become the table's headers: + # table = CSV::Table.new([], headers: ['Name', 'Age']) + # table.headers # => ["Name", "Age"] + # + # If argument +headers+ is not given and the table has rows, + # the headers are taken from the first row: + # rows = [ + # CSV::Row.new(['Foo', 'Bar'], []), + # CSV::Row.new(['foo', 'bar'], []), + # CSV::Row.new(['FOO', 'BAR'], []), + # ] + # table = CSV::Table.new(rows) + # table.headers # => ["Foo", "Bar"] + # + # If argument +headers+ is not given and the table is empty (has no rows), + # the headers are also empty: + # table = CSV::Table.new([]) + # table.headers # => [] + # + # --- + # + # Raises an exception if argument +array_of_rows+ is not an \Array object: + # # Raises NoMethodError (undefined method `first' for :foo:Symbol): + # CSV::Table.new(:foo) + # + # Raises an exception if an element of +array_of_rows+ is not a \CSV::Table object: + # # Raises NoMethodError (undefined method `headers' for :foo:Symbol): + # CSV::Table.new([:foo]) + def initialize(array_of_rows, headers: nil) + @table = array_of_rows + @headers = headers + unless @headers + if @table.empty? + @headers = [] + else + @headers = @table.first.headers + end + end + + @mode = :col_or_row + end + + # The current access mode for indexing and iteration. + attr_reader :mode + + # Internal data format used to compare equality. + attr_reader :table + protected :table + + ### Array Delegation ### + + extend Forwardable + def_delegators :@table, :empty?, :length, :size + + # :call-seq: + # table.by_col -> table_dup + # + # Returns a duplicate of +self+, in column mode + # (see {Column Mode}[#class-CSV::Table-label-Column+Mode]): + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # table.mode # => :col_or_row + # dup_table = table.by_col + # dup_table.mode # => :col + # dup_table.equal?(table) # => false # It's a dup + # + # This may be used to chain method calls without changing the mode + # (but also will affect performance and memory usage): + # dup_table.by_col['Name'] + # + # Also note that changes to the duplicate table will not affect the original. + def by_col + self.class.new(@table.dup).by_col! + end + + # :call-seq: + # table.by_col! -> self + # + # Sets the mode for +self+ to column mode + # (see {Column Mode}[#class-CSV::Table-label-Column+Mode]); returns +self+: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # table.mode # => :col_or_row + # table1 = table.by_col! + # table.mode # => :col + # table1.equal?(table) # => true # Returned self + def by_col! + @mode = :col + + self + end + + # :call-seq: + # table.by_col_or_row -> table_dup + # + # Returns a duplicate of +self+, in mixed mode + # (see {Mixed Mode}[#class-CSV::Table-label-Mixed+Mode]): + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true).by_col! + # table.mode # => :col + # dup_table = table.by_col_or_row + # dup_table.mode # => :col_or_row + # dup_table.equal?(table) # => false # It's a dup + # + # This may be used to chain method calls without changing the mode + # (but also will affect performance and memory usage): + # dup_table.by_col_or_row['Name'] + # + # Also note that changes to the duplicate table will not affect the original. + def by_col_or_row + self.class.new(@table.dup).by_col_or_row! + end + + # :call-seq: + # table.by_col_or_row! -> self + # + # Sets the mode for +self+ to mixed mode + # (see {Mixed Mode}[#class-CSV::Table-label-Mixed+Mode]); returns +self+: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true).by_col! + # table.mode # => :col + # table1 = table.by_col_or_row! + # table.mode # => :col_or_row + # table1.equal?(table) # => true # Returned self + def by_col_or_row! + @mode = :col_or_row + + self + end + + # :call-seq: + # table.by_row -> table_dup + # + # Returns a duplicate of +self+, in row mode + # (see {Row Mode}[#class-CSV::Table-label-Row+Mode]): + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # table.mode # => :col_or_row + # dup_table = table.by_row + # dup_table.mode # => :row + # dup_table.equal?(table) # => false # It's a dup + # + # This may be used to chain method calls without changing the mode + # (but also will affect performance and memory usage): + # dup_table.by_row[1] + # + # Also note that changes to the duplicate table will not affect the original. + def by_row + self.class.new(@table.dup).by_row! + end + + # :call-seq: + # table.by_row! -> self + # + # Sets the mode for +self+ to row mode + # (see {Row Mode}[#class-CSV::Table-label-Row+Mode]); returns +self+: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # table.mode # => :col_or_row + # table1 = table.by_row! + # table.mode # => :row + # table1.equal?(table) # => true # Returned self + def by_row! + @mode = :row + + self + end + + # :call-seq: + # table.headers -> array_of_headers + # + # Returns a new \Array containing the \String headers for the table. + # + # If the table is not empty, returns the headers from the first row: + # rows = [ + # CSV::Row.new(['Foo', 'Bar'], []), + # CSV::Row.new(['FOO', 'BAR'], []), + # CSV::Row.new(['foo', 'bar'], []), + # ] + # table = CSV::Table.new(rows) + # table.headers # => ["Foo", "Bar"] + # table.delete(0) + # table.headers # => ["FOO", "BAR"] + # table.delete(0) + # table.headers # => ["foo", "bar"] + # + # If the table is empty, returns a copy of the headers in the table itself: + # table.delete(0) + # table.headers # => ["Foo", "Bar"] + def headers + if @table.empty? + @headers.dup + else + @table.first.headers + end + end + + # :call-seq: + # table[n] -> row or column_data + # table[range] -> array_of_rows or array_of_column_data + # table[header] -> array_of_column_data + # + # Returns data from the table; does not modify the table. + # + # --- + # + # Fetch a \Row by Its \Integer Index:: + # - Form: table[n], +n+ an integer. + # - Access mode: :row or :col_or_row. + # - Return value: _nth_ row of the table, if that row exists; + # otherwise +nil+. + # + # Returns the _nth_ row of the table if that row exists: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # table.by_row! # => # + # table[1] # => # + # table.by_col_or_row! # => # + # table[1] # => # + # + # Counts backward from the last row if +n+ is negative: + # table[-1] # => # + # + # Returns +nil+ if +n+ is too large or too small: + # table[4] # => nil + # table[-4] # => nil + # + # Raises an exception if the access mode is :row + # and +n+ is not an \Integer: + # table.by_row! # => # + # # Raises TypeError (no implicit conversion of String into Integer): + # table['Name'] + # + # --- + # + # Fetch a Column by Its \Integer Index:: + # - Form: table[n], +n+ an \Integer. + # - Access mode: :col. + # - Return value: _nth_ column of the table, if that column exists; + # otherwise an \Array of +nil+ fields of length self.size. + # + # Returns the _nth_ column of the table if that column exists: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # table.by_col! # => # + # table[1] # => ["0", "1", "2"] + # + # Counts backward from the last column if +n+ is negative: + # table[-2] # => ["foo", "bar", "baz"] + # + # Returns an \Array of +nil+ fields if +n+ is too large or too small: + # table[4] # => [nil, nil, nil] + # table[-4] # => [nil, nil, nil] + # + # --- + # + # Fetch Rows by \Range:: + # - Form: table[range], +range+ a \Range object. + # - Access mode: :row or :col_or_row. + # - Return value: rows from the table, beginning at row range.start, + # if those rows exists. + # + # Returns rows from the table, beginning at row range.first, + # if those rows exist: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # table.by_row! # => # + # rows = table[1..2] # => # + # rows # => [#, #] + # table.by_col_or_row! # => # + # rows = table[1..2] # => # + # rows # => [#, #] + # + # If there are too few rows, returns all from range.start to the end: + # rows = table[1..50] # => # + # rows # => [#, #] + # + # Special case: if range.start == table.size, returns an empty \Array: + # table[table.size..50] # => [] + # + # If range.end is negative, calculates the ending index from the end: + # rows = table[0..-1] + # rows # => [#, #, #] + # + # If range.start is negative, calculates the starting index from the end: + # rows = table[-1..2] + # rows # => [#] + # + # If range.start is larger than table.size, returns +nil+: + # table[4..4] # => nil + # + # --- + # + # Fetch Columns by \Range:: + # - Form: table[range], +range+ a \Range object. + # - Access mode: :col. + # - Return value: column data from the table, beginning at column range.start, + # if those columns exist. + # + # Returns column values from the table, if the column exists; + # the values are arranged by row: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # table.by_col! + # table[0..1] # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] + # + # Special case: if range.start == headers.size, + # returns an \Array (size: table.size) of empty \Arrays: + # table[table.headers.size..50] # => [[], [], []] + # + # If range.end is negative, calculates the ending index from the end: + # table[0..-1] # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] + # + # If range.start is negative, calculates the starting index from the end: + # table[-2..2] # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] + # + # If range.start is larger than table.size, + # returns an \Array of +nil+ values: + # table[4..4] # => [nil, nil, nil] + # + # --- + # + # Fetch a Column by Its \String Header:: + # - Form: table[header], +header+ a \String header. + # - Access mode: :col or :col_or_row + # - Return value: column data from the table, if that +header+ exists. + # + # Returns column values from the table, if the column exists: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # table.by_col! # => # + # table['Name'] # => ["foo", "bar", "baz"] + # table.by_col_or_row! # => # + # col = table['Name'] + # col # => ["foo", "bar", "baz"] + # + # Modifying the returned column values does not modify the table: + # col[0] = 'bat' + # col # => ["bat", "bar", "baz"] + # table['Name'] # => ["foo", "bar", "baz"] + # + # Returns an \Array of +nil+ values if there is no such column: + # table['Nosuch'] # => [nil, nil, nil] + def [](index_or_header) + if @mode == :row or # by index + (@mode == :col_or_row and (index_or_header.is_a?(Integer) or index_or_header.is_a?(Range))) + @table[index_or_header] + else # by header + @table.map { |row| row[index_or_header] } + end + end + + # :call-seq: + # table[n] = row -> row + # table[n] = field_or_array_of_fields -> field_or_array_of_fields + # table[header] = field_or_array_of_fields -> field_or_array_of_fields + # + # Puts data onto the table. + # + # --- + # + # Set a \Row by Its \Integer Index:: + # - Form: table[n] = row, +n+ an \Integer, + # +row+ a \CSV::Row instance or an \Array of fields. + # - Access mode: :row or :col_or_row. + # - Return value: +row+. + # + # If the row exists, it is replaced: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # new_row = CSV::Row.new(['Name', 'Value'], ['bat', 3]) + # table.by_row! # => # + # return_value = table[0] = new_row + # return_value.equal?(new_row) # => true # Returned the row + # table[0].to_h # => {"Name"=>"bat", "Value"=>3} + # + # With access mode :col_or_row: + # table.by_col_or_row! # => # + # table[0] = CSV::Row.new(['Name', 'Value'], ['bam', 4]) + # table[0].to_h # => {"Name"=>"bam", "Value"=>4} + # + # With an \Array instead of a \CSV::Row, inherits headers from the table: + # array = ['bad', 5] + # return_value = table[0] = array + # return_value.equal?(array) # => true # Returned the array + # table[0].to_h # => {"Name"=>"bad", "Value"=>5} + # + # If the row does not exist, extends the table by adding rows: + # assigns rows with +nil+ as needed: + # table.size # => 3 + # table[5] = ['bag', 6] + # table.size # => 6 + # table[3] # => nil + # table[4]# => nil + # table[5].to_h # => {"Name"=>"bag", "Value"=>6} + # + # Note that the +nil+ rows are actually +nil+, not a row of +nil+ fields. + # + # --- + # + # Set a Column by Its \Integer Index:: + # - Form: table[n] = array_of_fields, +n+ an \Integer, + # +array_of_fields+ an \Array of \String fields. + # - Access mode: :col. + # - Return value: +array_of_fields+. + # + # If the column exists, it is replaced: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # new_col = [3, 4, 5] + # table.by_col! # => # + # return_value = table[1] = new_col + # return_value.equal?(new_col) # => true # Returned the column + # table[1] # => [3, 4, 5] + # # The rows, as revised: + # table.by_row! # => # + # table[0].to_h # => {"Name"=>"foo", "Value"=>3} + # table[1].to_h # => {"Name"=>"bar", "Value"=>4} + # table[2].to_h # => {"Name"=>"baz", "Value"=>5} + # table.by_col! # => # + # + # If there are too few values, fills with +nil+ values: + # table[1] = [0] + # table[1] # => [0, nil, nil] + # + # If there are too many values, ignores the extra values: + # table[1] = [0, 1, 2, 3, 4] + # table[1] # => [0, 1, 2] + # + # If a single value is given, replaces all fields in the column with that value: + # table[1] = 'bat' + # table[1] # => ["bat", "bat", "bat"] + # + # --- + # + # Set a Column by Its \String Header:: + # - Form: table[header] = field_or_array_of_fields, + # +header+ a \String header, +field_or_array_of_fields+ a field value + # or an \Array of \String fields. + # - Access mode: :col or :col_or_row. + # - Return value: +field_or_array_of_fields+. + # + # If the column exists, it is replaced: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # new_col = [3, 4, 5] + # table.by_col! # => # + # return_value = table['Value'] = new_col + # return_value.equal?(new_col) # => true # Returned the column + # table['Value'] # => [3, 4, 5] + # # The rows, as revised: + # table.by_row! # => # + # table[0].to_h # => {"Name"=>"foo", "Value"=>3} + # table[1].to_h # => {"Name"=>"bar", "Value"=>4} + # table[2].to_h # => {"Name"=>"baz", "Value"=>5} + # table.by_col! # => # + # + # If there are too few values, fills with +nil+ values: + # table['Value'] = [0] + # table['Value'] # => [0, nil, nil] + # + # If there are too many values, ignores the extra values: + # table['Value'] = [0, 1, 2, 3, 4] + # table['Value'] # => [0, 1, 2] + # + # If the column does not exist, extends the table by adding columns: + # table['Note'] = ['x', 'y', 'z'] + # table['Note'] # => ["x", "y", "z"] + # # The rows, as revised: + # table.by_row! + # table[0].to_h # => {"Name"=>"foo", "Value"=>0, "Note"=>"x"} + # table[1].to_h # => {"Name"=>"bar", "Value"=>1, "Note"=>"y"} + # table[2].to_h # => {"Name"=>"baz", "Value"=>2, "Note"=>"z"} + # table.by_col! + # + # If a single value is given, replaces all fields in the column with that value: + # table['Value'] = 'bat' + # table['Value'] # => ["bat", "bat", "bat"] + def []=(index_or_header, value) + if @mode == :row or # by index + (@mode == :col_or_row and index_or_header.is_a? Integer) + if value.is_a? Array + @table[index_or_header] = Row.new(headers, value) + else + @table[index_or_header] = value + end + else # set column + unless index_or_header.is_a? Integer + index = @headers.index(index_or_header) || @headers.size + @headers[index] = index_or_header + end + if value.is_a? Array # multiple values + @table.each_with_index do |row, i| + if row.header_row? + row[index_or_header] = index_or_header + else + row[index_or_header] = value[i] + end + end + else # repeated value + @table.each do |row| + if row.header_row? + row[index_or_header] = index_or_header + else + row[index_or_header] = value + end + end + end + end + end + + # :call-seq: + # table.values_at(*indexes) -> array_of_rows + # table.values_at(*headers) -> array_of_columns_data + # + # If the access mode is :row or :col_or_row, + # and each argument is either an \Integer or a \Range, + # returns rows. + # Otherwise, returns columns data. + # + # In either case, the returned values are in the order + # specified by the arguments. Arguments may be repeated. + # + # --- + # + # Returns rows as an \Array of \CSV::Row objects. + # + # No argument: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # table.values_at # => [] + # + # One index: + # values = table.values_at(0) + # values # => [#] + # + # Two indexes: + # values = table.values_at(2, 0) + # values # => [#, #] + # + # One \Range: + # values = table.values_at(1..2) + # values # => [#, #] + # + # \Ranges and indexes: + # values = table.values_at(0..1, 1..2, 0, 2) + # pp values + # Output: + # [#, + # #, + # #, + # #, + # #, + # #] + # + # --- + # + # Returns columns data as row Arrays, + # each consisting of the specified columns data for that row: + # values = table.values_at('Name') + # values # => [["foo"], ["bar"], ["baz"]] + # values = table.values_at('Value', 'Name') + # values # => [["0", "foo"], ["1", "bar"], ["2", "baz"]] + def values_at(*indices_or_headers) + if @mode == :row or # by indices + ( @mode == :col_or_row and indices_or_headers.all? do |index| + index.is_a?(Integer) or + ( index.is_a?(Range) and + index.first.is_a?(Integer) and + index.last.is_a?(Integer) ) + end ) + @table.values_at(*indices_or_headers) + else # by headers + @table.map { |row| row.values_at(*indices_or_headers) } + end + end + + # :call-seq: + # table << row_or_array -> self + # + # If +row_or_array+ is a \CSV::Row object, + # it is appended to the table: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # table << CSV::Row.new(table.headers, ['bat', 3]) + # table[3] # => # + # + # If +row_or_array+ is an \Array, it is used to create a new + # \CSV::Row object which is then appended to the table: + # table << ['bam', 4] + # table[4] # => # + def <<(row_or_array) + if row_or_array.is_a? Array # append Array + @table << Row.new(headers, row_or_array) + else # append Row + @table << row_or_array + end + + self # for chaining + end + + # + # :call-seq: + # table.push(*rows_or_arrays) -> self + # + # A shortcut for appending multiple rows. Equivalent to: + # rows.each {|row| self << row } + # + # Each argument may be either a \CSV::Row object or an \Array: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # rows = [ + # CSV::Row.new(table.headers, ['bat', 3]), + # ['bam', 4] + # ] + # table.push(*rows) + # table[3..4] # => [#, #] + def push(*rows) + rows.each { |row| self << row } + + self # for chaining + end + + # :call-seq: + # table.delete(*indexes) -> deleted_values + # table.delete(*headers) -> deleted_values + # + # If the access mode is :row or :col_or_row, + # and each argument is either an \Integer or a \Range, + # returns deleted rows. + # Otherwise, returns deleted columns data. + # + # In either case, the returned values are in the order + # specified by the arguments. Arguments may be repeated. + # + # --- + # + # Returns rows as an \Array of \CSV::Row objects. + # + # One index: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # deleted_values = table.delete(0) + # deleted_values # => [#] + # + # Two indexes: + # table = CSV.parse(source, headers: true) + # deleted_values = table.delete(2, 0) + # deleted_values # => [#, #] + # + # --- + # + # Returns columns data as column Arrays. + # + # One header: + # table = CSV.parse(source, headers: true) + # deleted_values = table.delete('Name') + # deleted_values # => ["foo", "bar", "baz"] + # + # Two headers: + # table = CSV.parse(source, headers: true) + # deleted_values = table.delete('Value', 'Name') + # deleted_values # => [["0", "1", "2"], ["foo", "bar", "baz"]] + def delete(*indexes_or_headers) + if indexes_or_headers.empty? + raise ArgumentError, "wrong number of arguments (given 0, expected 1+)" + end + deleted_values = indexes_or_headers.map do |index_or_header| + if @mode == :row or # by index + (@mode == :col_or_row and index_or_header.is_a? Integer) + @table.delete_at(index_or_header) + else # by header + if index_or_header.is_a? Integer + @headers.delete_at(index_or_header) + else + @headers.delete(index_or_header) + end + @table.map { |row| row.delete(index_or_header).last } + end + end + if indexes_or_headers.size == 1 + deleted_values[0] + else + deleted_values + end + end + + # :call-seq: + # table.delete_if {|row_or_column| ... } -> self + # + # Removes rows or columns for which the block returns a truthy value; + # returns +self+. + # + # Removes rows when the access mode is :row or :col_or_row; + # calls the block with each \CSV::Row object: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # table.by_row! # => # + # table.size # => 3 + # table.delete_if {|row| row['Name'].start_with?('b') } + # table.size # => 1 + # + # Removes columns when the access mode is :col; + # calls the block with each column as a 2-element array + # containing the header and an \Array of column fields: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # table.by_col! # => # + # table.headers.size # => 2 + # table.delete_if {|column_data| column_data[1].include?('2') } + # table.headers.size # => 1 + # + # Returns a new \Enumerator if no block is given: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # table.delete_if # => #:delete_if> + def delete_if(&block) + return enum_for(__method__) { @mode == :row or @mode == :col_or_row ? size : headers.size } unless block_given? + + if @mode == :row or @mode == :col_or_row # by index + @table.delete_if(&block) + else # by header + headers.each do |header| + delete(header) if yield([header, self[header]]) + end + end + + self # for chaining + end + + include Enumerable + + # :call-seq: + # table.each {|row_or_column| ... ) -> self + # + # Calls the block with each row or column; returns +self+. + # + # When the access mode is :row or :col_or_row, + # calls the block with each \CSV::Row object: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # table.by_row! # => # + # table.each {|row| p row } + # Output: + # # + # # + # # + # + # When the access mode is :col, + # calls the block with each column as a 2-element array + # containing the header and an \Array of column fields: + # table.by_col! # => # + # table.each {|column_data| p column_data } + # Output: + # ["Name", ["foo", "bar", "baz"]] + # ["Value", ["0", "1", "2"]] + # + # Returns a new \Enumerator if no block is given: + # table.each # => #:each> + def each(&block) + return enum_for(__method__) { @mode == :col ? headers.size : size } unless block_given? + + if @mode == :col + headers.each.with_index do |header, i| + yield([header, @table.map {|row| row[header, i]}]) + end + else + @table.each(&block) + end + + self # for chaining + end + + # :call-seq: + # table == other_table -> true or false + # + # Returns +true+ if all each row of +self+ == + # the corresponding row of +other_table+, otherwise, +false+. + # + # The access mode does no affect the result. + # + # Equal tables: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # other_table = CSV.parse(source, headers: true) + # table == other_table # => true + # + # Different row count: + # other_table.delete(2) + # table == other_table # => false + # + # Different last row: + # other_table << ['bat', 3] + # table == other_table # => false + def ==(other) + return @table == other.table if other.is_a? CSV::Table + @table == other + end + + # :call-seq: + # table.to_a -> array_of_arrays + # + # Returns the table as an \Array of \Arrays; + # the headers are in the first row: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # table.to_a # => [["Name", "Value"], ["foo", "0"], ["bar", "1"], ["baz", "2"]] + def to_a + array = [headers] + @table.each do |row| + array.push(row.fields) unless row.header_row? + end + + array + end + + # :call-seq: + # table.to_csv(**options) -> csv_string + # + # Returns the table as \CSV string. + # See {Options for Generating}[../CSV.html#class-CSV-label-Options+for+Generating]. + # + # Defaults option +write_headers+ to +true+: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # table.to_csv # => "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # + # Omits the headers if option +write_headers+ is given as +false+ + # (see {Option +write_headers+}[../CSV.html#class-CSV-label-Option+write_headers]): + # table.to_csv(write_headers: false) # => "foo,0\nbar,1\nbaz,2\n" + # + # Limit rows if option +limit+ is given like +2+: + # table.to_csv(limit: 2) # => "Name,Value\nfoo,0\nbar,1\n" + def to_csv(write_headers: true, limit: nil, **options) + array = write_headers ? [headers.to_csv(**options)] : [] + limit ||= @table.size + limit = @table.size + 1 + limit if limit < 0 + limit = 0 if limit < 0 + @table.first(limit).each do |row| + array.push(row.fields.to_csv(**options)) unless row.header_row? + end + + array.join("") + end + alias_method :to_s, :to_csv + + # + # Extracts the nested value specified by the sequence of +index+ or +header+ objects by calling dig at each step, + # returning nil if any intermediate step is nil. + # + def dig(index_or_header, *index_or_headers) + value = self[index_or_header] + if value.nil? + nil + elsif index_or_headers.empty? + value + else + unless value.respond_to?(:dig) + raise TypeError, "#{value.class} does not have \#dig method" + end + value.dig(*index_or_headers) + end + end + + # :call-seq: + # table.inspect => string + # + # Returns a US-ASCII-encoded \String showing table: + # - Class: CSV::Table. + # - Access mode: :row, :col, or :col_or_row. + # - Size: Row count, including the header row. + # + # Example: + # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" + # table = CSV.parse(source, headers: true) + # table.inspect # => "#\nName,Value\nfoo,0\nbar,1\nbaz,2\n" + # + def inspect + inspected = +"#<#{self.class} mode:#{@mode} row_count:#{to_a.size}>" + summary = to_csv(limit: 5) + inspected << "\n" << summary if summary.encoding.ascii_compatible? + inspected + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv/version.rb b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv/version.rb new file mode 100644 index 0000000..227f7f7 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv/version.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +class CSV + # The version of the installed library. + VERSION = "3.3.5" +end diff --git a/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv/writer.rb b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv/writer.rb new file mode 100644 index 0000000..b59f111 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/csv-3.3.5/lib/csv/writer.rb @@ -0,0 +1,209 @@ +# frozen_string_literal: true + +require_relative "input_record_separator" +require_relative "row" + +class CSV + # Note: Don't use this class directly. This is an internal class. + class Writer + # + # A CSV::Writer receives an output, prepares the header, format and output. + # It allows us to write new rows in the object and rewind it. + # + attr_reader :lineno + attr_reader :headers + + def initialize(output, options) + @output = output + @options = options + @lineno = 0 + @fields_converter = nil + prepare + if @options[:write_headers] and @headers + self << @headers + end + @fields_converter = @options[:fields_converter] + end + + # + # Adds a new row + # + def <<(row) + case row + when Row + row = row.fields + when Hash + row = @headers.collect {|header| row[header]} + end + + @headers ||= row if @use_headers + @lineno += 1 + + if @fields_converter + row = @fields_converter.convert(row, nil, lineno) + end + + i = -1 + converted_row = row.collect do |field| + i += 1 + quote(field, i) + end + line = converted_row.join(@column_separator) + @row_separator + if @output_encoding + line = line.encode(@output_encoding) + end + @output << line + + self + end + + # + # Winds back to the beginning + # + def rewind + @lineno = 0 + @headers = nil if @options[:headers].nil? + end + + private + def prepare + @encoding = @options[:encoding] + + prepare_header + prepare_format + prepare_output + end + + def prepare_header + headers = @options[:headers] + case headers + when Array + @headers = headers + @use_headers = true + when String + @headers = CSV.parse_line(headers, + col_sep: @options[:column_separator], + row_sep: @options[:row_separator], + quote_char: @options[:quote_character]) + @use_headers = true + when true + @headers = nil + @use_headers = true + else + @headers = nil + @use_headers = false + end + return unless @headers + + converter = @options[:header_fields_converter] + @headers = converter.convert(@headers, nil, 0, []) + @headers.each do |header| + header.freeze if header.is_a?(String) + end + end + + def prepare_force_quotes_fields(force_quotes) + @force_quotes_fields = {} + force_quotes.each do |name_or_index| + case name_or_index + when Integer + index = name_or_index + @force_quotes_fields[index] = true + when String, Symbol + name = name_or_index.to_s + if @headers.nil? + message = ":headers is required when you use field name " + + "in :force_quotes: " + + "#{name_or_index.inspect}: #{force_quotes.inspect}" + raise ArgumentError, message + end + index = @headers.index(name) + next if index.nil? + @force_quotes_fields[index] = true + else + message = ":force_quotes element must be " + + "field index or field name: " + + "#{name_or_index.inspect}: #{force_quotes.inspect}" + raise ArgumentError, message + end + end + end + + def prepare_format + @column_separator = @options[:column_separator].to_s.encode(@encoding) + row_separator = @options[:row_separator] + if row_separator == :auto + @row_separator = InputRecordSeparator.value.encode(@encoding) + else + @row_separator = row_separator.to_s.encode(@encoding) + end + @quote_character = @options[:quote_character] + force_quotes = @options[:force_quotes] + if force_quotes.is_a?(Array) + prepare_force_quotes_fields(force_quotes) + @force_quotes = false + elsif force_quotes + @force_quotes_fields = nil + @force_quotes = true + else + @force_quotes_fields = nil + @force_quotes = false + end + unless @force_quotes + @quotable_pattern = + Regexp.new("[\r\n".encode(@encoding) + + Regexp.escape(@column_separator) + + Regexp.escape(@quote_character.encode(@encoding)) + + "]".encode(@encoding)) + end + @quote_empty = @options.fetch(:quote_empty, true) + end + + def prepare_output + @output_encoding = nil + return unless @output.is_a?(StringIO) + + output_encoding = @output.internal_encoding || @output.external_encoding + if @encoding != output_encoding + if @options[:force_encoding] + @output_encoding = output_encoding + else + compatible_encoding = Encoding.compatible?(@encoding, output_encoding) + if compatible_encoding + @output.set_encoding(compatible_encoding) + @output.seek(0, IO::SEEK_END) + end + end + end + end + + def quote_field(field) + field = String(field) + encoded_quote_character = @quote_character.encode(field.encoding) + encoded_quote_character + + field.gsub(encoded_quote_character, + encoded_quote_character * 2) + + encoded_quote_character + end + + def quote(field, i) + if @force_quotes + quote_field(field) + elsif @force_quotes_fields and @force_quotes_fields[i] + quote_field(field) + else + if field.nil? # represent +nil+ fields as empty unquoted fields + "" + else + field = String(field) # Stringify fields + # represent empty fields as empty quoted fields + if (@quote_empty and field.empty?) or (field.valid_encoding? and @quotable_pattern.match?(field)) + quote_field(field) + else + field # unquoted field + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/.rspec b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/.rspec new file mode 100644 index 0000000..53607ea --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/.rspec @@ -0,0 +1 @@ +--colour diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CHANGELOG.md b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CHANGELOG.md new file mode 100644 index 0000000..c288123 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CHANGELOG.md @@ -0,0 +1,518 @@ +# Changelog + +## 1.6.2 / 2025-05-12 + +- Handle upcoming changes to the `cgi` gem in Ruby 3.5 ([#147][pull-147]) + +- Fix issues found with `htmldiff` in Ruby 1.8 (which is used approximately + never, since the code change which broke Ruby 1.8 was made 6 years ago). + [#148][pull-148] + +- Fixed some standardrb formatting and configuration issues. + +## 1.6.1 / 2025-03-25 + +- Performed further work on `Diff::LCS::Ldiff` improvements ([#46][issue-46]) + and resolve several thread safety issues cleanly by making it a class. + [#129][pull-129] + +- Restructure the project to be more consistent with the rest of the projects + that I manage. + +- Increased GitHub action security. + +- Added [trusted publishing][tp] for fully automated releases. + +## 1.6.0 / 2025-02-13 + +- Baptiste Courtois (@annih) has done significant work on making `bin/ldiff` + work better, contributing a number of issues and pull requests. These include: + + - Separation of command parsing from diff-generation in `Diff::LCS::Ldiff` + code extraction making it easier to use separately from the `bin/ldiff` + command in [#103][pull-103]. This partially resolves [#46][issue-46]. + + - Improvement of binary and empty file detection and tests in [#104][pull-104] + and [#105][pull-105]. This resolves issues [#100][issue-100], + [#102][issue-102]. + + - Various ldiff fixes for output [#101][pull-101] resolves issues + [#106][issue-106] (ldiff ed scripts are inverted), [#107][issue-107] (ldiff + hunk ranges are incorrect; regression or incorrect fix for [#60][issue-60]), + and [#95][issue-95]. + +- Patrick Linnane fixed various minor typos. [#93][pull-93] + +- Mark Young added a Changelog link to the RubyGems metadata. [#92][pull-92] + This has been modified to incorporate it into the README. + +- Updated the documentation on `Diff::LCS#lcs` to be clearer about the + requirements for object equality comparison. This resolves [#70][issue-70]. + +- Governance: + + Changes described here are effective 2024-12-31. + + - Update gem management details to use markdown files for everything, enabled + in part by [flavorjones/hoe-markdown][hoe-markdown]. Several files were + renamed to be more consistent with standard practices. + + - Updated security notes with an [age][age] public key rather than pointing to + Keybase.io and a PGP public key which I no longer use. The use of the + [Tidelift security contact][tidelift] is recommended over direct disclosure. + +## 1.5.1 / 2024-01-31 + +- Peter Goldstein updated CI configuration to add Ruby 3.1 and Masato Nakamura + added Ruby 3.2 and 3.3. [#82][pull-82], [#89][pull-89] + +- Switched to [standard ruby][standard ruby] formatting. + +- Justin Steele converted the licence file to Markdown. [#84][pull-84] + +- Updated the gem SPDX identifier for GPL 2.0 or later, resolving [#86][pull-86] + by Vit Ondruch. + +- Resolve a potential security issue with `ldiff` in its use of `IO.read` + instead of `File.read`. [#91][issue-91] + +- Added MFA authentication requirement for release to RubyGems. [#90][pull-90] + +- Added Dependabot management for actions and gems. [#90][pull-90] + +- Updated CodeQL configuration. [#90][pull-90] + +## 1.5.0 / 2021-12-23 + +- Updated the CI configuration and monkey-patch Hoe. + +- Kenichi Kamiya fixed a test configuration deprecation in SimpleCov. + [#69][pull-69] + +- Tien introduced several corrections and code improvements: + + - Removed an off-by-one error when calculating an index value by embracing + Ruby iteration properly. This had a side-effect of fixing a long-standing + bug in `#traverse_sequences` where the traversal would not be transitive. + That is, `LCS(s2, s1)` should produce a sequence that is transitive with + `LCS(s1, s2)` on traversal, and applying the diff computed from those + results would result in equivalent changes that could be played forward or + backward as appropriate. [#71][pull-71], [#75][pull-75] + + - The above fix resulted in a changed order of the longest common subsequence + when callbacks were applied. After analysis, it was determined that the + computed subsequence was _equivalent_ to the prior version, so the test was + updated. This also resulted in the clarification of documentation when + traversing the sub-sequences. [#79][pull-79] + + - An infinite loop case in the case where `Diff::LCS` would be included into + an enumerable class has been fixed. [#73][pull-73] + + - Clarified the purpose of a threshold test in calculation of LCS. + [#72][pull-72], [#80][pull-80] + +- Removed autotest directory + +## 1.4.4 / 2020-07-01 + +- Fixed an issue reported by Jun Aruga in the `Diff::LCS::Ldiff` binary text + detection. [#44][issue-44] + +- Fixed a theoretical issue reported by Jun Aruga in `Diff::LCS::Hunk` to raise + a more useful exception. [#43][issue-43] + +- Added documentation that should address custom object issues as reported in + [#35][issue-35]. + +- Fixed more diff errors, in part reported in [#65][issue-65]. + + - The use of `Numeric#abs` is incorrect in `Diff::LCS::Block#diff_size`. The + diff size _must_ be accurate for correct change placement. + + - When selecting `@max_diff_size` in `Diff::LCS::Hunk`, choose it based on + `block.diff_size.abs`. + + - Made a number of changes that will, unfortunately, increase allocations at + the cost of being safe with frozen strings. + + - Add some knowledge that when `Diff::LCS::Hunk#diff` is called, that we are + processing the _last_ hunk, so some changes will be made to how the output + is generated. + + - `old`, `ed`, and `reverse_ed` formats have no differences. + + - `unified` format will report `\ No newline at end of file` given the + correct conditions, at most once. Unified range reporting also differs for + the last hunk such that the `length` of the range is reduced by one. + + - `context` format will report `\No newline at end of file` given the + correct conditions, up to once per "file". Context range reporting also + differs for the last hunk such that the `end` part of the range is reduced + by one to a minimum of one. + +- Added a bunch more tests for the cases above, and fixed `hunk_spec.rb` so that + the phrase being compared isn't nonsense French. + +- Updated formatting. + +- Added a Rake task to assist with manual testing on Ruby 1.8. + +## 1.4.3 / 2020-06-29 + +- Fixed several issues with 1.4 on Rubies older than 2.0. Some of this was + providing useful shim functions to Hoe 3.x (which dropped these older Rubies a + while ago). Specifically: + + - Removed Array#lazy from a method in `Diff::LCS::Hunk`. + + - Changed some unit tests to use old-style Symbol-keyed hashes. + + - Changed some unit test helper functions to no longer use keyword parameters, + but only a trailing options hash. + + - Made the use of `psych` dependent on `RUBY_VERSION >= 1.9`. + + Resolves [#63][issue-63]. + +## 1.4.2 / 2020-06-23 + +- Camille Drapier fixed a small issue with RuboCop configuration. [#59][pull-59] + +- Applied another fix (and unit test) to fix an issue for the Chef team. + [#60][issue-60], [#61][pull-61] + +## 1.4.1 / 2020-06-23 + +- Fix an issue where diff sizes could be negative, and they should be. + [#57][issue-57], [#58][pull-58] + +## 1.4 / 2020-06-23 + +- Ruby versions lower than 2.4 are soft-deprecated and will not be run as part + of the CI process any longer. + +- Akinora MUSHA (knu) added the ability for `Diff::LCS::Change` objects to be + implicitly treated arrays. Originally provided as pull request [#47][pull-47], + but it introduced a number of test failures as documented in [#48][issue-48], + and remediation of `Diff::LCS` itself was introduced in [#49][pull-49]. + +- Resolved [#5][issue-05] with some tests comparing output from `system` calls + to `bin/ldiff` with some pre-generated output. Resolved [#6][issue-06] with + these tests. + +- Resolved a previously undetected `bin/ldiff` issue with `--context` output not + matching `diff --context` output. + +- Resolved an issue with later versions of Ruby not working with an `OptParse` + specification of `Numeric`; this has been changed to `Integer`. + +- Brandon Fish added TruffleRuby in [#52][pull-52]. + +- Fixed two missing classes as reported in [#53][issue-53]. + +## 1.3 / 2017-01-18 + +- Bugs fixed: + + - Fixed an error for `bin/ldiff --version`. Fixes issue [#21][issue-21]. + + - Force `Diff::LCS::Change` and `Diff::LCS::ContextChange` to only perform + equality comparisons against themselves. Provided by Kevin Mook in pull + request [#29][pull-29]. + + - Fix tab expansion in `htmldiff`, provided by Mark Friedgan in pull request + [#25][pull-25]. + + - Silence Ruby 2.4 `Fixnum` deprecation warnings. Fixes issue [#38][issue-38] + and pull request [#36][pull-36]. + + - Ensure that test dependencies are loaded properly. Fixes issue + [#33][issue-33] and pull request [#34][pull-34]. + + - Fix issue [#1][issue-01] with incorrect intuition of patch direction. + Tentative fix, but the previous failure cases pass now. + +- Tooling changes: + + - Added SimpleCov and Coveralls support. + + - Change the homepage (temporarily) to the GitHub repo. + + - Updated testing and gem infrastructure. + + - Modernized the specs. + +- Cleaned up documentation. + +- Added a Code of Conduct. + +## 1.2.5 / 2013-11-08 + +- Bugs fixed: + + - Comparing arrays flattened them too far, especially with `Diff::LCS.sdiff`. + Fixed by Josh Bronson in pull request [#23][pull-23]. + +## 1.2.4 / 2013-04-20 + +- Bugs fixed: + + - A bug was introduced after 1.1.3 when pruning common sequences at the start + of comparison. Paul Kunysch (@pck) fixed this in pull request + [#18][pull-18]. Thanks! + + - The Rubinius (1.9 mode) bug in [rubinius/rubinius#2268][rubinius#2268] has + been fixed by the Rubinius team two days after it was filed. Thanks for + fixing this so quickly! + +- Switching to Raggi's hoe-gemspec2 for gemspec generation. + +## 1.2.3 / 2013-04-11 + +- Bugs Fixed: + + - The new encoding detection for diff output generation (added in 1.2.2) + introduced a bug if the left side of the comparison was the empty set. + Originally found in [rspec/rspec-expectations#238][rspec-expectations#238] + and [rspec/rspec-expectations#239][rspec-expectations#239]. Jon Rowe + developed a reasonable heuristic (left side, right side, empty string + literal) to avoid this bug. + + - There is a known issue with Rubinius in 1.9 mode reported in + [rubinius/rubinius#2268][rubinius#2268] and demonstrated in the Travis CI + builds. For all other tested platforms, diff-lcs is considered stable. As + soon as a suitably small test-case can be created for the Rubinius team to + examine, this will be added to the Rubinius issue around this. + +## 1.2.2 / 2013-03-30 + +- Bugs Fixed: + + - `Diff::LCS::Hunk` could not properly generate a difference for comparison + sets that are not US-ASCII-compatible because of the use of literal regular + expressions and strings. Jon Rowe found this in + [rspec/rspec-expectations#219][rspec-expectations#219] and provided a first + pass implementation in pull request [#15][pull-15]. I've reworked it because + of test failures in Rubinius when running in Ruby 1.9 mode. This coerces the + added values to the encoding of the old dataset (as determined by the first + piece of the old dataset). + + - Adding Travis CI testing for Ruby 2.0. + +## 1.2.1 / 2013-02-09 + +- Bugs Fixed: + + - As seen in [rspec/rspec-expectations#200][rspec-expectations#200], the + release of `Diff::LCS` 1.2 introduced an unnecessary public API change to + `Diff::LCS::Hunk` (see the change at + [rspec/rspec-expectations@3d6fc82c][rspec-expectations@3d6fc82c] for + details). The new method name (and behaviour) is more correct, but I should + not have renamed the function or should have at least provided an alias. + This release restores `Diff::LCS::Hunk#unshift` as an alias to #merge. Note + that the old `#unshift` behaviour was incorrect and will not be restored. + +## 1.2.0 / 2013-01-21 + +- Minor Enhancements: + + - Added special case handling for `Diff::LCS.patch` so that it handles patches + that are empty or contain no changes. + + - Added two new methods (`#patch_me` and `#unpatch_me`) to the include-able + module. + +- Bugs Fixed: + + - Fixed issue [#1][issue-01] patch direction detection. + + - Resolved issue [#2][issue-02] by handling `string[string.size, 1]` properly + (it returns `""` not `nil`). + + - Michael Granger (ged) fixed an implementation error in `Diff::LCS::Change` + and added specs in pull request [#8][pull-08]. Thanks! + + - Made the code auto-testable. + + - Vít Ondruch (voxik) provided the latest version of the GPL2 license file in + pull request [#10][pull-10]. Thanks! + + - Fixed a documentation issue with the include-able versions of `#patch!` and + `#unpatch!` where they implied that they would replace the original value. + Given that `Diff::LCS.patch` always returns a copy, the documentation was + incorrect and has been corrected. To provide the behaviour that was + originally documented, two new methods were added to provide this behaviour. + Found by scooter-dangle in issue [#12][issue-12]. Thanks! + +- Code Style Changes: + + - Removed trailing spaces. + + - Calling class methods using `.` instead of `::`. + + - Vít Ondruch (voxik) removed unnecessary shebangs in pull request + [#9][pull-09]. Thanks! + + - Kenichi Kamiya (kachick) removed some warnings of an unused variable in + lucky pull request [#13][pull-13]. Thanks! + + - Embarked on a major refactoring to make the files a little more manageable + and understand the code on a deeper level. + + - Adding CI via Travis CI. + +## 1.1.3 / 2011-08-27 + +- Converted to 'hoe' for release. + +- Converted tests to RSpec 2. + +- Extracted the body of `htmldiff` into a class available from + `diff/lcs/htmldiff`. + +- Migrated development and issue tracking to GitHub. + +- Bugs fixed: + + - Eliminated the explicit use of RubyGems in both `bin/htmldiff` and + `bin/ldiff`. Resolves issue [#4][issue-04]. + + - Eliminated Ruby warnings. Resolves issue [#3][issue-03]. + +## 1.1.2 / 2004-10-20 + +- Fixed a problem reported by Mauricio Fernandez in `htmldiff`. + +## 1.1.1 / 2004-09-25 + +- Fixed bug #891 (Set returned from patch command does not contain last equal + part). + +- Fixed a problem with callback initialisation code (it assumed that all + callbacks passed as classes can be initialised; now, it rescues NoMethodError + in the event of private :new being called). + +- Modified the non-initialisable callbacks to have a private `#new` method. + +- Moved `ldiff` core code to `Diff::LCS::Ldiff` (`diff/lcs/ldiff.rb`). + +## 1.1.0 + +- Eliminated the need for `Diff::LCS::Event` and removed it. + +- Added a contextual diff callback, `Diff::LCS::ContextDiffCallback`. + +- Implemented (un-)patching for standard diff callback output formats with both + `#diff` and `#sdiff`. + +- Extensive documentation changes. + +## 1.0.4 + +- Fixed a problem with `bin/ldiff` output, especially for unified format. + Newlines that should have been present weren't. + +- Changed the `.tar.gz` installer to generate Windows batch files if ones do not + exist already. Removed the existing batch files as they didn't work. + +## 1.0.3 + +- Fixed a problem with `#traverse_sequences` where the first difference from the + left sequence might not be appropriately captured. + +## 1.0.2 + +- Fixed an issue with `ldiff` not working because actions were changed from + symbols to strings. + +## 1.0.1 + +- Minor modifications to the `gemspec`, the `README`. + +- Renamed the diff program to `ldiff` (as well as the companion batch file) so + as to not collide with the standard diff program. + +- Fixed issues with RubyGems. Requires RubyGems > 0.6.1 or >= 0.6.1 with the + latest CVS version. + +## 1.0 + +- Initial release based mostly on Perl's Algorithm::Diff. + +[age]: https://github.com/FiloSottile/age +[hoe-halostatue]: https://github.com/halostatue/hoe-halostatue +[hoe-markdown]: https://github.com/flavorjones/hoe-markdown +[issue-01]: https://github.com/halostatue/diff-lcs/issues/1 +[issue-02]: https://github.com/halostatue/diff-lcs/issues/2 +[issue-03]: https://github.com/halostatue/diff-lcs/issues/3 +[issue-04]: https://github.com/halostatue/diff-lcs/issues/4 +[issue-05]: https://github.com/halostatue/diff-lcs/issues/5 +[issue-06]: https://github.com/halostatue/diff-lcs/issues/6 +[issue-12]: https://github.com/halostatue/diff-lcs/issues/12 +[issue-21]: https://github.com/halostatue/diff-lcs/issues/21 +[issue-33]: https://github.com/halostatue/diff-lcs/issues/33 +[issue-35]: https://github.com/halostatue/diff-lcs/issues/35 +[issue-38]: https://github.com/halostatue/diff-lcs/issues/38 +[issue-43]: https://github.com/halostatue/diff-lcs/issues/43 +[issue-44]: https://github.com/halostatue/diff-lcs/issues/44 +[issue-46]: https://github.com/halostatue/diff-lcs/issues/46 +[issue-48]: https://github.com/halostatue/diff-lcs/issues/48 +[issue-53]: https://github.com/halostatue/diff-lcs/issues/53 +[issue-57]: https://github.com/halostatue/diff-lcs/issues/57 +[issue-60]: https://github.com/halostatue/diff-lcs/issues/60 +[issue-63]: https://github.com/halostatue/diff-lcs/issues/63 +[issue-65]: https://github.com/halostatue/diff-lcs/issues/65 +[issue-70]: https://github.com/halostatue/diff-lcs/issues/70 +[issue-91]: https://github.com/halostatue/diff-lcs/issues/91 +[issue-95]: https://github.com/halostatue/diff-lcs/issues/95 +[issue-100]: https://github.com/halostatue/diff-lcs/issues/100 +[issue-102]: https://github.com/halostatue/diff-lcs/issues/102 +[issue-106]: https://github.com/halostatue/diff-lcs/issues/106 +[issue-107]: https://github.com/halostatue/diff-lcs/issues/107 +[pull-08]: https://github.com/halostatue/diff-lcs/pull/8 +[pull-09]: https://github.com/halostatue/diff-lcs/pull/9 +[pull-10]: https://github.com/halostatue/diff-lcs/pull/10 +[pull-13]: https://github.com/halostatue/diff-lcs/pull/13 +[pull-15]: https://github.com/halostatue/diff-lcs/pull/15 +[pull-18]: https://github.com/halostatue/diff-lcs/pull/18 +[pull-23]: https://github.com/halostatue/diff-lcs/pull/23 +[pull-25]: https://github.com/halostatue/diff-lcs/pull/25 +[pull-29]: https://github.com/halostatue/diff-lcs/pull/29 +[pull-34]: https://github.com/halostatue/diff-lcs/pull/34 +[pull-36]: https://github.com/halostatue/diff-lcs/pull/36 +[pull-47]: https://github.com/halostatue/diff-lcs/pull/47 +[pull-49]: https://github.com/halostatue/diff-lcs/pull/49 +[pull-52]: https://github.com/halostatue/diff-lcs/pull/52 +[pull-58]: https://github.com/halostatue/diff-lcs/pull/58 +[pull-59]: https://github.com/halostatue/diff-lcs/pull/59 +[pull-61]: https://github.com/halostatue/diff-lcs/pull/61 +[pull-69]: https://github.com/halostatue/diff-lcs/pull/69 +[pull-71]: https://github.com/halostatue/diff-lcs/pull/71 +[pull-72]: https://github.com/halostatue/diff-lcs/pull/72 +[pull-73]: https://github.com/halostatue/diff-lcs/pull/73 +[pull-75]: https://github.com/halostatue/diff-lcs/pull/75 +[pull-79]: https://github.com/halostatue/diff-lcs/pull/79 +[pull-80]: https://github.com/halostatue/diff-lcs/pull/80 +[pull-82]: https://github.com/halostatue/diff-lcs/pull/82 +[pull-84]: https://github.com/halostatue/diff-lcs/pull/84 +[pull-86]: https://github.com/halostatue/diff-lcs/pull/86 +[pull-89]: https://github.com/halostatue/diff-lcs/pull/89 +[pull-90]: https://github.com/halostatue/diff-lcs/pull/90 +[pull-92]: https://github.com/halostatue/diff-lcs/pull/92 +[pull-93]: https://github.com/halostatue/diff-lcs/pull/93 +[pull-101]: https://github.com/halostatue/diff-lcs/pull/101 +[pull-103]: https://github.com/halostatue/diff-lcs/pull/103 +[pull-104]: https://github.com/halostatue/diff-lcs/pull/104 +[pull-105]: https://github.com/halostatue/diff-lcs/pull/105 +[pull-129]: https://github.com/halostatue/diff-lcs/pull/129 +[pull-147]: https://github.com/halostatue/diff-lcs/pull/147 +[pull-148]: https://github.com/halostatue/diff-lcs/pull/148 +[rspec-expectations#200]: https://github.com/rspec/rspec-expectations/pull/200 +[rspec-expectations#219]: https://github.com/rspec/rspec-expectations/issues/219 +[rspec-expectations#238]: https://github.com/rspec/rspec-expectations/issues/238 +[rspec-expectations#239]: https://github.com/rspec/rspec-expectations/issues/239 +[rspec-expectations@3d6fc82c]: https://github.com/rspec/rspec-expectations/commit/3d6fc82c +[rubinius#2268]: https://github.com/rubinius/rubinius/issues/2268 +[standard ruby]: https://github.com/standardrb/standard +[tidelift]: https://tidelift.com/security +[tp]: https://guides.rubygems.org/trusted-publishing/ diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CODE_OF_CONDUCT.md b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..184b5fb --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +- Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +- The use of sexualized language or imagery, and sexual attention or advances of + any kind +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email address, + without their explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official email address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at [INSERT CONTACT +METHOD]. All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +. Translations are available at +. + +[homepage]: https://www.contributor-covenant.org +[Mozilla CoC]: https://github.com/mozilla/diversity diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CONTRIBUTING.md b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CONTRIBUTING.md new file mode 100644 index 0000000..4bcde4b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CONTRIBUTING.md @@ -0,0 +1,71 @@ +# Contributing + +Contribution to diff-lcs is encouraged in any form: a bug report, a feature +request, or code contributions. There are a few DOs and DON'Ts for +contributions. + +- DO: + + - Keep the coding style that already exists for any updated Ruby code (support + or otherwise). I use [Standard Ruby][standardrb] for linting and formatting. + + - Use thoughtfully-named topic branches for contributions. Rebase your commits + into logical chunks as necessary. + + - Use [quality commit messages][qcm]. + + - Add your name or GitHub handle to `CONTRIBUTORS.md` and a record in the + `CHANGELOG.md` as a separate commit from your main change. (Follow the style + in the `CHANGELOG.md` and provide a link to your PR.) + + - Add or update tests as appropriate for your change. The test suite is + written in [RSpec][rspec]. + + - Add or update documentation as appropriate for your change. The + documentation is RDoc; diff-lcs does not use extensions that may be present + in alternative documentation generators. + +- DO NOT: + + - Modify `VERSION` in `lib/diff/lcs/version.rb`. When your patch is accepted + and a release is made, the version will be updated at that point. + + - Modify `diff-lcs.gemspec`; it is a generated file. (You _may_ use + `rake gemspec` to regenerate it if your change involves metadata related to + gem itself). + + - Modify the `Gemfile`. + +## Test Dependencies + +diff-lcs uses Ryan Davis's [Hoe][Hoe] to manage the release process, and it adds +a number of rake tasks. You will mostly be interested in `rake`, which runs +tests in the same way that `rake spec` does. + +To assist with the installation of the development dependencies for diff-lcs, I +have provided a Gemfile pointing to the (generated) `diff-lcs.gemspec` file. +`minitar.gemspec` file. This will permit you to use `bundle install` to install +the dependencies. + +You can run tests with code coverage analysis by running `rake spec:coverage`. + +## Workflow + +Here's the most direct way to get your work merged into the project: + +- Fork the project. +- Clone your fork (`git clone git://github.com//diff-lcs.git`). +- Create a topic branch to contain your change + (`git checkout -b my_awesome_feature`). +- Hack away, add tests. Not necessarily in that order. +- Make sure everything still passes by running `rake`. +- If necessary, rebase your commits into logical chunks, without errors. +- Push the branch up (`git push origin my_awesome_feature`). +- Create a pull request against halostatue/diff-lcs and describe what your + change does and the why you think it should be merged. + +[hoe]: https://github.com/seattlerb/hoe +[qcm]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html +[release-gem]: https://github.com/rubygems/release-gem +[rspec]: http://rspec.info/documentation/ +[standardrb]: https://github.com/standardrb/standard diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CONTRIBUTORS.md b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CONTRIBUTORS.md new file mode 100644 index 0000000..9053019 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/CONTRIBUTORS.md @@ -0,0 +1,49 @@ +# Contributors + +- Austin Ziegler (@halostatue) created diff-lcs. + +Thanks to everyone else who has contributed to diff-lcs over the years: + +- @ginriki +- @joshbronson +- @kevinmook +- @mckaz +- Akinori Musha +- Artem Ignatyev +- Brandon Fish +- Baptiste Courtois (@annih) +- Camille Drapier +- Cédric Boutillier +- @earlopain +- Gregg Kellogg +- Jagdeep Singh +- Jason Gladish +- Jon Rowe +- Josef Strzibny +- Josep (@apuratepp) +- Josh Bronson +- Jun Aruga +- Justin Steele +- Kenichi Kamiya +- Kensuke Nagae +- Kevin Ansfield +- Koichi Ito +- Mark Friedgan +- Masato Nakamura +- Mark Young +- Michael Granger +- Myron Marston +- Nicolas Leger +- Oleg Orlov +- Patrick Linnane +- Paul Kunysch +- Pete Higgins +- Peter Goldstein +- Peter Wagenet +- Philippe Lafoucrière +- Ryan Lovelett +- Scott Steele +- Simon Courtois +- Tien (@tiendo1011) +- Tomas Jura +- Vít Ondruch diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/LICENCE.md b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/LICENCE.md new file mode 100644 index 0000000..c57c3f1 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/LICENCE.md @@ -0,0 +1,40 @@ +# Licence + +This software is available under three licenses: the GNU GPL version 2 (or at +your option, a later version), the Perl Artistic license, or the MIT license. +Note that my preference for licensing is the MIT license, but Algorithm::Diff +was dually originally licensed with the Perl Artistic and the GNU GPL ("the same +terms as Perl itself") and given that the Ruby implementation originally hewed +pretty closely to the Perl version, I must maintain the additional licensing +terms. + +- Copyright 2004–2025 Austin Ziegler and contributors. +- Adapted from Algorithm::Diff (Perl) by Ned Konz and a Smalltalk version by + Mario I. Wolczko. + +## MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +## Perl Artistic License + +See the file docs/artistic.txt in the main distribution. + +## GNU GPL version 2 + +See the file docs/COPYING.txt in the main distribution. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/Manifest.txt b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/Manifest.txt new file mode 100644 index 0000000..fe58c86 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/Manifest.txt @@ -0,0 +1,115 @@ +.rspec +CHANGELOG.md +CODE_OF_CONDUCT.md +CONTRIBUTING.md +CONTRIBUTORS.md +LICENCE.md +Manifest.txt +README.md +Rakefile +SECURITY.md +bin/htmldiff +bin/ldiff +docs/COPYING.txt +docs/artistic.txt +lib/diff-lcs.rb +lib/diff/lcs.rb +lib/diff/lcs/array.rb +lib/diff/lcs/backports.rb +lib/diff/lcs/block.rb +lib/diff/lcs/callbacks.rb +lib/diff/lcs/change.rb +lib/diff/lcs/htmldiff.rb +lib/diff/lcs/hunk.rb +lib/diff/lcs/internals.rb +lib/diff/lcs/ldiff.rb +lib/diff/lcs/string.rb +lib/diff/lcs/version.rb +mise.toml +spec/change_spec.rb +spec/diff_spec.rb +spec/fixtures/123_x +spec/fixtures/456_x +spec/fixtures/aX +spec/fixtures/bXaX +spec/fixtures/ds1.csv +spec/fixtures/ds2.csv +spec/fixtures/empty +spec/fixtures/file1.bin +spec/fixtures/file2.bin +spec/fixtures/four_lines +spec/fixtures/four_lines_with_missing_new_line +spec/fixtures/ldiff/diff.missing_new_line1-e +spec/fixtures/ldiff/diff.missing_new_line1-f +spec/fixtures/ldiff/diff.missing_new_line2-e +spec/fixtures/ldiff/diff.missing_new_line2-f +spec/fixtures/ldiff/error.diff.chef-e +spec/fixtures/ldiff/error.diff.chef-f +spec/fixtures/ldiff/error.diff.missing_new_line1-e +spec/fixtures/ldiff/error.diff.missing_new_line1-f +spec/fixtures/ldiff/error.diff.missing_new_line2-e +spec/fixtures/ldiff/error.diff.missing_new_line2-f +spec/fixtures/ldiff/output.diff +spec/fixtures/ldiff/output.diff-c +spec/fixtures/ldiff/output.diff-e +spec/fixtures/ldiff/output.diff-f +spec/fixtures/ldiff/output.diff-u +spec/fixtures/ldiff/output.diff.bin1 +spec/fixtures/ldiff/output.diff.bin1-c +spec/fixtures/ldiff/output.diff.bin1-e +spec/fixtures/ldiff/output.diff.bin1-f +spec/fixtures/ldiff/output.diff.bin1-u +spec/fixtures/ldiff/output.diff.bin2 +spec/fixtures/ldiff/output.diff.bin2-c +spec/fixtures/ldiff/output.diff.bin2-e +spec/fixtures/ldiff/output.diff.bin2-f +spec/fixtures/ldiff/output.diff.bin2-u +spec/fixtures/ldiff/output.diff.chef +spec/fixtures/ldiff/output.diff.chef-c +spec/fixtures/ldiff/output.diff.chef-e +spec/fixtures/ldiff/output.diff.chef-f +spec/fixtures/ldiff/output.diff.chef-u +spec/fixtures/ldiff/output.diff.chef2 +spec/fixtures/ldiff/output.diff.chef2-c +spec/fixtures/ldiff/output.diff.chef2-d +spec/fixtures/ldiff/output.diff.chef2-e +spec/fixtures/ldiff/output.diff.chef2-f +spec/fixtures/ldiff/output.diff.chef2-u +spec/fixtures/ldiff/output.diff.empty.vs.four_lines +spec/fixtures/ldiff/output.diff.empty.vs.four_lines-c +spec/fixtures/ldiff/output.diff.empty.vs.four_lines-e +spec/fixtures/ldiff/output.diff.empty.vs.four_lines-f +spec/fixtures/ldiff/output.diff.empty.vs.four_lines-u +spec/fixtures/ldiff/output.diff.four_lines.vs.empty +spec/fixtures/ldiff/output.diff.four_lines.vs.empty-c +spec/fixtures/ldiff/output.diff.four_lines.vs.empty-e +spec/fixtures/ldiff/output.diff.four_lines.vs.empty-f +spec/fixtures/ldiff/output.diff.four_lines.vs.empty-u +spec/fixtures/ldiff/output.diff.issue95_trailing_context +spec/fixtures/ldiff/output.diff.issue95_trailing_context-c +spec/fixtures/ldiff/output.diff.issue95_trailing_context-e +spec/fixtures/ldiff/output.diff.issue95_trailing_context-f +spec/fixtures/ldiff/output.diff.issue95_trailing_context-u +spec/fixtures/ldiff/output.diff.missing_new_line1 +spec/fixtures/ldiff/output.diff.missing_new_line1-c +spec/fixtures/ldiff/output.diff.missing_new_line1-e +spec/fixtures/ldiff/output.diff.missing_new_line1-f +spec/fixtures/ldiff/output.diff.missing_new_line1-u +spec/fixtures/ldiff/output.diff.missing_new_line2 +spec/fixtures/ldiff/output.diff.missing_new_line2-c +spec/fixtures/ldiff/output.diff.missing_new_line2-e +spec/fixtures/ldiff/output.diff.missing_new_line2-f +spec/fixtures/ldiff/output.diff.missing_new_line2-u +spec/fixtures/new-chef +spec/fixtures/new-chef2 +spec/fixtures/old-chef +spec/fixtures/old-chef2 +spec/hunk_spec.rb +spec/issues_spec.rb +spec/lcs_spec.rb +spec/ldiff_spec.rb +spec/patch_spec.rb +spec/sdiff_spec.rb +spec/spec_helper.rb +spec/traverse_balanced_spec.rb +spec/traverse_sequences_spec.rb diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/README.md b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/README.md new file mode 100644 index 0000000..6583803 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/README.md @@ -0,0 +1,92 @@ +# Diff::LCS + +- home :: https://github.com/halostatue/diff-lcs +- changelog :: https://github.com/halostatue/diff-lcs/blob/main/CHANGELOG.md +- code :: https://github.com/halostatue/diff-lcs +- bugs :: https://github.com/halostatue/diff-lcs/issues +- rdoc :: http://rubydoc.info/github/halostatue/diff-lcs + + + + + +## Description + +Diff::LCS computes the difference between two Enumerable sequences using the +McIlroy-Hunt longest common subsequence (LCS) algorithm. It includes utilities +to create a simple HTML diff output format and a standard diff-like tool. + +This is release 1.6.1, providing a simple extension that allows for +Diff::LCS::Change objects to be treated implicitly as arrays and fixes a number +of formatting issues. + +Ruby versions below 2.5 are soft-deprecated, which means that older versions are +no longer part of the CI test suite. If any changes have been introduced that +break those versions, bug reports and patches will be accepted, but it will be +up to the reporter to verify any fixes prior to release. The next major release +will completely break compatibility. + +## Synopsis + +Using this module is quite simple. By default, Diff::LCS does not extend objects +with the Diff::LCS interface, but will be called as if it were a function: + +```ruby +require 'diff/lcs' + +seq1 = %w(a b c e h j l m n p) +seq2 = %w(b c d e f j k l m r s t) + +lcs = Diff::LCS.LCS(seq1, seq2) +diffs = Diff::LCS.diff(seq1, seq2) +sdiff = Diff::LCS.sdiff(seq1, seq2) +seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj) +bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj) +seq2 == Diff::LCS.patch!(seq1, diffs) +seq1 == Diff::LCS.unpatch!(seq2, diffs) +seq2 == Diff::LCS.patch!(seq1, sdiff) +seq1 == Diff::LCS.unpatch!(seq2, sdiff) +``` + +Objects can be extended with Diff::LCS: + +```ruby +seq1.extend(Diff::LCS) +lcs = seq1.lcs(seq2) +diffs = seq1.diff(seq2) +sdiff = seq1.sdiff(seq2) +seq = seq1.traverse_sequences(seq2, callback_obj) +bal = seq1.traverse_balanced(seq2, callback_obj) +seq2 == seq1.patch!(diffs) +seq1 == seq2.unpatch!(diffs) +seq2 == seq1.patch!(sdiff) +seq1 == seq2.unpatch!(sdiff) +``` + +By requiring 'diff/lcs/array' or 'diff/lcs/string', Array or String will be +extended for use this way. + +Note that Diff::LCS requires a sequenced enumerable container, which means that +the order of enumeration is both predictable and consistent for the same set of +data. While it is theoretically possible to generate a diff for an unordered +hash, it will only be meaningful if the enumeration of the hashes is consistent. +In general, this will mean that containers that behave like String or Array will +perform best. + +## History + +Diff::LCS is a port of Perl's Algorithm::Diff that uses the McIlroy-Hunt longest +common subsequence (LCS) algorithm to compute intelligent differences between +two sequenced enumerable containers. The implementation is based on Mario I. +Wolczko's [Smalltalk version 1.2][smalltalk] (1993) and Ned Konz's Perl version +[Algorithm::Diff 1.15][perl]. `Diff::LCS#sdiff` and +`Diff::LCS#traverse_balanced` were originally written for the Perl version by +Mike Schilli. + +The algorithm is described in A Fast Algorithm for Computing Longest Common +Subsequences, CACM, vol.20, no.5, pp.350-353, May 1977, with a few minor +improvements to improve the speed. A simplified description of the algorithm, +originally written for the Perl version, was written by Mark-Jason Dominus. + +[smalltalk]: ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st +[perl]: http://search.cpan.org/~nedkonz/Algorithm-Diff-1.15/ diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/Rakefile b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/Rakefile new file mode 100644 index 0000000..0bfe927 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/Rakefile @@ -0,0 +1,115 @@ +require "rubygems" +require "rspec" +require "rspec/core/rake_task" +require "hoe" +require "rake/clean" + +MAINTENANCE = ENV["MAINTENANCE"] == "true" +BUILD_DOCS = MAINTENANCE || ENV["DOCS"] == "true" +TRUSTED_RELEASE = ENV["rubygems_release_gem"] == "true" + +Hoe.plugin :halostatue +Hoe.plugin :rubygems + +Hoe.plugins.delete :debug +Hoe.plugins.delete :newb +Hoe.plugins.delete :signing +Hoe.plugins.delete :publish unless BUILD_DOCS + +if RUBY_VERSION < "1.9" + class Array # :nodoc: + def to_h + Hash[*flatten(1)] + end + end + + class Gem::Specification # :nodoc: + def metadata=(*) + end + + def default_value(*) + end + end + + class Object # :nodoc: + def caller_locations(*) + [] + end + end +end + +_spec = Hoe.spec "diff-lcs" do + developer("Austin Ziegler", "halostatue@gmail.com") + + self.trusted_release = TRUSTED_RELEASE + + require_ruby_version ">= 1.8" + + self.history_file = "CHANGELOG.md" + self.readme_file = "README.md" + self.licenses = ["MIT", "Artistic-1.0-Perl", "GPL-2.0-or-later"] + + spec_extras[:metadata] = ->(val) { + val["rubygems_mfa_required"] = "true" + } + + extra_dev_deps << ["hoe", "~> 4.0"] + extra_dev_deps << ["hoe-halostatue", "~> 2.0"] + extra_dev_deps << ["hoe-rubygems", "~> 1.0"] + extra_dev_deps << ["rspec", ">= 2.0", "< 4"] + extra_dev_deps << ["rake", ">= 10.0", "< 14"] + extra_dev_deps << ["rdoc", ">= 6.3.1", "< 7"] +end + +if BUILD_DOCS + rake_tasks = Rake.application.instance_variable_get(:@tasks) + tasks = ["publish_docs", "publish_on_announce", "debug_email", "post_blog", "announce"] + tasks.each do |task| + rake_tasks.delete(task) + end +end + +desc "Run all specifications" +RSpec::Core::RakeTask.new(:spec) do |t| + rspec_dirs = %w[spec lib].join(":") + t.rspec_opts = ["-I#{rspec_dirs}"] +end + +task :version do + require "diff/lcs/version" + puts Diff::LCS::VERSION +end + +Rake::Task["spec"].actions.uniq! { |a| a.source_location } + +# standard:disable Style/HashSyntax +task :default => :spec unless Rake::Task["default"].prereqs.include?("spec") +task :test => :spec unless Rake::Task["test"].prereqs.include?("spec") +# standard:enable Style/HashSyntax + +if RUBY_VERSION >= "3.0" && RUBY_ENGINE == "ruby" + namespace :spec do + desc "Runs test coverage. Only works Ruby 2.0+ and assumes 'simplecov' is installed." + task :coverage do + ENV["COVERAGE"] = "true" + Rake::Task["spec"].execute + end + end +end + +if MAINTENANCE + task ruby18: :package do + require "diff/lcs/version" + # standard:disable Layout/HeredocIndentation + puts <<-MESSAGE +You are starting a barebones Ruby 1.8 docker environment for testing. +A snapshot package has been built, so install it with: + + cd diff-lcs + gem install pkg/diff-lcs-#{Diff::LCS::VERSION} + + MESSAGE + # standard:enable Layout/HeredocIndentation + sh "docker run -it --rm -v #{Dir.pwd}:/root/diff-lcs bellbind/docker-ruby18-rails2 bash -l" + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/SECURITY.md b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/SECURITY.md new file mode 100644 index 0000000..16854f6 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/SECURITY.md @@ -0,0 +1,41 @@ +# diff-lcs Security + +## Supported Versions + +Security reports are accepted for the most recent major release and the previous +version for a limited time after the initial major release version. After a +major release, the previous version will receive full support for six months and +security support for an additional six months (for a total of twelve months). + +Because diff-lcs 1.x supports a wide range of Ruby versions, security reports +will only be accepted when they can be demonstrated on Ruby 3.1 or higher. + +> [!information] +> +> There will be a diff-lcs 2.0 released in 2025 which narrows support to modern +> versions of Ruby only. +> +> | Release Date | Support Ends | Security Support Ends | +> | ------------ | ------------ | --------------------- | +> | 2025 | +6 months | +12 months | +> +> If the 2.0.0 release happens on 2025-07-01, regular support for diff-lcs 1.x +> will end on 2026-12-31 and security support for diff-lcs 1.x will end on +> 2026-06-30. + +## Reporting a Vulnerability + +By preference, use the [Tidelift security contact][tidelift]. Tidelift will +coordinate the fix and disclosure. + +Alternatively, Send an email to [diff-lcs@halostatue.ca][email] with the text +`Diff::LCS` in the subject. Emails sent to this address should be encrypted +using [age][age] with the following public key: + +``` +age1fc6ngxmn02m62fej5cl30lrvwmxn4k3q2atqu53aatekmnqfwumqj4g93w +``` + +[tidelift]: https://tidelift.com/security +[email]: mailto:diff-lcs@halostatue.ca +[age]: https://github.com/FiloSottile/age diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/bin/htmldiff b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/bin/htmldiff new file mode 100755 index 0000000..bcd89d2 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/bin/htmldiff @@ -0,0 +1,35 @@ +#! /usr/bin/env ruby -w +# frozen_string_literal: true + +require "diff/lcs" +require "diff/lcs/htmldiff" + +begin + require "text/format" +rescue LoadError + Diff::LCS::HTMLDiff.can_expand_tabs = false +end + +if ARGV.size < 2 or ARGV.size > 3 + warn "usage: #{File.basename($0)} old new [output.html]" + warn " #{File.basename($0)} old new > output.html" + exit 127 +end + +left = IO.read(ARGV[0]).split($/) +right = IO.read(ARGV[1]).split($/) + +options = { :title => "diff #{ARGV[0]} #{ARGV[1]}" } + +htmldiff = Diff::LCS::HTMLDiff.new(left, right, options) + +if ARGV[2] + File.open(ARGV[2], "w") do |f| + htmldiff.options[:output] = f + htmldiff.run + end +else + htmldiff.run +end + +# vim: ft=ruby diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/bin/ldiff b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/bin/ldiff new file mode 100755 index 0000000..f4734f5 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/bin/ldiff @@ -0,0 +1,9 @@ +#! /usr/bin/env ruby -w +# frozen_string_literal: true + +require 'diff/lcs' +require 'diff/lcs/ldiff' + +exit Diff::LCS::Ldiff.run(ARGV) + +# vim: ft=ruby diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/docs/COPYING.txt b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/docs/COPYING.txt new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/docs/COPYING.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/docs/artistic.txt b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/docs/artistic.txt new file mode 100644 index 0000000..763e17a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/docs/artistic.txt @@ -0,0 +1,127 @@ +The "Artistic License" + + Preamble + +The intent of this document is to state the conditions under which a +Package may be copied, such that the Copyright Holder maintains some +semblance of artistic control over the development of the package, +while giving the users of the package the right to use and distribute +the Package in a more-or-less customary fashion, plus the right to make +reasonable modifications. + +Definitions: + + "Package" refers to the collection of files distributed by the + Copyright Holder, and derivatives of that collection of files + created through textual modification. + + "Standard Version" refers to such a Package if it has not been + modified, or has been modified in accordance with the wishes + of the Copyright Holder as specified below. + + "Copyright Holder" is whoever is named in the copyright or + copyrights for the package. + + "You" is you, if you're thinking about copying or distributing + this Package. + + "Reasonable copying fee" is whatever you can justify on the + basis of media cost, duplication charges, time of people involved, + and so on. (You will not be required to justify it to the + Copyright Holder, but only to the computing community at large + as a market that must bear the fee.) + + "Freely Available" means that no fee is charged for the item + itself, though there may be fees involved in handling the item. + It also means that recipients of the item may redistribute it + under the same conditions they received it. + +1. You may make and give away verbatim copies of the source form of the +Standard Version of this Package without restriction, provided that you +duplicate all of the original copyright notices and associated disclaimers. + +2. You may apply bug fixes, portability fixes and other modifications +derived from the Public Domain or from the Copyright Holder. A Package +modified in such a way shall still be considered the Standard Version. + +3. You may otherwise modify your copy of this Package in any way, provided +that you insert a prominent notice in each changed file stating how and +when you changed that file, and provided that you do at least ONE of the +following: + + a) place your modifications in the Public Domain or otherwise make them + Freely Available, such as by posting said modifications to Usenet or + an equivalent medium, or placing the modifications on a major archive + site such as uunet.uu.net, or by allowing the Copyright Holder to include + your modifications in the Standard Version of the Package. + + b) use the modified Package only within your corporation or organization. + + c) rename any non-standard executables so the names do not conflict + with standard executables, which must also be provided, and provide + a separate manual page for each non-standard executable that clearly + documents how it differs from the Standard Version. + + d) make other distribution arrangements with the Copyright Holder. + +4. You may distribute the programs of this Package in object code or +executable form, provided that you do at least ONE of the following: + + a) distribute a Standard Version of the executables and library files, + together with instructions (in the manual page or equivalent) on where + to get the Standard Version. + + b) accompany the distribution with the machine-readable source of + the Package with your modifications. + + c) give non-standard executables non-standard names, and clearly + document the differences in manual pages (or equivalent), together + with instructions on where to get the Standard Version. + + d) make other distribution arrangements with the Copyright Holder. + +5. You may charge a reasonable copying fee for any distribution of this +Package. You may charge any fee you choose for support of this +Package. You may not charge a fee for this Package itself. However, +you may distribute this Package in aggregate with other (possibly +commercial) programs as part of a larger (possibly commercial) software +distribution provided that you do not advertise this Package as a +product of your own. You may embed this Package's interpreter within +an executable of yours (by linking); this shall be construed as a mere +form of aggregation, provided that the complete Standard Version of the +interpreter is so embedded. + +6. The scripts and library files supplied as input to or produced as +output from the programs of this Package do not automatically fall +under the copyright of this Package, but belong to whoever generated +them, and may be sold commercially, and may be aggregated with this +Package. If such scripts or library files are aggregated with this +Package via the so-called "undump" or "unexec" methods of producing a +binary executable image, then distribution of such an image shall +neither be construed as a distribution of this Package nor shall it +fall under the restrictions of Paragraphs 3 and 4, provided that you do +not represent such an executable image as a Standard Version of this +Package. + +7. C subroutines (or comparably compiled subroutines in other +languages) supplied by you and linked into this Package in order to +emulate subroutines and variables of the language defined by this +Package shall not be considered part of this Package, but are the +equivalent of input as in Paragraph 6, provided these subroutines do +not change the language in any way that would cause it to fail the +regression tests for the language. + +8. Aggregation of this Package with a commercial distribution is always +permitted provided that the use of this Package is embedded; that is, +when no overt attempt is made to make this Package's interfaces visible +to the end user of the commercial distribution. Such use shall not be +construed as a distribution of this Package. + +9. The name of the Copyright Holder may not be used to endorse or promote +products derived from this software without specific prior written permission. + +10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + + The End diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff-lcs.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff-lcs.rb new file mode 100644 index 0000000..bc07bf9 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff-lcs.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +require "diff/lcs" diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs.rb new file mode 100644 index 0000000..5ee8937 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs.rb @@ -0,0 +1,742 @@ +# frozen_string_literal: true + +module Diff; end unless defined? Diff + +# == How Diff Works (by Mark-Jason Dominus) +# +# I once read an article written by the authors of +diff+; they said that they +# hard worked very hard on the algorithm until they found the right one. +# +# I think what they ended up using (and I hope someone will correct me, because +# I am not very confident about this) was the `longest common subsequence' +# method. In the LCS problem, you have two sequences of items: +# +# a b c d f g h j q z +# a b c d e f g i j k r x y z +# +# and you want to find the longest sequence of items that is present in both +# original sequences in the same order. That is, you want to find a new +# sequence *S* which can be obtained from the first sequence by deleting some +# items, and from the second sequence by deleting other items. You also want +# *S* to be as long as possible. In this case *S* is: +# +# a b c d f g j z +# +# From there it's only a small step to get diff-like output: +# +# e h i k q r x y +# + - + + - + + + +# +# This module solves the LCS problem. It also includes a canned function to +# generate +diff+-like output. +# +# It might seem from the example above that the LCS of two sequences is always +# pretty obvious, but that's not always the case, especially when the two +# sequences have many repeated elements. For example, consider +# +# a x b y c z p d q +# a b c a x b y c z +# +# A naive approach might start by matching up the +a+ and +b+ that appear at +# the beginning of each sequence, like this: +# +# a x b y c z p d q +# a b c a b y c z +# +# This finds the common subsequence +a b c z+. But actually, the LCS is +a x b +# y c z+: +# +# a x b y c z p d q +# a b c a x b y c z +module Diff::LCS +end + +require "diff/lcs/version" +require "diff/lcs/callbacks" +require "diff/lcs/internals" + +module Diff::LCS + # Returns an Array containing the longest common subsequence(s) between + # +self+ and +other+. See Diff::LCS#lcs. + # + # lcs = seq1.lcs(seq2) + # + # A note when using objects: Diff::LCS only works properly when each object + # can be used as a key in a Hash. This means that those objects must implement + # the methods +#hash+ and +#eql?+ such that two objects containing identical values + # compare identically for key purposes. That is: + # + # O.new('a').eql?(O.new('a')) == true && + # O.new('a').hash == O.new('a').hash + def lcs(other, &block) # :yields: self[i] if there are matched subsequences + Diff::LCS.lcs(self, other, &block) + end + + # Returns the difference set between +self+ and +other+. See Diff::LCS#diff. + def diff(other, callbacks = nil, &block) + Diff::LCS.diff(self, other, callbacks, &block) + end + + # Returns the balanced ("side-by-side") difference set between +self+ and + # +other+. See Diff::LCS#sdiff. + def sdiff(other, callbacks = nil, &block) + Diff::LCS.sdiff(self, other, callbacks, &block) + end + + # Traverses the discovered longest common subsequences between +self+ and + # +other+. See Diff::LCS#traverse_sequences. + def traverse_sequences(other, callbacks = nil, &block) + Diff::LCS.traverse_sequences(self, other, callbacks || Diff::LCS::SequenceCallbacks, &block) + end + + # Traverses the discovered longest common subsequences between +self+ and + # +other+ using the alternate, balanced algorithm. See + # Diff::LCS#traverse_balanced. + def traverse_balanced(other, callbacks = nil, &block) + Diff::LCS.traverse_balanced(self, other, callbacks || Diff::LCS::BalancedCallbacks, &block) + end + + # Attempts to patch +self+ with the provided +patchset+. A new sequence based + # on +self+ and the +patchset+ will be created. See Diff::LCS#patch. Attempts + # to autodiscover the direction of the patch. + def patch(patchset) + Diff::LCS.patch(self, patchset) + end + alias_method :unpatch, :patch + + # Attempts to patch +self+ with the provided +patchset+. A new sequence based + # on +self+ and the +patchset+ will be created. See Diff::LCS#patch. Does no + # patch direction autodiscovery. + def patch!(patchset) + Diff::LCS.patch!(self, patchset) + end + + # Attempts to unpatch +self+ with the provided +patchset+. A new sequence + # based on +self+ and the +patchset+ will be created. See Diff::LCS#unpatch. + # Does no patch direction autodiscovery. + def unpatch!(patchset) + Diff::LCS.unpatch!(self, patchset) + end + + # Attempts to patch +self+ with the provided +patchset+, using #patch!. If + # the sequence this is used on supports #replace, the value of +self+ will be + # replaced. See Diff::LCS#patch. Does no patch direction autodiscovery. + def patch_me(patchset) + if respond_to? :replace + replace(patch!(patchset)) + else + patch!(patchset) + end + end + + # Attempts to unpatch +self+ with the provided +patchset+, using #unpatch!. + # If the sequence this is used on supports #replace, the value of +self+ will + # be replaced. See Diff::LCS#unpatch. Does no patch direction autodiscovery. + def unpatch_me(patchset) + if respond_to? :replace + replace(unpatch!(patchset)) + else + unpatch!(patchset) + end + end +end + +class << Diff::LCS + def lcs(seq1, seq2, &block) # :yields: seq1[i] for each matched + matches = Diff::LCS::Internals.lcs(seq1, seq2) + ret = [] + string = seq1.is_a? String + matches.each_index do |i| + next if matches[i].nil? + + v = string ? seq1[i, 1] : seq1[i] + v = block[v] if block + ret << v + end + ret + end + alias_method :LCS, :lcs + + # #diff computes the smallest set of additions and deletions necessary to + # turn the first sequence into the second, and returns a description of these + # changes. + # + # See Diff::LCS::DiffCallbacks for the default behaviour. An alternate + # behaviour may be implemented with Diff::LCS::ContextDiffCallbacks. If a + # Class argument is provided for +callbacks+, #diff will attempt to + # initialise it. If the +callbacks+ object (possibly initialised) responds to + # #finish, it will be called. + def diff(seq1, seq2, callbacks = nil, &block) # :yields: diff changes + diff_traversal(:diff, seq1, seq2, callbacks || Diff::LCS::DiffCallbacks, &block) + end + + # #sdiff computes all necessary components to show two sequences and their + # minimized differences side by side, just like the Unix utility + # sdiff does: + # + # old < - + # same same + # before | after + # - > new + # + # See Diff::LCS::SDiffCallbacks for the default behaviour. An alternate + # behaviour may be implemented with Diff::LCS::ContextDiffCallbacks. If a + # Class argument is provided for +callbacks+, #diff will attempt to + # initialise it. If the +callbacks+ object (possibly initialised) responds to + # #finish, it will be called. + # + # Each element of a returned array is a Diff::LCS::ContextChange object, + # which can be implicitly converted to an array. + # + # Diff::LCS.sdiff(a, b).each do |action, (old_pos, old_element), (new_pos, new_element)| + # case action + # when '!' + # # replace + # when '-' + # # delete + # when '+' + # # insert + # end + # end + def sdiff(seq1, seq2, callbacks = nil, &block) # :yields: diff changes + diff_traversal(:sdiff, seq1, seq2, callbacks || Diff::LCS::SDiffCallbacks, &block) + end + + # #traverse_sequences is the most general facility provided by this module; + # #diff and #lcs are implemented as calls to it. + # + # The arguments to #traverse_sequences are the two sequences to traverse, and + # a callback object, like this: + # + # traverse_sequences(seq1, seq2, Diff::LCS::ContextDiffCallbacks.new) + # + # == Callback Methods + # + # Optional callback methods are emphasized. + # + # callbacks#match:: Called when +a+ and +b+ are pointing to + # common elements in +A+ and +B+. + # callbacks#discard_a:: Called when +a+ is pointing to an + # element not in +B+. + # callbacks#discard_b:: Called when +b+ is pointing to an + # element not in +A+. + # callbacks#finished_a:: Called when +a+ has reached the end of + # sequence +A+. + # callbacks#finished_b:: Called when +b+ has reached the end of + # sequence +B+. + # + # == Algorithm + # + # a---+ + # v + # A = a b c e h j l m n p + # B = b c d e f j k l m r s t + # ^ + # b---+ + # + # If there are two arrows (+a+ and +b+) pointing to elements of sequences +A+ + # and +B+, the arrows will initially point to the first elements of their + # respective sequences. #traverse_sequences will advance the arrows through + # the sequences one element at a time, calling a method on the user-specified + # callback object before each advance. It will advance the arrows in such a + # way that if there are elements A[i] and B[j] which are + # both equal and part of the longest common subsequence, there will be some + # moment during the execution of #traverse_sequences when arrow +a+ is + # pointing to A[i] and arrow +b+ is pointing to B[j]. When + # this happens, #traverse_sequences will call callbacks#match and + # then it will advance both arrows. + # + # Otherwise, one of the arrows is pointing to an element of its sequence that + # is not part of the longest common subsequence. #traverse_sequences will + # advance that arrow and will call callbacks#discard_a or + # callbacks#discard_b, depending on which arrow it advanced. If both + # arrows point to elements that are not part of the longest common + # subsequence, then #traverse_sequences will advance arrow +a+ and call the + # appropriate callback, then it will advance arrow +b+ and call the appropriate + # callback. + # + # The methods for callbacks#match, callbacks#discard_a, and + # callbacks#discard_b are invoked with an event comprising the + # action ("=", "+", or "-", respectively), the indexes +i+ and +j+, and the + # elements A[i] and B[j]. Return values are discarded by + # #traverse_sequences. + # + # === End of Sequences + # + # If arrow +a+ reaches the end of its sequence before arrow +b+ does, + # #traverse_sequence will try to call callbacks#finished_a with the + # last index and element of +A+ (A[-1]) and the current index and + # element of +B+ (B[j]). If callbacks#finished_a does not + # exist, then callbacks#discard_b will be called on each element of + # +B+ until the end of the sequence is reached (the call will be done with + # A[-1] and B[j] for each element). + # + # If +b+ reaches the end of +B+ before +a+ reaches the end of +A+, + # callbacks#finished_b will be called with the current index and + # element of +A+ (A[i]) and the last index and element of +B+ + # (A[-1]). Again, if callbacks#finished_b does not exist on + # the callback object, then callbacks#discard_a will be called on + # each element of +A+ until the end of the sequence is reached (A[i] + # and B[-1]). + # + # There is a chance that one additional callbacks#discard_a or + # callbacks#discard_b will be called after the end of the sequence + # is reached, if +a+ has not yet reached the end of +A+ or +b+ has not yet + # reached the end of +B+. + def traverse_sequences(seq1, seq2, callbacks = Diff::LCS::SequenceCallbacks) # :yields: change events + callbacks ||= Diff::LCS::SequenceCallbacks + matches = Diff::LCS::Internals.lcs(seq1, seq2) + + run_finished_a = run_finished_b = false + string = seq1.is_a?(String) + + a_size = seq1.size + b_size = seq2.size + ai = bj = 0 + + matches.each do |b_line| + if b_line.nil? + unless seq1[ai].nil? + ax = string ? seq1[ai, 1] : seq1[ai] + bx = string ? seq2[bj, 1] : seq2[bj] + + event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_a(event) + end + else + ax = string ? seq1[ai, 1] : seq1[ai] + + loop do + break unless bj < b_line + + bx = string ? seq2[bj, 1] : seq2[bj] + event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_b(event) + bj += 1 + end + bx = string ? seq2[bj, 1] : seq2[bj] + event = Diff::LCS::ContextChange.new("=", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.match(event) + bj += 1 + end + ai += 1 + end + + # The last entry (if any) processed was a match. +ai+ and +bj+ point just + # past the last matching lines in their sequences. + while (ai < a_size) || (bj < b_size) + # last A? + if ai == a_size && bj < b_size + if callbacks.respond_to?(:finished_a) && !run_finished_a + ax = string ? seq1[-1, 1] : seq1[-1] + bx = string ? seq2[bj, 1] : seq2[bj] + event = Diff::LCS::ContextChange.new(">", a_size - 1, ax, bj, bx) + event = yield event if block_given? + callbacks.finished_a(event) + run_finished_a = true + else + ax = string ? seq1[ai, 1] : seq1[ai] + loop do + bx = string ? seq2[bj, 1] : seq2[bj] + event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_b(event) + bj += 1 + break unless bj < b_size + end + end + end + + # last B? + if bj == b_size && ai < a_size + if callbacks.respond_to?(:finished_b) && !run_finished_b + ax = string ? seq1[ai, 1] : seq1[ai] + bx = string ? seq2[-1, 1] : seq2[-1] + event = Diff::LCS::ContextChange.new("<", ai, ax, b_size - 1, bx) + event = yield event if block_given? + callbacks.finished_b(event) + run_finished_b = true + else + bx = string ? seq2[bj, 1] : seq2[bj] + loop do + ax = string ? seq1[ai, 1] : seq1[ai] + event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_a(event) + ai += 1 + break unless bj < b_size + end + end + end + + if ai < a_size + ax = string ? seq1[ai, 1] : seq1[ai] + bx = string ? seq2[bj, 1] : seq2[bj] + event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_a(event) + ai += 1 + end + + if bj < b_size + ax = string ? seq1[ai, 1] : seq1[ai] + bx = string ? seq2[bj, 1] : seq2[bj] + event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_b(event) + bj += 1 + end + end + end + + # #traverse_balanced is an alternative to #traverse_sequences. It uses a + # different algorithm to iterate through the entries in the computed longest + # common subsequence. Instead of viewing the changes as insertions or + # deletions from one of the sequences, #traverse_balanced will report + # changes between the sequences. + # + # The arguments to #traverse_balanced are the two sequences to traverse and a + # callback object, like this: + # + # traverse_balanced(seq1, seq2, Diff::LCS::ContextDiffCallbacks.new) + # + # #sdiff is implemented with #traverse_balanced. + # + # == Callback Methods + # + # Optional callback methods are emphasized. + # + # callbacks#match:: Called when +a+ and +b+ are pointing to + # common elements in +A+ and +B+. + # callbacks#discard_a:: Called when +a+ is pointing to an + # element not in +B+. + # callbacks#discard_b:: Called when +b+ is pointing to an + # element not in +A+. + # callbacks#change:: Called when +a+ and +b+ are pointing to + # the same relative position, but + # A[a] and B[b] are not + # the same; a change has + # occurred. + # + # #traverse_balanced might be a bit slower than #traverse_sequences, + # noticeable only while processing huge amounts of data. + # + # == Algorithm + # + # a---+ + # v + # A = a b c e h j l m n p + # B = b c d e f j k l m r s t + # ^ + # b---+ + # + # === Matches + # + # If there are two arrows (+a+ and +b+) pointing to elements of sequences +A+ + # and +B+, the arrows will initially point to the first elements of their + # respective sequences. #traverse_sequences will advance the arrows through + # the sequences one element at a time, calling a method on the user-specified + # callback object before each advance. It will advance the arrows in such a + # way that if there are elements A[i] and B[j] which are + # both equal and part of the longest common subsequence, there will be some + # moment during the execution of #traverse_sequences when arrow +a+ is + # pointing to A[i] and arrow +b+ is pointing to B[j]. When + # this happens, #traverse_sequences will call callbacks#match and + # then it will advance both arrows. + # + # === Discards + # + # Otherwise, one of the arrows is pointing to an element of its sequence that + # is not part of the longest common subsequence. #traverse_sequences will + # advance that arrow and will call callbacks#discard_a or + # callbacks#discard_b, depending on which arrow it advanced. + # + # === Changes + # + # If both +a+ and +b+ point to elements that are not part of the longest + # common subsequence, then #traverse_sequences will try to call + # callbacks#change and advance both arrows. If + # callbacks#change is not implemented, then + # callbacks#discard_a and callbacks#discard_b will be + # called in turn. + # + # The methods for callbacks#match, callbacks#discard_a, + # callbacks#discard_b, and callbacks#change are invoked + # with an event comprising the action ("=", "+", "-", or "!", respectively), + # the indexes +i+ and +j+, and the elements A[i] and B[j]. + # Return values are discarded by #traverse_balanced. + # + # === Context + # + # Note that +i+ and +j+ may not be the same index position, even if +a+ and + # +b+ are considered to be pointing to matching or changed elements. + def traverse_balanced(seq1, seq2, callbacks = Diff::LCS::BalancedCallbacks) + matches = Diff::LCS::Internals.lcs(seq1, seq2) + a_size = seq1.size + b_size = seq2.size + ai = bj = mb = 0 + ma = -1 + string = seq1.is_a?(String) + + # Process all the lines in the match vector. + loop do + # Find next match indexes +ma+ and +mb+ + loop do + ma += 1 + break unless ma < matches.size && matches[ma].nil? + end + + break if ma >= matches.size # end of matches? + + mb = matches[ma] + + # Change(seq2) + while (ai < ma) || (bj < mb) + ax = string ? seq1[ai, 1] : seq1[ai] + bx = string ? seq2[bj, 1] : seq2[bj] + + case [(ai < ma), (bj < mb)] + when [true, true] + if callbacks.respond_to?(:change) + event = Diff::LCS::ContextChange.new("!", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.change(event) + ai += 1 + else + event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_a(event) + ai += 1 + ax = string ? seq1[ai, 1] : seq1[ai] + event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_b(event) + end + + bj += 1 + when [true, false] + event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_a(event) + ai += 1 + when [false, true] + event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_b(event) + bj += 1 + end + end + + # Match + ax = string ? seq1[ai, 1] : seq1[ai] + bx = string ? seq2[bj, 1] : seq2[bj] + event = Diff::LCS::ContextChange.new("=", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.match(event) + ai += 1 + bj += 1 + end + + while (ai < a_size) || (bj < b_size) + ax = string ? seq1[ai, 1] : seq1[ai] + bx = string ? seq2[bj, 1] : seq2[bj] + + case [(ai < a_size), (bj < b_size)] + when [true, true] + if callbacks.respond_to?(:change) + event = Diff::LCS::ContextChange.new("!", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.change(event) + ai += 1 + else + event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_a(event) + ai += 1 + ax = string ? seq1[ai, 1] : seq1[ai] + event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_b(event) + end + + bj += 1 + when [true, false] + event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_a(event) + ai += 1 + when [false, true] + event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_b(event) + bj += 1 + end + end + end + + # standard:disable Style/HashSyntax + PATCH_MAP = { # :nodoc: + :patch => {"+" => "+", "-" => "-", "!" => "!", "=" => "="}.freeze, + :unpatch => {"+" => "-", "-" => "+", "!" => "!", "=" => "="}.freeze + }.freeze + # standard:enable Style/HashSyntax + + # Applies a +patchset+ to the sequence +src+ according to the +direction+ + # (:patch or :unpatch), producing a new sequence. + # + # If the +direction+ is not specified, Diff::LCS::patch will attempt to + # discover the direction of the +patchset+. + # + # A +patchset+ can be considered to apply forward (:patch) if the + # following expression is true: + # + # patch(s1, diff(s1, s2)) -> s2 + # + # A +patchset+ can be considered to apply backward (:unpatch) if the + # following expression is true: + # + # patch(s2, diff(s1, s2)) -> s1 + # + # If the +patchset+ contains no changes, the +src+ value will be returned as + # either src.dup or +src+. A +patchset+ can be deemed as having no + # changes if the following predicate returns true: + # + # patchset.empty? or + # patchset.flatten(1).all? { |change| change.unchanged? } + # + # === Patchsets + # + # A +patchset+ is always an enumerable sequence of changes, hunks of changes, + # or a mix of the two. A hunk of changes is an enumerable sequence of + # changes: + # + # [ # patchset + # # change + # [ # hunk + # # change + # ] + # ] + # + # The +patch+ method accepts patchsets that are enumerable sequences + # containing either Diff::LCS::Change objects (or a subclass) or the array + # representations of those objects. Prior to application, array + # representations of Diff::LCS::Change objects will be reified. + def patch(src, patchset, direction = nil) + # Normalize the patchset. + has_changes, patchset = Diff::LCS::Internals.analyze_patchset(patchset) + + return src.respond_to?(:dup) ? src.dup : src unless has_changes + + string = src.is_a?(String) + # Start with a new empty type of the source's class + res = src.class.new + + direction ||= Diff::LCS::Internals.intuit_diff_direction(src, patchset) + + ai = bj = 0 + + patch_map = PATCH_MAP[direction] + + patchset.each do |change| + # Both Change and ContextChange support #action + action = patch_map[change.action] + + case change + when Diff::LCS::ContextChange + case direction + when :patch + el = change.new_element + op = change.old_position + np = change.new_position + when :unpatch + el = change.old_element + op = change.new_position + np = change.old_position + end + + case action + when "-" # Remove details from the old string + while ai < op + res << (string ? src[ai, 1] : src[ai]) + ai += 1 + bj += 1 + end + ai += 1 + when "+" + while bj < np + res << (string ? src[ai, 1] : src[ai]) + ai += 1 + bj += 1 + end + + res << el + bj += 1 + when "=" + # This only appears in sdiff output with the SDiff callback. + # Therefore, we only need to worry about dealing with a single + # element. + res << el + + ai += 1 + bj += 1 + when "!" + while ai < op + res << (string ? src[ai, 1] : src[ai]) + ai += 1 + bj += 1 + end + + bj += 1 + ai += 1 + + res << el + end + when Diff::LCS::Change + case action + when "-" + while ai < change.position + res << (string ? src[ai, 1] : src[ai]) + ai += 1 + bj += 1 + end + ai += 1 + when "+" + while bj < change.position + res << (string ? src[ai, 1] : src[ai]) + ai += 1 + bj += 1 + end + + bj += 1 + + res << change.element + end + end + end + + while ai < src.size + res << (string ? src[ai, 1] : src[ai]) + ai += 1 + bj += 1 + end + + res + end + + # Given a set of patchset, convert the current version to the prior version. + # Does no auto-discovery. + def unpatch!(src, patchset) + patch(src, patchset, :unpatch) + end + + # Given a set of patchset, convert the current version to the next version. + # Does no auto-discovery. + def patch!(src, patchset) + patch(src, patchset, :patch) + end +end + +require "diff/lcs/backports" diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/array.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/array.rb new file mode 100644 index 0000000..663918a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/array.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +require "diff/lcs" + +class Array + include Diff::LCS +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/backports.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/backports.rb new file mode 100644 index 0000000..6543c8a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/backports.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +unless 0.respond_to?(:positive?) + class Fixnum # standard:disable Lint/UnifiedInteger + def positive? + self > 0 + end + + def negative? + self < 0 + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/block.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/block.rb new file mode 100644 index 0000000..226ed6f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/block.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +# A block is an operation removing, adding, or changing a group of items. +# Basically, this is just a list of changes, where each change adds or +# deletes a single item. Used by bin/ldiff. +class Diff::LCS::Block + attr_reader :changes, :insert, :remove + + def initialize(chunk) + @changes = [] + @insert = [] + @remove = [] + + chunk.each do |item| + @changes << item + @remove << item if item.deleting? + @insert << item if item.adding? + end + end + + def diff_size + @insert.size - @remove.size + end + + def op + case [@remove.empty?, @insert.empty?] + when [false, false] + "!" + when [false, true] + "-" + when [true, false] + "+" + else # [true, true] + "^" + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/callbacks.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/callbacks.rb new file mode 100644 index 0000000..2c5a779 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/callbacks.rb @@ -0,0 +1,327 @@ +# frozen_string_literal: true + +require "diff/lcs/change" + +module Diff::LCS + # This callback object implements the default set of callback events, + # which only returns the event itself. Note that #finished_a and + # #finished_b are not implemented -- I haven't yet figured out where they + # would be useful. + # + # Note that this is intended to be called as is, e.g., + # + # Diff::LCS.LCS(seq1, seq2, Diff::LCS::DefaultCallbacks) + class DefaultCallbacks + class << self + # Called when two items match. + def match(event) + event + end + + # Called when the old value is discarded in favour of the new value. + def discard_a(event) + event + end + + # Called when the new value is discarded in favour of the old value. + def discard_b(event) + event + end + + # Called when both the old and new values have changed. + def change(event) + event + end + + private :new + end + end + + # An alias for DefaultCallbacks that is used in + # Diff::LCS#traverse_sequences. + # + # Diff::LCS.LCS(seq1, seq2, Diff::LCS::SequenceCallbacks) + SequenceCallbacks = DefaultCallbacks + + # An alias for DefaultCallbacks that is used in + # Diff::LCS#traverse_balanced. + # + # Diff::LCS.LCS(seq1, seq2, Diff::LCS::BalancedCallbacks) + BalancedCallbacks = DefaultCallbacks + + def self.callbacks_for(callbacks) + callbacks.new + rescue + callbacks + end +end + +# This will produce a compound array of simple diff change objects. Each +# element in the #diffs array is a +hunk+ or +hunk+ array, where each +# element in each +hunk+ array is a single Change object representing the +# addition or removal of a single element from one of the two tested +# sequences. The +hunk+ provides the full context for the changes. +# +# diffs = Diff::LCS.diff(seq1, seq2) +# # This example shows a simplified array format. +# # [ [ [ '-', 0, 'a' ] ], # 1 +# # [ [ '+', 2, 'd' ] ], # 2 +# # [ [ '-', 4, 'h' ], # 3 +# # [ '+', 4, 'f' ] ], +# # [ [ '+', 6, 'k' ] ], # 4 +# # [ [ '-', 8, 'n' ], # 5 +# # [ '-', 9, 'p' ], +# # [ '+', 9, 'r' ], +# # [ '+', 10, 's' ], +# # [ '+', 11, 't' ] ] ] +# +# There are five hunks here. The first hunk says that the +a+ at position 0 +# of the first sequence should be deleted ('-'). The second hunk +# says that the +d+ at position 2 of the second sequence should be inserted +# ('+'). The third hunk says that the +h+ at position 4 of the +# first sequence should be removed and replaced with the +f+ from position 4 +# of the second sequence. The other two hunks are described similarly. +# +# === Use +# +# This callback object must be initialised and is used by the Diff::LCS#diff +# method. +# +# cbo = Diff::LCS::DiffCallbacks.new +# Diff::LCS.LCS(seq1, seq2, cbo) +# cbo.finish +# +# Note that the call to #finish is absolutely necessary, or the last set of +# changes will not be visible. Alternatively, can be used as: +# +# cbo = Diff::LCS::DiffCallbacks.new { |tcbo| Diff::LCS.LCS(seq1, seq2, tcbo) } +# +# The necessary #finish call will be made. +# +# === Simplified Array Format +# +# The simplified array format used in the example above can be obtained +# with: +# +# require 'pp' +# pp diffs.map { |e| e.map { |f| f.to_a } } +class Diff::LCS::DiffCallbacks + # Returns the difference set collected during the diff process. + attr_reader :diffs + + def initialize # :yields: self + @hunk = [] + @diffs = [] + + return unless block_given? + + begin + yield self + ensure + finish + end + end + + # Finalizes the diff process. If an unprocessed hunk still exists, then it + # is appended to the diff list. + def finish + finish_hunk + end + + def match(_event) + finish_hunk + end + + def discard_a(event) + @hunk << Diff::LCS::Change.new("-", event.old_position, event.old_element) + end + + def discard_b(event) + @hunk << Diff::LCS::Change.new("+", event.new_position, event.new_element) + end + + def finish_hunk + @diffs << @hunk unless @hunk.empty? + @hunk = [] + end + private :finish_hunk +end + +# This will produce a compound array of contextual diff change objects. Each +# element in the #diffs array is a "hunk" array, where each element in each +# "hunk" array is a single change. Each change is a Diff::LCS::ContextChange +# that contains both the old index and new index values for the change. The +# "hunk" provides the full context for the changes. Both old and new objects +# will be presented for changed objects. +nil+ will be substituted for a +# discarded object. +# +# seq1 = %w(a b c e h j l m n p) +# seq2 = %w(b c d e f j k l m r s t) +# +# diffs = Diff::LCS.diff(seq1, seq2, Diff::LCS::ContextDiffCallbacks) +# # This example shows a simplified array format. +# # [ [ [ '-', [ 0, 'a' ], [ 0, nil ] ] ], # 1 +# # [ [ '+', [ 3, nil ], [ 2, 'd' ] ] ], # 2 +# # [ [ '-', [ 4, 'h' ], [ 4, nil ] ], # 3 +# # [ '+', [ 5, nil ], [ 4, 'f' ] ] ], +# # [ [ '+', [ 6, nil ], [ 6, 'k' ] ] ], # 4 +# # [ [ '-', [ 8, 'n' ], [ 9, nil ] ], # 5 +# # [ '+', [ 9, nil ], [ 9, 'r' ] ], +# # [ '-', [ 9, 'p' ], [ 10, nil ] ], +# # [ '+', [ 10, nil ], [ 10, 's' ] ], +# # [ '+', [ 10, nil ], [ 11, 't' ] ] ] ] +# +# The five hunks shown are comprised of individual changes; if there is a +# related set of changes, they are still shown individually. +# +# This callback can also be used with Diff::LCS#sdiff, which will produce +# results like: +# +# diffs = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextCallbacks) +# # This example shows a simplified array format. +# # [ [ [ "-", [ 0, "a" ], [ 0, nil ] ] ], # 1 +# # [ [ "+", [ 3, nil ], [ 2, "d" ] ] ], # 2 +# # [ [ "!", [ 4, "h" ], [ 4, "f" ] ] ], # 3 +# # [ [ "+", [ 6, nil ], [ 6, "k" ] ] ], # 4 +# # [ [ "!", [ 8, "n" ], [ 9, "r" ] ], # 5 +# # [ "!", [ 9, "p" ], [ 10, "s" ] ], +# # [ "+", [ 10, nil ], [ 11, "t" ] ] ] ] +# +# The five hunks are still present, but are significantly shorter in total +# presentation, because changed items are shown as changes ("!") instead of +# potentially "mismatched" pairs of additions and deletions. +# +# The result of this operation is similar to that of +# Diff::LCS::SDiffCallbacks. They may be compared as: +# +# s = Diff::LCS.sdiff(seq1, seq2).reject { |e| e.action == "=" } +# c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten(1) +# +# s == c # -> true +# +# === Use +# +# This callback object must be initialised and can be used by the +# Diff::LCS#diff or Diff::LCS#sdiff methods. +# +# cbo = Diff::LCS::ContextDiffCallbacks.new +# Diff::LCS.LCS(seq1, seq2, cbo) +# cbo.finish +# +# Note that the call to #finish is absolutely necessary, or the last set of +# changes will not be visible. Alternatively, can be used as: +# +# cbo = Diff::LCS::ContextDiffCallbacks.new { |tcbo| Diff::LCS.LCS(seq1, seq2, tcbo) } +# +# The necessary #finish call will be made. +# +# === Simplified Array Format +# +# The simplified array format used in the example above can be obtained +# with: +# +# require 'pp' +# pp diffs.map { |e| e.map { |f| f.to_a } } +class Diff::LCS::ContextDiffCallbacks < Diff::LCS::DiffCallbacks + def discard_a(event) + @hunk << Diff::LCS::ContextChange.simplify(event) + end + + def discard_b(event) + @hunk << Diff::LCS::ContextChange.simplify(event) + end + + def change(event) + @hunk << Diff::LCS::ContextChange.simplify(event) + end +end + +# This will produce a simple array of diff change objects. Each element in +# the #diffs array is a single ContextChange. In the set of #diffs provided +# by SDiffCallbacks, both old and new objects will be presented for both +# changed and unchanged objects. +nil+ will be substituted +# for a discarded object. +# +# The diffset produced by this callback, when provided to Diff::LCS#sdiff, +# will compute and display the necessary components to show two sequences +# and their minimized differences side by side, just like the Unix utility +# +sdiff+. +# +# same same +# before | after +# old < - +# - > new +# +# seq1 = %w(a b c e h j l m n p) +# seq2 = %w(b c d e f j k l m r s t) +# +# diffs = Diff::LCS.sdiff(seq1, seq2) +# # This example shows a simplified array format. +# # [ [ "-", [ 0, "a"], [ 0, nil ] ], +# # [ "=", [ 1, "b"], [ 0, "b" ] ], +# # [ "=", [ 2, "c"], [ 1, "c" ] ], +# # [ "+", [ 3, nil], [ 2, "d" ] ], +# # [ "=", [ 3, "e"], [ 3, "e" ] ], +# # [ "!", [ 4, "h"], [ 4, "f" ] ], +# # [ "=", [ 5, "j"], [ 5, "j" ] ], +# # [ "+", [ 6, nil], [ 6, "k" ] ], +# # [ "=", [ 6, "l"], [ 7, "l" ] ], +# # [ "=", [ 7, "m"], [ 8, "m" ] ], +# # [ "!", [ 8, "n"], [ 9, "r" ] ], +# # [ "!", [ 9, "p"], [ 10, "s" ] ], +# # [ "+", [ 10, nil], [ 11, "t" ] ] ] +# +# The result of this operation is similar to that of +# Diff::LCS::ContextDiffCallbacks. They may be compared as: +# +# s = Diff::LCS.sdiff(seq1, seq2).reject { |e| e.action == "=" } +# c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten(1) +# +# s == c # -> true +# +# === Use +# +# This callback object must be initialised and is used by the Diff::LCS#sdiff +# method. +# +# cbo = Diff::LCS::SDiffCallbacks.new +# Diff::LCS.LCS(seq1, seq2, cbo) +# +# As with the other initialisable callback objects, +# Diff::LCS::SDiffCallbacks can be initialised with a block. As there is no +# "fininishing" to be done, this has no effect on the state of the object. +# +# cbo = Diff::LCS::SDiffCallbacks.new { |tcbo| Diff::LCS.LCS(seq1, seq2, tcbo) } +# +# === Simplified Array Format +# +# The simplified array format used in the example above can be obtained +# with: +# +# require 'pp' +# pp diffs.map { |e| e.to_a } +class Diff::LCS::SDiffCallbacks + # Returns the difference set collected during the diff process. + attr_reader :diffs + + def initialize # :yields: self + @diffs = [] + yield self if block_given? + end + + def match(event) + @diffs << Diff::LCS::ContextChange.simplify(event) + end + + def discard_a(event) + @diffs << Diff::LCS::ContextChange.simplify(event) + end + + def discard_b(event) + @diffs << Diff::LCS::ContextChange.simplify(event) + end + + def change(event) + @diffs << Diff::LCS::ContextChange.simplify(event) + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/change.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/change.rb new file mode 100644 index 0000000..714d78c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/change.rb @@ -0,0 +1,174 @@ +# frozen_string_literal: true + +# Represents a simplistic (non-contextual) change. Represents the removal or +# addition of an element from either the old or the new sequenced +# enumerable. +class Diff::LCS::Change + IntClass = 1.class # Fixnum is deprecated in Ruby 2.4 # standard:disable Naming/ConstantName + + # The only actions valid for changes are '+' (add), '-' (delete), '=' + # (no change), '!' (changed), '<' (tail changes from first sequence), or + # '>' (tail changes from second sequence). The last two ('<>') are only + # found with Diff::LCS::diff and Diff::LCS::sdiff. + VALID_ACTIONS = %w[+ - = ! > <].freeze + + def self.valid_action?(action) + VALID_ACTIONS.include? action + end + + # Returns the action this Change represents. + attr_reader :action + + # Returns the position of the Change. + attr_reader :position + # Returns the sequence element of the Change. + attr_reader :element + + def initialize(*args) + @action, @position, @element = *args + + fail "Invalid Change Action '#{@action}'" unless Diff::LCS::Change.valid_action?(@action) + fail "Invalid Position Type" unless @position.is_a? IntClass + end + + def inspect(*_args) + "#<#{self.class}: #{to_a.inspect}>" + end + + def to_a + [@action, @position, @element] + end + + alias_method :to_ary, :to_a + + def self.from_a(arr) + arr = arr.flatten(1) + case arr.size + when 5 + Diff::LCS::ContextChange.new(*arr[0...5]) + when 3 + Diff::LCS::Change.new(*arr[0...3]) + else + fail "Invalid change array format provided." + end + end + + include Comparable + + def ==(other) + (self.class == other.class) and + (action == other.action) and + (position == other.position) and + (element == other.element) + end + + def <=>(other) + r = action <=> other.action + r = position <=> other.position if r.zero? + r = element <=> other.element if r.zero? + r + end + + def adding? + @action == "+" + end + + def deleting? + @action == "-" + end + + def unchanged? + @action == "=" + end + + def changed? + @action == "!" + end + + def finished_a? + @action == ">" + end + + def finished_b? + @action == "<" + end +end + +# Represents a contextual change. Contains the position and values of the +# elements in the old and the new sequenced enumerables as well as the action +# taken. +class Diff::LCS::ContextChange < Diff::LCS::Change + # We don't need these two values. + undef :position + undef :element + + # Returns the old position being changed. + attr_reader :old_position + # Returns the new position being changed. + attr_reader :new_position + # Returns the old element being changed. + attr_reader :old_element + # Returns the new element being changed. + attr_reader :new_element + + def initialize(*args) + @action, @old_position, @old_element, @new_position, @new_element = *args + + fail "Invalid Change Action '#{@action}'" unless Diff::LCS::Change.valid_action?(@action) + fail "Invalid (Old) Position Type" unless @old_position.nil? || @old_position.is_a?(IntClass) + fail "Invalid (New) Position Type" unless @new_position.nil? || @new_position.is_a?(IntClass) + end + + def to_a + [ + @action, + [@old_position, @old_element], + [@new_position, @new_element] + ] + end + + alias_method :to_ary, :to_a + + def self.from_a(arr) + Diff::LCS::Change.from_a(arr) + end + + # Simplifies a context change for use in some diff callbacks. '<' actions + # are converted to '-' and '>' actions are converted to '+'. + def self.simplify(event) + ea = event.to_a + + case ea[0] + when "-" + ea[2][1] = nil + when "<" + ea[0] = "-" + ea[2][1] = nil + when "+" + ea[1][1] = nil + when ">" + ea[0] = "+" + ea[1][1] = nil + end + + Diff::LCS::ContextChange.from_a(ea) + end + + def ==(other) + (self.class == other.class) and + (@action == other.action) and + (@old_position == other.old_position) and + (@new_position == other.new_position) and + (@old_element == other.old_element) and + (@new_element == other.new_element) + end + + def <=>(other) + r = @action <=> other.action + r = @old_position <=> other.old_position if r.zero? + r = @new_position <=> other.new_position if r.zero? + r = @old_element <=> other.old_element if r.zero? + r = @new_element <=> other.new_element if r.zero? + r + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/htmldiff.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/htmldiff.rb new file mode 100644 index 0000000..9073243 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/htmldiff.rb @@ -0,0 +1,160 @@ +# frozen_string_literal: true + +require "erb" + +# Produce a simple HTML diff view. +class Diff::LCS::HTMLDiff + class << self + # standard:disable ThreadSafety/ClassAndModuleAttributes + attr_accessor :can_expand_tabs # :nodoc: + # standard:enable ThreadSafety/ClassAndModuleAttributes + end + self.can_expand_tabs = true + + class Callbacks # :nodoc: + attr_accessor :output + attr_accessor :match_class + attr_accessor :only_a_class + attr_accessor :only_b_class + + def initialize(output, options = {}) + @output = output + options ||= {} + + @match_class = options[:match_class] || "match" + @only_a_class = options[:only_a_class] || "only_a" + @only_b_class = options[:only_b_class] || "only_b" + end + + def htmlize(element, css_class) + element = " " if element.empty? + %(
#{element}
\n) + end + private :htmlize + + # This will be called with both lines are the same + def match(event) + @output << htmlize(event.old_element, :match_class) + end + + # This will be called when there is a line in A that isn't in B + def discard_a(event) + @output << htmlize(event.old_element, :only_a_class) + end + + # This will be called when there is a line in B that isn't in A + def discard_b(event) + @output << htmlize(event.new_element, :only_b_class) + end + end + + # standard:disable Style/HashSyntax + DEFAULT_OPTIONS = { + :expand_tabs => nil, + :output => nil, + :css => nil, + :title => nil + }.freeze + # standard:enable Style/HashSyntax + + # standard:disable Layout/HeredocIndentation + DEFAULT_CSS = <<-CSS +body { margin: 0; } +.diff +{ + border: 1px solid black; + margin: 1em 2em; +} +p +{ + margin-left: 2em; +} +pre +{ + padding-left: 1em; + margin: 0; + font-family: Inconsolata, Consolas, Lucida, Courier, monospaced; + white-space: pre; +} +.match { } +.only_a +{ + background-color: #fdd; + color: red; + text-decoration: line-through; +} +.only_b +{ + background-color: #ddf; + color: blue; + border-left: 3px solid blue +} +h1 { margin-left: 2em; } + CSS + # standard:enable Layout/HeredocIndentation + + def initialize(left, right, options = nil) + @left = left + @right = right + @options = options + + @options = DEFAULT_OPTIONS.dup if @options.nil? + end + + def verify_options + @options[:expand_tabs] ||= 4 + @options[:expand_tabs] = 4 if @options[:expand_tabs].negative? + + @options[:output] ||= $stdout + + @options[:css] ||= DEFAULT_CSS.dup + + @options[:title] ||= "diff" + end + private :verify_options + + attr_reader :options + + def run + verify_options + + if @options[:expand_tabs].positive? && self.class.can_expand_tabs + formatter = Text::Format.new + formatter.tabstop = @options[:expand_tabs] + + @left.map! { |line| formatter.expand(line.chomp) } + @right.map! { |line| formatter.expand(line.chomp) } + end + + @left.map! { |line| ERB::Util.html_escape(line.chomp) } + @right.map! { |line| ERB::Util.html_escape(line.chomp) } + + # standard:disable Layout/HeredocIndentation + @options[:output] << <<-OUTPUT + + + #{@options[:title]} + + + +

#{@options[:title]}

+

Legend: Only in Old  + Only in New

+
+ OUTPUT + # standard:enable Layout/HeredocIndentation + + callbacks = Callbacks.new(@options[:output]) + Diff::LCS.traverse_sequences(@left, @right, callbacks) + + # standard:disable Layout/HeredocIndentation + @options[:output] << <<-OUTPUT +
+ + + OUTPUT + # standard:enable Layout/HeredocIndentation + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/hunk.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/hunk.rb new file mode 100644 index 0000000..24b33bc --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/hunk.rb @@ -0,0 +1,379 @@ +# frozen_string_literal: true + +require "diff/lcs/block" + +# A Hunk is a group of Blocks which overlap because of the context surrounding +# each block. (So if we're not using context, every hunk will contain one +# block.) Used in the diff program (bin/ldiff). +class Diff::LCS::Hunk + OLD_DIFF_OP_ACTION = {"+" => "a", "-" => "d", "!" => "c"}.freeze # :nodoc: + ED_DIFF_OP_ACTION = {"+" => "a", "-" => "d", "!" => "c"}.freeze # :nodoc: + + private_constant :OLD_DIFF_OP_ACTION, :ED_DIFF_OP_ACTION if respond_to?(:private_constant) + + # Create a hunk using references to both the old and new data, as well as the + # piece of data. + def initialize(data_old, data_new, piece, flag_context, file_length_difference) + # At first, a hunk will have just one Block in it + @blocks = [Diff::LCS::Block.new(piece)] + + if @blocks[0].remove.empty? && @blocks[0].insert.empty? + fail "Cannot build a hunk from #{piece.inspect}; has no add or remove actions" + end + + if String.method_defined?(:encoding) + @preferred_data_encoding = data_old.fetch(0) { data_new.fetch(0) { "" } }.encoding + end + + @data_old = data_old + @data_new = data_new + @old_empty = data_old.empty? || (data_old.size == 1 && data_old[0].empty?) + @new_empty = data_new.empty? || (data_new.size == 1 && data_new[0].empty?) + + before = after = file_length_difference + after += @blocks[0].diff_size + @file_length_difference = after # The caller must get this manually + @max_diff_size = @blocks.map { |e| e.diff_size.abs }.max + + # Save the start & end of each array. If the array doesn't exist (e.g., + # we're only adding items in this block), then figure out the line number + # based on the line number of the other file and the current difference in + # file lengths. + if @blocks[0].remove.empty? + a1 = a2 = nil + else + a1 = @blocks[0].remove[0].position + a2 = @blocks[0].remove[-1].position + end + + if @blocks[0].insert.empty? + b1 = b2 = nil + else + b1 = @blocks[0].insert[0].position + b2 = @blocks[0].insert[-1].position + end + + @start_old = a1 || (b1 - before) + @start_new = b1 || (a1 + before) + @end_old = a2 || (b2 - after) + @end_new = b2 || (a2 + after) + + self.flag_context = flag_context + end + + attr_reader :blocks + attr_reader :start_old, :start_new + attr_reader :end_old, :end_new + attr_reader :file_length_difference + + # Change the "start" and "end" fields to note that context should be added + # to this hunk. + attr_accessor :flag_context + undef :flag_context= + def flag_context=(context) # :nodoc: # standard:disable Lint/DuplicateMethods + return if context.nil? || context.zero? + + add_start = (context > @start_old) ? @start_old : context + + @start_old -= add_start + @start_new -= add_start + + old_size = @data_old.size + + add_end = + if (@end_old + context) >= old_size + old_size - @end_old - 1 + else + context + end + + @end_old += add_end + @end_new += add_end + end + + # Merges this hunk and the provided hunk together if they overlap. Returns + # a truthy value so that if there is no overlap, you can know the merge + # was skipped. + def merge(hunk) + return unless overlaps?(hunk) + + @start_old = hunk.start_old + @start_new = hunk.start_new + blocks.unshift(*hunk.blocks) + end + alias_method :unshift, :merge + + # Determines whether there is an overlap between this hunk and the + # provided hunk. This will be true if the difference between the two hunks + # start or end positions is within one position of each other. + def overlaps?(hunk) + hunk and (((@start_old - hunk.end_old) <= 1) or + ((@start_new - hunk.end_new) <= 1)) + end + + # Returns a diff string based on a format. + def diff(format, last = false) + case format + when :old + old_diff(last) + when :unified + unified_diff(last) + when :context + context_diff(last) + when :ed + self + when :reverse_ed, :ed_finish + ed_diff(format, last) + else + fail "Unknown diff format #{format}." + end + end + + # Note that an old diff can't have any context. Therefore, we know that + # there's only one block in the hunk. + def old_diff(last = false) + warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1 + + block = @blocks[0] + + if last + old_missing_newline = !@old_empty && missing_last_newline?(@data_old) + new_missing_newline = !@new_empty && missing_last_newline?(@data_new) + end + + # Calculate item number range. Old diff range is just like a context + # diff range, except the ranges are on one line with the action between + # them. + s = encode("#{context_range(:old, ",")}#{OLD_DIFF_OP_ACTION[block.op]}#{context_range(:new, ",")}\n") + # If removing anything, just print out all the remove lines in the hunk + # which is just all the remove lines in the block. + unless block.remove.empty? + @data_old[@start_old..@end_old].each { |e| s << encode("< ") + e.chomp + encode("\n") } + end + + s << encode("\\ No newline at end of file\n") if old_missing_newline && !new_missing_newline + s << encode("---\n") if block.op == "!" + + unless block.insert.empty? + @data_new[@start_new..@end_new].each { |e| s << encode("> ") + e.chomp + encode("\n") } + end + + s << encode("\\ No newline at end of file\n") if new_missing_newline && !old_missing_newline + + s + end + private :old_diff + + def unified_diff(last = false) + # Calculate item number range. + s = encode("@@ -#{unified_range(:old)} +#{unified_range(:new)} @@\n") + + # Outlist starts containing the hunk of the old file. Removing an item + # just means putting a '-' in front of it. Inserting an item requires + # getting it from the new file and splicing it in. We splice in + # +num_added+ items. Remove blocks use +num_added+ because splicing + # changed the length of outlist. + # + # We remove +num_removed+ items. Insert blocks use +num_removed+ + # because their item numbers -- corresponding to positions in the NEW + # file -- don't take removed items into account. + lo, hi, num_added, num_removed = @start_old, @end_old, 0, 0 + + # standard:disable Performance/UnfreezeString + outlist = @data_old[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") } + # standard:enable Performance/UnfreezeString + + last_block = blocks[-1] + + if last + old_missing_newline = !@old_empty && missing_last_newline?(@data_old) + new_missing_newline = !@new_empty && missing_last_newline?(@data_new) + end + + @blocks.each do |block| + block.remove.each do |item| + op = item.action.to_s # - + offset = item.position - lo + num_added + outlist[offset][0, 1] = encode(op) + num_removed += 1 + end + + if last && block == last_block && old_missing_newline && !new_missing_newline + outlist << encode('\\ No newline at end of file') + num_removed += 1 + end + + block.insert.each do |item| + op = item.action.to_s # + + offset = item.position - @start_new + num_removed + outlist[offset, 0] = encode(op) + @data_new[item.position].chomp + num_added += 1 + end + end + + outlist << encode('\\ No newline at end of file') if last && new_missing_newline + + s << outlist.join(encode("\n")) + + s + end + private :unified_diff + + def context_diff(last = false) + s = encode("***************\n") + s << encode("*** #{context_range(:old, ",")} ****\n") + r = context_range(:new, ",") + + if last + old_missing_newline = missing_last_newline?(@data_old) + new_missing_newline = missing_last_newline?(@data_new) + end + + # Print out file 1 part for each block in context diff format if there + # are any blocks that remove items + lo, hi = @start_old, @end_old + removes = @blocks.reject { |e| e.remove.empty? } + + unless removes.empty? + # standard:disable Performance/UnfreezeString + outlist = @data_old[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") } + # standard:enable Performance/UnfreezeString + + last_block = removes[-1] + + removes.each do |block| + block.remove.each do |item| + outlist[item.position - lo][0, 1] = encode(block.op) # - or ! + end + + if last && block == last_block && old_missing_newline + outlist << encode('\\ No newline at end of file') + end + end + + s << outlist.join(encode("\n")) << encode("\n") + end + + s << encode("--- #{r} ----\n") + lo, hi = @start_new, @end_new + inserts = @blocks.reject { |e| e.insert.empty? } + + unless inserts.empty? + # standard:disable Performance/UnfreezeString + outlist = @data_new[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") } + # standard:enable Performance/UnfreezeString + + last_block = inserts[-1] + + inserts.each do |block| + block.insert.each do |item| + outlist[item.position - lo][0, 1] = encode(block.op) # + or ! + end + + if last && block == last_block && new_missing_newline + outlist << encode('\\ No newline at end of file') + end + end + s << outlist.join(encode("\n")) + end + + s + end + private :context_diff + + def ed_diff(format, last) + warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1 + if last + # ed script doesn't support well incomplete lines + warn ": No newline at end of file\n" if !@old_empty && missing_last_newline?(@data_old) + warn ": No newline at end of file\n" if !@new_empty && missing_last_newline?(@data_new) + + if @blocks[0].op == "!" + return +"" if @blocks[0].changes[0].element == @blocks[0].changes[1].element + "\n" + return +"" if @blocks[0].changes[0].element + "\n" == @blocks[0].changes[1].element + end + end + + s = + if format == :reverse_ed + encode("#{ED_DIFF_OP_ACTION[@blocks[0].op]}#{context_range(:old, " ")}\n") + else + encode("#{context_range(:old, ",")}#{ED_DIFF_OP_ACTION[@blocks[0].op]}\n") + end + + unless @blocks[0].insert.empty? + @data_new[@start_new..@end_new].each do |e| + s << e.chomp + encode("\n") + end + s << encode(".\n") + end + s + end + private :ed_diff + + # Generate a range of item numbers to print. Only print 1 number if the + # range has only one item in it. Otherwise, it's 'start,end' + def context_range(mode, op) + case mode + when :old + s, e = (@start_old + 1), (@end_old + 1) + when :new + s, e = (@start_new + 1), (@end_new + 1) + end + + (s < e) ? "#{s}#{op}#{e}" : e.to_s + end + private :context_range + + # Generate a range of item numbers to print for unified diff. Print number + # where block starts, followed by number of lines in the block + # (don't print number of lines if it's 1) + def unified_range(mode) + case mode + when :old + return "0,0" if @old_empty + s, e = (@start_old + 1), (@end_old + 1) + when :new + return "0,0" if @new_empty + s, e = (@start_new + 1), (@end_new + 1) + end + + length = e - s + 1 + + (length <= 1) ? e.to_s : "#{s},#{length}" + end + private :unified_range + + def missing_last_newline?(data) + newline = encode("\n") + + if data[-2] + data[-2].end_with?(newline) && !data[-1].end_with?(newline) + elsif data[-1] + !data[-1].end_with?(newline) + else + true + end + end + + if String.method_defined?(:encoding) + def encode(literal, target_encoding = @preferred_data_encoding) + literal.encode target_encoding + end + + def encode_as(string, *args) + args.map { |arg| arg.encode(string.encoding) } + end + else + def encode(literal, _target_encoding = nil) + literal + end + + def encode_as(_string, *args) + args + end + end + + private :encode + private :encode_as +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/internals.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/internals.rb new file mode 100644 index 0000000..8a9160a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/internals.rb @@ -0,0 +1,308 @@ +# frozen_string_literal: true + +class << Diff::LCS + def diff_traversal(method, seq1, seq2, callbacks, &block) + callbacks = callbacks_for(callbacks) + case method + when :diff + traverse_sequences(seq1, seq2, callbacks) + when :sdiff + traverse_balanced(seq1, seq2, callbacks) + end + callbacks.finish if callbacks.respond_to? :finish + + if block + callbacks.diffs.map do |hunk| + if hunk.is_a? Array + hunk.map { |hunk_block| block[hunk_block] } + else + block[hunk] + end + end + else + callbacks.diffs + end + end + private :diff_traversal +end + +module Diff::LCS::Internals # :nodoc: +end + +class << Diff::LCS::Internals + # Compute the longest common subsequence between the sequenced + # Enumerables +a+ and +b+. The result is an array whose contents is such + # that + # + # result = Diff::LCS::Internals.lcs(a, b) + # result.each_with_index do |e, i| + # assert_equal(a[i], b[e]) unless e.nil? + # end + def lcs(a, b) + a_start = b_start = 0 + a_finish = a.size - 1 + b_finish = b.size - 1 + vector = [] + + # Collect any common elements at the beginning... + while (a_start <= a_finish) && (b_start <= b_finish) && (a[a_start] == b[b_start]) + vector[a_start] = b_start + a_start += 1 + b_start += 1 + end + + # Now the end... + while (a_start <= a_finish) && (b_start <= b_finish) && (a[a_finish] == b[b_finish]) + vector[a_finish] = b_finish + a_finish -= 1 + b_finish -= 1 + end + + # Now, compute the equivalence classes of positions of elements. + # An explanation for how this works: https://codeforces.com/topic/92191 + b_matches = position_hash(b, b_start..b_finish) + + thresh = [] + links = [] + string = a.is_a?(String) + + (a_start..a_finish).each do |i| + ai = string ? a[i, 1] : a[i] + bm = b_matches[ai] + k = nil + bm.reverse_each do |j| + # Although the threshold check is not mandatory for this to work, + # it may have an optimization purpose + # An attempt to remove it: https://github.com/halostatue/diff-lcs/pull/72 + # Why it is reintroduced: https://github.com/halostatue/diff-lcs/issues/78 + if k && (thresh[k] > j) && (thresh[k - 1] < j) + thresh[k] = j + else + k = replace_next_larger(thresh, j, k) + end + links[k] = [k.positive? ? links[k - 1] : nil, i, j] unless k.nil? + end + end + + unless thresh.empty? + link = links[thresh.size - 1] + until link.nil? + vector[link[1]] = link[2] + link = link[0] + end + end + + vector + end + + # This method will analyze the provided patchset to provide a single-pass + # normalization (conversion of the array form of Diff::LCS::Change objects to + # the object form of same) and detection of whether the patchset represents + # changes to be made. + def analyze_patchset(patchset, depth = 0) + fail "Patchset too complex" if depth > 1 + + has_changes = false + new_patchset = [] + + # Format: + # [ # patchset + # # hunk (change) + # [ # hunk + # # change + # ] + # ] + + patchset.each do |hunk| + case hunk + when Diff::LCS::Change + has_changes ||= !hunk.unchanged? + new_patchset << hunk + when Array + # Detect if the 'hunk' is actually an array-format change object. + if Diff::LCS::Change.valid_action? hunk[0] + hunk = Diff::LCS::Change.from_a(hunk) + has_changes ||= !hunk.unchanged? + new_patchset << hunk + else + with_changes, hunk = analyze_patchset(hunk, depth + 1) + has_changes ||= with_changes + new_patchset.concat(hunk) + end + else + fail ArgumentError, "Cannot normalise a hunk of class #{hunk.class}." + end + end + + [has_changes, new_patchset] + end + + # Examine the patchset and the source to see in which direction the + # patch should be applied. + # + # WARNING: By default, this examines the whole patch, so this could take + # some time. This also works better with Diff::LCS::ContextChange or + # Diff::LCS::Change as its source, as an array will cause the creation + # of one of the above. + def intuit_diff_direction(src, patchset, limit = nil) + string = src.is_a?(String) + count = left_match = left_miss = right_match = right_miss = 0 + + patchset.each do |change| + count += 1 + + case change + when Diff::LCS::ContextChange + le = string ? src[change.old_position, 1] : src[change.old_position] + re = string ? src[change.new_position, 1] : src[change.new_position] + + case change.action + when "-" # Remove details from the old string + if le == change.old_element + left_match += 1 + else + left_miss += 1 + end + when "+" + if re == change.new_element + right_match += 1 + else + right_miss += 1 + end + when "=" + left_miss += 1 if le != change.old_element + right_miss += 1 if re != change.new_element + when "!" + if le == change.old_element + left_match += 1 + elsif re == change.new_element + right_match += 1 + else + left_miss += 1 + right_miss += 1 + end + end + when Diff::LCS::Change + # With a simplistic change, we can't tell the difference between + # the left and right on '!' actions, so we ignore those. On '=' + # actions, if there's a miss, we miss both left and right. + element = string ? src[change.position, 1] : src[change.position] + + case change.action + when "-" + if element == change.element + left_match += 1 + else + left_miss += 1 + end + when "+" + if element == change.element + right_match += 1 + else + right_miss += 1 + end + when "=" + if element != change.element + left_miss += 1 + right_miss += 1 + end + end + end + + break if !limit.nil? && (count > limit) + end + + no_left = left_match.zero? && left_miss.positive? + no_right = right_match.zero? && right_miss.positive? + + case [no_left, no_right] + when [false, true] + :patch + when [true, false] + :unpatch + else + case left_match <=> right_match + when 1 + if left_miss.zero? + :patch + else + :unpatch + end + when -1 + if right_miss.zero? + :unpatch + else + :patch + end + else + fail "The provided patchset does not appear to apply to the provided \ +enumerable as either source or destination value." + end + end + end + + # Find the place at which +value+ would normally be inserted into the + # Enumerable. If that place is already occupied by +value+, do nothing + # and return +nil+. If the place does not exist (i.e., it is off the end + # of the Enumerable), add it to the end. Otherwise, replace the element + # at that point with +value+. It is assumed that the Enumerable's values + # are numeric. + # + # This operation preserves the sort order. + def replace_next_larger(enum, value, last_index = nil) + # Off the end? + if enum.empty? || (value > enum[-1]) + enum << value + return enum.size - 1 + end + + # Binary search for the insertion point + last_index ||= enum.size - 1 + first_index = 0 + while first_index <= last_index + i = (first_index + last_index) >> 1 + + found = enum[i] + + return nil if value == found + + if value > found + first_index = i + 1 + else + last_index = i - 1 + end + end + + # The insertion point is in first_index; overwrite the next larger + # value. + enum[first_index] = value + first_index + end + private :replace_next_larger + + # If +vector+ maps the matching elements of another collection onto this + # Enumerable, compute the inverse of +vector+ that maps this Enumerable + # onto the collection. (Currently unused.) + def inverse_vector(a, vector) + inverse = a.dup + (0...vector.size).each do |i| + inverse[vector[i]] = i unless vector[i].nil? + end + inverse + end + private :inverse_vector + + # Returns a hash mapping each element of an Enumerable to the set of + # positions it occupies in the Enumerable, optionally restricted to the + # elements specified in the range of indexes specified by +interval+. + def position_hash(enum, interval) + string = enum.is_a?(String) + hash = Hash.new { |h, k| h[k] = [] } + interval.each do |i| + k = string ? enum[i, 1] : enum[i] + hash[k] << i + end + hash + end + private :position_hash +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/ldiff.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/ldiff.rb new file mode 100644 index 0000000..6442c9b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/ldiff.rb @@ -0,0 +1,189 @@ +# frozen_string_literal: true + +require "optparse" +require "diff/lcs/hunk" + +class Diff::LCS::Ldiff # :nodoc: + # standard:disable Layout/HeredocIndentation + BANNER = <<-COPYRIGHT +ldiff #{Diff::LCS::VERSION} + Copyright 2004-2025 Austin Ziegler + + Part of Diff::LCS. + https://github.com/halostatue/diff-lcs + + This program is free software. It may be redistributed and/or modified under + the terms of the GPL version 2 (or later), the Perl Artistic licence, or the + MIT licence. + COPYRIGHT + # standard:enable Layout/HeredocIndentation + + InputInfo = Struct.new(:filename, :data, :stat) do + def initialize(filename) + super(filename, ::File.read(filename), ::File.stat(filename)) + end + end + + attr_reader :format, :lines # :nodoc: + attr_reader :file_old, :file_new # :nodoc: + attr_reader :data_old, :data_new # :nodoc: + + def self.run(args, input = $stdin, output = $stdout, error = $stderr) # :nodoc: + new.run(args, input, output, error) + end + + def initialize + @binary = nil + @format = :old + @lines = 0 + end + + def run(args, _input = $stdin, output = $stdout, error = $stderr) # :nodoc: + args.options do |o| + o.banner = "Usage: #{File.basename($0)} [options] oldfile newfile" + o.separator "" + o.on( + "-c", "-C", "--context [LINES]", Integer, + "Displays a context diff with LINES lines", "of context. Default 3 lines." + ) do |ctx| + @format = :context + @lines = ctx || 3 + end + o.on( + "-u", "-U", "--unified [LINES]", Integer, + "Displays a unified diff with LINES lines", "of context. Default 3 lines." + ) do |ctx| + @format = :unified + @lines = ctx || 3 + end + o.on("-e", "Creates an 'ed' script to change", "oldfile to newfile.") do |_ctx| + @format = :ed + end + o.on("-f", "Creates an 'ed' script to change", "oldfile to newfile in reverse order.") do |_ctx| + @format = :reverse_ed + end + o.on( + "-a", "--text", + "Treat the files as text and compare them", "line-by-line, even if they do not seem", "to be text." + ) do |_txt| + @binary = false + end + o.on("--binary", "Treats the files as binary.") do |_bin| + @binary = true + end + o.on("-q", "--brief", "Report only whether or not the files", "differ, not the details.") do |_ctx| + @format = :report + end + o.on_tail("--help", "Shows this text.") do + error << o + return 0 + end + o.on_tail("--version", "Shows the version of Diff::LCS.") do + error << Diff::LCS::Ldiff::BANNER + return 0 + end + o.on_tail "" + o.on_tail 'By default, runs produces an "old-style" diff, with output like UNIX diff.' + o.parse! + end + + unless args.size == 2 + error << args.options + return 127 + end + + # Defaults are for old-style diff + @format ||= :old + @lines ||= 0 + + file_old, file_new = *ARGV + diff?( + InputInfo.new(file_old), + InputInfo.new(file_new), + @format, + output, + binary: @binary, + lines: @lines + ) ? 1 : 0 + end + + def diff?(info_old, info_new, format, output, binary: nil, lines: 0) + case format + when :context + char_old = "*" * 3 + char_new = "-" * 3 + when :unified + char_old = "-" * 3 + char_new = "+" * 3 + end + + # After we've read up to a certain point in each file, the number of + # items we've read from each file will differ by FLD (could be 0). + file_length_difference = 0 + + # Test binary status + if binary.nil? + old_bin = info_old.data[0, 4096].include?("\0") + new_bin = info_new.data[0, 4096].include?("\0") + binary = old_bin || new_bin + end + + # diff yields lots of pieces, each of which is basically a Block object + if binary + has_diffs = (info_old.data != info_new.data) + if format != :report + if has_diffs + output << "Binary files #{info_old.filename} and #{info_new.filename} differ\n" + return true + end + return false + end + else + data_old = info_old.data.lines.to_a + data_new = info_new.data.lines.to_a + diffs = Diff::LCS.diff(data_old, data_new) + return false if diffs.empty? + end + + case format + when :report + output << "Files #{info_old.filename} and #{info_new.filename} differ\n" + return true + when :unified, :context + ft = info_old.stat.mtime.localtime.strftime("%Y-%m-%d %H:%M:%S.000000000 %z") + output << "#{char_old} #{info_old.filename}\t#{ft}\n" + ft = info_new.stat.mtime.localtime.strftime("%Y-%m-%d %H:%M:%S.000000000 %z") + output << "#{char_new} #{info_new.filename}\t#{ft}\n" + when :ed + real_output = output + output = [] + end + + # Loop over hunks. If a hunk overlaps with the last hunk, join them. + # Otherwise, print out the old one. + oldhunk = hunk = nil + diffs.each do |piece| + begin + hunk = Diff::LCS::Hunk.new(data_old, data_new, piece, lines, file_length_difference) + file_length_difference = hunk.file_length_difference + + next unless oldhunk + next if lines.positive? && hunk.merge(oldhunk) + + output << oldhunk.diff(format) + output << "\n" if format == :unified + ensure + oldhunk = hunk + end + end + + last = oldhunk.diff(format, true) + last << "\n" unless last.is_a?(Diff::LCS::Hunk) || last.empty? || last.end_with?("\n") + + output << last + + output.reverse_each { |e| real_output << e.diff(:ed_finish, e == output[0]) } if format == :ed + + true + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/string.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/string.rb new file mode 100644 index 0000000..9ab32e9 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/string.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class String + include Diff::LCS +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/version.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/version.rb new file mode 100644 index 0000000..82830e3 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/lib/diff/lcs/version.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module Diff + module LCS + VERSION = "1.6.2" + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/mise.toml b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/mise.toml new file mode 100644 index 0000000..22418cf --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/mise.toml @@ -0,0 +1,5 @@ +[tools] +ruby = "3.4" + +[env] +MAINTENANCE = "true" diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/change_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/change_spec.rb new file mode 100644 index 0000000..42533ae --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/change_spec.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Diff::LCS::Change do + describe "an add" do + subject { described_class.new("+", 0, "element") } + it { should_not be_deleting } + it { should be_adding } + it { should_not be_unchanged } + it { should_not be_changed } + it { should_not be_finished_a } + it { should_not be_finished_b } + end + + describe "a delete" do + subject { described_class.new("-", 0, "element") } + it { should be_deleting } + it { should_not be_adding } + it { should_not be_unchanged } + it { should_not be_changed } + it { should_not be_finished_a } + it { should_not be_finished_b } + end + + describe "an unchanged" do + subject { described_class.new("=", 0, "element") } + it { should_not be_deleting } + it { should_not be_adding } + it { should be_unchanged } + it { should_not be_changed } + it { should_not be_finished_a } + it { should_not be_finished_b } + end + + describe "a changed" do + subject { described_class.new("!", 0, "element") } + it { should_not be_deleting } + it { should_not be_adding } + it { should_not be_unchanged } + it { should be_changed } + it { should_not be_finished_a } + it { should_not be_finished_b } + end + + describe "a finished_a" do + subject { described_class.new(">", 0, "element") } + it { should_not be_deleting } + it { should_not be_adding } + it { should_not be_unchanged } + it { should_not be_changed } + it { should be_finished_a } + it { should_not be_finished_b } + end + + describe "a finished_b" do + subject { described_class.new("<", 0, "element") } + it { should_not be_deleting } + it { should_not be_adding } + it { should_not be_unchanged } + it { should_not be_changed } + it { should_not be_finished_a } + it { should be_finished_b } + end + + describe "as array" do + it "should be converted" do + action, position, element = described_class.new("!", 0, "element") + expect(action).to eq "!" + expect(position).to eq 0 + expect(element).to eq "element" + end + end +end + +describe Diff::LCS::ContextChange do + describe "as array" do + it "should be converted" do + action, (old_position, old_element), (new_position, new_element) = + described_class.new("!", 1, "old_element", 2, "new_element") + + expect(action).to eq "!" + expect(old_position).to eq 1 + expect(old_element).to eq "old_element" + expect(new_position).to eq 2 + expect(new_element).to eq "new_element" + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/diff_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/diff_spec.rb new file mode 100644 index 0000000..869f098 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/diff_spec.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Diff::LCS, ".diff" do + include Diff::LCS::SpecHelper::Matchers + + it "correctly diffs seq1 to seq2" do + diff_s1_s2 = Diff::LCS.diff(seq1, seq2) + expect(change_diff(correct_forward_diff)).to eq(diff_s1_s2) + end + + it "correctly diffs seq2 to seq1" do + diff_s2_s1 = Diff::LCS.diff(seq2, seq1) + expect(change_diff(correct_backward_diff)).to eq(diff_s2_s1) + end + + it "correctly diffs against an empty sequence" do + diff = Diff::LCS.diff(word_sequence, []) + correct_diff = [ + [ + ["-", 0, "abcd"], + ["-", 1, "efgh"], + ["-", 2, "ijkl"], + ["-", 3, "mnopqrstuvwxyz"] + ] + ] + + expect(change_diff(correct_diff)).to eq(diff) + + diff = Diff::LCS.diff([], word_sequence) + correct_diff.each do |hunk| + hunk.each { |change| change[0] = "+" } + end + expect(change_diff(correct_diff)).to eq(diff) + end + + it "correctly diffs 'xx' and 'xaxb'" do + left = "xx" + right = "xaxb" + expect(Diff::LCS.patch(left, Diff::LCS.diff(left, right))).to eq(right) + end + + it "returns an empty diff with (hello, hello)" do + expect(Diff::LCS.diff(hello, hello)).to be_empty + end + + it "returns an empty diff with (hello_ary, hello_ary)" do + expect(Diff::LCS.diff(hello_ary, hello_ary)).to be_empty + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/123_x b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/123_x new file mode 100644 index 0000000..cd34c23 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/123_x @@ -0,0 +1,2 @@ +123 +x diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/456_x b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/456_x new file mode 100644 index 0000000..9a823ac --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/456_x @@ -0,0 +1,2 @@ +456 +x diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/aX b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/aX new file mode 100644 index 0000000..5765d6a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/aX @@ -0,0 +1 @@ +aX diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/bXaX b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/bXaX new file mode 100644 index 0000000..a1c813d --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/bXaX @@ -0,0 +1 @@ +bXaX diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ds1.csv b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ds1.csv new file mode 100644 index 0000000..9ac8428 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ds1.csv @@ -0,0 +1,50 @@ +1,3 +2,7 +3,13 +4,21 +5,31 +6,43 +7,57 +8,73 +9,91 +10,111 +11,133 +12,157 +13,183 +14,211 +15,241 +16,273 +17,307 +18,343 +19,381 +20,421 +21,463 +22,507 +23,553 +24,601 +25,651 +26,703 +27,757 +28,813 +29,871 +30,931 +31,993 +32,1057 +33,1123 +34,1191 +35,1261 +36,1333 +37,1407 +38,1483 +39,1561 +40,1641 +41,1723 +42,1807 +43,1893 +44,1981 +45,2071 +46,2163 +47,2257 +48,2353 +49,2451 +50,2500 \ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ds2.csv b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ds2.csv new file mode 100644 index 0000000..797de76 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ds2.csv @@ -0,0 +1,51 @@ + 1,3 +2,7 +3,13 +4,21 +5,31 +6,42 +7,57 +8,73 +9,91 +10,111 +11,133 +12,157 +13,183 +14,211 +15,241 +16,273 +17,307 +18,343 +19,200 +20,421 +21,463 +22,507 +23,553 +24,601 +25,651 +26,703 +27,757 +28,813 +29,871 +30,931 +31,123 +32,1057 +33,1123 +34,1000 +35,1261 +36,1333 +37,1407 +38,1483 +39,1561 +40,1641 +41,1723 +42,1807 +43,1893 +44,1981 +45,2071 +46,2163 +47,1524 +48,2353 +49,2451 +50,2500 +51,2520 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/empty b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/empty new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/file1.bin b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/file1.bin new file mode 100644 index 0000000..f76dd23 Binary files /dev/null and b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/file1.bin differ diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/file2.bin b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/file2.bin new file mode 100644 index 0000000..ba18e3d Binary files /dev/null and b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/file2.bin differ diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines new file mode 100644 index 0000000..f384549 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines @@ -0,0 +1,4 @@ +one +two +three +four diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines_with_missing_new_line b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines_with_missing_new_line new file mode 100644 index 0000000..c40a3bd --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines_with_missing_new_line @@ -0,0 +1,4 @@ +one +two +three +four \ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-e new file mode 100644 index 0000000..1e8a89c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-e @@ -0,0 +1 @@ +No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-f new file mode 100644 index 0000000..1e8a89c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-f @@ -0,0 +1 @@ +No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-e new file mode 100644 index 0000000..1e8a89c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-e @@ -0,0 +1 @@ +No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-f new file mode 100644 index 0000000..1e8a89c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-f @@ -0,0 +1 @@ +No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-e new file mode 100644 index 0000000..8ed0319 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-e @@ -0,0 +1,2 @@ +: No newline at end of file +: No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-f new file mode 100644 index 0000000..8ed0319 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-f @@ -0,0 +1,2 @@ +: No newline at end of file +: No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-e new file mode 100644 index 0000000..397dd5b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-e @@ -0,0 +1 @@ +: No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-f new file mode 100644 index 0000000..397dd5b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-f @@ -0,0 +1 @@ +: No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-e new file mode 100644 index 0000000..f9493ef --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-e @@ -0,0 +1 @@ +: No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-f new file mode 100644 index 0000000..f9493ef --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-f @@ -0,0 +1 @@ +: No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff new file mode 100644 index 0000000..fa1a347 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff @@ -0,0 +1,4 @@ +1c1 +< aX +--- +> bXaX diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-c new file mode 100644 index 0000000..0e1ad99 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-c @@ -0,0 +1,7 @@ +*** spec/fixtures/aX 2020-06-23 11:15:32.000000000 -0400 +--- spec/fixtures/bXaX 2020-06-23 11:15:32.000000000 -0400 +*************** +*** 1 **** +! aX +--- 1 ---- +! bXaX diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-e new file mode 100644 index 0000000..13e0f7f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-e @@ -0,0 +1,3 @@ +1c +bXaX +. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-f new file mode 100644 index 0000000..77710c7 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-f @@ -0,0 +1,3 @@ +c1 +bXaX +. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-u new file mode 100644 index 0000000..b84f718 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-u @@ -0,0 +1,5 @@ +--- spec/fixtures/aX 2020-06-23 11:15:32.000000000 -0400 ++++ spec/fixtures/bXaX 2020-06-23 11:15:32.000000000 -0400 +@@ -1 +1 @@ +-aX ++bXaX diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1 b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1 new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-c new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-e new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-f new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-u new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2 b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2 new file mode 100644 index 0000000..41b625c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2 @@ -0,0 +1 @@ +Binary files spec/fixtures/file1.bin and spec/fixtures/file2.bin differ diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-c new file mode 100644 index 0000000..41b625c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-c @@ -0,0 +1 @@ +Binary files spec/fixtures/file1.bin and spec/fixtures/file2.bin differ diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-e new file mode 100644 index 0000000..41b625c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-e @@ -0,0 +1 @@ +Binary files spec/fixtures/file1.bin and spec/fixtures/file2.bin differ diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-f new file mode 100644 index 0000000..41b625c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-f @@ -0,0 +1 @@ +Binary files spec/fixtures/file1.bin and spec/fixtures/file2.bin differ diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-u new file mode 100644 index 0000000..41b625c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-u @@ -0,0 +1 @@ +Binary files spec/fixtures/file1.bin and spec/fixtures/file2.bin differ diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef new file mode 100644 index 0000000..8b98efb --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef @@ -0,0 +1,4 @@ +3c3 +< "description": "hi" +--- +> "description": "lo" diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-c new file mode 100644 index 0000000..efbfa19 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-c @@ -0,0 +1,15 @@ +*** spec/fixtures/old-chef 2020-06-23 23:18:20.000000000 -0400 +--- spec/fixtures/new-chef 2020-06-23 23:18:20.000000000 -0400 +*************** +*** 1,4 **** + { + "name": "x", +! "description": "hi" + } +\ No newline at end of file +--- 1,4 ---- + { + "name": "x", +! "description": "lo" + } +\ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-e new file mode 100644 index 0000000..775d881 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-e @@ -0,0 +1,3 @@ +3c + "description": "lo" +. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-f new file mode 100644 index 0000000..9bf1e67 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-f @@ -0,0 +1,3 @@ +c3 + "description": "lo" +. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-u new file mode 100644 index 0000000..dbacd88 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-u @@ -0,0 +1,9 @@ +--- spec/fixtures/old-chef 2020-06-23 23:18:20.000000000 -0400 ++++ spec/fixtures/new-chef 2020-06-23 23:18:20.000000000 -0400 +@@ -1,4 +1,4 @@ + { + "name": "x", +- "description": "hi" ++ "description": "lo" + } +\ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2 b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2 new file mode 100644 index 0000000..496b3dc --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2 @@ -0,0 +1,7 @@ +2d1 +< recipe[b::default] +14a14,17 +> recipe[o::new] +> recipe[p::new] +> recipe[q::new] +> recipe[r::new] diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-c new file mode 100644 index 0000000..8349a7a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-c @@ -0,0 +1,20 @@ +*** spec/fixtures/old-chef2 2020-06-30 09:43:35.000000000 -0400 +--- spec/fixtures/new-chef2 2020-06-30 09:44:32.000000000 -0400 +*************** +*** 1,5 **** + recipe[a::default] +- recipe[b::default] + recipe[c::default] + recipe[d::default] + recipe[e::default] +--- 1,4 ---- +*************** +*** 12,14 **** +--- 11,17 ---- + recipe[l::default] + recipe[m::default] + recipe[n::default] ++ recipe[o::new] ++ recipe[p::new] ++ recipe[q::new] ++ recipe[r::new] diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-d b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-d new file mode 100644 index 0000000..ca32a49 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-d @@ -0,0 +1,7 @@ +d2 +a14 +recipe[o::new] +recipe[p::new] +recipe[q::new] +recipe[r::new] +. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-e new file mode 100644 index 0000000..89f3fa0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-e @@ -0,0 +1,7 @@ +14a +recipe[o::new] +recipe[p::new] +recipe[q::new] +recipe[r::new] +. +2d diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-f new file mode 100644 index 0000000..ca32a49 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-f @@ -0,0 +1,7 @@ +d2 +a14 +recipe[o::new] +recipe[p::new] +recipe[q::new] +recipe[r::new] +. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-u new file mode 100644 index 0000000..ef025c7 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-u @@ -0,0 +1,16 @@ +--- spec/fixtures/old-chef2 2020-06-30 09:43:35.000000000 -0400 ++++ spec/fixtures/new-chef2 2020-06-30 09:44:32.000000000 -0400 +@@ -1,5 +1,4 @@ + recipe[a::default] +-recipe[b::default] + recipe[c::default] + recipe[d::default] + recipe[e::default] +@@ -12,3 +11,7 @@ + recipe[l::default] + recipe[m::default] + recipe[n::default] ++recipe[o::new] ++recipe[p::new] ++recipe[q::new] ++recipe[r::new] diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines new file mode 100644 index 0000000..e2afc31 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines @@ -0,0 +1,5 @@ +0a1,4 +> one +> two +> three +> four diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-c new file mode 100644 index 0000000..be0e827 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-c @@ -0,0 +1,9 @@ +*** spec/fixtures/empty 2025-01-31 12:14:52.856031635 +0100 +--- spec/fixtures/four_lines 2025-01-31 12:13:45.476036544 +0100 +*************** +*** 0 **** +--- 1,4 ---- ++ one ++ two ++ three ++ four diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-e new file mode 100644 index 0000000..f8f92fe --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-e @@ -0,0 +1,6 @@ +0a +one +two +three +four +. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-f new file mode 100644 index 0000000..f02e5a0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-f @@ -0,0 +1,6 @@ +a0 +one +two +three +four +. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-u new file mode 100644 index 0000000..60bd55c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-u @@ -0,0 +1,7 @@ +--- spec/fixtures/empty 2025-01-31 12:14:52.856031635 +0100 ++++ spec/fixtures/four_lines 2025-01-31 12:13:45.476036544 +0100 +@@ -0,0 +1,4 @@ ++one ++two ++three ++four diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty new file mode 100644 index 0000000..67d0a58 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty @@ -0,0 +1,5 @@ +1,4d0 +< one +< two +< three +< four diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-c new file mode 100644 index 0000000..b216344 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-c @@ -0,0 +1,9 @@ +*** spec/fixtures/four_lines 2025-01-31 12:13:45.476036544 +0100 +--- spec/fixtures/empty 2025-01-31 12:14:52.856031635 +0100 +*************** +*** 1,4 **** +- one +- two +- three +- four +--- 0 ---- diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-e new file mode 100644 index 0000000..c821d7c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-e @@ -0,0 +1 @@ +1,4d diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-f new file mode 100644 index 0000000..442bd5a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-f @@ -0,0 +1 @@ +d1 4 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-u new file mode 100644 index 0000000..79e6d75 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-u @@ -0,0 +1,7 @@ +--- spec/fixtures/four_lines 2025-01-31 12:13:45.476036544 +0100 ++++ spec/fixtures/empty 2025-01-31 12:14:52.856031635 +0100 +@@ -1,4 +0,0 @@ +-one +-two +-three +-four diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context new file mode 100644 index 0000000..4335560 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context @@ -0,0 +1,4 @@ +1c1 +< 123 +--- +> 456 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-c new file mode 100644 index 0000000..4b759fa --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-c @@ -0,0 +1,9 @@ +*** spec/fixtures/123_x 2025-01-31 17:00:17.070615716 +0100 +--- spec/fixtures/456_x 2025-01-31 16:58:26.380624827 +0100 +*************** +*** 1,2 **** +! 123 + x +--- 1,2 ---- +! 456 + x diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-e new file mode 100644 index 0000000..7a8334b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-e @@ -0,0 +1,3 @@ +1c +456 +. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-f new file mode 100644 index 0000000..97223a8 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-f @@ -0,0 +1,3 @@ +c1 +456 +. diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-u new file mode 100644 index 0000000..7fbf0e2 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-u @@ -0,0 +1,6 @@ +--- spec/fixtures/123_x 2025-01-31 17:00:17.070615716 +0100 ++++ spec/fixtures/456_x 2025-01-31 16:58:26.380624827 +0100 +@@ -1,2 +1,2 @@ +-123 ++456 + x diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1 b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1 new file mode 100644 index 0000000..c5cb113 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1 @@ -0,0 +1,5 @@ +4c4 +< four +--- +> four +\ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-c new file mode 100644 index 0000000..55d1ade --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-c @@ -0,0 +1,14 @@ +*** spec/fixtures/four_lines 2025-01-31 12:17:43.926013315 +0100 +--- spec/fixtures/four_lines_with_missing_new_line 2025-01-31 12:17:43.926013315 +0100 +*************** +*** 1,4 **** + one + two + three +! four +--- 1,4 ---- + one + two + three +! four +\ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-e new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-f new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-u new file mode 100644 index 0000000..010518b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-u @@ -0,0 +1,9 @@ +--- spec/fixtures/four_lines 2025-01-31 12:17:43.926013315 +0100 ++++ spec/fixtures/four_lines_with_missing_new_line 2025-01-31 12:17:43.926013315 +0100 +@@ -1,4 +1,4 @@ + one + two + three +-four ++four +\ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2 b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2 new file mode 100644 index 0000000..10e4326 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2 @@ -0,0 +1,5 @@ +4c4 +< four +\ No newline at end of file +--- +> four diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-c b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-c new file mode 100644 index 0000000..b431030 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-c @@ -0,0 +1,14 @@ +*** spec/fixtures/four_lines_with_missing_new_line 2025-01-31 12:17:43.926013315 +0100 +--- spec/fixtures/four_lines 2025-01-31 12:17:43.926013315 +0100 +*************** +*** 1,4 **** + one + two + three +! four +\ No newline at end of file +--- 1,4 ---- + one + two + three +! four diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-e b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-e new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-f b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-f new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-u b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-u new file mode 100644 index 0000000..2481a9e --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-u @@ -0,0 +1,9 @@ +--- spec/fixtures/four_lines_with_missing_new_line 2025-01-31 12:17:43.926013315 +0100 ++++ spec/fixtures/four_lines 2025-01-31 12:17:43.926013315 +0100 +@@ -1,4 +1,4 @@ + one + two + three +-four +\ No newline at end of file ++four diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef new file mode 100644 index 0000000..d7babfe --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef @@ -0,0 +1,4 @@ +{ + "name": "x", + "description": "lo" +} \ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef2 b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef2 new file mode 100644 index 0000000..8213c73 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef2 @@ -0,0 +1,17 @@ +recipe[a::default] +recipe[c::default] +recipe[d::default] +recipe[e::default] +recipe[f::default] +recipe[g::default] +recipe[h::default] +recipe[i::default] +recipe[j::default] +recipe[k::default] +recipe[l::default] +recipe[m::default] +recipe[n::default] +recipe[o::new] +recipe[p::new] +recipe[q::new] +recipe[r::new] diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef new file mode 100644 index 0000000..5f9e38b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef @@ -0,0 +1,4 @@ +{ + "name": "x", + "description": "hi" +} \ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef2 b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef2 new file mode 100644 index 0000000..4a23407 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef2 @@ -0,0 +1,14 @@ +recipe[a::default] +recipe[b::default] +recipe[c::default] +recipe[d::default] +recipe[e::default] +recipe[f::default] +recipe[g::default] +recipe[h::default] +recipe[i::default] +recipe[j::default] +recipe[k::default] +recipe[l::default] +recipe[m::default] +recipe[n::default] diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/hunk_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/hunk_spec.rb new file mode 100644 index 0000000..7d91039 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/hunk_spec.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +require "spec_helper" + +if String.method_defined?(:encoding) + require "diff/lcs/hunk" + + describe Diff::LCS::Hunk do + let(:old_data) { ["Tu a un carté avec {count} itéms".encode("UTF-16LE")] } + let(:new_data) { ["Tu a un carte avec {count} items".encode("UTF-16LE")] } + let(:pieces) { Diff::LCS.diff old_data, new_data } + let(:hunk) { Diff::LCS::Hunk.new(old_data, new_data, pieces[0], 3, 0) } + + it "produces a unified diff from the two pieces" do + expected = <<-EXPECTED.gsub(/^\s+/, "").encode("UTF-16LE").chomp + @@ -1 +1 @@ + -Tu a un carté avec {count} itéms + +Tu a un carte avec {count} items + EXPECTED + + expect(hunk.diff(:unified)).to eq(expected) + end + + it "produces a unified diff from the two pieces (last entry)" do + expected = <<-EXPECTED.gsub(/^\s+/, "").encode("UTF-16LE").chomp + @@ -1 +1 @@ + -Tu a un carté avec {count} itéms + +Tu a un carte avec {count} items + \\ No newline at end of file + EXPECTED + + expect(hunk.diff(:unified, true)).to eq(expected) + end + + it "produces a context diff from the two pieces" do + expected = <<-EXPECTED.gsub(/^\s+/, "").encode("UTF-16LE").chomp + *************** + *** 1 **** + ! Tu a un carté avec {count} itéms + --- 1 ---- + ! Tu a un carte avec {count} items + EXPECTED + + expect(hunk.diff(:context)).to eq(expected) + end + + it "produces an old diff from the two pieces" do + expected = <<-EXPECTED.gsub(/^ +/, "").encode("UTF-16LE").chomp + 1c1 + < Tu a un carté avec {count} itéms + --- + > Tu a un carte avec {count} items + + EXPECTED + + expect(hunk.diff(:old)).to eq(expected) + end + + it "produces a reverse ed diff from the two pieces" do + expected = <<-EXPECTED.gsub(/^ +/, "").encode("UTF-16LE").chomp + c1 + Tu a un carte avec {count} items + . + + EXPECTED + + expect(hunk.diff(:reverse_ed)).to eq(expected) + end + + context "with empty first data set" do + let(:old_data) { [] } + + it "produces a unified diff" do + expected = <<-EXPECTED.gsub(/^\s+/, "").encode("UTF-16LE").chomp + @@ -0,0 +1 @@ + +Tu a un carte avec {count} items + EXPECTED + + expect(hunk.diff(:unified)).to eq(expected) + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/issues_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/issues_spec.rb new file mode 100644 index 0000000..5b0fb2a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/issues_spec.rb @@ -0,0 +1,160 @@ +# frozen_string_literal: true + +require "spec_helper" +require "diff/lcs/hunk" + +describe "Diff::LCS Issues" do + include Diff::LCS::SpecHelper::Matchers + + describe "issue #1" do + shared_examples "handles simple diffs" do |s1, s2, forward_diff| + before do + @diff_s1_s2 = Diff::LCS.diff(s1, s2) + end + + it "creates the correct diff" do + expect(change_diff(forward_diff)).to eq(@diff_s1_s2) + end + + it "creates the correct patch s1->s2" do + expect(Diff::LCS.patch(s1, @diff_s1_s2)).to eq(s2) + end + + it "creates the correct patch s2->s1" do + expect(Diff::LCS.patch(s2, @diff_s1_s2)).to eq(s1) + end + end + + describe "string" do + it_has_behavior "handles simple diffs", "aX", "bXaX", [ + [ + ["+", 0, "b"], + ["+", 1, "X"] + ] + ] + it_has_behavior "handles simple diffs", "bXaX", "aX", [ + [ + ["-", 0, "b"], + ["-", 1, "X"] + ] + ] + end + + describe "array" do + it_has_behavior "handles simple diffs", %w[a X], %w[b X a X], [ + [ + ["+", 0, "b"], + ["+", 1, "X"] + ] + ] + it_has_behavior "handles simple diffs", %w[b X a X], %w[a X], [ + [ + ["-", 0, "b"], + ["-", 1, "X"] + ] + ] + end + end + + describe "issue #57" do + it "should fail with a correct error" do + # standard:disable Style/HashSyntax + expect { + actual = {:category => "app.rack.request"} + expected = {:category => "rack.middleware", :title => "Anonymous Middleware"} + expect(actual).to eq(expected) + }.to raise_error(RSpec::Expectations::ExpectationNotMetError) + # standard:enable Style/HashSyntax + end + end + + describe "issue #65" do + def diff_lines(old_lines, new_lines) + file_length_difference = 0 + previous_hunk = nil + output = [] + + Diff::LCS.diff(old_lines, new_lines).each do |piece| + hunk = Diff::LCS::Hunk.new(old_lines, new_lines, piece, 3, file_length_difference) + file_length_difference = hunk.file_length_difference + maybe_contiguous_hunks = previous_hunk.nil? || hunk.merge(previous_hunk) + + output << "#{previous_hunk.diff(:unified)}\n" unless maybe_contiguous_hunks + + previous_hunk = hunk + end + output << "#{previous_hunk.diff(:unified, true)}\n" unless previous_hunk.nil? + output.join + end + + it "should not misplace the new chunk" do + old_data = [ + "recipe[a::default]", "recipe[b::default]", "recipe[c::default]", + "recipe[d::default]", "recipe[e::default]", "recipe[f::default]", + "recipe[g::default]", "recipe[h::default]", "recipe[i::default]", + "recipe[j::default]", "recipe[k::default]", "recipe[l::default]", + "recipe[m::default]", "recipe[n::default]" + ] + + new_data = [ + "recipe[a::default]", "recipe[c::default]", "recipe[d::default]", + "recipe[e::default]", "recipe[f::default]", "recipe[g::default]", + "recipe[h::default]", "recipe[i::default]", "recipe[j::default]", + "recipe[k::default]", "recipe[l::default]", "recipe[m::default]", + "recipe[n::default]", "recipe[o::new]", "recipe[p::new]", + "recipe[q::new]", "recipe[r::new]" + ] + + # standard:disable Layout/HeredocIndentation + expect(diff_lines(old_data, new_data)).to eq(<<-EODIFF) +@@ -1,5 +1,4 @@ + recipe[a::default] +-recipe[b::default] + recipe[c::default] + recipe[d::default] + recipe[e::default] +@@ -12,3 +11,7 @@ + recipe[l::default] + recipe[m::default] + recipe[n::default] ++recipe[o::new] ++recipe[p::new] ++recipe[q::new] ++recipe[r::new] + EODIFF + # standard:enable Layout/HeredocIndentation + end + end + + describe "issue #107 (replaces issue #60)" do + it "should produce unified output with correct context" do + # standard:disable Layout/HeredocIndentation + old_data = <<-DATA_OLD.strip.split("\n").map(&:chomp) +{ + "name": "x", + "description": "hi" +} + DATA_OLD + + new_data = <<-DATA_NEW.strip.split("\n").map(&:chomp) +{ + "name": "x", + "description": "lo" +} + DATA_NEW + + diff = ::Diff::LCS.diff(old_data, new_data) + hunk = ::Diff::LCS::Hunk.new(old_data, new_data, diff.first, 3, 0) + + expect(hunk.diff(:unified)).to eq(<<-EXPECTED.chomp) +@@ -1,4 +1,4 @@ + { + "name": "x", +- "description": "hi" ++ "description": "lo" + } + EXPECTED + # standard:enable Layout/HeredocIndentation + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/lcs_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/lcs_spec.rb new file mode 100644 index 0000000..c17f22f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/lcs_spec.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Diff::LCS::Internals, ".lcs" do + include Diff::LCS::SpecHelper::Matchers + + it "returns a meaningful LCS array with (seq1, seq2)" do + res = Diff::LCS::Internals.lcs(seq1, seq2) + # The result of the LCS (less the +nil+ values) must be as long as the + # correct result. + expect(res.compact.size).to eq(correct_lcs.size) + expect(res).to correctly_map_sequence(seq1).to_other_sequence(seq2) + + # Compact these transformations and they should be the correct LCS. + x_seq1 = (0...res.size).map { |ix| res[ix] ? seq1[ix] : nil }.compact + x_seq2 = (0...res.size).map { |ix| res[ix] ? seq2[res[ix]] : nil }.compact + + expect(x_seq1).to eq(correct_lcs) + expect(x_seq2).to eq(correct_lcs) + end + + it "returns all indexes with (hello, hello)" do + expect(Diff::LCS::Internals.lcs(hello, hello)).to \ + eq((0...hello.size).to_a) + end + + it "returns all indexes with (hello_ary, hello_ary)" do + expect(Diff::LCS::Internals.lcs(hello_ary, hello_ary)).to \ + eq((0...hello_ary.size).to_a) + end +end + +describe Diff::LCS, ".LCS" do + include Diff::LCS::SpecHelper::Matchers + + it "returns the correct compacted values from Diff::LCS.LCS" do + res = Diff::LCS.LCS(seq1, seq2) + expect(res).to eq(correct_lcs) + expect(res.compact).to eq(res) + end + + it "is transitive" do + res = Diff::LCS.LCS(seq2, seq1) + expect(res).to eq(correct_lcs) + expect(res.compact).to eq(res) + end + + it "returns %W(h e l l o) with (hello, hello)" do + expect(Diff::LCS.LCS(hello, hello)).to eq(hello.chars) + end + + it "returns hello_ary with (hello_ary, hello_ary)" do + expect(Diff::LCS.LCS(hello_ary, hello_ary)).to eq(hello_ary) + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/ldiff_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/ldiff_spec.rb new file mode 100644 index 0000000..e13b561 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/ldiff_spec.rb @@ -0,0 +1,100 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe "bin/ldiff" do + include CaptureSubprocessIO + + # standard:disable Style/HashSyntax + fixtures = [ + {:name => "diff", :left => "aX", :right => "bXaX", :diff => 1}, + {:name => "diff.missing_new_line1", :left => "four_lines", :right => "four_lines_with_missing_new_line", :diff => 1}, + {:name => "diff.missing_new_line2", :left => "four_lines_with_missing_new_line", :right => "four_lines", :diff => 1}, + {:name => "diff.issue95_trailing_context", :left => "123_x", :right => "456_x", :diff => 1}, + {:name => "diff.four_lines.vs.empty", :left => "four_lines", :right => "empty", :diff => 1}, + {:name => "diff.empty.vs.four_lines", :left => "empty", :right => "four_lines", :diff => 1}, + {:name => "diff.bin1", :left => "file1.bin", :right => "file1.bin", :diff => 0}, + {:name => "diff.bin2", :left => "file1.bin", :right => "file2.bin", :diff => 1}, + {:name => "diff.chef", :left => "old-chef", :right => "new-chef", :diff => 1}, + {:name => "diff.chef2", :left => "old-chef2", :right => "new-chef2", :diff => 1} + ].product([nil, "-e", "-f", "-c", "-u"]).map { |(fixture, flag)| + fixture = fixture.dup + fixture[:flag] = flag + fixture + } + # standard:enable Style/HashSyntax + + def self.test_ldiff(fixture) + desc = [ + fixture[:flag], + "spec/fixtures/#{fixture[:left]}", + "spec/fixtures/#{fixture[:right]}", + "#", + "=>", + "spec/fixtures/ldiff/output.#{fixture[:name]}#{fixture[:flag]}" + ].join(" ") + + it desc do + stdout, stderr, status = run_ldiff(fixture) + expect(status).to eq(fixture[:diff]) + expect(stderr).to eq(read_fixture(fixture, mode: "error", allow_missing: true)) + expect(stdout).to eq(read_fixture(fixture, mode: "output", allow_missing: false)) + end + end + + fixtures.each do |fixture| + test_ldiff(fixture) + end + + def read_fixture(options, mode: "output", allow_missing: false) + fixture = options.fetch(:name) + flag = options.fetch(:flag) + name = "spec/fixtures/ldiff/#{mode}.#{fixture}#{flag}" + + return "" if !::File.exist?(name) && allow_missing + + data = IO.__send__(IO.respond_to?(:binread) ? :binread : :read, name) + clean_data(data, flag) + end + + def clean_data(data, flag) + data = + case flag + when "-c", "-u" + clean_output_timestamp(data) + else + data + end + data.gsub(/\r\n?/, "\n") + end + + def clean_output_timestamp(data) + data.gsub( + %r{ + ^ + [-+*]{3} + \s* + spec/fixtures/(\S+) + \s* + \d{4}-\d\d-\d\d + \s* + \d\d:\d\d:\d\d(?:\.\d+) + \s* + (?:[-+]\d{4}|Z) + }x, + '*** spec/fixtures/\1 0000-00-00 :00 =>:00 =>00.000000000 -0000' + ) + end + + def run_ldiff(options) + flag = options.fetch(:flag) + left = options.fetch(:left) + right = options.fetch(:right) + + stdout, stderr = capture_subprocess_io do + system("ruby -Ilib bin/ldiff #{flag} spec/fixtures/#{left} spec/fixtures/#{right}") + end + + [clean_data(stdout, flag), stderr, $?.exitstatus] + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/patch_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/patch_spec.rb new file mode 100644 index 0000000..8fc3ee2 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/patch_spec.rb @@ -0,0 +1,416 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe "Diff::LCS.patch" do + include Diff::LCS::SpecHelper::Matchers + + shared_examples "patch sequences correctly" do + it "correctly patches left-to-right (patch autodiscovery)" do + expect(Diff::LCS.patch(s1, patch_set)).to eq(s2) + end + + it "correctly patches left-to-right (explicit patch)" do + expect(Diff::LCS.patch(s1, patch_set, :patch)).to eq(s2) + expect(Diff::LCS.patch!(s1, patch_set)).to eq(s2) + end + + it "correctly patches right-to-left (unpatch autodiscovery)" do + expect(Diff::LCS.patch(s2, patch_set)).to eq(s1) + end + + it "correctly patches right-to-left (explicit unpatch)" do + expect(Diff::LCS.patch(s2, patch_set, :unpatch)).to eq(s1) + expect(Diff::LCS.unpatch!(s2, patch_set)).to eq(s1) + end + end + + describe "using a Diff::LCS.diff patchset" do + describe "an empty patchset returns the source" do + it "works on a string (hello)" do + diff = Diff::LCS.diff(hello, hello) + expect(Diff::LCS.patch(hello, diff)).to eq(hello) + end + + it "works on an array %W(h e l l o)" do + diff = Diff::LCS.diff(hello_ary, hello_ary) + expect(Diff::LCS.patch(hello_ary, diff)).to eq(hello_ary) + end + end + + describe "with default diff callbacks (DiffCallbacks)" do + describe "forward (s1 -> s2)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq1 } + let(:s2) { seq2 } + let(:patch_set) { Diff::LCS.diff(seq1, seq2) } + end + end + + describe "reverse (s2 -> s1)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq2 } + let(:s2) { seq1 } + let(:patch_set) { Diff::LCS.diff(seq2, seq1) } + end + end + end + + describe "with context diff callbacks (ContextDiffCallbacks)" do + describe "forward (s1 -> s2)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq1 } + let(:s2) { seq2 } + let(:patch_set) { + Diff::LCS.diff(seq1, seq2, Diff::LCS::ContextDiffCallbacks) + } + end + end + + describe "reverse (s2 -> s1)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq2 } + let(:s2) { seq1 } + let(:patch_set) { + Diff::LCS.diff(seq2, seq1, Diff::LCS::ContextDiffCallbacks) + } + end + end + end + + describe "with sdiff callbacks (SDiffCallbacks)" do + describe "forward (s1 -> s2)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq1 } + let(:s2) { seq2 } + let(:patch_set) { + Diff::LCS.diff(seq1, seq2, Diff::LCS::SDiffCallbacks) + } + end + end + + describe "reverse (s2 -> s1)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq2 } + let(:s2) { seq1 } + let(:patch_set) { + Diff::LCS.diff(seq2, seq1, Diff::LCS::SDiffCallbacks) + } + end + end + end + end + + describe "using a Diff::LCS.sdiff patchset" do + describe "an empty patchset returns the source" do + it "works on a string (hello)" do + expect(Diff::LCS.patch(hello, Diff::LCS.sdiff(hello, hello))).to eq(hello) + end + + it "works on an array %W(h e l l o)" do + expect(Diff::LCS.patch(hello_ary, Diff::LCS.sdiff(hello_ary, hello_ary))).to eq(hello_ary) + end + end + + describe "with default diff callbacks (DiffCallbacks)" do + describe "forward (s1 -> s2)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq1 } + let(:s2) { seq2 } + let(:patch_set) { + Diff::LCS.sdiff(seq1, seq2, Diff::LCS::DiffCallbacks) + } + end + end + + describe "reverse (s2 -> s1)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq2 } + let(:s2) { seq1 } + let(:patch_set) { + Diff::LCS.sdiff(seq2, seq1, Diff::LCS::DiffCallbacks) + } + end + end + end + + describe "with context diff callbacks (DiffCallbacks)" do + describe "forward (s1 -> s2)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq1 } + let(:s2) { seq2 } + let(:patch_set) { + Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks) + } + end + end + + describe "reverse (s2 -> s1)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq2 } + let(:s2) { seq1 } + let(:patch_set) { + Diff::LCS.sdiff(seq2, seq1, Diff::LCS::ContextDiffCallbacks) + } + end + end + end + + describe "with sdiff callbacks (SDiffCallbacks)" do + describe "forward (s1 -> s2)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq1 } + let(:s2) { seq2 } + let(:patch_set) { Diff::LCS.sdiff(seq1, seq2) } + end + end + + describe "reverse (s2 -> s1)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq2 } + let(:s2) { seq1 } + let(:patch_set) { Diff::LCS.sdiff(seq2, seq1) } + end + end + end + end + + # Note: because of the error in autodiscovery ("does not autodiscover s1 + # to s2 patches"), this cannot use the "patch sequences correctly" shared + # set. Once the bug in autodiscovery is fixed, this can be converted as + # above. + describe "fix bug 891: patchsets do not contain the last equal part" do + before :each do + @s1 = %w[a b c d e f g h i j k] # standard:disable Layout/SpaceInsideArrayPercentLiteral + @s2 = %w[a b c d D e f g h i j k] + end + + describe "using Diff::LCS.diff with default diff callbacks" do + before :each do + @patch_set_s1_s2 = Diff::LCS.diff(@s1, @s2) + @patch_set_s2_s1 = Diff::LCS.diff(@s2, @s1) + end + + it "autodiscovers s1 to s2 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 the left-to-right patches" do + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1)).to eq(@s1) + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2)).to eq(@s1) + end + + it "correctly patches left-to-right (explicit patch)" do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2, :patch)).to eq(@s2) + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1, :patch)).to eq(@s1) + expect(Diff::LCS.patch!(@s1, @patch_set_s1_s2)).to eq(@s2) + expect(Diff::LCS.patch!(@s2, @patch_set_s2_s1)).to eq(@s1) + end + + it "correctly patches right-to-left (explicit unpatch)" do + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2, :unpatch)).to eq(@s1) + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1, :unpatch)).to eq(@s2) + expect(Diff::LCS.unpatch!(@s2, @patch_set_s1_s2)).to eq(@s1) + expect(Diff::LCS.unpatch!(@s1, @patch_set_s2_s1)).to eq(@s2) + end + end + + describe "using Diff::LCS.diff with context diff callbacks" do + before :each do + @patch_set_s1_s2 = Diff::LCS.diff(@s1, @s2, Diff::LCS::ContextDiffCallbacks) + @patch_set_s2_s1 = Diff::LCS.diff(@s2, @s1, Diff::LCS::ContextDiffCallbacks) + end + + it "autodiscovers s1 to s2 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 the left-to-right patches" do + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1)).to eq(@s1) + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2)).to eq(@s1) + end + + it "correctly patches left-to-right (explicit patch)" do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2, :patch)).to eq(@s2) + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1, :patch)).to eq(@s1) + expect(Diff::LCS.patch!(@s1, @patch_set_s1_s2)).to eq(@s2) + expect(Diff::LCS.patch!(@s2, @patch_set_s2_s1)).to eq(@s1) + end + + it "correctly patches right-to-left (explicit unpatch)" do + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2, :unpatch)).to eq(@s1) + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1, :unpatch)).to eq(@s2) + expect(Diff::LCS.unpatch!(@s2, @patch_set_s1_s2)).to eq(@s1) + expect(Diff::LCS.unpatch!(@s1, @patch_set_s2_s1)).to eq(@s2) + end + end + + describe "using Diff::LCS.diff with sdiff callbacks" do + before(:each) do + @patch_set_s1_s2 = Diff::LCS.diff(@s1, @s2, Diff::LCS::SDiffCallbacks) + @patch_set_s2_s1 = Diff::LCS.diff(@s2, @s1, Diff::LCS::SDiffCallbacks) + end + + it "autodiscovers s1 to s2 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 the left-to-right patches" do + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1)).to eq(@s1) + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2)).to eq(@s1) + end + + it "correctly patches left-to-right (explicit patch)" do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2, :patch)).to eq(@s2) + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1, :patch)).to eq(@s1) + expect(Diff::LCS.patch!(@s1, @patch_set_s1_s2)).to eq(@s2) + expect(Diff::LCS.patch!(@s2, @patch_set_s2_s1)).to eq(@s1) + end + + it "correctly patches right-to-left (explicit unpatch)" do + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2, :unpatch)).to eq(@s1) + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1, :unpatch)).to eq(@s2) + expect(Diff::LCS.unpatch!(@s2, @patch_set_s1_s2)).to eq(@s1) + expect(Diff::LCS.unpatch!(@s1, @patch_set_s2_s1)).to eq(@s2) + end + end + + describe "using Diff::LCS.sdiff with default sdiff callbacks" do + before(:each) do + @patch_set_s1_s2 = Diff::LCS.sdiff(@s1, @s2) + @patch_set_s2_s1 = Diff::LCS.sdiff(@s2, @s1) + end + + it "autodiscovers s1 to s2 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 the left-to-right patches" do + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1)).to eq(@s1) + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2)).to eq(@s1) + end + + it "correctly patches left-to-right (explicit patch)" do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2, :patch)).to eq(@s2) + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1, :patch)).to eq(@s1) + expect(Diff::LCS.patch!(@s1, @patch_set_s1_s2)).to eq(@s2) + expect(Diff::LCS.patch!(@s2, @patch_set_s2_s1)).to eq(@s1) + end + + it "correctly patches right-to-left (explicit unpatch)" do + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2, :unpatch)).to eq(@s1) + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1, :unpatch)).to eq(@s2) + expect(Diff::LCS.unpatch!(@s2, @patch_set_s1_s2)).to eq(@s1) + expect(Diff::LCS.unpatch!(@s1, @patch_set_s2_s1)).to eq(@s2) + end + end + + describe "using Diff::LCS.sdiff with context diff callbacks" do + before(:each) do + @patch_set_s1_s2 = Diff::LCS.sdiff(@s1, @s2, Diff::LCS::ContextDiffCallbacks) + @patch_set_s2_s1 = Diff::LCS.sdiff(@s2, @s1, Diff::LCS::ContextDiffCallbacks) + end + + it "autodiscovers s1 to s2 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 the left-to-right patches" do + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1)).to eq(@s1) + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2)).to eq(@s1) + end + + it "correctly patches left-to-right (explicit patch)" do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2, :patch)).to eq(@s2) + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1, :patch)).to eq(@s1) + expect(Diff::LCS.patch!(@s1, @patch_set_s1_s2)).to eq(@s2) + expect(Diff::LCS.patch!(@s2, @patch_set_s2_s1)).to eq(@s1) + end + + it "correctly patches right-to-left (explicit unpatch)" do + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2, :unpatch)).to eq(@s1) + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1, :unpatch)).to eq(@s2) + expect(Diff::LCS.unpatch!(@s2, @patch_set_s1_s2)).to eq(@s1) + expect(Diff::LCS.unpatch!(@s1, @patch_set_s2_s1)).to eq(@s2) + end + end + + describe "using Diff::LCS.sdiff with default diff callbacks" do + before(:each) do + @patch_set_s1_s2 = Diff::LCS.sdiff(@s1, @s2, Diff::LCS::DiffCallbacks) + @patch_set_s2_s1 = Diff::LCS.sdiff(@s2, @s1, Diff::LCS::DiffCallbacks) + end + + it "autodiscovers s1 to s2 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 the left-to-right patches" do + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1)).to eq(@s1) + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2)).to eq(@s1) + end + + it "correctly patches left-to-right (explicit patch)" do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2, :patch)).to eq(@s2) + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1, :patch)).to eq(@s1) + expect(Diff::LCS.patch!(@s1, @patch_set_s1_s2)).to eq(@s2) + expect(Diff::LCS.patch!(@s2, @patch_set_s2_s1)).to eq(@s1) + end + + it "correctly patches right-to-left (explicit unpatch)" do + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2, :unpatch)).to eq(@s1) + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1, :unpatch)).to eq(@s2) + expect(Diff::LCS.unpatch!(@s2, @patch_set_s1_s2)).to eq(@s1) + expect(Diff::LCS.unpatch!(@s1, @patch_set_s2_s1)).to eq(@s2) + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/sdiff_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/sdiff_spec.rb new file mode 100644 index 0000000..aded301 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/sdiff_spec.rb @@ -0,0 +1,216 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe "Diff::LCS.sdiff" do + include Diff::LCS::SpecHelper::Matchers + + shared_examples "compare sequences correctly" do + it "compares s1 -> s2 correctly" do + expect(Diff::LCS.sdiff(s1, s2)).to eq(context_diff(result)) + end + + it "compares s2 -> s1 correctly" do + expect(Diff::LCS.sdiff(s2, s1)).to eq(context_diff(reverse_sdiff(result))) + end + end + + describe "using seq1 & seq2" do + let(:s1) { seq1 } + let(:s2) { seq2 } + let(:result) { correct_forward_sdiff } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(abc def yyy xxx ghi jkl) & %w(abc dxf xxx ghi jkl)" do + let(:s1) { %w[abc def yyy xxx ghi jkl] } + let(:s2) { %w[abc dxf xxx ghi jkl] } + let(:result) { + # standard:disable Layout/ExtraSpacing + [ + ["=", [0, "abc"], [0, "abc"]], + ["!", [1, "def"], [1, "dxf"]], + ["-", [2, "yyy"], [2, nil]], + ["=", [3, "xxx"], [2, "xxx"]], + ["=", [4, "ghi"], [3, "ghi"]], + ["=", [5, "jkl"], [4, "jkl"]] + ] + # standard:enable Layout/ExtraSpacing + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(a b c d e) & %w(a e)" do + let(:s1) { %w[a b c d e] } + let(:s2) { %w[a e] } + let(:result) { + [ + ["=", [0, "a"], [0, "a"]], + ["-", [1, "b"], [1, nil]], + ["-", [2, "c"], [1, nil]], + ["-", [3, "d"], [1, nil]], + ["=", [4, "e"], [1, "e"]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(a e) & %w(a b c d e)" do + let(:s1) { %w[a e] } + let(:s2) { %w[a b c d e] } + let(:result) { + [ + ["=", [0, "a"], [0, "a"]], + ["+", [1, nil], [1, "b"]], + ["+", [1, nil], [2, "c"]], + ["+", [1, nil], [3, "d"]], + ["=", [1, "e"], [4, "e"]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(v x a e) & %w(w y a b c d e)" do + let(:s1) { %w[v x a e] } + let(:s2) { %w[w y a b c d e] } + let(:result) { + [ + ["!", [0, "v"], [0, "w"]], + ["!", [1, "x"], [1, "y"]], + ["=", [2, "a"], [2, "a"]], + ["+", [3, nil], [3, "b"]], + ["+", [3, nil], [4, "c"]], + ["+", [3, nil], [5, "d"]], + ["=", [3, "e"], [6, "e"]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(x a e) & %w(a b c d e)" do + let(:s1) { %w[x a e] } + let(:s2) { %w[a b c d e] } + let(:result) { + [ + ["-", [0, "x"], [0, nil]], + ["=", [1, "a"], [0, "a"]], + ["+", [2, nil], [1, "b"]], + ["+", [2, nil], [2, "c"]], + ["+", [2, nil], [3, "d"]], + ["=", [2, "e"], [4, "e"]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(a e) & %w(x a b c d e)" do + let(:s1) { %w[a e] } + let(:s2) { %w[x a b c d e] } + let(:result) { + [ + ["+", [0, nil], [0, "x"]], + ["=", [0, "a"], [1, "a"]], + ["+", [1, nil], [2, "b"]], + ["+", [1, nil], [3, "c"]], + ["+", [1, nil], [4, "d"]], + ["=", [1, "e"], [5, "e"]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(a e v) & %w(x a b c d e w x)" do + let(:s1) { %w[a e v] } + let(:s2) { %w[x a b c d e w x] } + let(:result) { + [ + ["+", [0, nil], [0, "x"]], + ["=", [0, "a"], [1, "a"]], + ["+", [1, nil], [2, "b"]], + ["+", [1, nil], [3, "c"]], + ["+", [1, nil], [4, "d"]], + ["=", [1, "e"], [5, "e"]], + ["!", [2, "v"], [6, "w"]], + ["+", [3, nil], [7, "x"]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w() & %w(a b c)" do + let(:s1) { %w[] } + let(:s2) { %w[a b c] } + let(:result) { + [ + ["+", [0, nil], [0, "a"]], + ["+", [0, nil], [1, "b"]], + ["+", [0, nil], [2, "c"]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(a b c) & %w(1)" do + let(:s1) { %w[a b c] } + let(:s2) { %w[1] } + let(:result) { + [ + ["!", [0, "a"], [0, "1"]], + ["-", [1, "b"], [1, nil]], + ["-", [2, "c"], [1, nil]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(a b c) & %w(c)" do + let(:s1) { %w[a b c] } + let(:s2) { %w[c] } + let(:result) { + [ + ["-", [0, "a"], [0, nil]], + ["-", [1, "b"], [0, nil]], + ["=", [2, "c"], [0, "c"]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(abcd efgh ijkl mnop) & []" do + let(:s1) { %w[abcd efgh ijkl mnop] } + let(:s2) { [] } + let(:result) { + [ + ["-", [0, "abcd"], [0, nil]], + ["-", [1, "efgh"], [0, nil]], + ["-", [2, "ijkl"], [0, nil]], + ["-", [3, "mnop"], [0, nil]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using [[1,2]] & []" do + let(:s1) { [[1, 2]] } + let(:s2) { [] } + let(:result) { + [ + ["-", [0, [1, 2]], [0, nil]] + ] + } + + it_has_behavior "compare sequences correctly" + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/spec_helper.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/spec_helper.rb new file mode 100644 index 0000000..baaa3d0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/spec_helper.rb @@ -0,0 +1,376 @@ +# frozen_string_literal: true + +require "rubygems" +require "pathname" + +require "psych" if RUBY_VERSION >= "1.9" + +if ENV["COVERAGE"] + require "simplecov" + require "simplecov-lcov" + + SimpleCov::Formatter::LcovFormatter.config do |config| + config.report_with_single_file = true + config.lcov_file_name = "lcov.info" + end + + SimpleCov.start "test_frameworks" do + enable_coverage :branch + primary_coverage :branch + formatter SimpleCov::Formatter::MultiFormatter.new([ + SimpleCov::Formatter::HTMLFormatter, + SimpleCov::Formatter::LcovFormatter, + SimpleCov::Formatter::SimpleFormatter + ]) + end +end + +file = Pathname.new(__FILE__).expand_path +path = file.parent +parent = path.parent + +$:.unshift parent.join("lib") + +module CaptureSubprocessIO + def _synchronize + yield + end + + def capture_subprocess_io + _synchronize { _capture_subprocess_io { yield } } + end + + def _capture_subprocess_io + require "tempfile" + + captured_stdout, captured_stderr = Tempfile.new("out"), Tempfile.new("err") + + orig_stdout, orig_stderr = $stdout.dup, $stderr.dup + $stdout.reopen captured_stdout + $stderr.reopen captured_stderr + + yield + + $stdout.rewind + $stderr.rewind + + [captured_stdout.read, captured_stderr.read] + ensure + captured_stdout.unlink + captured_stderr.unlink + $stdout.reopen orig_stdout + $stderr.reopen orig_stderr + end + private :_capture_subprocess_io +end + +require "diff-lcs" + +module Diff::LCS::SpecHelper + def hello + "hello" + end + + def hello_ary + %w[h e l l o] + end + + def seq1 + %w[a b c e h j l m n p] + end + + def skipped_seq1 + %w[a h n p] + end + + def seq2 + %w[b c d e f j k l m r s t] + end + + def skipped_seq2 + %w[d f k r s t] + end + + def word_sequence + %w[abcd efgh ijkl mnopqrstuvwxyz] + end + + def correct_lcs + %w[b c e j l m] + end + + # standard:disable Layout/ExtraSpacing + def correct_forward_diff + [ + [ + ["-", 0, "a"] + ], + [ + ["+", 2, "d"] + ], + [ + ["-", 4, "h"], + ["+", 4, "f"] + ], + [ + ["+", 6, "k"] + ], + [ + ["-", 8, "n"], + ["+", 9, "r"], + ["-", 9, "p"], + ["+", 10, "s"], + ["+", 11, "t"] + ] + ] + end + + def correct_backward_diff + [ + [ + ["+", 0, "a"] + ], + [ + ["-", 2, "d"] + ], + [ + ["-", 4, "f"], + ["+", 4, "h"] + ], + [ + ["-", 6, "k"] + ], + [ + ["-", 9, "r"], + ["+", 8, "n"], + ["-", 10, "s"], + ["+", 9, "p"], + ["-", 11, "t"] + ] + ] + end + + def correct_forward_sdiff + [ + ["-", [0, "a"], [0, nil]], + ["=", [1, "b"], [0, "b"]], + ["=", [2, "c"], [1, "c"]], + ["+", [3, nil], [2, "d"]], + ["=", [3, "e"], [3, "e"]], + ["!", [4, "h"], [4, "f"]], + ["=", [5, "j"], [5, "j"]], + ["+", [6, nil], [6, "k"]], + ["=", [6, "l"], [7, "l"]], + ["=", [7, "m"], [8, "m"]], + ["!", [8, "n"], [9, "r"]], + ["!", [9, "p"], [10, "s"]], + ["+", [10, nil], [11, "t"]] + ] + end + # standard:enable Layout/ExtraSpacing + + def reverse_sdiff(forward_sdiff) + forward_sdiff.map { |line| + line[1], line[2] = line[2], line[1] + case line[0] + when "-" then line[0] = "+" + when "+" then line[0] = "-" + end + line + } + end + + def change_diff(diff) + map_diffs(diff, Diff::LCS::Change) + end + + def context_diff(diff) + map_diffs(diff, Diff::LCS::ContextChange) + end + + def format_diffs(diffs) + diffs.map { |e| + if e.is_a?(Array) + e.map { |f| f.to_a.join }.join(", ") + else + e.to_a.join + end + }.join("\n") + end + + def map_diffs(diffs, klass = Diff::LCS::ContextChange) + diffs.map do |chunks| + if klass == Diff::LCS::ContextChange + klass.from_a(chunks) + else + chunks.map { |changes| klass.from_a(changes) } + end + end + end + + def balanced_traversal(s1, s2, callback_type) + callback = __send__(callback_type) + Diff::LCS.traverse_balanced(s1, s2, callback) + callback + end + + def balanced_reverse(change_result) + new_result = [] + change_result.each do |line| + line = [line[0], line[2], line[1]] + case line[0] + when "<" + line[0] = ">" + when ">" + line[0] = "<" + end + new_result << line + end + new_result.sort_by { |line| [line[1], line[2]] } + end + + def map_to_no_change(change_result) + new_result = [] + change_result.each do |line| + case line[0] + when "!" + new_result << ["<", line[1], line[2]] + new_result << [">", line[1] + 1, line[2]] + else + new_result << line + end + end + new_result + end + + class SimpleCallback + def initialize + reset + end + + attr_reader :matched_a + attr_reader :matched_b + attr_reader :discards_a + attr_reader :discards_b + attr_reader :done_a + attr_reader :done_b + + def reset + @matched_a = [] + @matched_b = [] + @discards_a = [] + @discards_b = [] + @done_a = [] + @done_b = [] + self + end + + def match(event) + @matched_a << event.old_element + @matched_b << event.new_element + end + + def discard_b(event) + @discards_b << event.new_element + end + + def discard_a(event) + @discards_a << event.old_element + end + + def finished_a(event) + @done_a << [ + event.old_element, event.old_position, + event.new_element, event.new_position + ] + end + + def finished_b(event) + @done_b << [ + event.old_element, event.old_position, + event.new_element, event.new_position + ] + end + end + + def simple_callback + SimpleCallback.new + end + + class SimpleCallbackNoFinishers < SimpleCallback + undef :finished_a + undef :finished_b + end + + def simple_callback_no_finishers + SimpleCallbackNoFinishers.new + end + + class BalancedCallback + def initialize + reset + end + + attr_reader :result + + def reset + @result = [] + end + + def match(event) + @result << ["=", event.old_position, event.new_position] + end + + def discard_a(event) + @result << ["<", event.old_position, event.new_position] + end + + def discard_b(event) + @result << [">", event.old_position, event.new_position] + end + + def change(event) + @result << ["!", event.old_position, event.new_position] + end + end + + def balanced_callback + BalancedCallback.new + end + + class BalancedCallbackNoChange < BalancedCallback + undef :change + end + + def balanced_callback_no_change + BalancedCallbackNoChange.new + end + + module Matchers + extend RSpec::Matchers::DSL + + matcher :be_nil_or_match_values do |ii, s1, s2| + match do |ee| + expect(ee).to(satisfy { |vee| vee.nil? || s1[ii] == s2[ee] }) + end + end + + matcher :correctly_map_sequence do |s1| + match do |actual| + actual.each_index { |ii| expect(actual[ii]).to be_nil_or_match_values(ii, s1, @s2) } + end + + chain :to_other_sequence do |s2| + @s2 = s2 + end + end + end +end + +RSpec.configure do |conf| + conf.include Diff::LCS::SpecHelper + conf.alias_it_should_behave_like_to :it_has_behavior, "has behavior:" + # standard:disable Style/HashSyntax + conf.filter_run_excluding :broken => true + # standard:enable Style/HashSyntax +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/traverse_balanced_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/traverse_balanced_spec.rb new file mode 100644 index 0000000..3a3f677 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/traverse_balanced_spec.rb @@ -0,0 +1,312 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe "Diff::LCS.traverse_balanced" do + include Diff::LCS::SpecHelper::Matchers + + shared_examples "with a #change callback" do |s1, s2, result| + it "traverses s1 -> s2 correctly" do + traversal = balanced_traversal(s1, s2, :balanced_callback) + expect(traversal.result).to eq(result) + end + + it "traverses s2 -> s1 correctly" do + traversal = balanced_traversal(s2, s1, :balanced_callback) + expect(traversal.result).to eq(balanced_reverse(result)) + end + end + + shared_examples "without a #change callback" do |s1, s2, result| + it "traverses s1 -> s2 correctly" do + traversal = balanced_traversal(s1, s2, :balanced_callback_no_change) + expect(traversal.result).to eq(map_to_no_change(result)) + end + + it "traverses s2 -> s1 correctly" do + traversal = balanced_traversal(s2, s1, :balanced_callback_no_change) + expect(traversal.result).to eq(map_to_no_change(balanced_reverse(result))) + end + end + + describe "identical string sequences ('abc')" do + s1 = s2 = "abc" + + result = [ + ["=", 0, 0], + ["=", 1, 1], + ["=", 2, 2] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "identical array sequences %w(a b c)" do + s1 = s2 = %w[a b c] + + result = [ + ["=", 0, 0], + ["=", 1, 1], + ["=", 2, 2] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "sequences %w(a b c) & %w(a x c)" do + s1 = %w[a b c] + s2 = %w[a x c] + + result = [ + ["=", 0, 0], + ["!", 1, 1], + ["=", 2, 2] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "sequences %w(a x y c) & %w(a v w c)" do + s1 = %w[a x y c] + s2 = %w[a v w c] + + result = [ + ["=", 0, 0], + ["!", 1, 1], + ["!", 2, 2], + ["=", 3, 3] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "sequences %w(x y c) & %w(v w c)" do + s1 = %w[x y c] + s2 = %w[v w c] + result = [ + ["!", 0, 0], + ["!", 1, 1], + ["=", 2, 2] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "sequences %w(a x y z) & %w(b v w)" do + s1 = %w[a x y z] + s2 = %w[b v w] + result = [ + ["!", 0, 0], + ["!", 1, 1], + ["!", 2, 2], + ["<", 3, 3] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "sequences %w(a z) & %w(a)" do + s1 = %w[a z] + s2 = %w[a] + result = [ + ["=", 0, 0], + ["<", 1, 1] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "sequences %w(z a) & %w(a)" do + s1 = %w[z a] + s2 = %w[a] + result = [ + ["<", 0, 0], + ["=", 1, 0] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "sequences %w(a b c) & %w(x y z)" do + s1 = %w[a b c] + s2 = %w[x y z] + result = [ + ["!", 0, 0], + ["!", 1, 1], + ["!", 2, 2] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "sequences %w(abcd efgh ijkl mnoopqrstuvwxyz) & []" do + s1 = %w[abcd efgh ijkl mnopqrstuvwxyz] + s2 = [] + result = [ + ["<", 0, 0], + ["<", 1, 0], + ["<", 2, 0], + ["<", 3, 0] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "strings %q(a b c) & %q(a x c)" do + s1 = "a b c" + s2 = "a x c" + + result = [ + ["=", 0, 0], + ["=", 1, 1], + ["!", 2, 2], + ["=", 3, 3], + ["=", 4, 4] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "strings %q(a x y c) & %q(a v w c)" do + s1 = "a x y c" + s2 = "a v w c" + + result = [ + ["=", 0, 0], + ["=", 1, 1], + ["!", 2, 2], + ["=", 3, 3], + ["!", 4, 4], + ["=", 5, 5], + ["=", 6, 6] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "strings %q(x y c) & %q(v w c)" do + s1 = "x y c" + s2 = "v w c" + result = [ + ["!", 0, 0], + ["=", 1, 1], + ["!", 2, 2], + ["=", 3, 3], + ["=", 4, 4] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "strings %q(a x y z) & %q(b v w)" do + s1 = "a x y z" + s2 = "b v w" + result = [ + ["!", 0, 0], + ["=", 1, 1], + ["!", 2, 2], + ["=", 3, 3], + ["!", 4, 4], + ["<", 5, 5], + ["<", 6, 5] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "strings %q(a z) & %q(a)" do + s1 = "a z" + s2 = "a" + result = [ + ["=", 0, 0], + ["<", 1, 1], + ["<", 2, 1] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "strings %q(z a) & %q(a)" do + s1 = "z a" + s2 = "a" + result = [ + ["<", 0, 0], + ["<", 1, 0], + ["=", 2, 0] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "strings %q(a b c) & %q(x y z)" do + s1 = "a b c" + s2 = "x y z" + result = [ + ["!", 0, 0], + ["=", 1, 1], + ["!", 2, 2], + ["=", 3, 3], + ["!", 4, 4] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "strings %q(abcd efgh ijkl mnopqrstuvwxyz) & %q()" do + s1 = "abcd efgh ijkl mnopqrstuvwxyz" + s2 = "" + # standard:disable Layout/ExtraSpacing + result = [ + ["<", 0, 0], + ["<", 1, 0], + ["<", 2, 0], + ["<", 3, 0], + ["<", 4, 0], + ["<", 5, 0], + ["<", 6, 0], + ["<", 7, 0], + ["<", 8, 0], + ["<", 9, 0], + ["<", 10, 0], + ["<", 11, 0], + ["<", 12, 0], + ["<", 13, 0], + ["<", 14, 0], + ["<", 15, 0], + ["<", 16, 0], + ["<", 17, 0], + ["<", 18, 0], + ["<", 19, 0], + ["<", 20, 0], + ["<", 21, 0], + ["<", 22, 0], + ["<", 23, 0], + ["<", 24, 0], + ["<", 25, 0], + ["<", 26, 0], + ["<", 27, 0], + ["<", 28, 0] + ] + # standard:enable Layout/ExtraSpacing + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/traverse_sequences_spec.rb b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/traverse_sequences_spec.rb new file mode 100644 index 0000000..8e9928f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/diff-lcs-1.6.2/spec/traverse_sequences_spec.rb @@ -0,0 +1,137 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe "Diff::LCS.traverse_sequences" do + describe "callback with no finishers" do + describe "over (seq1, seq2)" do + before(:each) do + @callback_s1_s2 = simple_callback_no_finishers + Diff::LCS.traverse_sequences(seq1, seq2, @callback_s1_s2) + + @callback_s2_s1 = simple_callback_no_finishers + Diff::LCS.traverse_sequences(seq2, seq1, @callback_s2_s1) + end + + it "has the correct LCS result on left-matches" do + expect(@callback_s1_s2.matched_a).to eq(correct_lcs) + expect(@callback_s2_s1.matched_a).to eq(correct_lcs) + end + + it "has the correct LCS result on right-matches" do + expect(@callback_s1_s2.matched_b).to eq(correct_lcs) + expect(@callback_s2_s1.matched_b).to eq(correct_lcs) + end + + it "has the correct skipped sequences with the left sequence" do + expect(@callback_s1_s2.discards_a).to eq(skipped_seq1) + expect(@callback_s2_s1.discards_a).to eq(skipped_seq2) + end + + it "has the correct skipped sequences with the right sequence" do + expect(@callback_s1_s2.discards_b).to eq(skipped_seq2) + expect(@callback_s2_s1.discards_b).to eq(skipped_seq1) + end + + it "does not have anything done markers from the left or right sequences" do + expect(@callback_s1_s2.done_a).to be_empty + expect(@callback_s1_s2.done_b).to be_empty + expect(@callback_s2_s1.done_a).to be_empty + expect(@callback_s2_s1.done_b).to be_empty + end + end + + describe "over (hello, hello)" do + before(:each) do + @callback = simple_callback_no_finishers + Diff::LCS.traverse_sequences(hello, hello, @callback) + end + + it "has the correct LCS result on left-matches" do + expect(@callback.matched_a).to eq(hello.chars) + end + + it "has the correct LCS result on right-matches" do + expect(@callback.matched_b).to eq(hello.chars) + end + + it "has the correct skipped sequences with the left sequence" do + expect(@callback.discards_a).to be_empty + end + + it "has the correct skipped sequences with the right sequence" do + expect(@callback.discards_b).to be_empty + end + + it "does not have anything done markers from the left or right sequences" do + expect(@callback.done_a).to be_empty + expect(@callback.done_b).to be_empty + end + end + + describe "over (hello_ary, hello_ary)" do + before(:each) do + @callback = simple_callback_no_finishers + Diff::LCS.traverse_sequences(hello_ary, hello_ary, @callback) + end + + it "has the correct LCS result on left-matches" do + expect(@callback.matched_a).to eq(hello_ary) + end + + it "has the correct LCS result on right-matches" do + expect(@callback.matched_b).to eq(hello_ary) + end + + it "has the correct skipped sequences with the left sequence" do + expect(@callback.discards_a).to be_empty + end + + it "has the correct skipped sequences with the right sequence" do + expect(@callback.discards_b).to be_empty + end + + it "does not have anything done markers from the left or right sequences" do + expect(@callback.done_a).to be_empty + expect(@callback.done_b).to be_empty + end + end + end + + describe "callback with finisher" do + before(:each) do + @callback_s1_s2 = simple_callback + Diff::LCS.traverse_sequences(seq1, seq2, @callback_s1_s2) + @callback_s2_s1 = simple_callback + Diff::LCS.traverse_sequences(seq2, seq1, @callback_s2_s1) + end + + it "has the correct LCS result on left-matches" do + expect(@callback_s1_s2.matched_a).to eq(correct_lcs) + expect(@callback_s2_s1.matched_a).to eq(correct_lcs) + end + + it "has the correct LCS result on right-matches" do + expect(@callback_s1_s2.matched_b).to eq(correct_lcs) + expect(@callback_s2_s1.matched_b).to eq(correct_lcs) + end + + it "has the correct skipped sequences for the left sequence" do + expect(@callback_s1_s2.discards_a).to eq(skipped_seq1) + expect(@callback_s2_s1.discards_a).to eq(skipped_seq2) + end + + it "has the correct skipped sequences for the right sequence" do + expect(@callback_s1_s2.discards_b).to eq(skipped_seq2) + expect(@callback_s2_s1.discards_b).to eq(skipped_seq1) + end + + it "has done markers differently-sized sequences" do + expect(@callback_s1_s2.done_a).to eq([["p", 9, "t", 11]]) + expect(@callback_s1_s2.done_b).to be_empty + + expect(@callback_s2_s1.done_a).to be_empty + expect(@callback_s2_s1.done_b).to eq([["t", 11, "p", 9]]) + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/.editorconfig b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/.editorconfig new file mode 100644 index 0000000..13c6966 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/.editorconfig @@ -0,0 +1,18 @@ +; This file is for unifying the coding style for different editors and IDEs. +; More information at http://EditorConfig.org + +root = true +[*] +end_of_line = lf +trim_trailing_whitespace = true + +[**.rb] +indent_size = 2 +indent_style = spaces +insert_final_newline = true + +[**.xml] +trim_trailing_whitespace = false + +[**.html] +trim_trailing_whitespace = false diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/.github/dependabot.yml b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/.github/dependabot.yml new file mode 100644 index 0000000..5ace460 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/.github/workflows/ci.yml b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/.github/workflows/ci.yml new file mode 100644 index 0000000..875c76a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/.github/workflows/ci.yml @@ -0,0 +1,24 @@ +name: CI +on: [push, pull_request] +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + ruby: + - 2.7 + - "3.0" # Quoted, to avoid YAML float 3.0 interplated to "3" + - 3.1 + - 3.2 + - 3.3 + - 3.4 + steps: + - name: Check out repository code + uses: actions/checkout@v4 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + bundler-cache: true # Run "bundle install", and cache the result automatically. + - name: Run Rake + run: bundle exec rake diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/.gitignore b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/.gitignore new file mode 100644 index 0000000..e6d2c64 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/.gitignore @@ -0,0 +1,14 @@ +Gemfile.lock +.DS_Store +.yardoc/ +doc/ +tmp/ +log/ +pkg/ +*.swp +/.bundle +.rvmrc +coverage +*.gem +.idea +.tool-versions diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/.rubocop.yml b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/.rubocop.yml new file mode 100644 index 0000000..d06156e --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/.rubocop.yml @@ -0,0 +1,92 @@ +inherit_from: .rubocop_todo.yml + +# Offense count: 963 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +Style/StringLiterals: + Enabled: false + +# Offense count: 327 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SupportedStyles. +Style/SpaceInsideHashLiteralBraces: + Enabled: false + +# Offense count: 33 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters. +Style/SpaceInsideBlockBraces: + Enabled: false + +# Offense count: 1 +# Cop supports --auto-correct. +Style/SpaceBeforeSemicolon: + Enabled: false + +# Offense count: 20 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +Style/SignalException: + Enabled: false + +# Offense count: 1 +# Configuration parameters: Methods. +Style/SingleLineBlockParams: + Enabled: false + +# Offense count: 6 +# Cop supports --auto-correct. +Style/PerlBackrefs: + Enabled: false + +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: AllowAsExpressionSeparator. +Style/Semicolon: + Enabled: false + +# Offense count: 77 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +Style/BracesAroundHashParameters: + Enabled: false + +# Offense count: 36 +Style/Documentation: + Enabled: false + +# Offense count: 6 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles, AllowInnerSlashes. +Style/RegexpLiteral: + Enabled: false + +# Offense count: 5 +# Cop supports --auto-correct. +Style/NumericLiterals: + MinDigits: 6 + +# Offense count: 4 +# Cop supports --auto-correct. +Lint/UnusedMethodArgument: + Enabled: false + +# Offense count: 11 +# Cop supports --auto-correct. +Lint/UnusedBlockArgument: + Enabled: false + +# Offense count: 1 +Lint/Void: + Enabled: false + +# Offense count: 22 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +Style/IndentHash: + Enabled: false + +# Offense count: 7 +# Configuration parameters: MinBodyLength. +Style/GuardClause: + Enabled: false diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/.rubocop_todo.yml b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/.rubocop_todo.yml new file mode 100644 index 0000000..be9903f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/.rubocop_todo.yml @@ -0,0 +1,124 @@ +# This configuration was generated by `rubocop --auto-gen-config` +# on 2015-04-24 07:22:28 +0200 using RuboCop version 0.30.0. +# The point is for the user to remove these configuration records +# one by one as the offenses are removed from the code base. +# Note that changes in the inspected code, or installation of new +# versions of RuboCop, may require this file to be generated again. + +# Offense count: 33 +Lint/AmbiguousRegexpLiteral: + Enabled: false + +# Offense count: 1 +# Configuration parameters: AlignWith, SupportedStyles. +Lint/EndAlignment: + Enabled: false + +# Offense count: 1 +Lint/SuppressedException: + Enabled: false + +# Offense count: 5 +Lint/UselessAssignment: + Enabled: false + +# Offense count: 23 +Metrics/AbcSize: + Max: 86 + +# Offense count: 1 +# Configuration parameters: CountComments. +Metrics/ClassLength: + Max: 285 + +# Offense count: 8 +Metrics/CyclomaticComplexity: + Max: 17 + +# Offense count: 332 +# Configuration parameters: AllowURI, URISchemes. +Metrics/LineLength: + Max: 266 + +# Offense count: 17 +# Configuration parameters: CountComments. +Metrics/MethodLength: + Max: 39 + +# Offense count: 8 +Metrics/PerceivedComplexity: + Max: 20 + +# Offense count: 1 +Style/AccessorMethodName: + Enabled: false + +# Offense count: 1 +Style/AsciiComments: + Enabled: false + +# Offense count: 14 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles, ProceduralMethods, FunctionalMethods, IgnoredMethods. +Style/BlockDelimiters: + Enabled: false + +# Offense count: 2 +Style/CaseEquality: + Enabled: false + +# Offense count: 3 +# Configuration parameters: IndentWhenRelativeTo, SupportedStyles, IndentOneStep. +Style/CaseIndentation: + Enabled: false + +# Offense count: 4 +# Configuration parameters: EnforcedStyle, SupportedStyles. +Style/ClassAndModuleChildren: + Enabled: false + +# Offense count: 7 +Style/ConstantName: + Enabled: false + +# Offense count: 2 +Style/EachWithObject: + Enabled: false + +# Offense count: 2 +# Cop supports --auto-correct. +Style/ElseAlignment: + Enabled: false + +# Offense count: 3 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +Style/FirstParameterIndentation: + Enabled: false + +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles, UseHashRocketsWithSymbolValues. +Style/HashSyntax: + Enabled: false + +# Offense count: 7 +# Cop supports --auto-correct. +# Configuration parameters: MaxLineLength. +Style/IfUnlessModifier: + Enabled: false + +# Offense count: 11 +# Cop supports --auto-correct. +Style/Lambda: + Enabled: false + +# Offense count: 1 +# Configuration parameters: EnforcedStyle, MinBodyLength, SupportedStyles. +Style/Next: + Enabled: false + +# Offense count: 2 +# Configuration parameters: EnforcedStyle, SupportedStyles. +Style/RaiseArgs: + Enabled: false diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/CONTRIBUTING.md b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/CONTRIBUTING.md new file mode 100644 index 0000000..3bac5b1 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/CONTRIBUTING.md @@ -0,0 +1,23 @@ +# Contributing + +* Contributions will not be accepted without tests. +* Please post unconfirmed bugs to the mailing list first: https://groups.google.com/forum/#!forum/httparty-gem +* Don't change the version. The maintainers will handle that when they release. +* Always provide as much information and reproducibility as possible when filing an issue or submitting a pull request. + +## Workflow + +* Fork the project. +* Run `bundle` +* Run `bundle exec rake` +* Make your feature addition or bug fix. +* Add tests for it. This is important so I don't break it in a future version unintentionally. +* Run `bundle exec rake` (No, REALLY :)) +* Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself in another branch so I can ignore when I pull) +* Send me a pull request. Bonus points for topic branches. + +## Help and Docs + +* https://groups.google.com/forum/#!forum/httparty-gem +* http://stackoverflow.com/questions/tagged/httparty +* http://rdoc.info/projects/jnunemaker/httparty diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/Changelog.md b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/Changelog.md new file mode 100644 index 0000000..e0fc332 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/Changelog.md @@ -0,0 +1,624 @@ +# Changelog + +All notable [changes since 0.22 are documented in GitHub Releases](https://github.com/jnunemaker/httparty/releases). + +## 0.21.0 + +- [escape filename in the multipart/form-data Content-Disposition header](https://github.com/jnunemaker/httparty/commit/cdb45a678c43e44570b4e73f84b1abeb5ec22b8e) +- [Fix request marshaling](https://github.com/jnunemaker/httparty/pull/767) +- [Replace `mime-types` with `mini_mime`](https://github.com/jnunemaker/httparty/pull/769) + +## 0.20.0 + +Breaking changes + +- Require Ruby >= 2.3.0 + +Fixes + +- [`Marshal.dump` fails on response objects when request option `:logger` is set or `:parser` is a proc](https://github.com/jnunemaker/httparty/pull/714) +- [Switch `:pem` option to to `OpenSSL::PKey.read` to support other algorithms](https://github.com/jnunemaker/httparty/pull/720) + +## 0.19.1 + +- [Remove use of unary + method for creating non-frozen string to increase compatibility with older versions of ruby](https://github.com/jnunemaker/httparty/commit/4416141d37fd71bdba4f37589ec265f55aa446ce) + +## 0.19.0 + +- [Multipart/Form-Data: rewind files after read](https://github.com/jnunemaker/httparty/pull/709) +- [add frozen_string_literal pragma to all files](https://github.com/jnunemaker/httparty/pull/711) +- [Better handling of Accept-Encoding / Content-Encoding decompression (fixes #562)](https://github.com/jnunemaker/httparty/pull/729) + +## 0.18.1 + +- [Rename cop Lint/HandleExceptions to Lint/SuppressedException](https://github.com/jnunemaker/httparty/pull/699). +- [Encode keys in query params](https://github.com/jnunemaker/httparty/pull/698). +- [Fixed SSL doc example](https://github.com/jnunemaker/httparty/pull/692). +- [Add a build status badge](https://github.com/jnunemaker/httparty/pull/701). + +## 0.18.0 + +- [Support gzip/deflate transfer encoding when explicit headers are set](https://github.com/jnunemaker/httparty/pull/678). +- [Support edge case cookie format with a blank attribute](https://github.com/jnunemaker/httparty/pull/685). + +## 0.17.3 + +0.17.2 is broken https://github.com/jnunemaker/httparty/issues/681 + +## 0.17.2 + +- [Add Response#nil? deprecetion warning](https://github.com/jnunemaker/httparty/pull/680) + +## 0.17.1 + +- [Pass options to dynamic block headers](https://github.com/jnunemaker/httparty/pull/661) +- [Normalize urls with URI adapter to allow International Domain Names support](https://github.com/jnunemaker/httparty/pull/668) +- [Add max_retries support](https://github.com/jnunemaker/httparty/pull/660) +- [Minize gem size by removing test files](https://github.com/jnunemaker/httparty/pull/658) + +## 0.17.0 + +- [Fix encoding of streamed chunk](https://github.com/jnunemaker/httparty/pull/644) +- [Avoid modifying frozen strings](https://github.com/jnunemaker/httparty/pull/649) +- [Expose .connection on fragment block param](https://github.com/jnunemaker/httparty/pull/648) +- [Add support for `Net::HTTP#write_timeout` method (Ruby 2.6.0)](https://github.com/jnunemaker/httparty/pull/647) + +## 0.16.4 + +- [Add support for Ruby 2.6](https://github.com/jnunemaker/httparty/pull/636) +- [Fix a few multipart issues](https://github.com/jnunemaker/httparty/pull/626) +- [Improve a memory usage for https requests](https://github.com/jnunemaker/httparty/pull/625) +- [Add response code to streamed body](https://github.com/jnunemaker/httparty/pull/588) + +## 0.16.3 + +- [Add Logstash-compatible formatter](https://github.com/jnunemaker/httparty/pull/612) +- [Add support for headers specified with symbols](https://github.com/jnunemaker/httparty/pull/622) +- [Fix response object marshalling](https://github.com/jnunemaker/httparty/pull/618) +- [Add ability to send multipart, without passing file](https://github.com/jnunemaker/httparty/pull/615) +- [Fix detection of content_type for multipart payload](https://github.com/jnunemaker/httparty/pull/616) +- [Process dynamic headers before making actual request](https://github.com/jnunemaker/httparty/pull/606) +- [Fix multipart uploads with ActionDispatch::Http::UploadedFile TempFile by using original_filename](https://github.com/jnunemaker/httparty/pull/598) +- [Added support for lock and unlock http requests](https://github.com/jnunemaker/httparty/pull/596) + +## 0.16.2 + +- [Support ActionDispatch::Http::UploadedFile again](https://github.com/jnunemaker/httparty/pull/585) + +## 0.16.1 + +- [Parse content with application/hal+json content type as JSON](https://github.com/jnunemaker/httparty/pull/573) +- [Convert objects to string when concatenating in multipart stuff](https://github.com/jnunemaker/httparty/pull/575) +- [Fix multipart to set its header even when other headers are provided](https://github.com/jnunemaker/httparty/pull/576) + +## 0.16.0 + +- [Add multipart support](https://github.com/jnunemaker/httparty/pull/569) + +## 0.15.7 + +Fixed + +- [Add Response#pretty_print | Restore documented behavior](https://github.com/jnunemaker/httparty/pull/570) +- [Add ability to parse response from JSONAPI ](https://github.com/jnunemaker/httparty/pull/553) + +## 0.15.6 + +Fixed + +- [Encoding and content type stuff](https://github.com/jnunemaker/httparty/pull/543) + +## 0.15.5 + +Fixed + +- [Use non-destructive gsub](https://github.com/jnunemaker/httparty/pull/540) + +## 0.15.4 + +Fixed + +- Prevent gsub errors with different encodings. +- Prevent passing nil to encode_body. + +## 0.15.3 + +Fixed + +- [Fix processing nil body for HEAD requests](https://github.com/jnunemaker/httparty/pull/530). +- Add missing require to headers.rb (33439a8). + +## 0.15.2 + +Fixed + +- Remove symlink from specs. It was reportedly still getting bundled with gem. + +## 0.15.1 + +Fixed + +- Stop including test files in gem. Fixes installation issues on windows due to symlink in spec dir. + +## 0.15.0 + +Breaking Changes + +- require Ruby >= 2.0.0 + +Fixed + +- [fix numerous bugs](https://github.com/jnunemaker/httparty/pull/513) +- [handle utf-8 bom for json parsing](https://github.com/jnunemaker/httparty/pull/520) +- [do not overwrite default headers unless specified](https://github.com/jnunemaker/httparty/pull/518) + +## 0.14.0 + +Breaking Changes + +- None + +Added + +- [added status predicate methods to Response#respond_to?](https://github.com/jnunemaker/httparty/pull/482) +- [support for MKCOL method](https://github.com/jnunemaker/httparty/pull/465) +- one fewer dependency: [remove json gem from gemspec](https://github.com/jnunemaker/httparty/pull/464) +- [optional raising exception on certain status codes](https://github.com/jnunemaker/httparty/pull/455) + +Fixed + +- [allow empty array to be used as param](https://github.com/jnunemaker/httparty/pull/477) +- [stop mutating cookie hash](https://github.com/jnunemaker/httparty/pull/460) + +## 0.13.7 aka "party not as hard" + +- remove post install emoji as it caused installation issues for some people + +## 0.13.6 + +- avoid calling String#strip on invalid Strings +- preserve request method on 307 and 308 redirects +- output version with --version for command line bin +- maintain head request method across redirects by default +- add support for RFC2617 MD5-sess algorithm type +- add party popper emoji to post install message + +## 0.13.5 + +- allow setting a custom URI adapter + +## 0.13.4 + +- correct redirect url for redirect paths without leading slash +- remove core_extensions.rb as backwards compat for ruby 1.8 not needed +- replace URI.encode with ERB::Util.url_encode +- allow the response to be tapped + +## 0.13.3 + +- minor improvement + - added option to allow for streaming large files without loading them into memory (672cdae) + +## 0.13.2 + +- minor improvement + - [Set correct path on redirect to filename](https://github.com/jnunemaker/httparty/pull/337) + - ensure logger works with curl format + +## 0.13.1 2014-04-08 + +- new + - [Added ability to specify a body_stream in HttpRequest](https://github.com/jnunemaker/httparty/pull/275) + - [Added read_timeout and open_timeout options](https://github.com/jnunemaker/httparty/pull/278) +- change + - [Initialize HTTParty requests with an URI object and a String](https://github.com/jnunemaker/httparty/pull/274) +- minor improvement + - [Add stackexchange API example](https://github.com/jnunemaker/httparty/pull/280) + +## 0.13.0 2014-02-14 + +- new + - [Add CSV support](https://github.com/jnunemaker/httparty/pull/269) + - [Allows PKCS12 client certificates](https://github.com/jnunemaker/httparty/pull/246) +- bug fix + - [Digest auth no longer fails when multiple headers are sent by the server](https://github.com/jnunemaker/httparty/pull/272) + - [Use 'Basement.copy' when calling 'HTTParty.copy'](https://github.com/jnunemaker/httparty/pull/268) + - [No longer appends ampersand when queries are embedded in paths](https://github.com/jnunemaker/httparty/pull/252) +- change + - [Merge - instead of overwrite - default headers with request provided headers](https://github.com/jnunemaker/httparty/pull/270) + - [Modernize respond_to implementations to support second param](https://github.com/jnunemaker/httparty/pull/264) + - [Sort query parameters by key before processing](https://github.com/jnunemaker/httparty/pull/245) +- minor improvement + - [Add HTTParty::Error base class](https://github.com/jnunemaker/httparty/pull/260) + +## 0.12.0 2013-10-10 + +- new + - [Added initial logging support](https://github.com/jnunemaker/httparty/pull/243) + - [Add support for local host and port binding](https://github.com/jnunemaker/httparty/pull/238) + - [content_type_charset_support](https://github.com/jnunemaker/httparty/commit/82e351f0904e8ecc856015ff2854698a2ca47fbc) +- bug fix + - [No longer attempt to decompress the body on HEAD requests](https://github.com/jnunemaker/httparty/commit/f2b8cc3d49e0e9363d7054b14f30c340d7b8e7f1) + - [Adding java check in aliasing of multiple choices](https://github.com/jnunemaker/httparty/pull/204/commits) +- change + - [MIME-type files of javascript are returned as a string instead of JSON](https://github.com/jnunemaker/httparty/pull/239) + - [Made SSL connections use the system certificate store by default](https://github.com/jnunemaker/httparty/pull/226) + - [Do not pass proxy options to Net::HTTP connection if not specified](https://github.com/jnunemaker/httparty/pull/222) + - [Replace multi_json with stdlib json](https://github.com/jnunemaker/httparty/pull/214) + - [Require Ruby >= 1.9.3] + - [Response returns array of returned cookie strings](https://github.com/jnunemaker/httparty/pull/218) + - [Allow '=' within value of a cookie] +- minor improvements + - [Improve documentation of ssl_ca_file, ssl_ca_path](https://github.com/jnunemaker/httparty/pull/223) + - [Fix example URLs](https://github.com/jnunemaker/httparty/pull/232) + +## 0.11.0 2013-04-10 + +- new + - [Add COPY http request handling](https://github.com/jnunemaker/httparty/pull/190) + - [Ruby 2.0 tests](https://github.com/jnunemaker/httparty/pull/194) + - [Ruby >= 2.0.0 support both multiple_choice? and multiple_choices?] +- bug fix + - [Maintain blocks passed to 'perform' in redirects](https://github.com/jnunemaker/httparty/pull/191) + - [Fixed nc value being quoted, this was against spec](https://github.com/jnunemaker/httparty/pull/196) + - [Request#uri no longer duplicates non-relative-path params](https://github.com/jnunemaker/httparty/pull/189) +- change + - [Client-side-only cookie attributes are removed: case-insensitive](https://github.com/jnunemaker/httparty/pull/188) + +## 0.10.2 2013-01-26 + +- bug fix + - [hash_conversions misnamed variable](https://github.com/jnunemaker/httparty/pull/187) + +## 0.10.1 2013-01-26 + +- new + - [Added support for MOVE requests](https://github.com/jnunemaker/httparty/pull/183) + - [Bump multi xml version](https://github.com/jnunemaker/httparty/pull/181) + +## 0.10.0 2013-01-10 + +- changes + - removed yaml support because of security risk (see rails yaml issues) + +## 0.9.0 2012-09-07 + +- new + - [support for connection adapters](https://github.com/jnunemaker/httparty/pull/157) + - [allow ssl_version on ruby 1.9](https://github.com/jnunemaker/httparty/pull/159) +- bug fixes + - [don't treat port 4430 as ssl](https://github.com/jnunemaker/httparty/commit/a296b1c97f83d7dcc6ef85720a43664c265685ac) + - [deep clone default options](https://github.com/jnunemaker/httparty/commit/f74227d30f9389b4b23a888c9af49fb9b8248e1f) + - a few net digest auth fixes + +## 0.8.3 2012-04-21 + +- new + - [lazy parsing of responses](https://github.com/jnunemaker/httparty/commit/9fd5259c8dab00e426082b66af44ede2c9068f45) + - [add support for PATCH requests](https://github.com/jnunemaker/httparty/commit/7ab6641e37a9e31517e46f6124f38c615395d38a) +- bug fixes + - [subclasses no longer override superclass options](https://github.com/jnunemaker/httparty/commit/682af8fbf672e7b3009e650da776c85cdfe78d39) + +## 0.8.2 2012-04-12 + +- new + - add -r to make CLI return failure code if status >= 400 + - allow blank username from CLI +- bug fixes + - return nil for null body + - automatically deflate responses with a Content-Encoding: x-gzip header + - Do not HEAD on POST request with digest authentication + - add support for proxy authentication + - fix posting data with CLI + - require rexml/document if xml format from CLI + - support for fragmented responses + +## 0.8.1 2011-10-05 + +- bug fixes + - content-encoding header should be removed when automatically inflating the body + +## 0.8.0 2011-09-13 + +- new + - switch to multi json/xml for parsing by default +- bug fixes + - fix redirects to relative uri's + +## 0.7.8 2011-06-06 + +- bug fix + - Make response honor respond to + - net http timeout can also be a float + +## 0.7.7 2011-04-16 + +- bug fix + - Fix NoMethodError when using the NON_RAILS_QUERY_STRING_NORMALIZER with a hash whose key is a symbol and value is nil + +## 0.7.5 2011-04-16 + +- bug fix + - caused issue with latest rubygems + +## 0.7.4 2011-02-13 + +- bug fixes + - Set VERIFY_NONE when using https. Ruby 1.9.2 no longer sets this for us. gh-67 + +## 0.7.3 2011-01-20 + +- bug fixes + - Fix digest auth for unspecified quality of protection (bjoernalbers, mtrudel, dwo) + +## 0.7.2 2011-01-20 + +- bug fixes + - Fix gem dependencies + +## 0.7.1 2011-01-19 + +- bug fixes + - Fix uninitialized constant HTTParty::Response::Net in 1.9.2 (cap10morgan) + - Other fixes for 1.9.2, full suite still fails (cap10morgan) + +## 0.7.0 2011-01-18 + +- minor enhancements + - Added query methods for HTTP status codes, i.e. response.success? + response.created? (thanks citizenparker) + - Added support for ssl_ca_file and ssl_ca_path (dlitz) + - Allow custom query string normalization. gh-8 + - Unlock private keys with password (freerange) + - Added high level request documentation (phildarnowsky) + - Added basic post example (pbuckley) + - Response object has access to its corresponding request object + - Added example of siginin into tripit.com + - Added option to follow redirects (rkj). gh-56 +- bug fixes + - Fixed superclass mismatch exception while running tests + (thanks dlitz http://github.com/dlitz/httparty/commit/48224f0615b32133afcff4718ad426df7a4b401b) + +## 0.6.1 2010-07-07 + +- minor enhancements + - updated to crack 0.1.8 +- bug fixes + - subclasses always merge into the parent's default_options and + default_cookies (l4rk). + - subclasses play nicely with grand parents. gh-49 + +## 0.6.0 2010-06-13 + +- major enhancements + + - Digest Auth (bartiaco, sbecker, gilles, and aaronrussell) + - Maintain HTTP method across redirects (bartiaco and sbecker) + - HTTParty::Response#response returns the Net::HTTPResponse object + - HTTParty::Response#headers returns a HTTParty::Response::Headers object + which quacks like a Hash + Net::HTTPHeader. The #headers method continues + to be backwards-compatible with the old Hash return value but may become + deprecated in the future. + +- minor enhancements + - Update crack requirement to version 0.1.7 + You may still get a warning because Crack's version constant is out of date + - Timeout option can be set for all requests using HTTParty.default_timeout (taazza) + - Closed #38 "headers hash should downcase keys so canonical header name can be used" + - Closed #40 "Gzip response" wherein gziped and deflated responses are + automatically inflated. (carsonmcdonald) + +## 0.5.2 2010-01-31 + +- minor enhancements + - Update crack requirement to version 0.1.6 + +## 0.5.1 2010-01-30 + +- bug fixes + + - Handle 304 response correctly by returning the HTTParty::Response object instead of redirecting (seth and hellvinz) + - Only redirect 300 responses if the header contains a Location + - Don't append empty query strings to the uri. Closes #31 + - When no_follow is enabled, only raise the RedirectionTooDeep exception when a response tries redirecting. Closes #28 + +- major enhancements + + - Removed rubygems dependency. I suggest adding rubygems to RUBYOPT if this causes problems for you. + $ export RUBYOPT='rubygems' + - HTTParty#debug_output prints debugging information for the current request (iwarshak) + - HTTParty#no_follow now available as a class-level option. Sets whether or not to follow redirects. + +- minor enhancements + - HTTParty::VERSION now available + - Update crack requirement to version 0.1.5 + +## 0.5.0 2009-12-07 + +- bug fixes + + - inheritable attributes no longer mutable by subclasses (yyyc514) + - namespace BasicObject within HTTParty to avoid class name collisions (eric) + +- major enhancements + + - Custom Parsers via class or proc + - Deprecation warning on HTTParty::AllowedFormats + moved to HTTParty::Parser::SupportedFormats + +- minor enhancements + - Curl inspired output when using the binary in verbose mode (alexvollmer) + - raise UnsupportedURIScheme when scheme is not HTTP or HTTPS (djspinmonkey) + - Allow SSL for ports other than 443 when scheme is HTTPS (stefankroes) + - Accept PEM certificates via HTTParty#pem (chrislo) + - Support HEAD and OPTION verbs (grempe) + - Verify SSL certificates when providing a PEM file (collectiveidea/danielmorrison) + +## 0.4.5 2009-09-12 + +- bug fixes + + - Fixed class-level headers overwritten by cookie management code. Closes #19 + - Fixed "superclass mismatch for class BlankSlate" error. Closes #20 + - Fixed reading files as post data from the command line (vesan) + +- minor enhancements + - Timeout option added; will raise a Timeout::Error after the timeout has elapsed (attack). Closes #17 + HTTParty.get "http://github.com", timeout: 1 + - Building gem with Jeweler + +## 0.4.4 2009-07-19 + +- 2 minor update + - :query no longer sets form data. Use body and set content type to application/x-www-form-urlencoded if you need it. :query was wrong for that. + - Fixed a bug in the cookies class method that caused cookies to be forgotten after the first request. + - Also, some general cleanup of tests and such. + +## 0.4.3 2009-04-23 + +- 1 minor update + - added message to the response object + +## 0.4.2 2009-03-30 + +- 2 minor changes + - response code now returns an integer instead of a string (jqr) + - rubyforge project setup for crack so i'm now depending on that instead of jnunemaker-crack + +## 0.4.1 2009-03-29 + +- 1 minor fix + - gem 'jnunemaker-crack' instead of gem 'crack' + +## 0.4.0 2009-03-29 + +- 1 minor change + - Switched xml and json parsing to crack (same code as before just moved to gem for easier reuse in other projects) + +## 0.3.1 2009-02-10 + +- 1 minor fix, 1 minor enhancement + - Fixed unescaping umlauts (siebertm) + - Added yaml response parsing (Miha Filej) + +## 0.3.0 2009-01-31 + +- 1 major enhancement, 1 bug fix + - JSON gem no longer a requirement. It was conflicting with rails json stuff so I just stole ActiveSupport's json decoding and bundled it with HTTParty. + - Fixed bug where query strings were being duplicated on redirects + - Added a bunch of specs and moved some code around. + +## 0.2.10 2009-01-29 + +- 1 minor enhancement + - Made encoding on query parameters treat everything except URI::PATTERN::UNRESERVED as UNSAFE to force encoding of '+' character (Julian Russell) + +## 0.2.9 2009-01-29 + +- 3 minor enhancements + - Added a 'headers' accessor to the response with a hash of any HTTP headers. (Don Peterson) + - Add support for a ":cookies" option to be used at the class level, or as an option on any individual call. It should be passed a hash, which will be converted to the proper format and added to the request headers when the call is made. (Don Peterson) + - Refactored several specs and added a full suite of cucumber features (Don Peterson) + +## 0.2.8 2009-01-28 + +- 1 major fix + - fixed major bug with response where it wouldn't iterate or really work at all with parsed responses + +## 0.2.7 2009-01-28 + +- 2 minor fixes, 2 minor enhancements, 2 major enhancements + - fixed undefined method add_node for nil class error that occasionally happened (juliocesar) + - Handle nil or unexpected values better when typecasting. (Brian Landau) + - More robust handling of mime types (Alex Vollmer) + - Fixed support for specifying headers and added support for basic auth to CLI. (Alex Vollmer) + - Added first class response object that includes original body and status code (Alex Vollmer) + - Now parsing all response types as some non-200 responses provide important information, this means no more exception raising (Alex Vollmer) + +## 0.2.6 2009-01-05 + +- 1 minor bug fix + - added explicit require of time as Time#parse failed outside of rails (willcodeforfoo) + +## 0.2.5 2009-01-05 + +- 1 major enhancement + - Add command line interface to HTTParty (Alex Vollmer) + +## 0.2.4 2008-12-23 + +- 1 bug fix + - Fixed that mimetype detection was failing if no mimetype was returned from service (skippy) + +## 0.2.3 2008-12-23 + +- 1 bug fix + - Fixed typecasting class variable naming issue + +## 0.2.2 2008-12-08 + +- 1 bug fix + - Added the missing core extension hash method to_xml_attributes + +## 0.2.1 2008-12-08 + +- 1 bug fix + - Fixed that HTTParty was borking ActiveSupport and as such Rails (thanks to Rob Sanheim) + +## 0.2.0 2008-12-07 + +- 1 major enhancement + - Removed ActiveSupport as a dependency. Now requires json gem for json deserialization and uses an included class to do the xml parsing. + +## 0.1.8 2008-11-30 + +- 3 major enhancements + - Moved base_uri normalization into request class and out of httparty module, fixing + the problem where base_uri was not always being normalized. + - Stupid simple support for HTTParty.get/post/put/delete. (jqr) + - Switched gem management to Echoe from newgem. + +## 0.1.7 2008-11-30 + +- 1 major enhancement + - fixed multiple class definitions overriding each others options + +## 0.1.6 2008-11-26 + +- 1 major enhancement + - now passing :query to set_form_data if post request to avoid content length errors + +## 0.1.5 2008-11-14 + +- 2 major enhancements + - Refactored send request method out into its own object. + - Added :html format if you just want to do that. + +## 0.1.4 2008-11-08 + +- 3 major enhancements: + - Removed some cruft + - Added ability to follow redirects automatically and turn that off (Alex Vollmer) + +## 0.1.3 2008-08-22 + +- 3 major enhancements: + - Added http_proxy key for setting proxy server and port (francxk@gmail.com) + - Now raises exception when http error occurs (francxk@gmail.com) + - Changed auto format detection from file extension to response content type (Jay Pignata) + +## 0.1.2 2008-08-09 + +- 1 major enhancement: + - default_params were not being appended to query string if option[:query] was blank + +## 0.1.1 2008-07-30 + +- 2 major enhancement: + - Added :basic_auth key for options when making a request + - :query and :body both now work with query string or hash + +## 0.1.0 2008-07-27 + +- 1 major enhancement: + - Initial release diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/Gemfile b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/Gemfile new file mode 100644 index 0000000..ae8ef23 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/Gemfile @@ -0,0 +1,27 @@ +source 'https://rubygems.org' +gemspec + +gem 'base64' +gem 'rake' +gem 'mongrel', '1.2.0.pre2' +gem 'json' + +group :development do + gem 'guard' + gem 'guard-rspec' + gem 'guard-bundler' +end + +group :test do + gem 'rexml' + gem 'rspec', '~> 3.4' + gem 'simplecov', require: false + gem 'aruba' + gem 'cucumber', '~> 2.3' + gem 'webmock' + gem 'addressable' +end + +group :development, :test do + gem 'pry' +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/Guardfile b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/Guardfile new file mode 100644 index 0000000..4075dc5 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/Guardfile @@ -0,0 +1,17 @@ +rspec_options = { + all_after_pass: false, + all_on_start: false, + failed_mode: :keep, + cmd: 'bundle exec rspec', +} + +guard 'rspec', rspec_options do + watch(%r{^spec/.+_spec\.rb$}) + watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } + watch('spec/spec_helper.rb') { "spec" } +end + +guard 'bundler' do + watch('Gemfile') + watch(/^.+\.gemspec/) +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/MIT-LICENSE b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/MIT-LICENSE new file mode 100644 index 0000000..ea4d340 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/MIT-LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2008 John Nunemaker + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/README.md b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/README.md new file mode 100644 index 0000000..9aa163d --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/README.md @@ -0,0 +1,79 @@ +# httparty + +[![CI](https://github.com/jnunemaker/httparty/actions/workflows/ci.yml/badge.svg)](https://github.com/jnunemaker/httparty/actions/workflows/ci.yml) + +Makes http fun again! Ain't no party like a httparty, because a httparty don't stop. + +## Install + +``` +gem install httparty +``` + +## Requirements + +- Ruby 2.7.0 or higher +- You like to party! + +## Examples + +```ruby +# Use the class methods to get down to business quickly +response = HTTParty.get('http://api.stackexchange.com/2.2/questions?site=stackoverflow') + +puts response.body, response.code, response.message, response.headers.inspect + +# Or wrap things up in your own class +class StackExchange + include HTTParty + base_uri 'api.stackexchange.com' + + def initialize(service, page) + @options = { query: { site: service, page: page } } + end + + def questions + self.class.get("/2.2/questions", @options) + end + + def users + self.class.get("/2.2/users", @options) + end +end + +stack_exchange = StackExchange.new("stackoverflow", 1) +puts stack_exchange.questions +puts stack_exchange.users +``` + +See the [examples directory](http://github.com/jnunemaker/httparty/tree/main/examples) for even more goodies. + +## Command Line Interface + +httparty also includes the executable `httparty` which can be +used to query web services and examine the resulting output. By default +it will output the response as a pretty-printed Ruby object (useful for +grokking the structure of output). This can also be overridden to output +formatted XML or JSON. Execute `httparty --help` for all the +options. Below is an example of how easy it is. + +``` +httparty "https://api.stackexchange.com/2.2/questions?site=stackoverflow" +``` + +## Help and Docs + +- [Docs](https://github.com/jnunemaker/httparty/tree/main/docs) +- https://github.com/jnunemaker/httparty/discussions +- https://www.rubydoc.info/github/jnunemaker/httparty + +## Contributing + +- Fork the project. +- Run `bundle` +- Run `bundle exec rake` +- Make your feature addition or bug fix. +- Add tests for it. This is important so I don't break it in a future version unintentionally. +- Run `bundle exec rake` (No, REALLY :)) +- Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself in another branch so I can ignore when I pull) +- Send me a pull request. Bonus points for topic branches. diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/Rakefile b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/Rakefile new file mode 100644 index 0000000..d994fb6 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/Rakefile @@ -0,0 +1,10 @@ +begin + require 'rspec/core/rake_task' + RSpec::Core::RakeTask.new(:spec) +rescue LoadError +end + +require 'cucumber/rake/task' +Cucumber::Rake::Task.new(:features) + +task default: [:spec, :features] diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/bin/httparty b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/bin/httparty new file mode 100755 index 0000000..3bdb86f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/bin/httparty @@ -0,0 +1,123 @@ +#!/usr/bin/env ruby + +require "optparse" +require "pp" + +$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "/../lib")) +require "httparty" + +opts = { + action: :get, + headers: {}, + verbose: false +} + +OptionParser.new do |o| + o.banner = "USAGE: #{$PROGRAM_NAME} [options] [url]" + + o.on("-f", + "--format [FORMAT]", + "Output format to use instead of pretty-print ruby: " \ + "plain, csv, json or xml") do |f| + opts[:output_format] = f.downcase.to_sym + end + + o.on("-a", + "--action [ACTION]", + "HTTP action: get (default), post, put, delete, head, or options") do |a| + opts[:action] = a.downcase.to_sym + end + + o.on("-d", + "--data [BODY]", + "Data to put in request body (prefix with '@' for file)") do |d| + if d =~ /^@/ + opts[:body] = open(d[1..-1]).read + else + opts[:body] = d + end + end + + o.on("-H", "--header [NAME:VALUE]", "Additional HTTP headers in NAME:VALUE form") do |h| + abort "Invalid header specification, should be Name:Value" unless h =~ /.+:.+/ + name, value = h.split(':') + opts[:headers][name.strip] = value.strip + end + + o.on("-v", "--verbose", "If set, print verbose output") do |v| + opts[:verbose] = true + end + + o.on("-u", "--user [CREDS]", "Use basic authentication. Value should be user:password") do |u| + abort "Invalid credentials format. Must be user:password" unless u =~ /.*:.+/ + user, password = u.split(':') + opts[:basic_auth] = { username: user, password: password } + end + + o.on("-r", "--response-code", "Command fails if response code >= 400") do + opts[:response_code] = true + end + + o.on("-h", "--help", "Show help documentation") do |h| + puts o + exit + end + + o.on("--version", "Show HTTParty version") do |ver| + puts "Version: #{HTTParty::VERSION}" + exit + end +end.parse! + +if ARGV.empty? + STDERR.puts "You need to provide a URL" + STDERR.puts "USAGE: #{$PROGRAM_NAME} [options] [url]" +end + +def dump_headers(response) + resp_type = Net::HTTPResponse::CODE_TO_OBJ[response.code.to_s] + puts "#{response.code} #{resp_type.to_s.sub(/^Net::HTTP/, '')}" + response.headers.each do |n, v| + puts "#{n}: #{v}" + end + puts +end + +if opts[:verbose] + puts "#{opts[:action].to_s.upcase} #{ARGV.first}" + opts[:headers].each do |n, v| + puts "#{n}: #{v}" + end + puts +end + +response = HTTParty.send(opts[:action], ARGV.first, opts) +if opts[:output_format].nil? + dump_headers(response) if opts[:verbose] + pp response +else + print_format = opts[:output_format] + dump_headers(response) if opts[:verbose] + + case opts[:output_format] + when :json + begin + require 'json' + puts JSON.pretty_generate(response.parsed_response) + rescue LoadError + puts YAML.dump(response) + rescue JSON::JSONError + puts response.inspect + end + when :xml + require 'rexml/document' + REXML::Document.new(response.body).write(STDOUT, 2) + puts + when :csv + require 'csv' + puts CSV.parse(response.body).map(&:to_s) + else + puts response + end +end +exit false if opts[:response_code] && response.code >= 400 diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/cucumber.yml b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/cucumber.yml new file mode 100644 index 0000000..80df8ac --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/cucumber.yml @@ -0,0 +1 @@ +default: features --format progress diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/docs/README.md b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/docs/README.md new file mode 100644 index 0000000..3806d48 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/docs/README.md @@ -0,0 +1,193 @@ +# httparty + +Makes http fun again! + +## Table of contents +- [Parsing JSON](#parsing-json) +- [Working with SSL](#working-with-ssl) + +## Parsing JSON +If the response Content Type is `application/json`, HTTParty will parse the response and return Ruby objects such as a hash or array. The default behavior for parsing JSON will return keys as strings. This can be supressed with the `format` option. To get hash keys as symbols: + +```ruby +response = HTTParty.get('http://example.com', format: :plain) +JSON.parse response, symbolize_names: true +``` + +## Posting JSON +When using Content Type `application/json` with `POST`, `PUT` or `PATCH` requests, the body should be a string of valid JSON: + +```ruby +# With written JSON +HTTParty.post('http://example.com', body: "{\"foo\":\"bar\"}", headers: { 'Content-Type' => 'application/json' }) + +# Using JSON.generate +HTTParty.post('http://example.com', body: JSON.generate({ foo: 'bar' }), headers: { 'Content-Type' => 'application/json' }) + +# Using object.to_json +HTTParty.post('http://example.com', body: { foo: 'bar' }.to_json, headers: { 'Content-Type' => 'application/json' }) +``` + +## Working with SSL + +You can use this guide to work with SSL certificates. + +#### Using `pem` option + +```ruby +# Use this example if you are using a pem file +# - cert.pem must contain the content of a PEM file having the private key appended (separated from the cert by a newline \n) +# - Use an empty string for the password if the cert is not password protected + +class Client + include HTTParty + + base_uri "https://example.com" + pem File.read("#{File.expand_path('.')}/path/to/certs/cert.pem"), "123456" +end +``` + +#### Using `pkcs12` option + +```ruby +# Use this example if you are using a pkcs12 file + +class Client + include HTTParty + + base_uri "https://example.com" + pkcs12 File.read("#{File.expand_path('.')}/path/to/certs/cert.p12"), "123456" +end +``` + +#### Using `ssl_ca_file` option + +```ruby +# Use this example if you are using a pkcs12 file + +class Client + include HTTParty + + base_uri "https://example.com" + ssl_ca_file "#{File.expand_path('.')}/path/to/certs/cert.pem" +end +``` + +#### Using `ssl_ca_path` option + +```ruby +# Use this example if you are using a pkcs12 file + +class Client + include HTTParty + + base_uri "https://example.com" + ssl_ca_path '/path/to/certs' +end +``` + +You can also include all of these options with the call: + +```ruby +class Client + include HTTParty + + base_uri "https://example.com" + + def self.fetch + get("/resources", pem: File.read("#{File.expand_path('.')}/path/to/certs/cert.pem"), pem_password: "123456") + end +end +``` + +### Avoid SSL verification + +In some cases you may want to skip SSL verification, because the entity that issued the certificate is not a valid one, but you still want to work with it. You can achieve this through: + +```ruby +# Skips SSL certificate verification + +class Client + include HTTParty + + base_uri "https://example.com" + pem File.read("#{File.expand_path('.')}/path/to/certs/cert.pem"), "123456" + + def self.fetch + get("/resources", verify: false) + # You can also use something like: + # get("resources", verify_peer: false) + end +end +``` + +### HTTP Compression + +The `Accept-Encoding` request header and `Content-Encoding` response header +are used to control compression (gzip, etc.) over the wire. Refer to +[RFC-2616](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html) for details. +(For clarity: these headers are **not** used for character encoding i.e. `utf-8` +which is specified in the `Accept` and `Content-Type` headers.) + +Unless you have specific requirements otherwise, we recommend to **not** set +set the `Accept-Encoding` header on HTTParty requests. In this case, `Net::HTTP` +will set a sensible default compression scheme and automatically decompress the response. + +If you explicitly set `Accept-Encoding`, there be dragons: + +* If the HTTP response `Content-Encoding` received on the wire is `gzip` or `deflate`, + `Net::HTTP` will automatically decompress it, and will omit `Content-Encoding` + from your `HTTParty::Response` headers. + +* For the following encodings, HTTParty will automatically decompress them if you include + the required gem into your project. Similar to above, if decompression succeeds, + `Content-Encoding` will be omitted from your `HTTParty::Response` headers. + **Warning:** Support for these encodings is experimental and not fully battle-tested. + + | Content-Encoding | Required Gem | + | --- | --- | + | `br` (Brotli) | [brotli](https://rubygems.org/gems/brotli) | + | `compress` (LZW) | [ruby-lzws](https://rubygems.org/gems/ruby-lzws) | + | `zstd` (Zstandard) | [zstd-ruby](https://rubygems.org/gems/zstd-ruby) | + +* For other encodings, `HTTParty::Response#body` will return the raw uncompressed byte string, + and you'll need to inspect the `Content-Encoding` response header and decompress it yourself. + In this case, `HTTParty::Response#parsed_response` will be `nil`. + +* Lastly, you may use the `skip_decompression` option to disable all automatic decompression + and always get `HTTParty::Response#body` in its raw form along with the `Content-Encoding` header. + +```ruby +# Accept-Encoding=gzip,deflate can be safely assumed to be auto-decompressed + +res = HTTParty.get('https://example.com/test.json', headers: { 'Accept-Encoding' => 'gzip,deflate,identity' }) +JSON.parse(res.body) # safe + + +# Accept-Encoding=br,compress requires third-party gems + +require 'brotli' +require 'lzws' +require 'zstd-ruby' +res = HTTParty.get('https://example.com/test.json', headers: { 'Accept-Encoding' => 'br,compress,zstd' }) +JSON.parse(res.body) + + +# Accept-Encoding=* may return unhandled Content-Encoding + +res = HTTParty.get('https://example.com/test.json', headers: { 'Accept-Encoding' => '*' }) +encoding = res.headers['Content-Encoding'] +if encoding +JSON.parse(your_decompression_handling(res.body, encoding)) +else +# Content-Encoding not present implies decompressed +JSON.parse(res.body) +end + + +# Gimme the raw data! + +res = HTTParty.get('https://example.com/test.json', skip_decompression: true) +encoding = res.headers['Content-Encoding'] +JSON.parse(your_decompression_handling(res.body, encoding)) +``` diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/README.md b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/README.md new file mode 100644 index 0000000..e79ddc4 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/README.md @@ -0,0 +1,89 @@ +## Examples + +* [Amazon Book Search](aaws.rb) + * Httparty included into poro class + * Uses `get` requests + * Transforms query params to uppercased params + +* [Google Search](google.rb) + * Httparty included into poro class + * Uses `get` requests + +* [Crack Custom Parser](crack.rb) + * Creates a custom parser for XML using crack gem + * Uses `get` request + +* [Create HTML Nokogiri parser](nokogiri_html_parser.rb) + * Adds Html as a format + * passed the body of request to Nokogiri + +* [More Custom Parsers](custom_parsers.rb) + * Create an additional parser for atom or make it the ONLY parser + +* [Basic Auth, Delicious](delicious.rb) + * Basic Auth, shows how to merge those into options + * Uses `get` requests + +* [Passing Headers, User Agent](headers_and_user_agents.rb) + * Use the class method of Httparty + * Pass the User-Agent in the headers + * Uses `get` requests + +* [Basic Post Request](basic.rb) + * Httparty included into poro class + * Uses `post` requests + +* [Access Rubyurl Shortener](rubyurl.rb) + * Httparty included into poro class + * Uses `post` requests + +* [Add a custom log file](logging.rb) + * create a log file and have httparty log requests + +* [Accessing StackExchange](stackexchange.rb) + * Httparty included into poro class + * Creates methods for different endpoints + * Uses `get` requests + +* [Accessing Tripit](tripit_sign_in.rb) + * Httparty included into poro class + * Example of using `debug_output` to see headers/urls passed + * Getting and using Cookies + * Uses `get` requests + +* [Accessing Twitter](twitter.rb) + * Httparty included into poro class + * Basic Auth + * Loads settings from a config file + * Uses `get` requests + * Uses `post` requests + +* [Accessing WhoIsMyRep](whoismyrep.rb) + * Httparty included into poro class + * Uses `get` requests + * Two ways to pass params to get, inline on the url or in query hash + +* [Rescue Json Error](rescue_json.rb) + * Rescue errors due to parsing response + +* [Download file using stream mode](stream_download.rb) + * Uses `get` requests + * Uses `stream_body` mode + * Download file without using the memory + +* [Microsoft graph](microsoft_graph.rb) + * Basic Auth + * Uses `post` requests + * Uses multipart + +* [Multipart](multipart.rb) + * Multipart data upload _(with and without file)_ + +* [Uploading File](body_stream.rb) + * Uses `body_stream` to upload file + +* [Accessing x509 Peer Certificate](peer_cert.rb) + * Provides access to the server's TLS certificate + +* [Accessing IDNs](idn.rb) + * Uses a `get` request with an International domain names, which are Urls with emojis and non-ASCII characters such as accented letters. \ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/aaws.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/aaws.rb new file mode 100644 index 0000000..1fb9a62 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/aaws.rb @@ -0,0 +1,36 @@ +require 'rubygems' +require 'active_support' +require 'active_support/core_ext/hash' +require 'active_support/core_ext/string' + +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' +config = YAML.load(File.read(File.join(ENV['HOME'], '.aaws'))) + +module AAWS + class Book + include HTTParty + base_uri 'http://ecs.amazonaws.com' + default_params Service: 'AWSECommerceService', Operation: 'ItemSearch', SearchIndex: 'Books' + + def initialize(key) + @auth = { AWSAccessKeyId: key } + end + + def search(options = {}) + raise ArgumentError, 'You must search for something' if options[:query].blank? + + # amazon uses nasty camelized query params + options[:query] = options[:query] + .reverse_merge(@auth) + .transform_keys { |k| k.to_s.camelize } + + # make a request and return the items (NOTE: this doesn't handle errors at this point) + self.class.get('/onca/xml', options)['ItemSearchResponse']['Items'] + end + end +end + +aaws = AAWS::Book.new(config[:access_key]) +pp aaws.search(query: { title: 'Ruby On Rails' }) diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/basic.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/basic.rb new file mode 100644 index 0000000..6f784be --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/basic.rb @@ -0,0 +1,28 @@ +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' + +# You can also use post, put, delete, head, options in the same fashion +response = HTTParty.get('https://api.stackexchange.com/2.2/questions?site=stackoverflow') +puts response.body, response.code, response.message, response.headers.inspect + +# An example post to a minimal rails app in the development environment +# Note that "skip_before_filter :verify_authenticity_token" must be set in the +# "pears" controller for this example + +class Partay + include HTTParty + base_uri 'http://localhost:3000' +end + +options = { + body: { + pear: { # your resource + foo: '123', # your columns/data + bar: 'second', + baz: 'last thing' + } + } +} + +pp Partay.post('/pears.xml', options) diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/body_stream.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/body_stream.rb new file mode 100644 index 0000000..8ca405e --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/body_stream.rb @@ -0,0 +1,14 @@ +# To upload file to a server use :body_stream + +HTTParty.put( + 'http://localhost:3000/train', + body_stream: File.open('sample_configs/config_train_server_md.yml', 'r') +) + + +# Actually, it works with any IO object + +HTTParty.put( + 'http://localhost:3000/train', + body_stream: StringIO.new('foo') +) diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/crack.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/crack.rb new file mode 100644 index 0000000..bd5eb58 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/crack.rb @@ -0,0 +1,19 @@ +require 'rubygems' +require 'crack' + +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' + +class Rep + include HTTParty + + parser( + proc do |body, format| + Crack::XML.parse(body) + end + ) +end + +pp Rep.get('http://whoismyrepresentative.com/getall_mems.php?zip=46544') +pp Rep.get('http://whoismyrepresentative.com/getall_mems.php', query: { zip: 46544 }) diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/custom_parsers.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/custom_parsers.rb new file mode 100644 index 0000000..1c88f0f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/custom_parsers.rb @@ -0,0 +1,68 @@ +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' + +class ParseAtom + include HTTParty + + # Support Atom along with the default parsers: xml, json, etc. + class Parser::Atom < HTTParty::Parser + SupportedFormats.merge!({"application/atom+xml" => :atom}) + + protected + + # perform atom parsing on body + def atom + body.to_atom + end + end + + parser Parser::Atom +end + +class OnlyParseAtom + include HTTParty + + # Only support Atom + class Parser::OnlyAtom < HTTParty::Parser + SupportedFormats = { "application/atom+xml" => :atom } + + protected + + # perform atom parsing on body + def atom + body.to_atom + end + end + + parser Parser::OnlyAtom +end + +class SkipParsing + include HTTParty + + # Parse the response body however you like + class Parser::Simple < HTTParty::Parser + def parse + body + end + end + + parser Parser::Simple +end + +class AdHocParsing + include HTTParty + parser( + proc do |body, format| + case format + when :json + body.to_json + when :xml + body.to_xml + else + body + end + end + ) +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/delicious.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/delicious.rb new file mode 100644 index 0000000..86a7ad6 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/delicious.rb @@ -0,0 +1,37 @@ +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' +config = YAML.load(File.read(File.join(ENV['HOME'], '.delicious'))) + +class Delicious + include HTTParty + base_uri 'https://api.del.icio.us/v1' + + def initialize(u, p) + @auth = { username: u, password: p } + end + + # query params that filter the posts are: + # tag (optional). Filter by this tag. + # dt (optional). Filter by this date (CCYY-MM-DDThh:mm:ssZ). + # url (optional). Filter by this url. + # ie: posts(query: {tag: 'ruby'}) + def posts(options = {}) + options.merge!({ basic_auth: @auth }) + self.class.get('/posts/get', options) + end + + # query params that filter the posts are: + # tag (optional). Filter by this tag. + # count (optional). Number of items to retrieve (Default:15, Maximum:100). + def recent(options = {}) + options.merge!({ basic_auth: @auth }) + self.class.get('/posts/recent', options) + end +end + +delicious = Delicious.new(config['username'], config['password']) +pp delicious.posts(query: { tag: 'ruby' }) +pp delicious.recent + +delicious.recent['posts']['post'].each { |post| puts post['href'] } diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/google.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/google.rb new file mode 100644 index 0000000..e91d793 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/google.rb @@ -0,0 +1,16 @@ +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' + +class Google + include HTTParty + format :html +end + +# google.com redirects to www.google.com so this is live test for redirection +pp Google.get('http://google.com') + +puts '', '*' * 70, '' + +# check that ssl is requesting right +pp Google.get('https://www.google.com') diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/headers_and_user_agents.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/headers_and_user_agents.rb new file mode 100644 index 0000000..da8e7c6 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/headers_and_user_agents.rb @@ -0,0 +1,10 @@ +# To send custom user agents to identify your application to a web service (or mask as a specific browser for testing), send "User-Agent" as a hash to headers as shown below. + +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' + +response = HTTParty.get('http://example.com', { + headers: {"User-Agent" => "Httparty"}, + debug_output: STDOUT, # To show that User-Agent is Httparty +}) diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/idn.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/idn.rb new file mode 100644 index 0000000..4c3d9ba --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/idn.rb @@ -0,0 +1,10 @@ +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' + +class Idn + include HTTParty + uri_adapter Addressable::URI +end + +pp Idn.get("https://i❤️.ws/emojidomain/💎?format=json") \ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/logging.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/logging.rb new file mode 100644 index 0000000..d0dbae5 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/logging.rb @@ -0,0 +1,36 @@ +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'logger' +require 'pp' + +my_logger = Logger.new STDOUT + +my_logger.info "Logging can be used on the main HTTParty class. It logs redirects too." +HTTParty.get "http://google.com", logger: my_logger + +my_logger.info '*' * 70 + +my_logger.info "It can be used also on a custom class." + +class Google + include HTTParty + logger ::Logger.new STDOUT +end + +Google.get "http://google.com" + +my_logger.info '*' * 70 + +my_logger.info "The default formatter is :apache. The :curl formatter can also be used." +my_logger.info "You can tell which method to call on the logger too. It is info by default." +HTTParty.get "http://google.com", logger: my_logger, log_level: :debug, log_format: :curl + +my_logger.info '*' * 70 + +my_logger.info "These configs are also available on custom classes." +class Google + include HTTParty + logger ::Logger.new(STDOUT), :debug, :curl +end + +Google.get "http://google.com" diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/microsoft_graph.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/microsoft_graph.rb new file mode 100644 index 0000000..0e44b6c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/microsoft_graph.rb @@ -0,0 +1,52 @@ +require 'httparty' + +class MicrosoftGraph + MS_BASE_URL = "https://login.microsoftonline.com".freeze + TOKEN_REQUEST_PATH = "oauth2/v2.0/token".freeze + + def initialize(tenant_id) + @tenant_id = tenant_id + end + + # Make a request to the Microsoft Graph API, for instance https://graph.microsoft.com/v1.0/users + def request(url) + return false unless (token = bearer_token) + + response = HTTParty.get( + url, + headers: { + Authorization: "Bearer #{token}" + } + ) + + return false unless response.code == 200 + + return JSON.parse(response.body) + end + + private + + # A post to the Microsoft Graph to get a bearer token for the specified tenant. In this example + # our Rails application has already been given permission to request these tokens by the admin of + # the specified tenant_id. + # + # See here for more information https://developer.microsoft.com/en-us/graph/docs/concepts/auth_v2_service + # + # This request also makes use of the multipart/form-data post body. + def bearer_token + response = HTTParty.post( + "#{MS_BASE_URL}/#{@tenant_id}/#{TOKEN_REQUEST_PATH}", + multipart: true, + body: { + client_id: Rails.application.credentials[Rails.env.to_sym][:microsoft_client_id], + client_secret: Rails.application.credentials[Rails.env.to_sym][:microsoft_client_secret], + scope: 'https://graph.microsoft.com/.default', + grant_type: 'client_credentials' + } + ) + + return false unless response.code == 200 + + JSON.parse(response.body)['access_token'] + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/multipart.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/multipart.rb new file mode 100644 index 0000000..24c6916 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/multipart.rb @@ -0,0 +1,22 @@ +# If you are uploading file in params, multipart will used as content-type automatically + +HTTParty.post( + 'http://localhost:3000/user', + body: { + name: 'Foo Bar', + email: 'example@email.com', + avatar: File.open('/full/path/to/avatar.jpg') + } +) + + +# However, you can force it yourself + +HTTParty.post( + 'http://localhost:3000/user', + multipart: true, + body: { + name: 'Foo Bar', + email: 'example@email.com' + } +) diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/nokogiri_html_parser.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/nokogiri_html_parser.rb new file mode 100644 index 0000000..94c3ae1 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/nokogiri_html_parser.rb @@ -0,0 +1,19 @@ +require 'rubygems' +require 'nokogiri' + +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' + +class HtmlParserIncluded < HTTParty::Parser + def html + Nokogiri::HTML(body) + end +end + +class Page + include HTTParty + parser HtmlParserIncluded +end + +pp Page.get('http://www.google.com') diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/party_foul_mode.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/party_foul_mode.rb new file mode 100644 index 0000000..e11dcfc --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/party_foul_mode.rb @@ -0,0 +1,90 @@ +require 'httparty' + +class APIClient + include HTTParty + base_uri 'api.example.com' + + def self.fetch_user(id) + begin + get("/users/#{id}", foul: true) + rescue HTTParty::NetworkError => e + handle_network_error(e) + rescue HTTParty::ResponseError => e + handle_api_error(e) + end + end + + private + + def self.handle_network_error(error) + case error.cause + when Errno::ECONNREFUSED + { + error: :server_down, + message: "The API server appears to be down", + details: error.message + } + when Net::OpenTimeout, Timeout::Error + { + error: :timeout, + message: "The request timed out", + details: error.message + } + when SocketError + { + error: :network_error, + message: "Could not connect to the API server", + details: error.message + } + when OpenSSL::SSL::SSLError + { + error: :ssl_error, + message: "SSL certificate verification failed", + details: error.message + } + else + { + error: :unknown_network_error, + message: "An unexpected network error occurred", + details: error.message + } + end + end + + def self.handle_api_error(error) + { + error: :api_error, + message: "API returned error #{error.response.code}", + details: error.response.body + } + end +end + +# Example usage: + +# 1. When server is down +result = APIClient.fetch_user(123) +puts "Server down example:" +puts result.inspect +puts + +# 2. When request times out +result = APIClient.fetch_user(456) +puts "Timeout example:" +puts result.inspect +puts + +# 3. When SSL error occurs +result = APIClient.fetch_user(789) +puts "SSL error example:" +puts result.inspect +puts + +# 4. Simple example without a wrapper class +begin + HTTParty.get('https://api.example.com/users', foul: true) +rescue HTTParty::Foul => e + puts "Direct usage example:" + puts "Error type: #{e.cause.class}" + puts "Error message: #{e.message}" +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/peer_cert.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/peer_cert.rb new file mode 100644 index 0000000..a16de68 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/peer_cert.rb @@ -0,0 +1,9 @@ +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') + +peer_cert = nil +HTTParty.get("https://www.example.com") do |fragment| + peer_cert ||= fragment.connection.peer_cert +end + +puts "The server's certificate expires #{peer_cert.not_after}" diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/rescue_json.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/rescue_json.rb new file mode 100644 index 0000000..a4b6621 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/rescue_json.rb @@ -0,0 +1,17 @@ +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') + +# Take note of the "; 1" at the end of the following line. It's required only if +# running this in IRB, because IRB will try to inspect the variable named +# "request", triggering the exception. +request = HTTParty.get 'https://rubygems.org/api/v1/versions/doesnotexist.json' ; 1 + +# Check an exception due to parsing the response +# because HTTParty evaluate the response lazily +begin + request.inspect + # This would also suffice by forcing the request to be parsed: + # request.parsed_response +rescue => e + puts "Rescued #{e.inspect}" +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/rubyurl.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/rubyurl.rb new file mode 100644 index 0000000..54458e0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/rubyurl.rb @@ -0,0 +1,14 @@ +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' + +class Rubyurl + include HTTParty + base_uri 'rubyurl.com' + + def self.shorten(website_url) + post('/api/links.json', query: { link: { website_url: website_url } }) + end +end + +pp Rubyurl.shorten('http://istwitterdown.com/') diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/stackexchange.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/stackexchange.rb new file mode 100644 index 0000000..f262dc1 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/stackexchange.rb @@ -0,0 +1,24 @@ +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' + +class StackExchange + include HTTParty + base_uri 'api.stackexchange.com' + + def initialize(service, page) + @options = { query: { site: service, page: page } } + end + + def questions + self.class.get("/2.2/questions", @options) + end + + def users + self.class.get("/2.2/users", @options) + end +end + +stack_exchange = StackExchange.new("stackoverflow", 1) +pp stack_exchange.questions +pp stack_exchange.users diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/stream_download.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/stream_download.rb new file mode 100644 index 0000000..4dfcf98 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/stream_download.rb @@ -0,0 +1,26 @@ +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' + +# download file linux-4.6.4.tar.xz without using the memory +response = nil +filename = "linux-4.6.4.tar.xz" +url = "https://cdn.kernel.org/pub/linux/kernel/v4.x/#{filename}" + +File.open(filename, "w") do |file| + response = HTTParty.get(url, stream_body: true) do |fragment| + if [301, 302].include?(fragment.code) + print "skip writing for redirect" + elsif fragment.code == 200 + print "." + file.write(fragment) + else + raise StandardError, "Non-success status code while streaming #{fragment.code}" + end + end +end +puts + +pp "Success: #{response.success?}" +pp File.stat(filename).inspect +File.unlink(filename) diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/tripit_sign_in.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/tripit_sign_in.rb new file mode 100644 index 0000000..e0fc0cf --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/tripit_sign_in.rb @@ -0,0 +1,44 @@ +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') + +class TripIt + include HTTParty + base_uri 'https://www.tripit.com' + debug_output + + def initialize(email, password) + @email = email + get_response = self.class.get('/account/login') + get_response_cookie = parse_cookie(get_response.headers['Set-Cookie']) + + post_response = self.class.post( + '/account/login', + body: { + login_email_address: email, + login_password: password + }, + headers: {'Cookie' => get_response_cookie.to_cookie_string } + ) + + @cookie = parse_cookie(post_response.headers['Set-Cookie']) + end + + def account_settings + self.class.get('/account/edit', headers: { 'Cookie' => @cookie.to_cookie_string }) + end + + def logged_in? + account_settings.include? "You're logged in as #{@email}" + end + + private + + def parse_cookie(resp) + cookie_hash = CookieHash.new + resp.get_fields('Set-Cookie').each { |c| cookie_hash.add_cookies(c) } + cookie_hash + end +end + +tripit = TripIt.new('email', 'password') +puts "Logged in: #{tripit.logged_in?}" diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/twitter.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/twitter.rb new file mode 100644 index 0000000..812c1f1 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/twitter.rb @@ -0,0 +1,31 @@ +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' +config = YAML.load(File.read(File.join(ENV['HOME'], '.twitter'))) + +class Twitter + include HTTParty + base_uri 'twitter.com' + + def initialize(u, p) + @auth = {username: u, password: p} + end + + # which can be :friends, :user or :public + # options[:query] can be things like since, since_id, count, etc. + def timeline(which = :friends, options = {}) + options.merge!({ basic_auth: @auth }) + self.class.get("/statuses/#{which}_timeline.json", options) + end + + def post(text) + options = { query: { status: text }, basic_auth: @auth } + self.class.post('/statuses/update.json', options) + end +end + +twitter = Twitter.new(config['email'], config['password']) +pp twitter.timeline +# pp twitter.timeline(:friends, query: {since_id: 868482746}) +# pp twitter.timeline(:friends, query: 'since_id=868482746') +# pp twitter.post('this is a test of 0.2.0') diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/whoismyrep.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/whoismyrep.rb new file mode 100644 index 0000000..c991918 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/examples/whoismyrep.rb @@ -0,0 +1,10 @@ +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' + +class Rep + include HTTParty +end + +pp Rep.get('http://whoismyrepresentative.com/getall_mems.php?zip=46544') +pp Rep.get('http://whoismyrepresentative.com/getall_mems.php', query: { zip: 46544 }) diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/httparty.gemspec b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/httparty.gemspec new file mode 100644 index 0000000..864263e --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/httparty.gemspec @@ -0,0 +1,32 @@ +# -*- encoding: utf-8 -*- +$LOAD_PATH.push File.expand_path("../lib", __FILE__) +require "httparty/version" + +Gem::Specification.new do |s| + s.name = "httparty" + s.version = HTTParty::VERSION + s.platform = Gem::Platform::RUBY + s.licenses = ['MIT'] + s.authors = ["John Nunemaker", "Sandro Turriate"] + s.email = ["nunemaker@gmail.com"] + s.homepage = "https://github.com/jnunemaker/httparty" + s.summary = 'Makes http fun! Also, makes consuming restful web services dead easy.' + s.description = 'Makes http fun! Also, makes consuming restful web services dead easy.' + s.metadata["changelog_uri"] = 'https://github.com/jnunemaker/httparty/releases' + + s.required_ruby_version = '>= 2.7.0' + + s.add_dependency 'csv' + s.add_dependency 'multi_xml', ">= 0.5.2" + s.add_dependency 'mini_mime', ">= 1.0.0" + + # If this line is removed, all hard partying will cease. + s.post_install_message = "When you HTTParty, you must party hard!" + + all_files = `git ls-files`.split("\n") + test_files = `git ls-files -- {test,spec,features}/*`.split("\n") + + s.files = all_files - test_files + s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) } + s.require_paths = ["lib"] +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty.rb new file mode 100644 index 0000000..f04f8d0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty.rb @@ -0,0 +1,699 @@ +# frozen_string_literal: true + +require 'pathname' +require 'net/http' +require 'uri' + +require 'httparty/module_inheritable_attributes' +require 'httparty/cookie_hash' +require 'httparty/net_digest_auth' +require 'httparty/version' +require 'httparty/connection_adapter' +require 'httparty/logger/logger' +require 'httparty/request/body' +require 'httparty/response_fragment' +require 'httparty/decompressor' +require 'httparty/text_encoder' +require 'httparty/headers_processor' + +# @see HTTParty::ClassMethods +module HTTParty + def self.included(base) + base.extend ClassMethods + base.send :include, ModuleInheritableAttributes + base.send(:mattr_inheritable, :default_options) + base.send(:mattr_inheritable, :default_cookies) + base.instance_variable_set(:@default_options, {}) + base.instance_variable_set(:@default_cookies, CookieHash.new) + end + + # == Common Request Options + # Request methods (get, post, patch, put, delete, head, options) all take a common set of options. These are: + # + # [:+body+:] Body of the request. If passed an object that responds to #to_hash, will try to normalize it first, by default passing it to ActiveSupport::to_params. Any other kind of object will get used as-is. + # [:+http_proxyaddr+:] Address of proxy server to use. + # [:+http_proxyport+:] Port of proxy server to use. + # [:+http_proxyuser+:] User for proxy server authentication. + # [:+http_proxypass+:] Password for proxy server authentication. + # [:+limit+:] Maximum number of redirects to follow. Takes precedences over :+no_follow+. + # [:+query+:] Query string, or an object that responds to #to_hash representing it. Normalized according to the same rules as :+body+. If you specify this on a POST, you must use an object which responds to #to_hash. See also HTTParty::ClassMethods.default_params. + # [:+timeout+:] Timeout for opening connection and reading data. + # [:+local_host+:] Local address to bind to before connecting. + # [:+local_port+:] Local port to bind to before connecting. + # [:+body_stream+:] Allow streaming to a REST server to specify a body_stream. + # [:+stream_body+:] Allow for streaming large files without loading them into memory. + # [:+multipart+:] Force content-type to be multipart + # + # There are also another set of options with names corresponding to various class methods. The methods in question are those that let you set a class-wide default, and the options override the defaults on a request-by-request basis. Those options are: + # * :+base_uri+: see HTTParty::ClassMethods.base_uri. + # * :+basic_auth+: see HTTParty::ClassMethods.basic_auth. Only one of :+basic_auth+ and :+digest_auth+ can be used at a time; if you try using both, you'll get an ArgumentError. + # * :+debug_output+: see HTTParty::ClassMethods.debug_output. + # * :+digest_auth+: see HTTParty::ClassMethods.digest_auth. Only one of :+basic_auth+ and :+digest_auth+ can be used at a time; if you try using both, you'll get an ArgumentError. + # * :+format+: see HTTParty::ClassMethods.format. + # * :+headers+: see HTTParty::ClassMethods.headers. Must be a an object which responds to #to_hash. + # * :+maintain_method_across_redirects+: see HTTParty::ClassMethods.maintain_method_across_redirects. + # * :+no_follow+: see HTTParty::ClassMethods.no_follow. + # * :+parser+: see HTTParty::ClassMethods.parser. + # * :+uri_adapter+: see HTTParty::ClassMethods.uri_adapter + # * :+connection_adapter+: see HTTParty::ClassMethods.connection_adapter. + # * :+pem+: see HTTParty::ClassMethods.pem. + # * :+query_string_normalizer+: see HTTParty::ClassMethods.query_string_normalizer + # * :+ssl_ca_file+: see HTTParty::ClassMethods.ssl_ca_file. + # * :+ssl_ca_path+: see HTTParty::ClassMethods.ssl_ca_path. + + module ClassMethods + # Turns on or off the foul option. + # + # class Foo + # include HTTParty + # foul true + # end + def foul(bool) + default_options[:foul] = bool + end + + # Turns on logging + # + # class Foo + # include HTTParty + # logger Logger.new('http_logger'), :info, :apache + # end + def logger(logger, level = :info, format = :apache) + default_options[:logger] = logger + default_options[:log_level] = level + default_options[:log_format] = format + end + + # Raises HTTParty::ResponseError if response's code matches this statuses + # + # class Foo + # include HTTParty + # raise_on [404, 500, '5[0-9]*'] + # end + def raise_on(codes = []) + default_options[:raise_on] = *codes + end + + # Allows setting http proxy information to be used + # + # class Foo + # include HTTParty + # http_proxy 'http://foo.com', 80, 'user', 'pass' + # end + def http_proxy(addr = nil, port = nil, user = nil, pass = nil) + default_options[:http_proxyaddr] = addr + default_options[:http_proxyport] = port + default_options[:http_proxyuser] = user + default_options[:http_proxypass] = pass + end + + # Allows setting a base uri to be used for each request. + # Will normalize uri to include http, etc. + # + # class Foo + # include HTTParty + # base_uri 'twitter.com' + # end + def base_uri(uri = nil) + return default_options[:base_uri] unless uri + default_options[:base_uri] = HTTParty.normalize_base_uri(uri) + end + + # Allows setting basic authentication username and password. + # + # class Foo + # include HTTParty + # basic_auth 'username', 'password' + # end + def basic_auth(u, p) + default_options[:basic_auth] = {username: u, password: p} + end + + # Allows setting digest authentication username and password. + # + # class Foo + # include HTTParty + # digest_auth 'username', 'password' + # end + def digest_auth(u, p) + default_options[:digest_auth] = {username: u, password: p} + end + + # Do not send rails style query strings. + # Specifically, don't use bracket notation when sending an array + # + # For a query: + # get '/', query: {selected_ids: [1,2,3]} + # + # The default query string looks like this: + # /?selected_ids[]=1&selected_ids[]=2&selected_ids[]=3 + # + # Call `disable_rails_query_string_format` to transform the query string + # into: + # /?selected_ids=1&selected_ids=2&selected_ids=3 + # + # @example + # class Foo + # include HTTParty + # disable_rails_query_string_format + # end + def disable_rails_query_string_format + query_string_normalizer Request::NON_RAILS_QUERY_STRING_NORMALIZER + end + + # Allows setting default parameters to be appended to each request. + # Great for api keys and such. + # + # class Foo + # include HTTParty + # default_params api_key: 'secret', another: 'foo' + # end + def default_params(h = {}) + raise ArgumentError, 'Default params must be an object which responds to #to_hash' unless h.respond_to?(:to_hash) + default_options[:default_params] ||= {} + default_options[:default_params].merge!(h) + end + + # Allows setting a default timeout for all HTTP calls + # Timeout is specified in seconds. + # + # class Foo + # include HTTParty + # default_timeout 10 + # end + def default_timeout(value) + validate_timeout_argument(__method__, value) + default_options[:timeout] = value + end + + # Allows setting a default open_timeout for all HTTP calls in seconds + # + # class Foo + # include HTTParty + # open_timeout 10 + # end + def open_timeout(value) + validate_timeout_argument(__method__, value) + default_options[:open_timeout] = value + end + + # Allows setting a default read_timeout for all HTTP calls in seconds + # + # class Foo + # include HTTParty + # read_timeout 10 + # end + def read_timeout(value) + validate_timeout_argument(__method__, value) + default_options[:read_timeout] = value + end + + # Allows setting a default write_timeout for all HTTP calls in seconds + # Supported by Ruby > 2.6.0 + # + # class Foo + # include HTTParty + # write_timeout 10 + # end + def write_timeout(value) + validate_timeout_argument(__method__, value) + default_options[:write_timeout] = value + end + + + # Set an output stream for debugging, defaults to $stderr. + # The output stream is passed on to Net::HTTP#set_debug_output. + # + # class Foo + # include HTTParty + # debug_output $stderr + # end + def debug_output(stream = $stderr) + default_options[:debug_output] = stream + end + + # Allows setting HTTP headers to be used for each request. + # + # class Foo + # include HTTParty + # headers 'Accept' => 'text/html' + # end + def headers(h = nil) + if h + raise ArgumentError, 'Headers must be an object which responds to #to_hash' unless h.respond_to?(:to_hash) + default_options[:headers] ||= {} + default_options[:headers].merge!(h.to_hash) + else + default_options[:headers] || {} + end + end + + def cookies(h = {}) + raise ArgumentError, 'Cookies must be an object which responds to #to_hash' unless h.respond_to?(:to_hash) + default_cookies.add_cookies(h) + end + + # Proceed to the location header when an HTTP response dictates a redirect. + # Redirects are always followed by default. + # + # @example + # class Foo + # include HTTParty + # base_uri 'http://google.com' + # follow_redirects true + # end + def follow_redirects(value = true) + default_options[:follow_redirects] = value + end + + # Allows setting the format with which to parse. + # Must be one of the allowed formats ie: json, xml + # + # class Foo + # include HTTParty + # format :json + # end + def format(f = nil) + if f.nil? + default_options[:format] + else + parser(Parser) if parser.nil? + default_options[:format] = f + validate_format + end + end + + # Declare whether or not to follow redirects. When true, an + # {HTTParty::RedirectionTooDeep} error will raise upon encountering a + # redirect. You can then gain access to the response object via + # HTTParty::RedirectionTooDeep#response. + # + # @see HTTParty::ResponseError#response + # + # @example + # class Foo + # include HTTParty + # base_uri 'http://google.com' + # no_follow true + # end + # + # begin + # Foo.get('/') + # rescue HTTParty::RedirectionTooDeep => e + # puts e.response.body + # end + def no_follow(value = false) + default_options[:no_follow] = value + end + + # Declare that you wish to maintain the chosen HTTP method across redirects. + # The default behavior is to follow redirects via the GET method, except + # if you are making a HEAD request, in which case the default is to + # follow all redirects with HEAD requests. + # If you wish to maintain the original method, you can set this option to true. + # + # @example + # class Foo + # include HTTParty + # base_uri 'http://google.com' + # maintain_method_across_redirects true + # end + + def maintain_method_across_redirects(value = true) + default_options[:maintain_method_across_redirects] = value + end + + # Declare that you wish to resend the full HTTP request across redirects, + # even on redirects that should logically become GET requests. + # A 303 redirect in HTTP signifies that the redirected url should normally + # retrieved using a GET request, for instance, it is the output of a previous + # POST. maintain_method_across_redirects respects this behavior, but you + # can force HTTParty to resend_on_redirect even on 303 responses. + # + # @example + # class Foo + # include HTTParty + # base_uri 'http://google.com' + # resend_on_redirect + # end + + def resend_on_redirect(value = true) + default_options[:resend_on_redirect] = value + end + + # Allows setting a PEM file to be used + # + # class Foo + # include HTTParty + # pem File.read('/home/user/my.pem'), "optional password" + # end + def pem(pem_contents, password = nil) + default_options[:pem] = pem_contents + default_options[:pem_password] = password + end + + # Allows setting a PKCS12 file to be used + # + # class Foo + # include HTTParty + # pkcs12 File.read('/home/user/my.p12'), "password" + # end + def pkcs12(p12_contents, password) + default_options[:p12] = p12_contents + default_options[:p12_password] = password + end + + # Override the way query strings are normalized. + # Helpful for overriding the default rails normalization of Array queries. + # + # For a query: + # get '/', query: {selected_ids: [1,2,3]} + # + # The default query string normalizer returns: + # /?selected_ids[]=1&selected_ids[]=2&selected_ids[]=3 + # + # Let's change it to this: + # /?selected_ids=1&selected_ids=2&selected_ids=3 + # + # Pass a Proc to the query normalizer which accepts the yielded query. + # + # @example Modifying Array query strings + # class ServiceWrapper + # include HTTParty + # + # query_string_normalizer proc { |query| + # query.map do |key, value| + # value.map {|v| "#{key}=#{v}"} + # end.join('&') + # } + # end + # + # @param [Proc] normalizer custom query string normalizer. + # @yield [Hash, String] query string + # @yieldreturn [Array] an array that will later be joined with '&' + def query_string_normalizer(normalizer) + default_options[:query_string_normalizer] = normalizer + end + + # Allows setting of SSL version to use. This only works in Ruby 1.9+. + # You can get a list of valid versions from OpenSSL::SSL::SSLContext::METHODS. + # + # class Foo + # include HTTParty + # ssl_version :SSLv3 + # end + def ssl_version(version) + default_options[:ssl_version] = version + end + + # Deactivate automatic decompression of the response body. + # This will require you to explicitly handle body decompression + # by inspecting the Content-Encoding response header. + # + # Refer to docs/README.md "HTTP Compression" section for + # further details. + # + # @example + # class Foo + # include HTTParty + # skip_decompression + # end + def skip_decompression(value = true) + default_options[:skip_decompression] = !!value + end + + # Allows setting of SSL ciphers to use. This only works in Ruby 1.9+. + # You can get a list of valid specific ciphers from OpenSSL::Cipher.ciphers. + # You also can specify a cipher suite here, listed here at openssl.org: + # http://www.openssl.org/docs/apps/ciphers.html#CIPHER_SUITE_NAMES + # + # class Foo + # include HTTParty + # ciphers "RC4-SHA" + # end + def ciphers(cipher_names) + default_options[:ciphers] = cipher_names + end + + # Allows setting an OpenSSL certificate authority file. The file + # should contain one or more certificates in PEM format. + # + # Setting this option enables certificate verification. All + # certificates along a chain must be available in ssl_ca_file or + # ssl_ca_path for verification to succeed. + # + # + # class Foo + # include HTTParty + # ssl_ca_file '/etc/ssl/certs/ca-certificates.crt' + # end + def ssl_ca_file(path) + default_options[:ssl_ca_file] = path + end + + # Allows setting an OpenSSL certificate authority path (directory). + # + # Setting this option enables certificate verification. All + # certificates along a chain must be available in ssl_ca_file or + # ssl_ca_path for verification to succeed. + # + # class Foo + # include HTTParty + # ssl_ca_path '/etc/ssl/certs/' + # end + def ssl_ca_path(path) + default_options[:ssl_ca_path] = path + end + + # Allows setting a custom parser for the response. + # + # class Foo + # include HTTParty + # parser Proc.new {|data| ...} + # end + def parser(custom_parser = nil) + if custom_parser.nil? + default_options[:parser] + else + default_options[:parser] = custom_parser + validate_format + end + end + + # Allows setting a custom URI adapter. + # + # class Foo + # include HTTParty + # uri_adapter Addressable::URI + # end + def uri_adapter(uri_adapter) + raise ArgumentError, 'The URI adapter should respond to #parse' unless uri_adapter.respond_to?(:parse) + default_options[:uri_adapter] = uri_adapter + end + + # Allows setting a custom connection_adapter for the http connections + # + # @example + # class Foo + # include HTTParty + # connection_adapter Proc.new {|uri, options| ... } + # end + # + # @example provide optional configuration for your connection_adapter + # class Foo + # include HTTParty + # connection_adapter Proc.new {|uri, options| ... }, {foo: :bar} + # end + # + # @see HTTParty::ConnectionAdapter + def connection_adapter(custom_adapter = nil, options = nil) + if custom_adapter.nil? + default_options[:connection_adapter] + else + default_options[:connection_adapter] = custom_adapter + default_options[:connection_adapter_options] = options + end + end + + # Allows making a get request to a url. + # + # class Foo + # include HTTParty + # end + # + # # Simple get with full url + # Foo.get('http://foo.com/resource.json') + # + # # Simple get with full url and query parameters + # # ie: http://foo.com/resource.json?limit=10 + # Foo.get('http://foo.com/resource.json', query: {limit: 10}) + def get(path, options = {}, &block) + perform_request Net::HTTP::Get, path, options, &block + end + + # Allows making a post request to a url. + # + # class Foo + # include HTTParty + # end + # + # # Simple post with full url and setting the body + # Foo.post('http://foo.com/resources', body: {bar: 'baz'}) + # + # # Simple post with full url using :query option, + # # which appends the parameters to the URI. + # Foo.post('http://foo.com/resources', query: {bar: 'baz'}) + def post(path, options = {}, &block) + perform_request Net::HTTP::Post, path, options, &block + end + + # Perform a PATCH request to a path + def patch(path, options = {}, &block) + perform_request Net::HTTP::Patch, path, options, &block + end + + # Perform a PUT request to a path + def put(path, options = {}, &block) + perform_request Net::HTTP::Put, path, options, &block + end + + # Perform a DELETE request to a path + def delete(path, options = {}, &block) + perform_request Net::HTTP::Delete, path, options, &block + end + + # Perform a MOVE request to a path + def move(path, options = {}, &block) + perform_request Net::HTTP::Move, path, options, &block + end + + # Perform a COPY request to a path + def copy(path, options = {}, &block) + perform_request Net::HTTP::Copy, path, options, &block + end + + # Perform a HEAD request to a path + def head(path, options = {}, &block) + ensure_method_maintained_across_redirects options + perform_request Net::HTTP::Head, path, options, &block + end + + # Perform an OPTIONS request to a path + def options(path, options = {}, &block) + perform_request Net::HTTP::Options, path, options, &block + end + + # Perform a MKCOL request to a path + def mkcol(path, options = {}, &block) + perform_request Net::HTTP::Mkcol, path, options, &block + end + + def lock(path, options = {}, &block) + perform_request Net::HTTP::Lock, path, options, &block + end + + def unlock(path, options = {}, &block) + perform_request Net::HTTP::Unlock, path, options, &block + end + + def build_request(http_method, path, options = {}) + options = ModuleInheritableAttributes.hash_deep_dup(default_options).merge(options) + HeadersProcessor.new(headers, options).call + process_cookies(options) + Request.new(http_method, path, options) + end + + attr_reader :default_options + + private + + def validate_timeout_argument(timeout_type, value) + raise ArgumentError, "#{ timeout_type } must be an integer or float" unless value && (value.is_a?(Integer) || value.is_a?(Float)) + end + + def ensure_method_maintained_across_redirects(options) + unless options.key?(:maintain_method_across_redirects) + options[:maintain_method_across_redirects] = true + end + end + + def perform_request(http_method, path, options, &block) #:nodoc: + build_request(http_method, path, options).perform(&block) + end + + def process_cookies(options) #:nodoc: + return unless options[:cookies] || default_cookies.any? + options[:headers] ||= headers.dup + options[:headers]['cookie'] = cookies.merge(options.delete(:cookies) || {}).to_cookie_string + end + + def validate_format + if format && parser.respond_to?(:supports_format?) && !parser.supports_format?(format) + supported_format_names = parser.supported_formats.map(&:to_s).sort.join(', ') + raise UnsupportedFormat, "'#{format.inspect}' Must be one of: #{supported_format_names}" + end + end + end + + def self.normalize_base_uri(url) #:nodoc: + normalized_url = url.dup + use_ssl = (normalized_url =~ /^https/) || (normalized_url =~ /:443\b/) + ends_with_slash = normalized_url =~ /\/$/ + + normalized_url.chop! if ends_with_slash + normalized_url.gsub!(/^https?:\/\//i, '') + + "http#{'s' if use_ssl}://#{normalized_url}" + end + + class Basement #:nodoc: + include HTTParty + end + + def self.get(*args, &block) + Basement.get(*args, &block) + end + + def self.post(*args, &block) + Basement.post(*args, &block) + end + + def self.patch(*args, &block) + Basement.patch(*args, &block) + end + + def self.put(*args, &block) + Basement.put(*args, &block) + end + + def self.delete(*args, &block) + Basement.delete(*args, &block) + end + + def self.move(*args, &block) + Basement.move(*args, &block) + end + + def self.copy(*args, &block) + Basement.copy(*args, &block) + end + + def self.head(*args, &block) + Basement.head(*args, &block) + end + + def self.options(*args, &block) + Basement.options(*args, &block) + end + + def self.build_request(*args, &block) + Basement.build_request(*args, &block) + end +end + +require 'httparty/hash_conversions' +require 'httparty/utils' +require 'httparty/exceptions' +require 'httparty/parser' +require 'httparty/request' +require 'httparty/response' diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/connection_adapter.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/connection_adapter.rb new file mode 100644 index 0000000..262016f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/connection_adapter.rb @@ -0,0 +1,237 @@ +# frozen_string_literal: true + +module HTTParty + # Default connection adapter that returns a new Net::HTTP each time + # + # == Custom Connection Factories + # + # If you like to implement your own connection adapter, subclassing + # HTTParty::ConnectionAdapter will make it easier. Just override + # the #connection method. The uri and options attributes will have + # all the info you need to construct your http connection. Whatever + # you return from your connection method needs to adhere to the + # Net::HTTP interface as this is what HTTParty expects. + # + # @example log the uri and options + # class LoggingConnectionAdapter < HTTParty::ConnectionAdapter + # def connection + # puts uri + # puts options + # Net::HTTP.new(uri) + # end + # end + # + # @example count number of http calls + # class CountingConnectionAdapter < HTTParty::ConnectionAdapter + # @@count = 0 + # + # self.count + # @@count + # end + # + # def connection + # self.count += 1 + # super + # end + # end + # + # === Configuration + # There is lots of configuration data available for your connection adapter + # in the #options attribute. It is up to you to interpret them within your + # connection adapter. Take a look at the implementation of + # HTTParty::ConnectionAdapter#connection for examples of how they are used. + # The keys used in options are + # * :+timeout+: timeout in seconds + # * :+open_timeout+: http connection open_timeout in seconds, overrides timeout if set + # * :+read_timeout+: http connection read_timeout in seconds, overrides timeout if set + # * :+write_timeout+: http connection write_timeout in seconds, overrides timeout if set (Ruby >= 2.6.0 required) + # * :+debug_output+: see HTTParty::ClassMethods.debug_output. + # * :+cert_store+: contains certificate data. see method 'attach_ssl_certificates' + # * :+pem+: contains pem client certificate data. see method 'attach_ssl_certificates' + # * :+p12+: contains PKCS12 client client certificate data. see method 'attach_ssl_certificates' + # * :+verify+: verify the server’s certificate against the ca certificate. + # * :+verify_peer+: set to false to turn off server verification but still send client certificate + # * :+ssl_ca_file+: see HTTParty::ClassMethods.ssl_ca_file. + # * :+ssl_ca_path+: see HTTParty::ClassMethods.ssl_ca_path. + # * :+ssl_version+: SSL versions to allow. see method 'attach_ssl_certificates' + # * :+ciphers+: The list of SSL ciphers to support + # * :+connection_adapter_options+: contains the hash you passed to HTTParty.connection_adapter when you configured your connection adapter + # * :+local_host+: The local address to bind to + # * :+local_port+: The local port to bind to + # * :+http_proxyaddr+: HTTP Proxy address + # * :+http_proxyport+: HTTP Proxy port + # * :+http_proxyuser+: HTTP Proxy user + # * :+http_proxypass+: HTTP Proxy password + # + # === Inherited methods + # * :+clean_host+: Method used to sanitize host names + + class ConnectionAdapter + # Private: Regex used to strip brackets from IPv6 URIs. + StripIpv6BracketsRegex = /\A\[(.*)\]\z/ + + OPTION_DEFAULTS = { + verify: true, + verify_peer: true + } + + # Public + def self.call(uri, options) + new(uri, options).connection + end + + def self.default_cert_store + @default_cert_store ||= OpenSSL::X509::Store.new.tap do |cert_store| + cert_store.set_default_paths + end + end + + attr_reader :uri, :options + + def initialize(uri, options = {}) + uri_adapter = options[:uri_adapter] || URI + raise ArgumentError, "uri must be a #{uri_adapter}, not a #{uri.class}" unless uri.is_a? uri_adapter + + @uri = uri + @options = OPTION_DEFAULTS.merge(options) + end + + def connection + host = clean_host(uri.host) + port = uri.port || (uri.scheme == 'https' ? 443 : 80) + if options.key?(:http_proxyaddr) + http = Net::HTTP.new( + host, + port, + options[:http_proxyaddr], + options[:http_proxyport], + options[:http_proxyuser], + options[:http_proxypass] + ) + else + http = Net::HTTP.new(host, port) + end + + http.use_ssl = ssl_implied?(uri) + + attach_ssl_certificates(http, options) + + if add_timeout?(options[:timeout]) + http.open_timeout = options[:timeout] + http.read_timeout = options[:timeout] + http.write_timeout = options[:timeout] + end + + if add_timeout?(options[:read_timeout]) + http.read_timeout = options[:read_timeout] + end + + if add_timeout?(options[:open_timeout]) + http.open_timeout = options[:open_timeout] + end + + if add_timeout?(options[:write_timeout]) + http.write_timeout = options[:write_timeout] + end + + if add_max_retries?(options[:max_retries]) + http.max_retries = options[:max_retries] + end + + if options[:debug_output] + http.set_debug_output(options[:debug_output]) + end + + if options[:ciphers] + http.ciphers = options[:ciphers] + end + + # Bind to a specific local address or port + # + # @see https://bugs.ruby-lang.org/issues/6617 + if options[:local_host] + http.local_host = options[:local_host] + end + + if options[:local_port] + http.local_port = options[:local_port] + end + + http + end + + private + + def add_timeout?(timeout) + timeout && (timeout.is_a?(Integer) || timeout.is_a?(Float)) + end + + def add_max_retries?(max_retries) + max_retries && max_retries.is_a?(Integer) && max_retries >= 0 + end + + def clean_host(host) + strip_ipv6_brackets(host) + end + + def strip_ipv6_brackets(host) + StripIpv6BracketsRegex =~ host ? $1 : host + end + + def ssl_implied?(uri) + uri.port == 443 || uri.scheme == 'https' + end + + def verify_ssl_certificate? + !(options[:verify] == false || options[:verify_peer] == false) + end + + def attach_ssl_certificates(http, options) + if http.use_ssl? + if options.fetch(:verify, true) + http.verify_mode = OpenSSL::SSL::VERIFY_PEER + if options[:cert_store] + http.cert_store = options[:cert_store] + else + # Use the default cert store by default, i.e. system ca certs + http.cert_store = self.class.default_cert_store + end + else + http.verify_mode = OpenSSL::SSL::VERIFY_NONE + end + + # Client certificate authentication + # Note: options[:pem] must contain the content of a PEM file having the private key appended + if options[:pem] + http.cert = OpenSSL::X509::Certificate.new(options[:pem]) + http.key = OpenSSL::PKey.read(options[:pem], options[:pem_password]) + http.verify_mode = verify_ssl_certificate? ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE + end + + # PKCS12 client certificate authentication + if options[:p12] + p12 = OpenSSL::PKCS12.new(options[:p12], options[:p12_password]) + http.cert = p12.certificate + http.key = p12.key + http.verify_mode = verify_ssl_certificate? ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE + end + + # SSL certificate authority file and/or directory + if options[:ssl_ca_file] + http.ca_file = options[:ssl_ca_file] + http.verify_mode = OpenSSL::SSL::VERIFY_PEER + end + + if options[:ssl_ca_path] + http.ca_path = options[:ssl_ca_path] + http.verify_mode = OpenSSL::SSL::VERIFY_PEER + end + + # This is only Ruby 1.9+ + if options[:ssl_version] && http.respond_to?(:ssl_version=) + http.ssl_version = options[:ssl_version] + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/cookie_hash.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/cookie_hash.rb new file mode 100644 index 0000000..7d33d17 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/cookie_hash.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +class HTTParty::CookieHash < Hash #:nodoc: + CLIENT_COOKIES = %w(path expires domain path secure httponly samesite) + + def add_cookies(data) + case data + when Hash + merge!(data) + when String + data.split('; ').each do |cookie| + key, value = cookie.split('=', 2) + self[key.to_sym] = value if key + end + else + raise "add_cookies only takes a Hash or a String" + end + end + + def to_cookie_string + select { |k, v| !CLIENT_COOKIES.include?(k.to_s.downcase) }.collect { |k, v| "#{k}=#{v}" }.join('; ') + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/decompressor.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/decompressor.rb new file mode 100644 index 0000000..8557c47 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/decompressor.rb @@ -0,0 +1,102 @@ +# frozen_string_literal: true + +module HTTParty + # Decompresses the response body based on the Content-Encoding header. + # + # Net::HTTP automatically decompresses Content-Encoding values "gzip" and "deflate". + # This class will handle "br" (Brotli) and "compress" (LZW) if the requisite + # gems are installed. Otherwise, it returns nil if the body data cannot be + # decompressed. + # + # @abstract Read the HTTP Compression section for more information. + class Decompressor + + # "gzip" and "deflate" are handled by Net::HTTP + # hence they do not need to be handled by HTTParty + SupportedEncodings = { + 'none' => :none, + 'identity' => :none, + 'br' => :brotli, + 'compress' => :lzw, + 'zstd' => :zstd + }.freeze + + # The response body of the request + # @return [String] + attr_reader :body + + # The Content-Encoding algorithm used to encode the body + # @return [Symbol] e.g. :gzip + attr_reader :encoding + + # @param [String] body - the response body of the request + # @param [Symbol] encoding - the Content-Encoding algorithm used to encode the body + def initialize(body, encoding) + @body = body + @encoding = encoding + end + + # Perform decompression on the response body + # @return [String] the decompressed body + # @return [nil] when the response body is nil or cannot decompressed + def decompress + return nil if body.nil? + return body if encoding.nil? || encoding.strip.empty? + + if supports_encoding? + decompress_supported_encoding + else + nil + end + end + + protected + + def supports_encoding? + SupportedEncodings.keys.include?(encoding) + end + + def decompress_supported_encoding + method = SupportedEncodings[encoding] + if respond_to?(method, true) + send(method) + else + raise NotImplementedError, "#{self.class.name} has not implemented a decompression method for #{encoding.inspect} encoding." + end + end + + def none + body + end + + def brotli + return nil unless defined?(::Brotli) + begin + ::Brotli.inflate(body) + rescue StandardError + nil + end + end + + def lzw + begin + if defined?(::LZWS::String) + ::LZWS::String.decompress(body) + elsif defined?(::LZW::Simple) + ::LZW::Simple.new.decompress(body) + end + rescue StandardError + nil + end + end + + def zstd + return nil unless defined?(::Zstd) + begin + ::Zstd.decompress(body) + rescue StandardError + nil + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/exceptions.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/exceptions.rb new file mode 100644 index 0000000..ddc93fc --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/exceptions.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +module HTTParty + COMMON_NETWORK_ERRORS = [ + EOFError, + Errno::ECONNABORTED, + Errno::ECONNREFUSED, + Errno::ECONNRESET, + Errno::EHOSTUNREACH, + Errno::EINVAL, + Errno::ENETUNREACH, + Errno::ENOTSOCK, + Errno::EPIPE, + Errno::ETIMEDOUT, + Net::HTTPBadResponse, + Net::HTTPHeaderSyntaxError, + Net::ProtocolError, + Net::ReadTimeout, + OpenSSL::SSL::SSLError, + SocketError, + Timeout::Error # Also covers subclasses like Net::OpenTimeout + ].freeze + + # @abstract Exceptions raised by HTTParty inherit from Error + class Error < StandardError; end + + # @abstract Exceptions raised by HTTParty inherit from this because it is funny + # and if you don't like fun you should be using a different library. + class Foul < Error; end + + # Exception raised when you attempt to set a non-existent format + class UnsupportedFormat < Foul; end + + # Exception raised when using a URI scheme other than HTTP or HTTPS + class UnsupportedURIScheme < Foul; end + + # @abstract Exceptions which inherit from ResponseError contain the Net::HTTP + # response object accessible via the {#response} method. + class ResponseError < Foul + # Returns the response of the last request + # @return [Net::HTTPResponse] A subclass of Net::HTTPResponse, e.g. + # Net::HTTPOK + attr_reader :response + + # Instantiate an instance of ResponseError with a Net::HTTPResponse object + # @param [Net::HTTPResponse] + def initialize(response) + @response = response + super(response) + end + end + + # Exception that is raised when request has redirected too many times. + # Calling {#response} returns the Net:HTTP response object. + class RedirectionTooDeep < ResponseError; end + + # Exception that is raised when request redirects and location header is present more than once + class DuplicateLocationHeader < ResponseError; end + + # Exception that is raised when common network errors occur. + class NetworkError < Foul; end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/hash_conversions.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/hash_conversions.rb new file mode 100644 index 0000000..270effe --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/hash_conversions.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +require 'erb' + +module HTTParty + module HashConversions + # @return This hash as a query string + # + # @example + # { name: "Bob", + # address: { + # street: '111 Ruby Ave.', + # city: 'Ruby Central', + # phones: ['111-111-1111', '222-222-2222'] + # } + # }.to_params + # #=> "name=Bob&address[city]=Ruby Central&address[phones][]=111-111-1111&address[phones][]=222-222-2222&address[street]=111 Ruby Ave." + def self.to_params(hash) + hash.to_hash.map { |k, v| normalize_param(k, v) }.join.chop + end + + # @param key The key for the param. + # @param value The value for the param. + # + # @return This key value pair as a param + # + # @example normalize_param(:name, "Bob Jones") #=> "name=Bob%20Jones&" + def self.normalize_param(key, value) + normalized_keys = normalize_keys(key, value) + + normalized_keys.flatten.each_slice(2).inject(''.dup) do |string, (k, v)| + string << "#{ERB::Util.url_encode(k)}=#{ERB::Util.url_encode(v.to_s)}&" + end + end + + def self.normalize_keys(key, value) + stack = [] + normalized_keys = [] + + if value.respond_to?(:to_ary) + if value.empty? + normalized_keys << ["#{key}[]", ''] + else + normalized_keys = value.to_ary.flat_map do |element| + normalize_keys("#{key}[]", element) + end + end + elsif value.respond_to?(:to_hash) + stack << [key, value.to_hash] + else + normalized_keys << [key.to_s, value] + end + + stack.each do |parent, hash| + hash.each do |child_key, child_value| + if child_value.respond_to?(:to_hash) + stack << ["#{parent}[#{child_key}]", child_value.to_hash] + elsif child_value.respond_to?(:to_ary) + child_value.to_ary.each do |v| + normalized_keys << normalize_keys("#{parent}[#{child_key}][]", v).flatten + end + else + normalized_keys << normalize_keys("#{parent}[#{child_key}]", child_value).flatten + end + end + end + + normalized_keys + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/headers_processor.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/headers_processor.rb new file mode 100644 index 0000000..05b82c6 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/headers_processor.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module HTTParty + class HeadersProcessor + attr_reader :headers, :options + + def initialize(headers, options) + @headers = headers + @options = options + end + + def call + return unless options[:headers] + + options[:headers] = headers.merge(options[:headers]) if headers.any? + options[:headers] = Utils.stringify_keys(process_dynamic_headers) + end + + private + + def process_dynamic_headers + options[:headers].each_with_object({}) do |header, processed_headers| + key, value = header + processed_headers[key] = if value.respond_to?(:call) + value.arity == 0 ? value.call : value.call(options) + else + value + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/logger/apache_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/logger/apache_formatter.rb new file mode 100644 index 0000000..1e3fe97 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/logger/apache_formatter.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +module HTTParty + module Logger + class ApacheFormatter #:nodoc: + TAG_NAME = HTTParty.name + + attr_accessor :level, :logger + + def initialize(logger, level) + @logger = logger + @level = level.to_sym + end + + def format(request, response) + @request = request + @response = response + + logger.public_send level, message + end + + private + + attr_reader :request, :response + + def message + "[#{TAG_NAME}] [#{current_time}] #{response.code} \"#{http_method} #{path}\" #{content_length || '-'} " + end + + def current_time + Time.now.strftime('%Y-%m-%d %H:%M:%S %z') + end + + def http_method + request.http_method.name.split('::').last.upcase + end + + def path + request.path.to_s + end + + def content_length + response.respond_to?(:headers) ? response.headers['Content-Length'] : response['Content-Length'] + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/logger/curl_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/logger/curl_formatter.rb new file mode 100644 index 0000000..eee2aad --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/logger/curl_formatter.rb @@ -0,0 +1,93 @@ +# frozen_string_literal: true + +module HTTParty + module Logger + class CurlFormatter #:nodoc: + TAG_NAME = HTTParty.name + OUT = '>' + IN = '<' + + attr_accessor :level, :logger + + def initialize(logger, level) + @logger = logger + @level = level.to_sym + @messages = [] + end + + def format(request, response) + @request = request + @response = response + + log_request + log_response + + logger.public_send level, messages.join("\n") + end + + private + + attr_reader :request, :response + attr_accessor :messages + + def log_request + log_url + log_headers + log_query + log OUT, request.raw_body if request.raw_body + log OUT + end + + def log_response + log IN, "HTTP/#{response.http_version} #{response.code}" + log_response_headers + log IN, "\n#{response.body}" + log IN + end + + def log_url + http_method = request.http_method.name.split('::').last.upcase + uri = if request.options[:base_uri] + request.options[:base_uri] + request.path.path + else + request.path.to_s + end + + log OUT, "#{http_method} #{uri}" + end + + def log_headers + return unless request.options[:headers] && request.options[:headers].size > 0 + + log OUT, 'Headers: ' + log_hash request.options[:headers] + end + + def log_query + return unless request.options[:query] + + log OUT, 'Query: ' + log_hash request.options[:query] + end + + def log_response_headers + headers = response.respond_to?(:headers) ? response.headers : response + response.each_header do |response_header| + log IN, "#{response_header.capitalize}: #{headers[response_header]}" + end + end + + def log_hash(hash) + hash.each { |k, v| log(OUT, "#{k}: #{v}") } + end + + def log(direction, line = '') + messages << "[#{TAG_NAME}] [#{current_time}] #{direction} #{line}" + end + + def current_time + Time.now.strftime("%Y-%m-%d %H:%M:%S %z") + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/logger/logger.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/logger/logger.rb new file mode 100644 index 0000000..b1db782 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/logger/logger.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require 'httparty/logger/apache_formatter' +require 'httparty/logger/curl_formatter' +require 'httparty/logger/logstash_formatter' + +module HTTParty + module Logger + def self.formatters + @formatters ||= { + :curl => Logger::CurlFormatter, + :apache => Logger::ApacheFormatter, + :logstash => Logger::LogstashFormatter, + } + end + + def self.add_formatter(name, formatter) + raise HTTParty::Error.new("Log Formatter with name #{name} already exists") if formatters.include?(name) + formatters.merge!(name.to_sym => formatter) + end + + def self.build(logger, level, formatter) + level ||= :info + formatter ||= :apache + + logger_klass = formatters[formatter] || Logger::ApacheFormatter + logger_klass.new(logger, level) + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/logger/logstash_formatter.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/logger/logstash_formatter.rb new file mode 100644 index 0000000..dd129ec --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/logger/logstash_formatter.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +module HTTParty + module Logger + class LogstashFormatter #:nodoc: + TAG_NAME = HTTParty.name + + attr_accessor :level, :logger + + def initialize(logger, level) + @logger = logger + @level = level.to_sym + end + + def format(request, response) + @request = request + @response = response + + logger.public_send level, logstash_message + end + + private + + attr_reader :request, :response + + def logstash_message + require 'json' + { + '@timestamp' => current_time, + '@version' => 1, + 'content_length' => content_length || '-', + 'http_method' => http_method, + 'message' => message, + 'path' => path, + 'response_code' => response.code, + 'severity' => level, + 'tags' => [TAG_NAME], + }.to_json + end + + def message + "[#{TAG_NAME}] #{response.code} \"#{http_method} #{path}\" #{content_length || '-'} " + end + + def current_time + Time.now.strftime('%Y-%m-%d %H:%M:%S %z') + end + + def http_method + @http_method ||= request.http_method.name.split('::').last.upcase + end + + def path + @path ||= request.path.to_s + end + + def content_length + @content_length ||= response.respond_to?(:headers) ? response.headers['Content-Length'] : response['Content-Length'] + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/module_inheritable_attributes.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/module_inheritable_attributes.rb new file mode 100644 index 0000000..eb841fa --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/module_inheritable_attributes.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +module HTTParty + module ModuleInheritableAttributes #:nodoc: + def self.included(base) + base.extend(ClassMethods) + end + + # borrowed from Rails 3.2 ActiveSupport + def self.hash_deep_dup(hash) + duplicate = hash.dup + + duplicate.each_pair do |key, value| + if value.is_a?(Hash) + duplicate[key] = hash_deep_dup(value) + elsif value.is_a?(Proc) + duplicate[key] = value.dup + else + duplicate[key] = value + end + end + + duplicate + end + + module ClassMethods #:nodoc: + def mattr_inheritable(*args) + @mattr_inheritable_attrs ||= [:mattr_inheritable_attrs] + @mattr_inheritable_attrs += args + + args.each do |arg| + singleton_class.attr_accessor(arg) + end + + @mattr_inheritable_attrs + end + + def inherited(subclass) + super + @mattr_inheritable_attrs.each do |inheritable_attribute| + ivar = :"@#{inheritable_attribute}" + subclass.instance_variable_set(ivar, instance_variable_get(ivar).clone) + + if instance_variable_get(ivar).respond_to?(:merge) + subclass.class_eval <<~RUBY, __FILE__, __LINE__ + 1 + def self.#{inheritable_attribute} + duplicate = ModuleInheritableAttributes.hash_deep_dup(#{ivar}) + #{ivar} = superclass.#{inheritable_attribute}.merge(duplicate) + end + RUBY + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/net_digest_auth.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/net_digest_auth.rb new file mode 100644 index 0000000..a6b6cc2 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/net_digest_auth.rb @@ -0,0 +1,135 @@ +# frozen_string_literal: true + +require 'digest/md5' +require 'net/http' + +module Net + module HTTPHeader + def digest_auth(username, password, response) + authenticator = DigestAuthenticator.new( + username, + password, + @method, + @path, + response + ) + + authenticator.authorization_header.each do |v| + add_field('Authorization', v) + end + + authenticator.cookie_header.each do |v| + add_field('Cookie', v) + end + end + + class DigestAuthenticator + def initialize(username, password, method, path, response_header) + @username = username + @password = password + @method = method + @path = path + @response = parse(response_header) + @cookies = parse_cookies(response_header) + end + + def authorization_header + @cnonce = md5(random) + header = [ + %(Digest username="#{@username}"), + %(realm="#{@response['realm']}"), + %(nonce="#{@response['nonce']}"), + %(uri="#{@path}"), + %(response="#{request_digest}") + ] + + header << %(algorithm="#{@response['algorithm']}") if algorithm_present? + + if qop_present? + header << %(cnonce="#{@cnonce}") + header << %(qop="#{@response['qop']}") + header << 'nc=00000001' + end + + header << %(opaque="#{@response['opaque']}") if opaque_present? + header + end + + def cookie_header + @cookies + end + + private + + def parse(response_header) + header = response_header['www-authenticate'] + + header = header.gsub(/qop=(auth(?:-int)?)/, 'qop="\\1"') + + header =~ /Digest (.*)/ + params = {} + if $1 + non_quoted = $1.gsub(/(\w+)="(.*?)"/) { params[$1] = $2 } + non_quoted.gsub(/(\w+)=([^,]*)/) { params[$1] = $2 } + end + params + end + + def parse_cookies(response_header) + return [] unless response_header['Set-Cookie'] + + cookies = response_header['Set-Cookie'].split('; ') + + cookies.reduce([]) do |ret, cookie| + ret << cookie + ret + end + + cookies + end + + def opaque_present? + @response.key?('opaque') && !@response['opaque'].empty? + end + + def qop_present? + @response.key?('qop') && !@response['qop'].empty? + end + + def random + format '%x', (Time.now.to_i + rand(65535)) + end + + def request_digest + a = [md5(a1), @response['nonce'], md5(a2)] + a.insert(2, '00000001', @cnonce, @response['qop']) if qop_present? + md5(a.join(':')) + end + + def md5(str) + Digest::MD5.hexdigest(str) + end + + def algorithm_present? + @response.key?('algorithm') && !@response['algorithm'].empty? + end + + def use_md5_sess? + algorithm_present? && @response['algorithm'] == 'MD5-sess' + end + + def a1 + a1_user_realm_pwd = [@username, @response['realm'], @password].join(':') + if use_md5_sess? + [ md5(a1_user_realm_pwd), @response['nonce'], @cnonce ].join(':') + else + a1_user_realm_pwd + end + end + + def a2 + [@method, @path].join(':') + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/parser.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/parser.rb new file mode 100644 index 0000000..44451ce --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/parser.rb @@ -0,0 +1,157 @@ +# frozen_string_literal: true + +module HTTParty + # The default parser used by HTTParty, supports xml, json, html, csv and + # plain text. + # + # == Custom Parsers + # + # If you'd like to do your own custom parsing, subclassing HTTParty::Parser + # will make that process much easier. There are a few different ways you can + # utilize HTTParty::Parser as a superclass. + # + # @example Intercept the parsing for all formats + # class SimpleParser < HTTParty::Parser + # def parse + # perform_parsing + # end + # end + # + # @example Add the atom format and parsing method to the default parser + # class AtomParsingIncluded < HTTParty::Parser + # SupportedFormats.merge!( + # {"application/atom+xml" => :atom} + # ) + # + # def atom + # perform_atom_parsing + # end + # end + # + # @example Only support the atom format + # class ParseOnlyAtom < HTTParty::Parser + # SupportedFormats = {"application/atom+xml" => :atom} + # + # def atom + # perform_atom_parsing + # end + # end + # + # @abstract Read the Custom Parsers section for more information. + class Parser + SupportedFormats = { + 'text/xml' => :xml, + 'application/xml' => :xml, + 'application/json' => :json, + 'application/vnd.api+json' => :json, + 'application/hal+json' => :json, + 'text/json' => :json, + 'application/javascript' => :plain, + 'text/javascript' => :plain, + 'text/html' => :html, + 'text/plain' => :plain, + 'text/csv' => :csv, + 'application/csv' => :csv, + 'text/comma-separated-values' => :csv + } + + # The response body of the request + # @return [String] + attr_reader :body + + # The intended parsing format for the request + # @return [Symbol] e.g. :json + attr_reader :format + + # Instantiate the parser and call {#parse}. + # @param [String] body the response body + # @param [Symbol] format the response format + # @return parsed response + def self.call(body, format) + new(body, format).parse + end + + # @return [Hash] the SupportedFormats hash + def self.formats + const_get(:SupportedFormats) + end + + # @param [String] mimetype response MIME type + # @return [Symbol] + # @return [nil] mime type not supported + def self.format_from_mimetype(mimetype) + formats[formats.keys.detect {|k| mimetype.include?(k)}] + end + + # @return [Array] list of supported formats + def self.supported_formats + formats.values.uniq + end + + # @param [Symbol] format e.g. :json, :xml + # @return [Boolean] + def self.supports_format?(format) + supported_formats.include?(format) + end + + def initialize(body, format) + @body = body + @format = format + end + + # @return [Object] the parsed body + # @return [nil] when the response body is nil, an empty string, spaces only or "null" + def parse + return nil if body.nil? + return nil if body == 'null' + return nil if body.valid_encoding? && body.strip.empty? + if body.valid_encoding? && body.encoding == Encoding::UTF_8 + @body = body.gsub(/\A#{UTF8_BOM}/, '') + end + if supports_format? + parse_supported_format + else + body + end + end + + protected + + def xml + require 'multi_xml' + MultiXml.parse(body) + end + + UTF8_BOM = "\xEF\xBB\xBF" + + def json + require 'json' + JSON.parse(body, :quirks_mode => true, :allow_nan => true) + end + + def csv + require 'csv' + CSV.parse(body) + end + + def html + body + end + + def plain + body + end + + def supports_format? + self.class.supports_format?(format) + end + + def parse_supported_format + if respond_to?(format, true) + send(format) + else + raise NotImplementedError, "#{self.class.name} has not implemented a parsing method for the #{format.inspect} format." + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/request.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/request.rb new file mode 100644 index 0000000..36b7d35 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/request.rb @@ -0,0 +1,437 @@ +# frozen_string_literal: true + +require 'erb' + +module HTTParty + class Request #:nodoc: + SupportedHTTPMethods = [ + Net::HTTP::Get, + Net::HTTP::Post, + Net::HTTP::Patch, + Net::HTTP::Put, + Net::HTTP::Delete, + Net::HTTP::Head, + Net::HTTP::Options, + Net::HTTP::Move, + Net::HTTP::Copy, + Net::HTTP::Mkcol, + Net::HTTP::Lock, + Net::HTTP::Unlock, + ] + + SupportedURISchemes = ['http', 'https', 'webcal', nil] + + NON_RAILS_QUERY_STRING_NORMALIZER = proc do |query| + Array(query).sort_by { |a| a[0].to_s }.map do |key, value| + if value.nil? + key.to_s + elsif value.respond_to?(:to_ary) + value.to_ary.map {|v| "#{key}=#{ERB::Util.url_encode(v.to_s)}"} + else + HashConversions.to_params(key => value) + end + end.flatten.join('&') + end + + JSON_API_QUERY_STRING_NORMALIZER = proc do |query| + Array(query).sort_by { |a| a[0].to_s }.map do |key, value| + if value.nil? + key.to_s + elsif value.respond_to?(:to_ary) + values = value.to_ary.map{|v| ERB::Util.url_encode(v.to_s)} + "#{key}=#{values.join(',')}" + else + HashConversions.to_params(key => value) + end + end.flatten.join('&') + end + + def self._load(data) + http_method, path, options, last_response, last_uri, raw_request = Marshal.load(data) + instance = new(http_method, path, options) + instance.last_response = last_response + instance.last_uri = last_uri + instance.instance_variable_set("@raw_request", raw_request) + instance + end + + attr_accessor :http_method, :options, :last_response, :redirect, :last_uri + attr_reader :path + + def initialize(http_method, path, o = {}) + @changed_hosts = false + @credentials_sent = false + + self.http_method = http_method + self.options = { + limit: o.delete(:no_follow) ? 1 : 5, + assume_utf16_is_big_endian: true, + default_params: {}, + follow_redirects: true, + parser: Parser, + uri_adapter: URI, + connection_adapter: ConnectionAdapter + }.merge(o) + self.path = path + set_basic_auth_from_uri + end + + def path=(uri) + uri_adapter = options[:uri_adapter] + + @path = if uri.is_a?(uri_adapter) + uri + elsif String.try_convert(uri) + uri_adapter.parse(uri).normalize + else + raise ArgumentError, + "bad argument (expected #{uri_adapter} object or URI string)" + end + end + + def request_uri(uri) + if uri.respond_to? :request_uri + uri.request_uri + else + uri.path + end + end + + def uri + if redirect && path.relative? && path.path[0] != '/' + last_uri_host = @last_uri.path.gsub(/[^\/]+$/, '') + + path.path = "/#{path.path}" if last_uri_host[-1] != '/' + path.path = "#{last_uri_host}#{path.path}" + end + + if path.relative? && path.host + new_uri = options[:uri_adapter].parse("#{@last_uri.scheme}:#{path}").normalize + elsif path.relative? + new_uri = options[:uri_adapter].parse("#{base_uri}#{path}").normalize + else + new_uri = path.clone + end + + # avoid double query string on redirects [#12] + unless redirect + new_uri.query = query_string(new_uri) + end + + unless SupportedURISchemes.include? new_uri.scheme + raise UnsupportedURIScheme, "'#{new_uri}' Must be HTTP, HTTPS or Generic" + end + + @last_uri = new_uri + end + + def base_uri + if redirect + base_uri = "#{@last_uri.scheme}://#{@last_uri.host}" + base_uri = "#{base_uri}:#{@last_uri.port}" if @last_uri.port != 80 + base_uri + else + options[:base_uri] && HTTParty.normalize_base_uri(options[:base_uri]) + end + end + + def format + options[:format] || (format_from_mimetype(last_response['content-type']) if last_response) + end + + def parser + options[:parser] + end + + def connection_adapter + options[:connection_adapter] + end + + def perform(&block) + validate + setup_raw_request + chunked_body = nil + current_http = http + + begin + self.last_response = current_http.request(@raw_request) do |http_response| + if block + chunks = [] + + http_response.read_body do |fragment| + encoded_fragment = encode_text(fragment, http_response['content-type']) + chunks << encoded_fragment if !options[:stream_body] + block.call ResponseFragment.new(encoded_fragment, http_response, current_http) + end + + chunked_body = chunks.join + end + end + + handle_host_redirection if response_redirects? + result = handle_unauthorized + result ||= handle_response(chunked_body, &block) + result + rescue *COMMON_NETWORK_ERRORS => e + raise options[:foul] ? HTTParty::NetworkError.new("#{e.class}: #{e.message}") : e + end + end + + def handle_unauthorized(&block) + return unless digest_auth? && response_unauthorized? && response_has_digest_auth_challenge? + return if @credentials_sent + @credentials_sent = true + perform(&block) + end + + def raw_body + @raw_request.body + end + + def _dump(_level) + opts = options.dup + opts.delete(:logger) + opts.delete(:parser) if opts[:parser] && opts[:parser].is_a?(Proc) + Marshal.dump([http_method, path, opts, last_response, @last_uri, @raw_request]) + end + + private + + def http + connection_adapter.call(uri, options) + end + + def credentials + (options[:basic_auth] || options[:digest_auth]).to_hash + end + + def username + credentials[:username] + end + + def password + credentials[:password] + end + + def normalize_query(query) + if query_string_normalizer + query_string_normalizer.call(query) + else + HashConversions.to_params(query) + end + end + + def query_string_normalizer + options[:query_string_normalizer] + end + + def setup_raw_request + if options[:headers].respond_to?(:to_hash) + headers_hash = options[:headers].to_hash + else + headers_hash = nil + end + + @raw_request = http_method.new(request_uri(uri), headers_hash) + @raw_request.body_stream = options[:body_stream] if options[:body_stream] + + if options[:body] + body = Body.new( + options[:body], + query_string_normalizer: query_string_normalizer, + force_multipart: options[:multipart] + ) + + if body.multipart? + content_type = "multipart/form-data; boundary=#{body.boundary}" + @raw_request['Content-Type'] = content_type + end + @raw_request.body = body.call + end + + @raw_request.instance_variable_set(:@decode_content, decompress_content?) + + if options[:basic_auth] && send_authorization_header? + @raw_request.basic_auth(username, password) + @credentials_sent = true + end + setup_digest_auth if digest_auth? && response_unauthorized? && response_has_digest_auth_challenge? + end + + def digest_auth? + !!options[:digest_auth] + end + + def decompress_content? + !options[:skip_decompression] + end + + def response_unauthorized? + !!last_response && last_response.code == '401' + end + + def response_has_digest_auth_challenge? + !last_response['www-authenticate'].nil? && last_response['www-authenticate'].length > 0 + end + + def setup_digest_auth + @raw_request.digest_auth(username, password, last_response) + end + + def query_string(uri) + query_string_parts = [] + query_string_parts << uri.query unless uri.query.nil? + + if options[:query].respond_to?(:to_hash) + query_string_parts << normalize_query(options[:default_params].merge(options[:query].to_hash)) + else + query_string_parts << normalize_query(options[:default_params]) unless options[:default_params].empty? + query_string_parts << options[:query] unless options[:query].nil? + end + + query_string_parts.reject!(&:empty?) unless query_string_parts == [''] + query_string_parts.size > 0 ? query_string_parts.join('&') : nil + end + + def assume_utf16_is_big_endian + options[:assume_utf16_is_big_endian] + end + + def handle_response(raw_body, &block) + if response_redirects? + handle_redirection(&block) + else + raw_body ||= last_response.body + + body = decompress(raw_body, last_response['content-encoding']) unless raw_body.nil? + + unless body.nil? + body = encode_text(body, last_response['content-type']) + + if decompress_content? + last_response.delete('content-encoding') + raw_body = body + end + end + + Response.new(self, last_response, lambda { parse_response(body) }, body: raw_body) + end + end + + def handle_redirection(&block) + options[:limit] -= 1 + if options[:logger] + logger = HTTParty::Logger.build(options[:logger], options[:log_level], options[:log_format]) + logger.format(self, last_response) + end + self.path = last_response['location'] + self.redirect = true + if last_response.class == Net::HTTPSeeOther + unless options[:maintain_method_across_redirects] && options[:resend_on_redirect] + self.http_method = Net::HTTP::Get + end + elsif last_response.code != '307' && last_response.code != '308' + unless options[:maintain_method_across_redirects] + self.http_method = Net::HTTP::Get + end + end + if http_method == Net::HTTP::Get + clear_body + end + capture_cookies(last_response) + perform(&block) + end + + def handle_host_redirection + check_duplicate_location_header + redirect_path = options[:uri_adapter].parse(last_response['location']).normalize + return if redirect_path.relative? || path.host == redirect_path.host || uri.host == redirect_path.host + @changed_hosts = true + end + + def check_duplicate_location_header + location = last_response.get_fields('location') + if location.is_a?(Array) && location.count > 1 + raise DuplicateLocationHeader.new(last_response) + end + end + + def send_authorization_header? + !@changed_hosts + end + + def response_redirects? + case last_response + when Net::HTTPNotModified # 304 + false + when Net::HTTPRedirection + options[:follow_redirects] && last_response.key?('location') + end + end + + def parse_response(body) + parser.call(body, format) + end + + # Some Web Application Firewalls reject incoming GET requests that have a body + # if we redirect, and the resulting verb is GET then we will clear the body that + # may be left behind from the initiating request + def clear_body + options[:body] = nil + @raw_request.body = nil + end + + def capture_cookies(response) + return unless response['Set-Cookie'] + cookies_hash = HTTParty::CookieHash.new + cookies_hash.add_cookies(options[:headers].to_hash['Cookie']) if options[:headers] && options[:headers].to_hash['Cookie'] + response.get_fields('Set-Cookie').each { |cookie| cookies_hash.add_cookies(cookie) } + + options[:headers] ||= {} + options[:headers]['Cookie'] = cookies_hash.to_cookie_string + end + + # Uses the HTTP Content-Type header to determine the format of the + # response It compares the MIME type returned to the types stored in the + # SupportedFormats hash + def format_from_mimetype(mimetype) + if mimetype && parser.respond_to?(:format_from_mimetype) + parser.format_from_mimetype(mimetype) + end + end + + def validate + raise HTTParty::RedirectionTooDeep.new(last_response), 'HTTP redirects too deep' if options[:limit].to_i <= 0 + raise ArgumentError, 'only get, post, patch, put, delete, head, and options methods are supported' unless SupportedHTTPMethods.include?(http_method) + raise ArgumentError, ':headers must be a hash' if options[:headers] && !options[:headers].respond_to?(:to_hash) + raise ArgumentError, 'only one authentication method, :basic_auth or :digest_auth may be used at a time' if options[:basic_auth] && options[:digest_auth] + raise ArgumentError, ':basic_auth must be a hash' if options[:basic_auth] && !options[:basic_auth].respond_to?(:to_hash) + raise ArgumentError, ':digest_auth must be a hash' if options[:digest_auth] && !options[:digest_auth].respond_to?(:to_hash) + raise ArgumentError, ':query must be hash if using HTTP Post' if post? && !options[:query].nil? && !options[:query].respond_to?(:to_hash) + end + + def post? + Net::HTTP::Post == http_method + end + + def set_basic_auth_from_uri + if path.userinfo + username, password = path.userinfo.split(':') + options[:basic_auth] = {username: username, password: password} + @credentials_sent = true + end + end + + def decompress(body, encoding) + Decompressor.new(body, encoding).decompress + end + + def encode_text(text, content_type) + TextEncoder.new( + text, + content_type: content_type, + assume_utf16_is_big_endian: assume_utf16_is_big_endian + ).call + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/request/body.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/request/body.rb new file mode 100644 index 0000000..3e63664 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/request/body.rb @@ -0,0 +1,107 @@ +# frozen_string_literal: true + +require_relative 'multipart_boundary' + +module HTTParty + class Request + class Body + NEWLINE = "\r\n" + private_constant :NEWLINE + + def initialize(params, query_string_normalizer: nil, force_multipart: false) + @params = params + @query_string_normalizer = query_string_normalizer + @force_multipart = force_multipart + end + + def call + if params.respond_to?(:to_hash) + multipart? ? generate_multipart : normalize_query(params) + else + params + end + end + + def boundary + @boundary ||= MultipartBoundary.generate + end + + def multipart? + params.respond_to?(:to_hash) && (force_multipart || has_file?(params)) + end + + private + + # https://html.spec.whatwg.org/#multipart-form-data + MULTIPART_FORM_DATA_REPLACEMENT_TABLE = { + '"' => '%22', + "\r" => '%0D', + "\n" => '%0A' + }.freeze + + def generate_multipart + normalized_params = params.flat_map { |key, value| HashConversions.normalize_keys(key, value) } + + multipart = normalized_params.inject(''.dup) do |memo, (key, value)| + memo << "--#{boundary}#{NEWLINE}" + memo << %(Content-Disposition: form-data; name="#{key}") + # value.path is used to support ActionDispatch::Http::UploadedFile + # https://github.com/jnunemaker/httparty/pull/585 + memo << %(; filename="#{file_name(value).gsub(/["\r\n]/, MULTIPART_FORM_DATA_REPLACEMENT_TABLE)}") if file?(value) + memo << NEWLINE + memo << "Content-Type: #{content_type(value)}#{NEWLINE}" if file?(value) + memo << NEWLINE + memo << content_body(value) + memo << NEWLINE + end + + multipart << "--#{boundary}--#{NEWLINE}" + end + + def has_file?(value) + if value.respond_to?(:to_hash) + value.to_hash.any? { |_, v| has_file?(v) } + elsif value.respond_to?(:to_ary) + value.to_ary.any? { |v| has_file?(v) } + else + file?(value) + end + end + + def file?(object) + object.respond_to?(:path) && object.respond_to?(:read) + end + + def normalize_query(query) + if query_string_normalizer + query_string_normalizer.call(query) + else + HashConversions.to_params(query) + end + end + + def content_body(object) + if file?(object) + object = (file = object).read + object.force_encoding(Encoding::UTF_8) if object.respond_to?(:force_encoding) + file.rewind if file.respond_to?(:rewind) + end + + object.to_s + end + + def content_type(object) + return object.content_type if object.respond_to?(:content_type) + require 'mini_mime' + mime = MiniMime.lookup_by_filename(object.path) + mime ? mime.content_type : 'application/octet-stream' + end + + def file_name(object) + object.respond_to?(:original_filename) ? object.original_filename : File.basename(object.path) + end + + attr_reader :params, :query_string_normalizer, :force_multipart + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/request/multipart_boundary.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/request/multipart_boundary.rb new file mode 100644 index 0000000..f9e2ac1 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/request/multipart_boundary.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'securerandom' + +module HTTParty + class Request + class MultipartBoundary + def self.generate + "------------------------#{SecureRandom.urlsafe_base64(12)}" + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/response.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/response.rb new file mode 100644 index 0000000..2a6fa42 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/response.rb @@ -0,0 +1,156 @@ +# frozen_string_literal: true + +module HTTParty + class Response < Object + def self.underscore(string) + string.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').gsub(/([a-z])([A-Z])/, '\1_\2').downcase + end + + def self._load(data) + req, resp, parsed_resp, resp_body = Marshal.load(data) + + new(req, resp, -> { parsed_resp }, body: resp_body) + end + + attr_reader :request, :response, :body, :headers + + def initialize(request, response, parsed_block, options = {}) + @request = request + @response = response + @body = options[:body] || response.body + @parsed_block = parsed_block + @headers = Headers.new(response.to_hash) + + if request.options[:logger] + logger = ::HTTParty::Logger.build( + request.options[:logger], + request.options[:log_level], + request.options[:log_format] + ) + logger.format(request, self) + end + + throw_exception + end + + def parsed_response + @parsed_response ||= @parsed_block.call + end + + def code + response.code.to_i + end + + def http_version + response.http_version + end + + def tap + yield self + self + end + + def inspect + inspect_id = ::Kernel::format '%x', (object_id * 2) + %(#<#{self.class}:0x#{inspect_id} parsed_response=#{parsed_response.inspect}, @response=#{response.inspect}, @headers=#{headers.inspect}>) + end + + CODES_TO_OBJ = ::Net::HTTPResponse::CODE_CLASS_TO_OBJ.merge ::Net::HTTPResponse::CODE_TO_OBJ + + CODES_TO_OBJ.each do |response_code, klass| + name = klass.name.sub('Net::HTTP', '') + name = "#{underscore(name)}?".to_sym + + define_method(name) do + klass === response + end + end + + # Support old multiple_choice? method from pre 2.0.0 era. + if ::RUBY_PLATFORM != 'java' + alias_method :multiple_choice?, :multiple_choices? + end + + # Support old status codes method from pre 2.6.0 era. + if ::RUBY_PLATFORM != 'java' + alias_method :gateway_time_out?, :gateway_timeout? + alias_method :request_entity_too_large?, :payload_too_large? + alias_method :request_time_out?, :request_timeout? + alias_method :request_uri_too_long?, :uri_too_long? + alias_method :requested_range_not_satisfiable?, :range_not_satisfiable? + end + + def nil? + warn_about_nil_deprecation + response.nil? || response.body.nil? || response.body.empty? + end + + def to_s + if !response.nil? && !response.body.nil? && response.body.respond_to?(:to_s) + response.body.to_s + else + inspect + end + end + + def pretty_print(pp) + if !parsed_response.nil? && parsed_response.respond_to?(:pretty_print) + parsed_response.pretty_print(pp) + else + super + end + end + + def display(port=$>) + if !parsed_response.nil? && parsed_response.respond_to?(:display) + parsed_response.display(port) + elsif !response.nil? && !response.body.nil? && response.body.respond_to?(:display) + response.body.display(port) + else + port.write(inspect) + end + end + + def respond_to_missing?(name, *args) + return true if super + parsed_response.respond_to?(name) || response.respond_to?(name) + end + + def _dump(_level) + Marshal.dump([request, response, parsed_response, body]) + end + + protected + + def method_missing(name, *args, &block) + if parsed_response.respond_to?(name) + parsed_response.send(name, *args, &block) + elsif response.respond_to?(name) + response.send(name, *args, &block) + else + super + end + end + + def throw_exception + if @request.options[:raise_on].to_a.detect { |c| code.to_s.match(/#{c.to_s}/) } + ::Kernel.raise ::HTTParty::ResponseError.new(@response), "Code #{code} - #{body}" + end + end + + private + + def warn_about_nil_deprecation + trace_line = caller.reject { |line| line.include?('httparty') }.first + warning = "[DEPRECATION] HTTParty will no longer override `response#nil?`. " \ + "This functionality will be removed in future versions. " \ + "Please, add explicit check `response.body.nil? || response.body.empty?`. " \ + "For more info refer to: https://github.com/jnunemaker/httparty/issues/568\n" \ + "#{trace_line}" + + warn(warning) + end + end +end + +require 'httparty/response/headers' diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/response/headers.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/response/headers.rb new file mode 100644 index 0000000..cc5fc7b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/response/headers.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require 'delegate' + +module HTTParty + class Response #:nodoc: + class Headers < ::SimpleDelegator + include ::Net::HTTPHeader + + def initialize(header_values = nil) + @header = {} + if header_values + header_values.each_pair do |k,v| + if v.is_a?(Array) + v.each do |sub_v| + add_field(k, sub_v) + end + else + add_field(k, v) + end + end + end + super(@header) + end + + def ==(other) + if other.is_a?(::Net::HTTPHeader) + @header == other.instance_variable_get(:@header) + elsif other.is_a?(Hash) + @header == other || @header == Headers.new(other).instance_variable_get(:@header) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/response_fragment.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/response_fragment.rb new file mode 100644 index 0000000..1fb15a0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/response_fragment.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require 'delegate' + +module HTTParty + # Allow access to http_response and code by delegation on fragment + class ResponseFragment < SimpleDelegator + attr_reader :http_response, :connection + + def code + @http_response.code.to_i + end + + def initialize(fragment, http_response, connection) + @fragment = fragment + @http_response = http_response + @connection = connection + super fragment + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/text_encoder.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/text_encoder.rb new file mode 100644 index 0000000..006893e --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/text_encoder.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +module HTTParty + class TextEncoder + attr_reader :text, :content_type, :assume_utf16_is_big_endian + + def initialize(text, assume_utf16_is_big_endian: true, content_type: nil) + @text = +text + @content_type = content_type + @assume_utf16_is_big_endian = assume_utf16_is_big_endian + end + + def call + if can_encode? + encoded_text + else + text + end + end + + private + + def can_encode? + ''.respond_to?(:encoding) && charset + end + + def encoded_text + if 'utf-16'.casecmp(charset) == 0 + encode_utf_16 + else + encode_with_ruby_encoding + end + end + + def encode_utf_16 + if text.bytesize >= 2 + if text.getbyte(0) == 0xFF && text.getbyte(1) == 0xFE + return text.force_encoding('UTF-16LE') + elsif text.getbyte(0) == 0xFE && text.getbyte(1) == 0xFF + return text.force_encoding('UTF-16BE') + end + end + + if assume_utf16_is_big_endian # option + text.force_encoding('UTF-16BE') + else + text.force_encoding('UTF-16LE') + end + end + + def encode_with_ruby_encoding + # NOTE: This will raise an argument error if the + # charset does not exist + encoding = Encoding.find(charset) + text.force_encoding(encoding.to_s) + rescue ArgumentError + text + end + + def charset + return nil if content_type.nil? + + if (matchdata = content_type.match(/;\s*charset\s*=\s*([^=,;"\s]+)/i)) + return matchdata.captures.first + end + + if (matchdata = content_type.match(/;\s*charset\s*=\s*"((\\.|[^\\"])+)"/i)) + return matchdata.captures.first.gsub(/\\(.)/, '\1') + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/utils.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/utils.rb new file mode 100644 index 0000000..8393e92 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/utils.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module HTTParty + module Utils + def self.stringify_keys(hash) + return hash.transform_keys(&:to_s) if hash.respond_to?(:transform_keys) + + hash.each_with_object({}) do |(key, value), new_hash| + new_hash[key.to_s] = value + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/version.rb b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/version.rb new file mode 100644 index 0000000..4e0f71b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/lib/httparty/version.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +module HTTParty + VERSION = '0.23.2' +end diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/script/release b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/script/release new file mode 100755 index 0000000..72bd6b4 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/script/release @@ -0,0 +1,42 @@ +#!/bin/sh +#/ Usage: release +#/ +#/ Tag the version in the repo and push the gem. +#/ + +set -e +cd $(dirname "$0")/.. + +[ "$1" = "--help" -o "$1" = "-h" -o "$1" = "help" ] && { + grep '^#/' <"$0"| cut -c4- + exit 0 +} + +gem_name=httparty + +# Build a new gem archive. +rm -rf $gem_name-*.gem +gem build -q $gem_name.gemspec + +# Make sure we're on the main branch. +(git branch | grep -q '* main') || { + echo "Only release from the main branch." + exit 1 +} + +# Figure out what version we're releasing. +tag=v`ls $gem_name-*.gem | sed "s/^$gem_name-\(.*\)\.gem$/\1/"` + +echo "Releasing $tag" + +# Make sure we haven't released this version before. +git fetch -t origin + +(git tag -l | grep -q "$tag") && { + echo "Whoops, there's already a '${tag}' tag." + exit 1 +} + +# Tag it and bag it. +gem push $gem_name-*.gem && git tag "$tag" && + git push origin main && git push origin "$tag" diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/website/css/common.css b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/website/css/common.css new file mode 100644 index 0000000..1467d23 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/website/css/common.css @@ -0,0 +1,47 @@ +@media screen, projection { + /* + Copyright (c) 2007, Yahoo! Inc. All rights reserved. + Code licensed under the BSD License: + http://developer.yahoo.net/yui/license.txt + version: 2.2.0 + */ + body {font:13px arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}table {font-size:inherit;font:100%;}select, input, textarea {font:99% arial,helvetica,clean,sans-serif;}pre, code {font:115% monospace;*font-size:100%;}body * {line-height:1.22em;} + body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}/*ol,ul {list-style:none;}*/caption,th {text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym {border:0;} + /* end of yahoo reset and fonts */ + + body {color:#333; background:#4b1a1a; line-height:1.3;} + p {margin:0 0 20px;} + a {color:#4b1a1a;} + a:hover {text-decoration:none;} + strong {font-weight:bold;} + em {font-style:italics;} + h1,h2,h3,h4,h5,h6 {font-weight:bold;} + h1 {font-size:197%; margin:30px 0; color:#4b1a1a;} + h2 {font-size:174%; margin:20px 0; color:#b8111a;} + h3 {font-size:152%; margin:10px 0;} + h4 {font-size:129%; margin:10px 0;} + pre {background:#eee; margin:0 0 20px; padding:20px; border:1px solid #ccc; font-size:100%; overflow:auto;} + code {font-size:100%; margin:0; padding:0;} + ul, ol {margin:10px 0 10px 25px;} + ol li {margin:0 0 10px;} + + + + + + div#wrapper {background:#fff; width:560px; margin:0 auto; padding:20px; border:10px solid #bc8c46; border-width:0 10px;} + div#header {position:relative; border-bottom:1px dotted; margin:0 0 10px; padding:0 0 10px;} + div#header p {margin:0; padding:0;} + div#header h1 {margin:0; padding:0;} + ul#nav {position:absolute; top:0; right:0; list-style:none; margin:0; padding:0;} + ul#nav li {display:inline; padding:0 0 0 5px;} + ul#nav li a {} + div#content {} + div#footer {margin:40px 0 0; border-top:1px dotted; padding:10px 0 0;} + + + + + + +} \ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/website/index.html b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/website/index.html new file mode 100644 index 0000000..86916b3 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/httparty-0.23.2/website/index.html @@ -0,0 +1,73 @@ + + + + + HTTParty by John Nunemaker + + + + +
+ + +
+

Install

+
$ sudo gem install httparty
+ +

Some Quick Examples

+ +

The following is a simple example of wrapping Twitter's API for posting updates.

+ +
class Twitter
+  include HTTParty
+  base_uri 'twitter.com'
+  basic_auth 'username', 'password'
+end
+
+Twitter.post('/statuses/update.json', query: {status: "It's an HTTParty and everyone is invited!"})
+ +

That is really it! The object returned is a ruby hash that is decoded from Twitter's json response. JSON parsing is used because of the .json extension in the path of the request. You can also explicitly set a format (see the examples).

+ +

That works and all but what if you don't want to embed your username and password in the class? Below is an example to fix that:

+ +
class Twitter
+  include HTTParty
+  base_uri 'twitter.com'
+
+  def initialize(u, p)
+    @auth = {username: u, password: p}
+  end
+
+  def post(text)
+    options = { query: {status: text}, basic_auth: @auth }
+    self.class.post('/statuses/update.json', options)
+  end
+end
+
+Twitter.new('username', 'password').post("It's an HTTParty and everyone is invited!")
+ +

More Examples: There are several examples in the gem itself.

+ +

Support

+

Conversations welcome in the google group and bugs/features over at Github.

+ + +
+ + +
+ + + \ No newline at end of file diff --git a/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/.github/workflows/ci.yml b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/.github/workflows/ci.yml new file mode 100644 index 0000000..17c98d9 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/.github/workflows/ci.yml @@ -0,0 +1,51 @@ +name: Mini Mime Tests + +on: + pull_request: + push: + branches: + - main + +jobs: + build: + runs-on: ${{ matrix.os }}-latest + name: "Ruby ${{ matrix.ruby }} / ${{ matrix.os }} / Failure allowed: ${{ matrix.experimental }}" + continue-on-error: ${{ matrix.experimental }} + timeout-minutes: 5 + + strategy: + fail-fast: false + matrix: + os: ["ubuntu"] + ruby: ["2.6", "2.7", "3.0", "3.1", "3.2"] + experimental: [false] + include: + - ruby: "3.2" + os: "windows" + experimental: false + - ruby: "ruby-head" + os: "ubuntu" + experimental: true + - ruby: "truffleruby-head" + os: "ubuntu" + experimental: true + - ruby: "jruby-head" + os: "ubuntu" + experimental: true + - ruby: "jruby-9.3.9.0" + os: "ubuntu" + experimental: true + - ruby: "jruby-9.4.0.0" + os: "ubuntu" + experimental: true + steps: + - uses: actions/checkout@v3 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + bundler-cache: true + - name: Rubocop + run: bundle exec rubocop + if: "!contains(matrix.ruby, 'jruby')" + - name: Tests + run: bundle exec rake test diff --git a/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/.github/workflows/db.yml b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/.github/workflows/db.yml new file mode 100644 index 0000000..b95e8f8 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/.github/workflows/db.yml @@ -0,0 +1,26 @@ +name: Update MIME type DB + +on: + schedule: + # 10am on the 1st every month https://crontab.guru/#0_10_1_*_* + - cron: "0 10 1 * *" + workflow_dispatch: + +jobs: + update_db: + runs-on: ubuntu-latest + name: "Update MIME type DB" + steps: + - uses: actions/checkout@v3 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: "2.7" + bundler-cache: true + - name: Update mime-types-data + run: bundle update mime-types-data + - name: Update DB + run: bundle exec rake rebuild_db + - name: Create PR + run: bin/db_pull_request + env: + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/.gitignore b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/.gitignore new file mode 100644 index 0000000..0cb6eeb --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/.gitignore @@ -0,0 +1,9 @@ +/.bundle/ +/.yardoc +/Gemfile.lock +/_yardoc/ +/coverage/ +/doc/ +/pkg/ +/spec/reports/ +/tmp/ diff --git a/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/.rubocop.yml b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/.rubocop.yml new file mode 100644 index 0000000..05f8562 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/.rubocop.yml @@ -0,0 +1,5 @@ +inherit_gem: + rubocop-discourse: default.yml +inherit_mode: + merge: + - Exclude diff --git a/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/CHANGELOG b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/CHANGELOG new file mode 100644 index 0000000..99b1d31 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/CHANGELOG @@ -0,0 +1,65 @@ +08-08-2023 + - Version 1.1.5 + - Update mime types from upstream + +08-08-2023 + - Version 1.1.4 + - Version 1.1.3 had issues on Windows which does not support pread, added a polyfill + +04-08-2023 + - Version 1.1.3 + - Added fork safety by migrating from seek+read to pread + +11-10-2021 + - Version 1.1.2 + - update mime types from upstream + +23-08-2021 + - Version 1.1.1 + - update mime types from upstream + +05-04-2021 + - Version 1.1.0 + - MiniMime.lookup_by_extension is now case insensitive + +26-03-2021 + - Version 1.0.3 + - Update mime types from upstream + +08-07-2019 + - Version 1.0.2 + - Update mime types from upstream + +14-08-2018 + - Version 1.0.1 + - Update mime types from upstream + - Add lookup_by_extension to the public API + +08-11-2017 + - Version 1.0.0 + - Other than the version number, no difference from 0.1.4 + +11-08-2017 + - Version 0.1.4 + - Return preferred extension when looking up by content type + + +28-03-2016 + + - Version 0.1.3 + - Prefer non-obsolete mime types to obsolete ones + +14-12-2016 + + - Version 0.1.2 + - Backwards compat with ancient Ruby to match mail gem + +14-12-2016 + + - Version 0.1.1 + - Adjusted API to be more consistent + +14-12-2016 + + - Version 0.1.0 + - Initial version diff --git a/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/CODE_OF_CONDUCT.md b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..951cdde --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/CODE_OF_CONDUCT.md @@ -0,0 +1,74 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of experience, +nationality, personal appearance, race, religion, or sexual identity and +orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or +advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at sam.saffron@gmail.com. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/Gemfile b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/Gemfile new file mode 100644 index 0000000..1e36790 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/Gemfile @@ -0,0 +1,9 @@ +# frozen_string_literal: true +source 'https://rubygems.org' + +# Specify your gem's dependencies in mini_mime.gemspec +gemspec + +gem "mime-types", "~> 3" if RUBY_VERSION > '2' +gem "memory_profiler" +gem "benchmark-ips" diff --git a/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/LICENSE.txt b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/LICENSE.txt new file mode 100644 index 0000000..e2ea531 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Discourse Construction Kit, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/README.md b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/README.md new file mode 100644 index 0000000..e44033f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/README.md @@ -0,0 +1,114 @@ +# MiniMime + +Minimal mime type implementation for use with the mail and rest-client gem. + +## Installation + +Add this line to your application's Gemfile: + +```ruby +gem 'mini_mime' +``` + +And then execute: + + $ bundle + +Or install it yourself as: + + $ gem install mini_mime + +## Usage + +``` +require 'mini_mime' + +MiniMime.lookup_by_filename("a.txt").content_type +# => "text/plain" + +MiniMime.lookup_by_extension("txt").content_type +# => "text/plain" + +MiniMime.lookup_by_content_type("text/plain").extension +# => "txt" + +MiniMime.lookup_by_content_type("text/plain").binary? +# => false + +``` + +## Configuration + +If you'd like to add your own mime types, try using custom database files: + +``` +MiniMime::Configuration.ext_db_path = "path_to_file_extension_db" +MiniMime::Configuration.content_type_db_path = "path_to_content_type_db" +``` + +Check out the [default databases](lib/db) for proper formatting and structure hints. + +## Performance + +MiniMime is optimised to minimize memory usage. It keeps a cache of 100 mime type lookups (and 100 misses). There are benchmarks in the [bench directory](https://github.com/discourse/mini_mime/blob/master/bench/bench.rb) + +``` +Memory stats for requiring mime/types/columnar +Total allocated: 8712144 bytes (98242 objects) +Total retained: 3372545 bytes (33599 objects) + +Memory stats for requiring mini_mime +Total allocated: 42625 bytes (369 objects) +Total retained: 8992 bytes (72 objects) +Warming up -------------------------------------- +cached content_type lookup MiniMime + 85.109k i/100ms +content_type lookup MIME::Types + 17.879k i/100ms +Calculating ------------------------------------- +cached content_type lookup MiniMime + 1.105M (± 4.1%) i/s - 5.532M in 5.014895s +content_type lookup MIME::Types + 193.528k (± 7.1%) i/s - 965.466k in 5.013925s +Warming up -------------------------------------- +uncached content_type lookup MiniMime + 1.410k i/100ms +content_type lookup MIME::Types + 18.012k i/100ms +Calculating ------------------------------------- +uncached content_type lookup MiniMime + 14.689k (± 4.2%) i/s - 73.320k in 5.000779s +content_type lookup MIME::Types + 193.459k (± 6.9%) i/s - 972.648k in 5.050731s +``` + +As a general guideline, cached lookups are 6x faster than MIME::Types equivalent. Uncached lookups are 10x slower. + +Note: It was run on macOS 10.14.2, and versions of Ruby and gems are below. + +- Ruby 2.6.0 +- mini_mime (1.0.1) +- mime-types (3.2.2) +- mime-types-data (3.2018.0812) + +## Development + +MiniMime uses the officially maintained list of mime types at [mime-types-data](https://github.com/mime-types/mime-types-data) repo to build the internal database. + +To update the database run: + +```ruby +bundle exec rake rebuild_db +``` + +After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. + +To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). + +## Contributing + +Bug reports and pull requests are welcome on GitHub at https://github.com/discourse/mini_mime. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. + +## License + +The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT). diff --git a/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/Rakefile b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/Rakefile new file mode 100644 index 0000000..31a3514 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/Rakefile @@ -0,0 +1,97 @@ +# frozen_string_literal: true +require "bundler/gem_tasks" +require "rake/testtask" + +Rake::TestTask.new(:test) do |t| + t.libs << "test" + t.libs << "lib" + t.test_files = FileList['test/**/*_test.rb'] +end + +task default: :test + +def pad(array) + max = [] + array.each do |row| + i = 0 + row.each do |col| + max[i] = [max[i] || 0, col.length].max + i += 1 + end + end + + array.each do |row| + i = 0 + row.each do |col| + col << " " * (max[i] - col.length) + i += 1 + end + end + +end + +desc "generate mime type database" +task :rebuild_db do + puts "Generating mime type DB" + require 'mime/types' + index = {} + + MIME::Types.each do |type| + type.extensions.each { |ext| (index[ext.downcase] ||= []) << type } + end + + index.each do |k, list| + list.sort! { |a, b| a.priority_compare(b) } + end + + buffer = [] + + index.each do |ext, list| + mime_type = list.detect { |t| !t.obsolete? } + mime_type ||= list.detect(&:registered) + mime_type ||= list.first + buffer << [ext.dup, mime_type.content_type.dup, mime_type.encoding.dup] + end + + pad(buffer) + + buffer.sort! { |a, b| a[0] <=> b[0] } + + File.open("lib/db/ext_mime.db", File::CREAT | File::TRUNC | File::RDWR) do |f| + buffer.each do |row| + f.write "#{row[0]} #{row[1]} #{row[2]}\n" + end + end + + puts "#{buffer.count} rows written to lib/db/ext_mime.db" + + buffer.sort! { |a, b| [a[1], a[0]] <=> [b[1], b[0]] } + + # strip cause we are going to re-pad + buffer.each do |row| + row.each do |col| + col.strip! + end + end + + # we got to confirm we pick the right extension for each type + buffer.each do |row| + row[0] = MIME::Types.type_for("xyz.#{row[0].strip}")[0].extensions[0].dup + end + + pad(buffer) + + File.open("lib/db/content_type_mime.db", File::CREAT | File::TRUNC | File::RDWR) do |f| + last = nil + count = 0 + buffer.each do |row| + unless last == row[1] + f.write "#{row[0]} #{row[1]} #{row[2]}\n" + count += 1 + end + last = row[1] + end + puts "#{count} rows written to lib/db/content_type_mime.db" + end + +end diff --git a/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/bench/bench.rb b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/bench/bench.rb new file mode 100644 index 0000000..a246a49 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/bench/bench.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true +require 'memory_profiler' +require 'benchmark/ips' + +$: << File.expand_path('../../lib', __FILE__) + +puts +puts "Memory stats for requiring mime/types/columnar" +result = MemoryProfiler.report do + require 'mime/types/columnar' +end + +puts "Total allocated: #{result.total_allocated_memsize} bytes (#{result.total_allocated} objects)" +puts "Total retained: #{result.total_retained_memsize} bytes (#{result.total_retained} objects)" + +puts +puts "Memory stats for requiring mini_mime" +result = MemoryProfiler.report do + require 'mini_mime' +end + +puts "Total allocated: #{result.total_allocated_memsize} bytes (#{result.total_allocated} objects)" +puts "Total retained: #{result.total_retained_memsize} bytes (#{result.total_retained} objects)" + +Benchmark.ips do |bm| + bm.report 'cached content_type lookup MiniMime' do + MiniMime.lookup_by_filename("a.txt").content_type + end + + bm.report 'content_type lookup MIME::Types' do + MIME::Types.type_for("a.txt")[0].content_type + end +end + +module MiniMime + class Db + class RandomAccessDb + alias_method :lookup, :lookup_uncached + end + end +end + +Benchmark.ips do |bm| + bm.report 'uncached content_type lookup MiniMime' do + MiniMime.lookup_by_filename("a.txt").content_type + end + + bm.report 'content_type lookup MIME::Types' do + MIME::Types.type_for("a.txt")[0].content_type + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/bin/console b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/bin/console new file mode 100755 index 0000000..184d708 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/bin/console @@ -0,0 +1,15 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require "bundler/setup" +require "mini_mime" + +# You can add fixtures and/or initialization code here to make experimenting +# with your gem easier. You can also use a different console, if you like. + +# (If you use this, don't forget to add pry to your Gemfile!) +# require "pry" +# Pry.start + +require "irb" +IRB.start diff --git a/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/bin/db_pull_request b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/bin/db_pull_request new file mode 100755 index 0000000..55bba04 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/bin/db_pull_request @@ -0,0 +1,20 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require "time" + +if `git status --porcelain lib/db`.empty? + puts "Skipping, no DB changes to commit..." + return +end + +moment = Time.now.utc +branch_name = "db-updates-#{moment.strftime("%Y%m%d%H%M%S")}" + +system("git", "checkout", "-b", branch_name) || abort("Unable to create branch") +system("git", "add", "lib/db") +system("git", "config", "--local", "user.email", "actions@github.com") +system("git", "config", "--local", "user.name", "github-actions") +system("git", "commit", "-m", "DB updates #{moment.iso8601}") || abort("Unable to commit changes") +system("git", "push", "-u", "origin", branch_name) || abort("Unable to push branch") +system("gh", "pr", "create", "--title", "DB updates #{moment.iso8601}", "--body", "From Github Actions") || abort("Unable to create PR") diff --git a/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/bin/setup b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/bin/setup new file mode 100755 index 0000000..dce67d8 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/bin/setup @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -euo pipefail +IFS=$'\n\t' +set -vx + +bundle install + +# Do any other automated setup that you need to do here diff --git a/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/lib/db/content_type_mime.db b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/lib/db/content_type_mime.db new file mode 100644 index 0000000..e571ada --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/lib/db/content_type_mime.db @@ -0,0 +1,880 @@ +ez application/andrew-inset base64 +aw application/applixware base64 +atom application/atom+xml 8bit +atomcat application/atomcat+xml 8bit +atomsvc application/atomsvc+xml 8bit +ccxml application/ccxml+xml base64 +cdmia application/cdmi-capability base64 +cdmic application/cdmi-container base64 +cdmid application/cdmi-domain base64 +cdmio application/cdmi-object base64 +cdmiq application/cdmi-queue base64 +cu application/cu-seeme base64 +davmount application/davmount+xml base64 +dcm application/dicom base64 +dbk application/docbook+xml base64 +dssc application/dssc+der base64 +xdssc application/dssc+xml base64 +ecma application/ecmascript base64 +emma application/emma+xml base64 +epub application/epub+zip base64 +exi application/exi base64 +pfr application/font-tdpfr base64 +gml application/gml+xml base64 +gpx application/gpx+xml base64 +gxf application/gxf base64 +gz application/gzip base64 +stk application/hyperstudio base64 +ink application/inkml+xml base64 +ipfix application/ipfix base64 +jar application/java-archive base64 +ser application/java-serialized-object base64 +js application/javascript 8bit +json application/json 8bit +jsonml application/jsonml+json base64 +lostxml application/lost+xml base64 +hqx application/mac-binhex40 8bit +mads application/mads+xml base64 +webmanifest application/manifest+json base64 +mrc application/marc base64 +mrcx application/marcxml+xml base64 +ma application/mathematica base64 +mathml application/mathml+xml base64 +mbox application/mbox base64 +mscml application/mediaservercontrol+xml base64 +metalink application/metalink+xml base64 +meta4 application/metalink4+xml base64 +mets application/mets+xml base64 +mods application/mods+xml base64 +m21 application/mp21 base64 +mp4 application/mp4 base64 +doc application/msword base64 +mxf application/mxf base64 +nc application/netcdf base64 +bin application/octet-stream base64 +oda application/oda base64 +opf application/oebps-package+xml base64 +ogx application/ogg base64 +omdoc application/omdoc+xml base64 +onepkg application/onenote base64 +oxps application/oxps base64 +xer application/patch-ops-error+xml base64 +pdf application/pdf base64 +asc application/pgp-signature base64 +prf application/pics-rules base64 +p10 application/pkcs10 base64 +p7m application/pkcs7-mime base64 +p7s application/pkcs7-signature base64 +p8 application/pkcs8 base64 +ac application/pkix-attr-cert base64 +cer application/pkix-cert base64 +crl application/pkix-crl base64 +pkipath application/pkix-pkipath base64 +pki application/pkixcmp base64 +pls application/pls+xml base64 +eps application/postscript 8bit +cw application/prs.cww base64 +rnd application/prs.nprend base64 +pskcxml application/pskc+xml base64 +rdf application/rdf+xml 8bit +rif application/reginfo+xml base64 +rnc application/relax-ng-compact-syntax base64 +rl application/resource-lists+xml base64 +rld application/resource-lists-diff+xml base64 +rs application/rls-services+xml base64 +gbr application/rpki-ghostbusters base64 +mft application/rpki-manifest base64 +roa application/rpki-roa base64 +rsd application/rsd+xml base64 +rss application/rss+xml base64 +rtf application/rtf base64 +sbml application/sbml+xml base64 +scq application/scvp-cv-request base64 +scs application/scvp-cv-response base64 +spq application/scvp-vp-request base64 +spp application/scvp-vp-response base64 +sdp application/sdp base64 +setpay application/set-payment-initiation base64 +setreg application/set-registration-initiation base64 +sgml application/sgml base64 +soc application/sgml-open-catalog base64 +shf application/shf+xml base64 +siv application/sieve base64 +smi application/smil+xml 8bit +rq application/sparql-query base64 +srx application/sparql-results+xml base64 +gram application/srgs base64 +grxml application/srgs+xml base64 +sru application/sru+xml base64 +ssdl application/ssdl+xml base64 +ssml application/ssml+xml base64 +tei application/tei+xml base64 +tfi application/thraud+xml base64 +tsd application/timestamped-data base64 +pwn application/vnd.3M.Post-it-Notes base64 +plb application/vnd.3gpp.pic-bw-large base64 +psb application/vnd.3gpp.pic-bw-small base64 +pvb application/vnd.3gpp.pic-bw-var base64 +sms application/vnd.3gpp.sms base64 +tcap application/vnd.3gpp2.tcap base64 +gph application/vnd.FloGraphIt base64 +zmm application/vnd.HandHeld-Entertainment+xml base64 +kne application/vnd.Kinar base64 +mwf application/vnd.MFER base64 +daf application/vnd.Mobius.DAF base64 +dis application/vnd.Mobius.DIS base64 +mbk application/vnd.Mobius.MBK base64 +mqy application/vnd.Mobius.MQY base64 +msl application/vnd.Mobius.MSL base64 +plc application/vnd.Mobius.PLC base64 +txf application/vnd.Mobius.TXF base64 +qxd application/vnd.Quark.QuarkXPress 8bit +twd application/vnd.SimTech-MindMapper base64 +aso application/vnd.accpac.simply.aso base64 +imp application/vnd.accpac.simply.imp base64 +acu application/vnd.acucobol base64 +atc application/vnd.acucorp 7bit +air application/vnd.adobe.air-application-installer-package+zip base64 +fcdt application/vnd.adobe.formscentral.fcdt base64 +fxp application/vnd.adobe.fxp base64 +xdp application/vnd.adobe.xdp+xml base64 +xfdf application/vnd.adobe.xfdf base64 +ahead application/vnd.ahead.space base64 +azf application/vnd.airzip.filesecure.azf base64 +azs application/vnd.airzip.filesecure.azs base64 +azw application/vnd.amazon.ebook base64 +acc application/vnd.americandynamics.acc base64 +ami application/vnd.amiga.ami base64 +apk application/vnd.android.package-archive base64 +cii application/vnd.anser-web-certificate-issue-initiation base64 +fti application/vnd.anser-web-funds-transfer-initiation base64 +atx application/vnd.antix.game-component base64 +mpkg application/vnd.apple.installer+xml base64 +m3u8 application/vnd.apple.mpegurl base64 +pkpass application/vnd.apple.pkpass base64 +swi application/vnd.aristanetworks.swi base64 +iota application/vnd.astraea-software.iota base64 +aep application/vnd.audiograph base64 +mpm application/vnd.blueice.multipass base64 +bmi application/vnd.bmi base64 +rep application/vnd.businessobjects base64 +cdxml application/vnd.chemdraw+xml base64 +mmd application/vnd.chipnuts.karaoke-mmd base64 +cdy application/vnd.cinderella base64 +cla application/vnd.claymore base64 +rp9 application/vnd.cloanto.rp9 base64 +c4d application/vnd.clonk.c4group base64 +c11amc application/vnd.cluetrust.cartomobile-config base64 +c11amz application/vnd.cluetrust.cartomobile-config-pkg base64 +csp application/vnd.commonspace base64 +cdbcmsg application/vnd.contact.cmsg base64 +cmc application/vnd.cosmocaller base64 +clkx application/vnd.crick.clicker base64 +clkk application/vnd.crick.clicker.keyboard base64 +clkp application/vnd.crick.clicker.palette base64 +clkt application/vnd.crick.clicker.template base64 +clkw application/vnd.crick.clicker.wordbank base64 +wbs application/vnd.criticaltools.wbs+xml base64 +pml application/vnd.ctc-posml base64 +ppd application/vnd.cups-ppd base64 +curl application/vnd.curl base64 +car application/vnd.curl.car base64 +pcurl application/vnd.curl.pcurl base64 +dart application/vnd.dart base64 +rdz application/vnd.data-vision.rdz base64 +uvd application/vnd.dece.data base64 +uvt application/vnd.dece.ttml+xml base64 +uvvx application/vnd.dece.unspecified base64 +uvvz application/vnd.dece.zip base64 +fe_launch application/vnd.denovo.fcselayout-link base64 +dna application/vnd.dna base64 +mlp application/vnd.dolby.mlp base64 +dpg application/vnd.dpgraph base64 +dfac application/vnd.dreamfactory base64 +kpxx application/vnd.ds-keypoint base64 +ait application/vnd.dvb.ait base64 +svc application/vnd.dvb.service base64 +geo application/vnd.dynageo base64 +mag application/vnd.ecowin.chart base64 +nml application/vnd.enliven base64 +esf application/vnd.epson.esf base64 +msf application/vnd.epson.msf base64 +qam application/vnd.epson.quickanime base64 +slt application/vnd.epson.salt base64 +ssf application/vnd.epson.ssf base64 +es3 application/vnd.eszigno3+xml base64 +ez2 application/vnd.ezpix-album base64 +ez3 application/vnd.ezpix-package base64 +fdf application/vnd.fdf base64 +mseed application/vnd.fdsn.mseed base64 +dataless application/vnd.fdsn.seed base64 +ftc application/vnd.fluxtime.clip base64 +frm application/vnd.framemaker base64 +fnc application/vnd.frogans.fnc base64 +ltf application/vnd.frogans.ltf base64 +fsc application/vnd.fsc.weblaunch 7bit +oas application/vnd.fujitsu.oasys base64 +oa2 application/vnd.fujitsu.oasys2 base64 +oa3 application/vnd.fujitsu.oasys3 base64 +fg5 application/vnd.fujitsu.oasysgp base64 +bh2 application/vnd.fujitsu.oasysprs base64 +ddd application/vnd.fujixerox.ddd base64 +xdw application/vnd.fujixerox.docuworks base64 +xbd application/vnd.fujixerox.docuworks.binder base64 +fzs application/vnd.fuzzysheet base64 +txd application/vnd.genomatix.tuxedo base64 +ggb application/vnd.geogebra.file base64 +ggs application/vnd.geogebra.slides base64 +ggt application/vnd.geogebra.tool base64 +gex application/vnd.geometry-explorer base64 +gxt application/vnd.geonext base64 +g2w application/vnd.geoplan base64 +g3w application/vnd.geospace base64 +gmx application/vnd.gmx base64 +kml application/vnd.google-earth.kml+xml 8bit +kmz application/vnd.google-earth.kmz 8bit +gqf application/vnd.grafeq base64 +gac application/vnd.groove-account base64 +ghf application/vnd.groove-help base64 +gim application/vnd.groove-identity-message base64 +grv application/vnd.groove-injector base64 +gtm application/vnd.groove-tool-message base64 +tpl application/vnd.groove-tool-template base64 +vcg application/vnd.groove-vcard base64 +hal application/vnd.hal+xml base64 +hbci application/vnd.hbci base64 +les application/vnd.hhe.lesson-player base64 +plt application/vnd.hp-HPGL base64 +pcl application/vnd.hp-PCL base64 +pclxl application/vnd.hp-PCLXL base64 +hpid application/vnd.hp-hpid base64 +hps application/vnd.hp-hps base64 +jlt application/vnd.hp-jlyt base64 +sfd-hdstx application/vnd.hydrostatix.sof-data base64 +mpy application/vnd.ibm.MiniPay base64 +emm application/vnd.ibm.electronic-media base64 +afp application/vnd.ibm.modcap base64 +irm application/vnd.ibm.rights-management base64 +sc application/vnd.ibm.secure-container base64 +icc application/vnd.iccprofile base64 +igl application/vnd.igloader base64 +ivp application/vnd.immervision-ivp base64 +ivu application/vnd.immervision-ivu base64 +igm application/vnd.insors.igm base64 +xpw application/vnd.intercon.formnet base64 +i2g application/vnd.intergeo base64 +qbo application/vnd.intu.qbo base64 +qfx application/vnd.intu.qfx base64 +rcprofile application/vnd.ipunplugged.rcprofile base64 +irp application/vnd.irepository.package+xml base64 +xpr application/vnd.is-xpr base64 +fcs application/vnd.isac.fcs base64 +jam application/vnd.jam base64 +rms application/vnd.jcp.javame.midlet-rms base64 +jisp application/vnd.jisp base64 +joda application/vnd.joost.joda-archive base64 +ktr application/vnd.kahootz base64 +karbon application/vnd.kde.karbon base64 +chrt application/vnd.kde.kchart base64 +kfo application/vnd.kde.kformula base64 +flw application/vnd.kde.kivio base64 +kon application/vnd.kde.kontour base64 +kpr application/vnd.kde.kpresenter base64 +ksp application/vnd.kde.kspread base64 +kwd application/vnd.kde.kword base64 +htke application/vnd.kenameaapp base64 +kia application/vnd.kidspiration base64 +skd application/vnd.koan base64 +sse application/vnd.kodak-descriptor base64 +lasxml application/vnd.las.las+xml base64 +lbd application/vnd.llamagraphics.life-balance.desktop base64 +lbe application/vnd.llamagraphics.life-balance.exchange+xml base64 +wks application/vnd.lotus-1-2-3 base64 +apr application/vnd.lotus-approach base64 +pre application/vnd.lotus-freelance base64 +nsf application/vnd.lotus-notes base64 +org application/vnd.lotus-organizer base64 +scm application/vnd.lotus-screencam base64 +lwp application/vnd.lotus-wordpro base64 +portpkg application/vnd.macports.portpkg base64 +mcd application/vnd.mcd base64 +mc1 application/vnd.medcalcdata base64 +cdkey application/vnd.mediastation.cdkey base64 +mfm application/vnd.mfmp base64 +flo application/vnd.micrografx.flo base64 +igx application/vnd.micrografx.igx base64 +mif application/vnd.mif base64 +mpn application/vnd.mophun.application base64 +mpc application/vnd.mophun.certificate base64 +xul application/vnd.mozilla.xul+xml base64 +cil application/vnd.ms-artgalry base64 +asf application/vnd.ms-asf base64 +cab application/vnd.ms-cab-compressed base64 +xls application/vnd.ms-excel base64 +xlam application/vnd.ms-excel.addin.macroEnabled.12 base64 +xlsb application/vnd.ms-excel.sheet.binary.macroEnabled.12 base64 +xlsm application/vnd.ms-excel.sheet.macroEnabled.12 base64 +xltm application/vnd.ms-excel.template.macroEnabled.12 base64 +eot application/vnd.ms-fontobject base64 +chm application/vnd.ms-htmlhelp base64 +ims application/vnd.ms-ims base64 +lrm application/vnd.ms-lrm base64 +thmx application/vnd.ms-officetheme base64 +msg application/vnd.ms-outlook base64 +cat application/vnd.ms-pki.seccat base64 +stl application/vnd.ms-pki.stl base64 +ppt application/vnd.ms-powerpoint base64 +ppam application/vnd.ms-powerpoint.addin.macroEnabled.12 base64 +pptm application/vnd.ms-powerpoint.presentation.macroEnabled.12 base64 +sldm application/vnd.ms-powerpoint.slide.macroEnabled.12 base64 +ppsm application/vnd.ms-powerpoint.slideshow.macroEnabled.12 base64 +potm application/vnd.ms-powerpoint.template.macroEnabled.12 base64 +mpp application/vnd.ms-project base64 +docm application/vnd.ms-word.document.macroEnabled.12 base64 +dotm application/vnd.ms-word.template.macroEnabled.12 base64 +wcm application/vnd.ms-works base64 +wpl application/vnd.ms-wpl base64 +xps application/vnd.ms-xpsdocument 8bit +mseq application/vnd.mseq base64 +mus application/vnd.musician base64 +msty application/vnd.muvee.style base64 +taglet application/vnd.mynfc base64 +ent application/vnd.nervana base64 +nlu application/vnd.neurolanguage.nlu base64 +nitf application/vnd.nitf base64 +nnd application/vnd.noblenet-directory base64 +nns application/vnd.noblenet-sealer base64 +nnw application/vnd.noblenet-web base64 +ngdat application/vnd.nokia.n-gage.data base64 +n-gage application/vnd.nokia.n-gage.symbian.install base64 +rpst application/vnd.nokia.radio-preset base64 +rpss application/vnd.nokia.radio-presets base64 +edm application/vnd.novadigm.EDM base64 +edx application/vnd.novadigm.EDX base64 +ext application/vnd.novadigm.EXT base64 +odc application/vnd.oasis.opendocument.chart base64 +odc application/vnd.oasis.opendocument.chart-template base64 +odb application/vnd.oasis.opendocument.database base64 +odf application/vnd.oasis.opendocument.formula base64 +odf application/vnd.oasis.opendocument.formula-template base64 +odg application/vnd.oasis.opendocument.graphics base64 +otg application/vnd.oasis.opendocument.graphics-template base64 +odi application/vnd.oasis.opendocument.image base64 +odi application/vnd.oasis.opendocument.image-template base64 +odp application/vnd.oasis.opendocument.presentation base64 +otp application/vnd.oasis.opendocument.presentation-template base64 +ods application/vnd.oasis.opendocument.spreadsheet base64 +ots application/vnd.oasis.opendocument.spreadsheet-template base64 +odt application/vnd.oasis.opendocument.text base64 +odm application/vnd.oasis.opendocument.text-master base64 +ott application/vnd.oasis.opendocument.text-template base64 +oth application/vnd.oasis.opendocument.text-web base64 +xo application/vnd.olpc-sugar base64 +dd2 application/vnd.oma.dd2+xml base64 +oxt application/vnd.openofficeorg.extension base64 +pptx application/vnd.openxmlformats-officedocument.presentationml.presentation base64 +sldx application/vnd.openxmlformats-officedocument.presentationml.slide base64 +ppsx application/vnd.openxmlformats-officedocument.presentationml.slideshow base64 +potx application/vnd.openxmlformats-officedocument.presentationml.template base64 +xlsx application/vnd.openxmlformats-officedocument.spreadsheetml.sheet base64 +xltx application/vnd.openxmlformats-officedocument.spreadsheetml.template base64 +docx application/vnd.openxmlformats-officedocument.wordprocessingml.document base64 +dotx application/vnd.openxmlformats-officedocument.wordprocessingml.template base64 +mgp application/vnd.osgeo.mapguide.package base64 +dp application/vnd.osgi.dp base64 +esa application/vnd.osgi.subsystem base64 +prc application/vnd.palm base64 +paw application/vnd.pawaafile base64 +str application/vnd.pg.format base64 +ei6 application/vnd.pg.osasli base64 +efif application/vnd.picsel base64 +wg application/vnd.pmi.widget base64 +plf application/vnd.pocketlearn base64 +pbd application/vnd.powerbuilder6 base64 +box application/vnd.previewsystems.box base64 +mgz application/vnd.proteus.magazine base64 +qps application/vnd.publishare-delta-tree base64 +pti application/vnd.pvi.ptid1 base64 +bed application/vnd.realvnc.bed base64 +mxl application/vnd.recordare.musicxml base64 +musicxml application/vnd.recordare.musicxml+xml base64 +cryptonote application/vnd.rig.cryptonote base64 +cod application/vnd.rim.cod base64 +rm application/vnd.rn-realmedia base64 +rmvb application/vnd.rn-realmedia-vbr base64 +link66 application/vnd.route66.link66+xml base64 +st application/vnd.sailingtracker.track base64 +sdoc application/vnd.sealed.doc base64 +seml application/vnd.sealed.eml base64 +smht application/vnd.sealed.mht base64 +sppt application/vnd.sealed.ppt base64 +sxls application/vnd.sealed.xls base64 +stml application/vnd.sealedmedia.softseal.html base64 +spdf application/vnd.sealedmedia.softseal.pdf base64 +see application/vnd.seemail base64 +sema application/vnd.sema base64 +semd application/vnd.semd base64 +semf application/vnd.semf base64 +ifm application/vnd.shana.informed.formdata base64 +itp application/vnd.shana.informed.formtemplate base64 +iif application/vnd.shana.informed.interchange base64 +ipk application/vnd.shana.informed.package base64 +mmf application/vnd.smaf base64 +teacher application/vnd.smart.teacher base64 +sdkd application/vnd.solent.sdkm+xml base64 +dxp application/vnd.spotfire.dxp base64 +sfs application/vnd.spotfire.sfs base64 +sdc application/vnd.stardivision.calc base64 +sds application/vnd.stardivision.chart base64 +sda application/vnd.stardivision.draw base64 +sdd application/vnd.stardivision.impress base64 +sdf application/vnd.stardivision.math base64 +sdw application/vnd.stardivision.writer base64 +sgl application/vnd.stardivision.writer-global base64 +smzip application/vnd.stepmania.package base64 +sm application/vnd.stepmania.stepchart base64 +sxc application/vnd.sun.xml.calc base64 +stc application/vnd.sun.xml.calc.template base64 +sxd application/vnd.sun.xml.draw base64 +std application/vnd.sun.xml.draw.template base64 +sxi application/vnd.sun.xml.impress base64 +sti application/vnd.sun.xml.impress.template base64 +sxm application/vnd.sun.xml.math base64 +sxw application/vnd.sun.xml.writer base64 +sxg application/vnd.sun.xml.writer.global base64 +stw application/vnd.sun.xml.writer.template base64 +sus application/vnd.sus-calendar base64 +svd application/vnd.svd base64 +sis application/vnd.symbian.install base64 +xsm application/vnd.syncml+xml base64 +bdm application/vnd.syncml.dm+wbxml base64 +xdm application/vnd.syncml.dm+xml base64 +tao application/vnd.tao.intent-module-archive base64 +cap application/vnd.tcpdump.pcap base64 +tmo application/vnd.tmobile-livetv base64 +tpt application/vnd.trid.tpt base64 +mxs application/vnd.triscape.mxs base64 +tra application/vnd.trueapp base64 +ufd application/vnd.ufdl base64 +utz application/vnd.uiq.theme base64 +umj application/vnd.umajin base64 +unityweb application/vnd.unity base64 +uoml application/vnd.uoml+xml base64 +vcx application/vnd.vcx base64 +vsc application/vnd.vidsoft.vidconference 8bit +vsd application/vnd.visio base64 +vis application/vnd.visionary base64 +vsf application/vnd.vsf base64 +sic application/vnd.wap.sic base64 +slc application/vnd.wap.slc base64 +wbxml application/vnd.wap.wbxml base64 +wmlc application/vnd.wap.wmlc base64 +wmlsc application/vnd.wap.wmlscriptc base64 +wtb application/vnd.webturbo base64 +nbp application/vnd.wolfram.player base64 +wpd application/vnd.wordperfect base64 +wqd application/vnd.wqd base64 +stf application/vnd.wt.stf base64 +wv application/vnd.wv.csp+wbxml base64 +xar application/vnd.xara base64 +xfdl application/vnd.xfdl base64 +hvd application/vnd.yamaha.hv-dic base64 +hvs application/vnd.yamaha.hv-script base64 +hvp application/vnd.yamaha.hv-voice base64 +osf application/vnd.yamaha.openscoreformat base64 +osfpvg application/vnd.yamaha.openscoreformat.osfpvg+xml base64 +saf application/vnd.yamaha.smaf-audio base64 +spf application/vnd.yamaha.smaf-phrase base64 +cmp application/vnd.yellowriver-custom-menu base64 +zir application/vnd.zul base64 +zaz application/vnd.zzazz.deck+xml base64 +vxml application/voicexml+xml base64 +wasm application/wasm 8bit +wif application/watcherinfo+xml base64 +wgt application/widget base64 +wp5 application/wordperfect5.1 base64 +wsdl application/wsdl+xml base64 +wspolicy application/wspolicy+xml base64 +wk application/x-123 base64 +7z application/x-7z-compressed base64 +bck application/x-VMSBACKUP base64 +wz application/x-Wingz base64 +abw application/x-abiword base64 +ace application/x-ace-compressed base64 +dmg application/x-apple-diskimage base64 +aab application/x-authorware-bin base64 +aam application/x-authorware-map base64 +aas application/x-authorware-seg base64 +bcpio application/x-bcpio base64 +torrent application/x-bittorrent base64 +bleep application/x-bleeper base64 +blb application/x-blorb base64 +bz application/x-bzip base64 +boz application/x-bzip2 base64 +cb7 application/x-cbr base64 +vcd application/x-cdlink base64 +cfs application/x-cfs-compressed base64 +chat application/x-chat base64 +pgn application/x-chess-pgn base64 +crx application/x-chrome-extension base64 +z application/x-compressed base64 +nsc application/x-conference base64 +cpio application/x-cpio base64 +csh application/x-csh 8bit +csm application/x-cu-seeme base64 +deb application/x-debian-package base64 +dgc application/x-dgc-compressed base64 +dcr application/x-director base64 +wad application/x-doom base64 +ncx application/x-dtbncx+xml base64 +dtb application/x-dtbook+xml base64 +res application/x-dtbresource+xml base64 +dvi application/x-dvi base64 +evy application/x-envoy base64 +eva application/x-eva base64 +bdf application/x-font-bdf base64 +gsf application/x-font-ghostscript base64 +psf application/x-font-linux-psf base64 +pcf application/x-font-pcf base64 +snf application/x-font-snf base64 +afm application/x-font-type1 base64 +arc application/x-freearc base64 +spl application/x-futuresplash base64 +gca application/x-gca-compressed base64 +ulx application/x-glulx base64 +gnumeric application/x-gnumeric base64 +gramps application/x-gramps-xml base64 +gtar application/x-gtar base64 +hdf application/x-hdf base64 +hep application/x-hep base64 +rhtml application/x-html+ruby 8bit +phtml application/x-httpd-php 8bit +ibooks application/x-ibooks+zip base64 +ica application/x-ica base64 +imagemap application/x-imagemap 8bit +install application/x-install-instructions base64 +iso application/x-iso9660-image base64 +key application/x-iwork-keynote-sffkey base64 +numbers application/x-iwork-numbers-sffnumbers base64 +pages application/x-iwork-pages-sffpages base64 +jnlp application/x-java-jnlp-file base64 +ltx application/x-latex 8bit +cpt application/x-mac-compactpro base64 +mie application/x-mie base64 +mobi application/x-mobipocket-ebook base64 +application application/x-ms-application base64 +exe application/x-ms-dos-executable base64 +lnk application/x-ms-shortcut base64 +wmd application/x-ms-wmd base64 +wmz application/x-ms-wmz base64 +xbap application/x-ms-xbap base64 +mda application/x-msaccess base64 +obd application/x-msbinder base64 +crd application/x-mscardfile base64 +clp application/x-msclip base64 +cmd application/x-msdos-program base64 +exe application/x-msdownload base64 +m13 application/x-msmediaview base64 +emf application/x-msmetafile base64 +mny application/x-msmoney base64 +pub application/x-mspublisher base64 +scd application/x-msschedule base64 +trm application/x-msterminal base64 +wri application/x-mswrite base64 +pac application/x-ns-proxy-autoconfig base64 +nzb application/x-nzb base64 +oex application/x-opera-extension base64 +pm application/x-pagemaker base64 +pl application/x-perl 8bit +p12 application/x-pkcs12 base64 +p7b application/x-pkcs7-certificates base64 +p7r application/x-pkcs7-certreqresp base64 +py application/x-python 8bit +qtl application/x-quicktimeplayer base64 +rar application/x-rar-compressed base64 +ris application/x-research-info-systems base64 +rb application/x-ruby 8bit +sh application/x-sh 8bit +shar application/x-shar 8bit +swf application/x-shockwave-flash base64 +xap application/x-silverlight-app base64 +notebook application/x-smarttech-notebook base64 +sav application/x-spss base64 +sql application/x-sql base64 +sit application/x-stuffit base64 +sitx application/x-stuffitx base64 +srt application/x-subrip base64 +sv4cpio application/x-sv4cpio base64 +sv4crc application/x-sv4crc base64 +t3 application/x-t3vm-image base64 +gam application/x-tads base64 +tar application/x-tar base64 +tcl application/x-tcl 8bit +tex application/x-tex 8bit +tfm application/x-tex-tfm base64 +texinfo application/x-texinfo 8bit +obj application/x-tgif base64 +tbk application/x-toolbook base64 +ustar application/x-ustar base64 +src application/x-wais-source base64 +webapp application/x-web-app-manifest+json base64 +wp6 application/x-wordperfect6.1 base64 +crt application/x-x509-ca-cert base64 +fig application/x-xfig base64 +xlf application/x-xliff+xml base64 +xpi application/x-xpinstall base64 +xz application/x-xz base64 +z1 application/x-zmachine base64 +xaml application/xaml+xml base64 +xdf application/xcap-diff+xml base64 +xenc application/xenc+xml base64 +xht application/xhtml+xml 8bit +xml application/xml 8bit +dtd application/xml-dtd 8bit +xop application/xop+xml base64 +xpl application/xproc+xml base64 +xslt application/xslt+xml base64 +xspf application/xspf+xml base64 +mxml application/xv+xml base64 +yang application/yang base64 +yin application/yin+xml base64 +zip application/zip base64 +amr audio/AMR base64 +awb audio/AMR-WB base64 +evc audio/EVRC base64 +l16 audio/L16 base64 +smv audio/SMV base64 +adp audio/adpcm base64 +au audio/basic base64 +kar audio/midi base64 +mp4 audio/mp4 base64 +mpga audio/mpeg base64 +oga audio/ogg base64 +s3m audio/s3m base64 +sil audio/silk base64 +uva audio/vnd.dece.audio base64 +eol audio/vnd.digital-winds 7bit +dra audio/vnd.dra base64 +dts audio/vnd.dts base64 +dtshd audio/vnd.dts.hd base64 +plj audio/vnd.everad.plj base64 +lvp audio/vnd.lucent.voice base64 +pya audio/vnd.ms-playready.media.pya base64 +mxmf audio/vnd.nokia.mobile-xmf base64 +vbk audio/vnd.nortel.vbk base64 +ecelp4800 audio/vnd.nuera.ecelp4800 base64 +ecelp7470 audio/vnd.nuera.ecelp7470 base64 +ecelp9600 audio/vnd.nuera.ecelp9600 base64 +qcp audio/vnd.qcelp base64 +rip audio/vnd.rip base64 +smp3 audio/vnd.sealedmedia.softseal.mpeg base64 +wav audio/wav base64 +weba audio/webm base64 +aac audio/x-aac base64 +aif audio/x-aiff base64 +caf audio/x-caf base64 +flac audio/x-flac base64 +mka audio/x-matroska base64 +m3u audio/x-mpegurl base64 +wax audio/x-ms-wax base64 +wma audio/x-ms-wma base64 +wmv audio/x-ms-wmv base64 +ra audio/x-pn-realaudio base64 +rmp audio/x-pn-realaudio-plugin base64 +xm audio/xm base64 +cdx chemical/x-cdx base64 +cif chemical/x-cif base64 +cmdf chemical/x-cmdf base64 +cml chemical/x-cml base64 +csml chemical/x-csml base64 +ttc font/collection base64 +otf font/otf base64 +ttf font/ttf base64 +woff font/woff base64 +woff2 font/woff2 base64 +avif image/avif base64 +bmp image/bmp base64 +cgm image/cgm base64 +g3 image/g3fax base64 +gif image/gif base64 +heic image/heic base64 +heics image/heic-sequence base64 +heif image/heif base64 +heifs image/heif-sequence base64 +ief image/ief base64 +jp2 image/jp2 base64 +jpeg image/jpeg base64 +jpm image/jpm base64 +jpx image/jpx base64 +ktx image/ktx base64 +png image/png base64 +btif image/prs.btif base64 +sgi image/sgi base64 +svg image/svg+xml 8bit +tiff image/tiff base64 +psd image/vnd.adobe.photoshop base64 +uvg image/vnd.dece.graphic base64 +djvu image/vnd.djvu base64 +sub image/vnd.dvb.subtitle base64 +dwg image/vnd.dwg base64 +dxf image/vnd.dxf base64 +fbs image/vnd.fastbidsheet base64 +fpx image/vnd.fpx base64 +fst image/vnd.fst base64 +mmr image/vnd.fujixerox.edmics-mmr base64 +rlc image/vnd.fujixerox.edmics-rlc base64 +pgb image/vnd.globalgraphics.pgb base64 +ico image/vnd.microsoft.icon base64 +mdi image/vnd.ms-modi base64 +wdp image/vnd.ms-photo base64 +npx image/vnd.net-fpx base64 +wbmp image/vnd.wap.wbmp base64 +xif image/vnd.xiff base64 +webp image/webp base64 +3ds image/x-3ds base64 +dng image/x-adobe-dng base64 +cr2 image/x-canon-cr2 base64 +crw image/x-canon-crw base64 +ras image/x-cmu-raster base64 +cmx image/x-cmx base64 +xcfbz2 image/x-compressed-xcf base64 +erf image/x-epson-erf base64 +fh image/x-freehand base64 +raf image/x-fuji-raf base64 +3fr image/x-hasselblad-3fr base64 +k25 image/x-kodak-k25 base64 +kdc image/x-kodak-kdc base64 +mrw image/x-minolta-mrw base64 +sid image/x-mrsid-image base64 +nef image/x-nikon-nef base64 +orf image/x-olympus-orf base64 +psp image/x-paintshoppro base64 +raw image/x-panasonic-raw base64 +pcx image/x-pcx base64 +pef image/x-pentax-pef base64 +pct image/x-pict base64 +pnm image/x-portable-anymap base64 +pbm image/x-portable-bitmap base64 +pgm image/x-portable-graymap base64 +ppm image/x-portable-pixmap base64 +rgb image/x-rgb base64 +x3f image/x-sigma-x3f base64 +arw image/x-sony-arw base64 +sr2 image/x-sony-sr2 base64 +srf image/x-sony-srf base64 +tga image/x-targa base64 +dgn image/x-vnd.dgn base64 +xbm image/x-xbitmap 7bit +xcf image/x-xcf base64 +xpm image/x-xpixmap 8bit +xwd image/x-xwindowdump base64 +eml message/rfc822 8bit +igs model/iges base64 +msh model/mesh base64 +dae model/vnd.collada+xml base64 +dwf model/vnd.dwf base64 +gdl model/vnd.gdl base64 +gtw model/vnd.gtw base64 +mts model/vnd.mts base64 +x_b model/vnd.parasolid.transmit.binary base64 +x_t model/vnd.parasolid.transmit.text quoted-printable +vtu model/vnd.vtu base64 +wrl model/vrml base64 +x3db model/x3d+binary base64 +x3dv model/x3d+vrml base64 +x3d model/x3d+xml base64 +appcache text/cache-manifest quoted-printable +ics text/calendar quoted-printable +css text/css 8bit +csv text/csv 8bit +html text/html 8bit +js text/javascript quoted-printable +markdown text/markdown quoted-printable +n3 text/n3 quoted-printable +txt text/plain quoted-printable +dsc text/prs.lines.tag quoted-printable +rtx text/richtext 8bit +sgml text/sgml quoted-printable +tsv text/tab-separated-values quoted-printable +t text/troff 8bit +ttl text/turtle quoted-printable +uri text/uri-list quoted-printable +vcard text/vcard quoted-printable +dcurl text/vnd.curl.dcurl quoted-printable +mcurl text/vnd.curl.mcurl quoted-printable +scurl text/vnd.curl.scurl quoted-printable +fly text/vnd.fly quoted-printable +flx text/vnd.fmi.flexstor quoted-printable +gv text/vnd.graphviz quoted-printable +3dml text/vnd.in3d.3dml quoted-printable +spot text/vnd.in3d.spot quoted-printable +ccc text/vnd.net2phone.commcenter.command quoted-printable +jad text/vnd.sun.j2me.app-descriptor 8bit +si text/vnd.wap.si quoted-printable +sl text/vnd.wap.sl quoted-printable +wml text/vnd.wap.wml quoted-printable +wmls text/vnd.wap.wmlscript quoted-printable +vtt text/vtt quoted-printable +asm text/x-asm quoted-printable +c text/x-c quoted-printable +coffee text/x-coffescript 8bit +htc text/x-component 8bit +f text/x-fortran quoted-printable +java text/x-java-source quoted-printable +nfo text/x-nfo quoted-printable +opml text/x-opml quoted-printable +p text/x-pascal quoted-printable +etx text/x-setext quoted-printable +sfv text/x-sfv quoted-printable +uu text/x-uuencode quoted-printable +vcs text/x-vcalendar 8bit +vcf text/x-vcard 8bit +yaml text/x-yaml 8bit +xml text/xml 8bit +3gp video/3gpp base64 +3g2 video/3gpp2 base64 +dv video/DV base64 +h261 video/H261 base64 +h263 video/H263 base64 +h264 video/H264 base64 +jpgv video/JPEG base64 +mj2 video/MJ2 base64 +ts video/MP2T base64 +mp4 video/mp4 base64 +mp2 video/mpeg base64 +ogg video/ogg base64 +qt video/quicktime base64 +uvh video/vnd.dece.hd base64 +uvm video/vnd.dece.mobile base64 +uvp video/vnd.dece.pd base64 +uvs video/vnd.dece.sd base64 +uvv video/vnd.dece.video base64 +dvb video/vnd.dvb.file base64 +fvt video/vnd.fvt base64 +mxu video/vnd.mpegurl 8bit +pyv video/vnd.ms-playready.media.pyv base64 +nim video/vnd.nokia.interleaved-multimedia base64 +mp4 video/vnd.objectvideo base64 +s11 video/vnd.sealed.mpeg1 base64 +smpg video/vnd.sealed.mpeg4 base64 +sswf video/vnd.sealed.swf base64 +smov video/vnd.sealedmedia.softseal.mov base64 +uvu video/vnd.uvvu.mp4 base64 +viv video/vnd.vivo base64 +dl video/x-dl base64 +fli video/x-fli base64 +flv video/x-flv base64 +gl video/x-gl base64 +ivf video/x-ivf base64 +mk3d video/x-matroska base64 +mng video/x-mng base64 +mjpg video/x-motion-jpeg base64 +asf video/x-ms-asf base64 +vob video/x-ms-vob base64 +wm video/x-ms-wm base64 +wmx video/x-ms-wmx base64 +wvx video/x-ms-wvx base64 +avi video/x-msvideo base64 +movie video/x-sgi-movie base64 +xyz x-chemical/x-xyz base64 +ice x-conference/x-cooltalk base64 diff --git a/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/lib/db/ext_mime.db b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/lib/db/ext_mime.db new file mode 100644 index 0000000..5cf98a5 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/lib/db/ext_mime.db @@ -0,0 +1,1201 @@ +123 application/vnd.lotus-1-2-3 base64 +3dml text/vnd.in3d.3dml quoted-printable +3ds image/x-3ds base64 +3fr image/x-hasselblad-3fr base64 +3g2 video/3gpp2 base64 +3gp video/3gpp base64 +3gpp video/3gpp base64 +3gpp2 video/3gpp2 base64 +7z application/x-7z-compressed base64 +@dir application/x-director base64 +@dxr application/x-director base64 +aab application/x-authorware-bin base64 +aac audio/x-aac base64 +aam application/x-authorware-map base64 +aas application/x-authorware-seg base64 +abw application/x-abiword base64 +ac application/pkix-attr-cert base64 +acc application/vnd.americandynamics.acc base64 +ace application/x-ace-compressed base64 +acu application/vnd.acucobol base64 +acutc application/vnd.acucorp 7bit +adp audio/adpcm base64 +aep application/vnd.audiograph base64 +afm application/x-font-type1 base64 +afp application/vnd.ibm.modcap base64 +ahead application/vnd.ahead.space base64 +ai application/pdf base64 +aif audio/x-aiff base64 +aifc audio/x-aiff base64 +aiff audio/x-aiff base64 +air application/vnd.adobe.air-application-installer-package+zip base64 +ait application/vnd.dvb.ait base64 +ami application/vnd.amiga.ami base64 +amr audio/AMR base64 +ani application/octet-stream base64 +apk application/vnd.android.package-archive base64 +appcache text/cache-manifest quoted-printable +application application/x-ms-application base64 +apr application/vnd.lotus-approach base64 +arc application/x-freearc base64 +arw image/x-sony-arw base64 +asc application/pgp-signature base64 +asf application/vnd.ms-asf base64 +asm text/x-asm quoted-printable +aso application/vnd.accpac.simply.aso base64 +asx video/x-ms-asf base64 +atc application/vnd.acucorp 7bit +atom application/atom+xml 8bit +atomcat application/atomcat+xml 8bit +atomsvc application/atomsvc+xml 8bit +atx application/vnd.antix.game-component base64 +au audio/basic base64 +avi video/x-msvideo base64 +avif image/avif base64 +aw application/applixware base64 +awb audio/AMR-WB base64 +azf application/vnd.airzip.filesecure.azf base64 +azs application/vnd.airzip.filesecure.azs base64 +azw application/vnd.amazon.ebook base64 +bat application/x-msdos-program base64 +bck application/x-VMSBACKUP base64 +bcpio application/x-bcpio base64 +bdf application/x-font-bdf base64 +bdm application/vnd.syncml.dm+wbxml base64 +bed application/vnd.realvnc.bed base64 +bh2 application/vnd.fujitsu.oasysprs base64 +bin application/octet-stream base64 +bkm application/vnd.nervana base64 +blb application/x-blorb base64 +bleep application/x-bleeper base64 +blorb application/x-blorb base64 +bmi application/vnd.bmi base64 +bmp image/bmp base64 +book application/vnd.framemaker base64 +box application/vnd.previewsystems.box base64 +boz application/x-bzip2 base64 +bpd application/vnd.hbci base64 +bpk application/octet-stream base64 +btif image/prs.btif base64 +bz application/x-bzip base64 +bz2 application/x-bzip2 base64 +c text/plain quoted-printable +c11amc application/vnd.cluetrust.cartomobile-config base64 +c11amz application/vnd.cluetrust.cartomobile-config-pkg base64 +c4d application/vnd.clonk.c4group base64 +c4f application/vnd.clonk.c4group base64 +c4g application/vnd.clonk.c4group base64 +c4p application/vnd.clonk.c4group base64 +c4u application/vnd.clonk.c4group base64 +cab application/vnd.ms-cab-compressed base64 +caf audio/x-caf base64 +cap application/vnd.tcpdump.pcap base64 +car application/vnd.curl.car base64 +cat application/vnd.ms-pki.seccat base64 +cb7 application/x-cbr base64 +cba application/x-cbr base64 +cbr application/x-cbr base64 +cbt application/x-cbr base64 +cbz application/x-cbr base64 +cc text/plain quoted-printable +ccc text/vnd.net2phone.commcenter.command quoted-printable +cct application/x-director base64 +ccxml application/ccxml+xml base64 +cdbcmsg application/vnd.contact.cmsg base64 +cdf application/netcdf base64 +cdkey application/vnd.mediastation.cdkey base64 +cdmia application/cdmi-capability base64 +cdmic application/cdmi-container base64 +cdmid application/cdmi-domain base64 +cdmio application/cdmi-object base64 +cdmiq application/cdmi-queue base64 +cdx chemical/x-cdx base64 +cdxml application/vnd.chemdraw+xml base64 +cdy application/vnd.cinderella base64 +cer application/pkix-cert base64 +cfs application/x-cfs-compressed base64 +cgm image/cgm base64 +chat application/x-chat base64 +chm application/vnd.ms-htmlhelp base64 +chrt application/vnd.kde.kchart base64 +cif chemical/x-cif base64 +cii application/vnd.anser-web-certificate-issue-initiation base64 +cil application/vnd.ms-artgalry base64 +cjs text/javascript quoted-printable +cla application/vnd.claymore base64 +class application/octet-stream base64 +clkk application/vnd.crick.clicker.keyboard base64 +clkp application/vnd.crick.clicker.palette base64 +clkt application/vnd.crick.clicker.template base64 +clkw application/vnd.crick.clicker.wordbank base64 +clkx application/vnd.crick.clicker base64 +clp application/x-msclip base64 +clpi video/MP2T base64 +cmc application/vnd.cosmocaller base64 +cmd application/x-msdos-program base64 +cmdf chemical/x-cmdf base64 +cml chemical/x-cml base64 +cmp application/vnd.yellowriver-custom-menu base64 +cmx image/x-cmx base64 +cod application/vnd.rim.cod base64 +coffee text/x-coffescript 8bit +com application/x-msdos-program base64 +conf text/plain quoted-printable +cpi video/MP2T base64 +cpio application/x-cpio base64 +cpp text/plain quoted-printable +cpt application/x-mac-compactpro base64 +cr2 image/x-canon-cr2 base64 +crd application/x-mscardfile base64 +crl application/pkix-crl base64 +crt application/x-x509-ca-cert base64 +crw image/x-canon-crw base64 +crx application/x-chrome-extension base64 +cryptonote application/vnd.rig.cryptonote base64 +csh application/x-csh 8bit +csm application/x-cu-seeme base64 +csml chemical/x-csml base64 +csp application/vnd.commonspace base64 +css text/css 8bit +cst application/x-director base64 +csv text/csv 8bit +cu application/cu-seeme base64 +curl application/vnd.curl base64 +cw application/prs.cww base64 +cww application/prs.cww base64 +cxt application/x-director base64 +cxx text/x-c quoted-printable +dae model/vnd.collada+xml base64 +daf application/vnd.Mobius.DAF base64 +dart application/vnd.dart base64 +dat text/plain quoted-printable +dataless application/vnd.fdsn.seed base64 +davmount application/davmount+xml base64 +dbk application/docbook+xml base64 +dcm application/dicom base64 +dcr application/x-director base64 +dcurl text/vnd.curl.dcurl quoted-printable +dd2 application/vnd.oma.dd2+xml base64 +ddd application/vnd.fujixerox.ddd base64 +deb application/x-debian-package base64 +def text/plain quoted-printable +deploy application/octet-stream base64 +der application/x-x509-ca-cert base64 +dfac application/vnd.dreamfactory base64 +dgc application/x-dgc-compressed base64 +dgn image/x-vnd.dgn base64 +dic text/x-c quoted-printable +dir application/x-director base64 +dis application/vnd.Mobius.DIS base64 +dist application/octet-stream base64 +distz application/octet-stream base64 +djv image/vnd.djvu base64 +djvu image/vnd.djvu base64 +dl video/x-dl base64 +dll application/octet-stream base64 +dmg application/x-apple-diskimage base64 +dmp application/vnd.tcpdump.pcap base64 +dms application/octet-stream base64 +dna application/vnd.dna base64 +dng image/x-adobe-dng base64 +doc application/msword base64 +docm application/vnd.ms-word.document.macroEnabled.12 base64 +docx application/vnd.openxmlformats-officedocument.wordprocessingml.document base64 +dot application/msword base64 +dotm application/vnd.ms-word.template.macroEnabled.12 base64 +dotx application/vnd.openxmlformats-officedocument.wordprocessingml.template base64 +dp application/vnd.osgi.dp base64 +dpg application/vnd.dpgraph base64 +dra audio/vnd.dra base64 +dsc text/prs.lines.tag quoted-printable +dssc application/dssc+der base64 +dtb application/x-dtbook+xml base64 +dtd application/xml-dtd 8bit +dts audio/vnd.dts base64 +dtshd audio/vnd.dts.hd base64 +dump application/octet-stream base64 +dv video/DV base64 +dvb video/vnd.dvb.file base64 +dvi application/x-dvi base64 +dwf model/vnd.dwf base64 +dwg image/vnd.dwg base64 +dxf image/vnd.dxf base64 +dxp application/vnd.spotfire.dxp base64 +dxr application/x-director base64 +dylib application/octet-stream base64 +ecelp4800 audio/vnd.nuera.ecelp4800 base64 +ecelp7470 audio/vnd.nuera.ecelp7470 base64 +ecelp9600 audio/vnd.nuera.ecelp9600 base64 +ecma application/ecmascript base64 +edm application/vnd.novadigm.EDM base64 +edx application/vnd.novadigm.EDX base64 +efif application/vnd.picsel base64 +ei6 application/vnd.pg.osasli base64 +elc application/octet-stream base64 +emf application/x-msmetafile base64 +eml message/rfc822 8bit +emm application/vnd.ibm.electronic-media base64 +emma application/emma+xml base64 +emz application/x-msmetafile base64 +ent application/vnd.nervana base64 +entity application/vnd.nervana base64 +eol audio/vnd.digital-winds 7bit +eot application/vnd.ms-fontobject base64 +eps application/postscript 8bit +epub application/epub+zip base64 +erf image/x-epson-erf base64 +es application/ecmascript base64 +es3 application/vnd.eszigno3+xml base64 +esa application/vnd.osgi.subsystem base64 +esf application/vnd.epson.esf base64 +et3 application/vnd.eszigno3+xml base64 +etx text/x-setext quoted-printable +eva application/x-eva base64 +evc audio/EVRC base64 +evy application/x-envoy base64 +exe application/x-ms-dos-executable base64 +exi application/exi base64 +ext application/vnd.novadigm.EXT base64 +ez application/andrew-inset base64 +ez2 application/vnd.ezpix-album base64 +ez3 application/vnd.ezpix-package base64 +f text/x-fortran quoted-printable +f4a audio/mp4 base64 +f4b audio/mp4 base64 +f4p video/mp4 base64 +f4v video/mp4 base64 +f77 text/x-fortran quoted-printable +f90 text/x-fortran quoted-printable +fb application/vnd.framemaker base64 +fbdoc application/vnd.framemaker base64 +fbs image/vnd.fastbidsheet base64 +fcdt application/vnd.adobe.formscentral.fcdt base64 +fcs application/vnd.isac.fcs base64 +fdf application/vnd.fdf base64 +fe_launch application/vnd.denovo.fcselayout-link base64 +fg5 application/vnd.fujitsu.oasysgp base64 +fgd application/x-director base64 +fh image/x-freehand base64 +fh4 image/x-freehand base64 +fh5 image/x-freehand base64 +fh7 image/x-freehand base64 +fhc image/x-freehand base64 +fig application/x-xfig base64 +flac audio/x-flac base64 +fli video/x-fli base64 +flo application/vnd.micrografx.flo base64 +flv video/x-flv base64 +flw application/vnd.kde.kivio base64 +flx text/vnd.fmi.flexstor quoted-printable +fly text/vnd.fly quoted-printable +fm application/vnd.framemaker base64 +fnc application/vnd.frogans.fnc base64 +for text/x-fortran quoted-printable +fpx image/vnd.fpx base64 +frame application/vnd.framemaker base64 +frm application/vnd.framemaker base64 +fsc application/vnd.fsc.weblaunch 7bit +fst image/vnd.fst base64 +ftc application/vnd.fluxtime.clip base64 +fti application/vnd.anser-web-funds-transfer-initiation base64 +fvt video/vnd.fvt base64 +fxp application/vnd.adobe.fxp base64 +fxpl application/vnd.adobe.fxp base64 +fzs application/vnd.fuzzysheet base64 +g2w application/vnd.geoplan base64 +g3 image/g3fax base64 +g3w application/vnd.geospace base64 +gac application/vnd.groove-account base64 +gam application/x-tads base64 +gbr application/rpki-ghostbusters base64 +gca application/x-gca-compressed base64 +gdl model/vnd.gdl base64 +geo application/vnd.dynageo base64 +gex application/vnd.geometry-explorer base64 +ggb application/vnd.geogebra.file base64 +ggs application/vnd.geogebra.slides base64 +ggt application/vnd.geogebra.tool base64 +ghf application/vnd.groove-help base64 +gif image/gif base64 +gim application/vnd.groove-identity-message base64 +gl video/x-gl base64 +gml application/gml+xml base64 +gmx application/vnd.gmx base64 +gnumeric application/x-gnumeric base64 +gpg application/octet-stream base64 +gph application/vnd.FloGraphIt base64 +gpx application/gpx+xml base64 +gqf application/vnd.grafeq base64 +gqs application/vnd.grafeq base64 +gram application/srgs base64 +gramps application/x-gramps-xml base64 +gre application/vnd.geometry-explorer base64 +grv application/vnd.groove-injector base64 +grxml application/srgs+xml base64 +gsf application/x-font-ghostscript base64 +gtar application/x-gtar base64 +gtm application/vnd.groove-tool-message base64 +gtw model/vnd.gtw base64 +gv text/vnd.graphviz quoted-printable +gxf application/gxf base64 +gxt application/vnd.geonext base64 +gz application/gzip base64 +h text/plain quoted-printable +h261 video/H261 base64 +h263 video/H263 base64 +h264 video/H264 base64 +hal application/vnd.hal+xml base64 +hbc application/vnd.hbci base64 +hbci application/vnd.hbci base64 +hdf application/x-hdf base64 +heic image/heic base64 +heics image/heic-sequence base64 +heif image/heif base64 +heifs image/heif-sequence base64 +hep application/x-hep base64 +hh text/plain quoted-printable +hif image/heic base64 +hlp text/plain quoted-printable +hpgl application/vnd.hp-HPGL base64 +hpid application/vnd.hp-hpid base64 +hpp text/plain quoted-printable +hps application/vnd.hp-hps base64 +hqx application/mac-binhex40 8bit +htc text/x-component 8bit +htke application/vnd.kenameaapp base64 +htm text/html 8bit +html text/html 8bit +htmlx text/html 8bit +htx text/html 8bit +hvd application/vnd.yamaha.hv-dic base64 +hvp application/vnd.yamaha.hv-voice base64 +hvs application/vnd.yamaha.hv-script base64 +i2g application/vnd.intergeo base64 +ibooks application/x-ibooks+zip base64 +ica application/x-ica base64 +icc application/vnd.iccprofile base64 +ice x-conference/x-cooltalk base64 +icm application/vnd.iccprofile base64 +ico image/vnd.microsoft.icon base64 +ics text/calendar quoted-printable +ief image/ief base64 +ifb text/calendar quoted-printable +ifm application/vnd.shana.informed.formdata base64 +iges model/iges base64 +igl application/vnd.igloader base64 +igm application/vnd.insors.igm base64 +igs model/iges base64 +igx application/vnd.micrografx.igx base64 +iif application/vnd.shana.informed.interchange base64 +imagemap application/x-imagemap 8bit +imap application/x-imagemap 8bit +imp application/vnd.accpac.simply.imp base64 +ims application/vnd.ms-ims base64 +in text/plain quoted-printable +ink application/inkml+xml base64 +inkml application/inkml+xml base64 +install application/x-install-instructions base64 +iota application/vnd.astraea-software.iota base64 +ipa application/octet-stream base64 +ipfix application/ipfix base64 +ipk application/vnd.shana.informed.package base64 +irm application/vnd.ibm.rights-management base64 +irp application/vnd.irepository.package+xml base64 +iso application/x-iso9660-image base64 +itp application/vnd.shana.informed.formtemplate base64 +ivf video/x-ivf base64 +ivp application/vnd.immervision-ivp base64 +ivu application/vnd.immervision-ivu base64 +jad text/vnd.sun.j2me.app-descriptor 8bit +jam application/vnd.jam base64 +jar application/java-archive base64 +java text/x-java-source quoted-printable +jfif image/jpeg base64 +jisp application/vnd.jisp base64 +jlt application/vnd.hp-jlyt base64 +jnlp application/x-java-jnlp-file base64 +joda application/vnd.joost.joda-archive base64 +jp2 image/jp2 base64 +jpe image/jpeg base64 +jpeg image/jpeg base64 +jpf image/jpx base64 +jpg image/jpeg base64 +jpg2 image/jp2 base64 +jpgm image/jpm base64 +jpgv video/JPEG base64 +jpm image/jpm base64 +jpx image/jpx base64 +js text/javascript quoted-printable +json application/json 8bit +jsonml application/jsonml+json base64 +k25 image/x-kodak-k25 base64 +kar audio/midi base64 +karbon application/vnd.kde.karbon base64 +kcm application/vnd.nervana base64 +kdc image/x-kodak-kdc base64 +key application/x-iwork-keynote-sffkey base64 +kfo application/vnd.kde.kformula base64 +kia application/vnd.kidspiration base64 +kml application/vnd.google-earth.kml+xml 8bit +kmz application/vnd.google-earth.kmz 8bit +kne application/vnd.Kinar base64 +knp application/vnd.Kinar base64 +kom application/vnd.hbci base64 +kon application/vnd.kde.kontour base64 +kpr application/vnd.kde.kpresenter base64 +kpt application/vnd.kde.kpresenter base64 +kpxx application/vnd.ds-keypoint base64 +ksp application/vnd.kde.kspread base64 +ktr application/vnd.kahootz base64 +ktx image/ktx base64 +ktz application/vnd.kahootz base64 +kwd application/vnd.kde.kword base64 +kwt application/vnd.kde.kword base64 +l16 audio/L16 base64 +lasxml application/vnd.las.las+xml base64 +latex application/x-latex 8bit +lbd application/vnd.llamagraphics.life-balance.desktop base64 +lbe application/vnd.llamagraphics.life-balance.exchange+xml base64 +les application/vnd.hhe.lesson-player base64 +lha application/octet-stream base64 +link66 application/vnd.route66.link66+xml base64 +list text/plain quoted-printable +list3820 application/vnd.ibm.modcap base64 +listafp application/vnd.ibm.modcap base64 +lnk application/x-ms-shortcut base64 +log text/plain quoted-printable +lostxml application/lost+xml base64 +lrf application/octet-stream base64 +lrm application/vnd.ms-lrm base64 +ltf application/vnd.frogans.ltf base64 +ltx application/x-latex 8bit +lvp audio/vnd.lucent.voice base64 +lwp application/vnd.lotus-wordpro base64 +lzh application/octet-stream base64 +m13 application/x-msmediaview base64 +m14 application/x-msmediaview base64 +m1v video/mpeg base64 +m21 application/mp21 base64 +m2a audio/mpeg base64 +m2ts video/MP2T base64 +m2v video/mpeg base64 +m3a audio/mpeg base64 +m3u audio/x-mpegurl base64 +m3u8 application/vnd.apple.mpegurl base64 +m4a audio/mp4 base64 +m4u video/vnd.mpegurl 8bit +m4v video/vnd.objectvideo base64 +ma application/mathematica base64 +mads application/mads+xml base64 +mag application/vnd.ecowin.chart base64 +maker application/vnd.framemaker base64 +man text/troff 8bit +manifest text/cache-manifest quoted-printable +mar application/octet-stream base64 +markdown text/markdown quoted-printable +mathml application/mathml+xml base64 +mb application/mathematica base64 +mbk application/vnd.Mobius.MBK base64 +mbox application/mbox base64 +mc1 application/vnd.medcalcdata base64 +mcd application/vnd.mcd base64 +mcurl text/vnd.curl.mcurl quoted-printable +md text/markdown quoted-printable +mda application/x-msaccess base64 +mdb application/x-msaccess base64 +mde application/x-msaccess base64 +mdf application/x-msaccess base64 +mdi image/vnd.ms-modi base64 +me text/troff 8bit +mesh model/mesh base64 +meta4 application/metalink4+xml base64 +metalink application/metalink+xml base64 +mets application/mets+xml base64 +mfm application/vnd.mfmp base64 +mft application/rpki-manifest base64 +mgp application/vnd.osgeo.mapguide.package base64 +mgz application/vnd.proteus.magazine base64 +mid audio/midi base64 +midi audio/midi base64 +mie application/x-mie base64 +mif application/vnd.mif base64 +mime message/rfc822 8bit +mj2 video/MJ2 base64 +mjp2 video/MJ2 base64 +mjpeg video/x-motion-jpeg base64 +mjpg video/x-motion-jpeg base64 +mjs text/javascript quoted-printable +mk3d video/x-matroska base64 +mka audio/x-matroska base64 +mkd text/markdown quoted-printable +mks video/x-matroska base64 +mkv video/x-matroska base64 +mlp application/vnd.dolby.mlp base64 +mmd application/vnd.chipnuts.karaoke-mmd base64 +mmf application/vnd.smaf base64 +mmr image/vnd.fujixerox.edmics-mmr base64 +mng video/x-mng base64 +mny application/x-msmoney base64 +mobi application/x-mobipocket-ebook base64 +mods application/mods+xml base64 +mov video/quicktime base64 +movie video/x-sgi-movie base64 +mp2 audio/mpeg base64 +mp21 application/mp21 base64 +mp2a audio/mpeg base64 +mp3 audio/mpeg base64 +mp3g video/mpeg base64 +mp4 application/mp4 base64 +mp4a audio/mp4 base64 +mp4s application/mp4 base64 +mp4v video/mp4 base64 +mpc application/vnd.mophun.certificate base64 +mpe video/mpeg base64 +mpeg video/mpeg base64 +mpg video/mpeg base64 +mpg4 application/mp4 base64 +mpga audio/mpeg base64 +mpkg application/vnd.apple.installer+xml base64 +mpl video/MP2T base64 +mpls video/MP2T base64 +mpm application/vnd.blueice.multipass base64 +mpn application/vnd.mophun.application base64 +mpp application/vnd.ms-project base64 +mpt application/vnd.ms-project base64 +mpy application/vnd.ibm.MiniPay base64 +mqy application/vnd.Mobius.MQY base64 +mrc application/marc base64 +mrcx application/marcxml+xml base64 +mrw image/x-minolta-mrw base64 +ms text/troff 8bit +mscml application/mediaservercontrol+xml base64 +mseed application/vnd.fdsn.mseed base64 +mseq application/vnd.mseq base64 +msf application/vnd.epson.msf base64 +msg application/vnd.ms-outlook base64 +msh model/mesh base64 +msi application/x-msdownload base64 +msl application/vnd.Mobius.MSL base64 +msty application/vnd.muvee.style base64 +mts model/vnd.mts base64 +mus application/vnd.musician base64 +musicxml application/vnd.recordare.musicxml+xml base64 +mvb application/x-msmediaview base64 +mwf application/vnd.MFER base64 +mxf application/mxf base64 +mxl application/vnd.recordare.musicxml base64 +mxmf audio/vnd.nokia.mobile-xmf base64 +mxml application/xv+xml base64 +mxs application/vnd.triscape.mxs base64 +mxu video/vnd.mpegurl 8bit +n-gage application/vnd.nokia.n-gage.symbian.install base64 +n3 text/n3 quoted-printable +nb application/mathematica base64 +nbp application/vnd.wolfram.player base64 +nc application/netcdf base64 +ncx application/x-dtbncx+xml base64 +nef image/x-nikon-nef base64 +nfo text/x-nfo quoted-printable +ngdat application/vnd.nokia.n-gage.data base64 +nim video/vnd.nokia.interleaved-multimedia base64 +nitf application/vnd.nitf base64 +nlu application/vnd.neurolanguage.nlu base64 +nml application/vnd.enliven base64 +nnd application/vnd.noblenet-directory base64 +nns application/vnd.noblenet-sealer base64 +nnw application/vnd.noblenet-web base64 +notebook application/x-smarttech-notebook base64 +npx image/vnd.net-fpx base64 +nsc application/x-conference base64 +nsf application/vnd.lotus-notes base64 +ntf application/vnd.nitf base64 +numbers application/x-iwork-numbers-sffnumbers base64 +nzb application/x-nzb base64 +oa2 application/vnd.fujitsu.oasys2 base64 +oa3 application/vnd.fujitsu.oasys3 base64 +oas application/vnd.fujitsu.oasys base64 +obd application/x-msbinder base64 +obj application/x-tgif base64 +oda application/oda base64 +odb application/vnd.oasis.opendocument.database base64 +odc application/vnd.oasis.opendocument.chart base64 +odf application/vnd.oasis.opendocument.formula base64 +odft application/vnd.oasis.opendocument.formula-template base64 +odg application/vnd.oasis.opendocument.graphics base64 +odi application/vnd.oasis.opendocument.image base64 +odm application/vnd.oasis.opendocument.text-master base64 +odp application/vnd.oasis.opendocument.presentation base64 +ods application/vnd.oasis.opendocument.spreadsheet base64 +odt application/vnd.oasis.opendocument.text base64 +oex application/x-opera-extension base64 +oga audio/ogg base64 +ogg audio/ogg base64 +ogv video/ogg base64 +ogx application/ogg base64 +omdoc application/omdoc+xml base64 +onepkg application/onenote base64 +onetmp application/onenote base64 +onetoc application/onenote base64 +onetoc2 application/onenote base64 +opf application/oebps-package+xml base64 +opml text/x-opml quoted-printable +oprc application/vnd.palm base64 +opus audio/ogg base64 +orf image/x-olympus-orf base64 +org application/vnd.lotus-organizer base64 +osf application/vnd.yamaha.openscoreformat base64 +osfpvg application/vnd.yamaha.openscoreformat.osfpvg+xml base64 +otc application/vnd.oasis.opendocument.chart-template base64 +otf font/otf base64 +otg application/vnd.oasis.opendocument.graphics-template base64 +oth application/vnd.oasis.opendocument.text-web base64 +oti application/vnd.oasis.opendocument.image-template base64 +otp application/vnd.oasis.opendocument.presentation-template base64 +ots application/vnd.oasis.opendocument.spreadsheet-template base64 +ott application/vnd.oasis.opendocument.text-template base64 +oxps application/oxps base64 +oxt application/vnd.openofficeorg.extension base64 +p text/x-pascal quoted-printable +p10 application/pkcs10 base64 +p12 application/x-pkcs12 base64 +p7b application/x-pkcs7-certificates base64 +p7c application/pkcs7-mime base64 +p7m application/pkcs7-mime base64 +p7r application/x-pkcs7-certreqresp base64 +p7s application/pkcs7-signature base64 +p8 application/pkcs8 base64 +pac application/x-ns-proxy-autoconfig base64 +pages application/x-iwork-pages-sffpages base64 +pas text/x-pascal quoted-printable +paw application/vnd.pawaafile base64 +pbd application/vnd.powerbuilder6 base64 +pbm image/x-portable-bitmap base64 +pcap application/vnd.tcpdump.pcap base64 +pcf application/x-font-pcf base64 +pcl application/vnd.hp-PCL base64 +pclxl application/vnd.hp-PCLXL base64 +pct image/x-pict base64 +pcurl application/vnd.curl.pcurl base64 +pcx image/x-pcx base64 +pdb application/vnd.palm base64 +pdf application/pdf base64 +pef image/x-pentax-pef base64 +pfa application/x-font-type1 base64 +pfb application/x-font-type1 base64 +pfm application/x-font-type1 base64 +pfr application/font-tdpfr base64 +pfx application/x-pkcs12 base64 +pgb image/vnd.globalgraphics.pgb base64 +pgm image/x-portable-graymap base64 +pgn application/x-chess-pgn base64 +pgp application/octet-stream base64 +php application/x-httpd-php 8bit +pht application/x-httpd-php 8bit +phtml application/x-httpd-php 8bit +pic image/x-pict base64 +pkd application/vnd.hbci base64 +pkg application/octet-stream base64 +pki application/pkixcmp base64 +pkipath application/pkix-pkipath base64 +pkpass application/vnd.apple.pkpass base64 +pl application/x-perl 8bit +plb application/vnd.3gpp.pic-bw-large base64 +plc application/vnd.Mobius.PLC base64 +plf application/vnd.pocketlearn base64 +plj audio/vnd.everad.plj base64 +pls application/pls+xml base64 +plt application/vnd.hp-HPGL base64 +pm application/x-pagemaker base64 +pm5 application/x-pagemaker base64 +pml application/vnd.ctc-posml base64 +png image/png base64 +pnm image/x-portable-anymap base64 +portpkg application/vnd.macports.portpkg base64 +pot application/vnd.ms-powerpoint base64 +potm application/vnd.ms-powerpoint.template.macroEnabled.12 base64 +potx application/vnd.openxmlformats-officedocument.presentationml.template base64 +ppam application/vnd.ms-powerpoint.addin.macroEnabled.12 base64 +ppd application/vnd.cups-ppd base64 +ppm image/x-portable-pixmap base64 +pps application/vnd.ms-powerpoint base64 +ppsm application/vnd.ms-powerpoint.slideshow.macroEnabled.12 base64 +ppsx application/vnd.openxmlformats-officedocument.presentationml.slideshow base64 +ppt application/vnd.ms-powerpoint base64 +pptm application/vnd.ms-powerpoint.presentation.macroEnabled.12 base64 +pptx application/vnd.openxmlformats-officedocument.presentationml.presentation base64 +pqa application/vnd.palm base64 +prc application/vnd.palm base64 +pre application/vnd.lotus-freelance base64 +prf application/pics-rules base64 +ps application/postscript 8bit +ps1 application/x-msdos-program base64 +psb application/vnd.3gpp.pic-bw-small base64 +psd image/vnd.adobe.photoshop base64 +psf application/x-font-linux-psf base64 +pskcxml application/pskc+xml base64 +psp image/x-paintshoppro base64 +pspimage image/x-paintshoppro base64 +pt5 application/x-pagemaker base64 +pti application/vnd.pvi.ptid1 base64 +ptid application/vnd.pvi.ptid1 base64 +pub application/x-mspublisher base64 +pvb application/vnd.3gpp.pic-bw-var base64 +pwn application/vnd.3M.Post-it-Notes base64 +py application/x-python 8bit +pya audio/vnd.ms-playready.media.pya base64 +pyv video/vnd.ms-playready.media.pyv base64 +qam application/vnd.epson.quickanime base64 +qbo application/vnd.intu.qbo base64 +qcp audio/vnd.qcelp base64 +qfx application/vnd.intu.qfx base64 +qps application/vnd.publishare-delta-tree base64 +qt video/quicktime base64 +qtl application/x-quicktimeplayer base64 +qwd application/vnd.Quark.QuarkXPress 8bit +qwt application/vnd.Quark.QuarkXPress 8bit +qxb application/vnd.Quark.QuarkXPress 8bit +qxd application/vnd.Quark.QuarkXPress 8bit +qxl application/vnd.Quark.QuarkXPress 8bit +qxt application/vnd.Quark.QuarkXPress 8bit +ra audio/x-pn-realaudio base64 +raf image/x-fuji-raf base64 +ram audio/x-pn-realaudio base64 +rar application/x-rar-compressed base64 +ras image/x-cmu-raster base64 +raw image/x-panasonic-raw base64 +rb application/x-ruby 8bit +rbw application/x-ruby 8bit +rcprofile application/vnd.ipunplugged.rcprofile base64 +rct application/prs.nprend base64 +rdf application/rdf+xml 8bit +rdz application/vnd.data-vision.rdz base64 +reg application/x-msdos-program base64 +rep application/vnd.businessobjects base64 +req application/vnd.nervana base64 +request application/vnd.nervana base64 +res application/x-dtbresource+xml base64 +rgb image/x-rgb base64 +rhtml application/x-html+ruby 8bit +rif application/reginfo+xml base64 +rip audio/vnd.rip base64 +ris application/x-research-info-systems base64 +rl application/resource-lists+xml base64 +rlc image/vnd.fujixerox.edmics-rlc base64 +rld application/resource-lists-diff+xml base64 +rm application/vnd.rn-realmedia base64 +rmi audio/midi base64 +rmp audio/x-pn-realaudio-plugin base64 +rms application/vnd.jcp.javame.midlet-rms base64 +rmvb application/vnd.rn-realmedia-vbr base64 +rnc application/relax-ng-compact-syntax base64 +rnd application/prs.nprend base64 +roa application/rpki-roa base64 +roff text/troff 8bit +rp9 application/vnd.cloanto.rp9 base64 +rpm audio/x-pn-realaudio-plugin base64 +rpss application/vnd.nokia.radio-presets base64 +rpst application/vnd.nokia.radio-preset base64 +rq application/sparql-query base64 +rs application/rls-services+xml base64 +rsd application/rsd+xml base64 +rss application/rss+xml base64 +rst text/plain quoted-printable +rtf application/rtf base64 +rtx text/richtext 8bit +s text/x-asm quoted-printable +s11 video/vnd.sealed.mpeg1 base64 +s14 video/vnd.sealed.mpeg4 base64 +s1a application/vnd.sealedmedia.softseal.pdf base64 +s1e application/vnd.sealed.xls base64 +s1h application/vnd.sealedmedia.softseal.html base64 +s1m audio/vnd.sealedmedia.softseal.mpeg base64 +s1p application/vnd.sealed.ppt base64 +s1q video/vnd.sealedmedia.softseal.mov base64 +s1w application/vnd.sealed.doc base64 +s3m audio/s3m base64 +saf application/vnd.yamaha.smaf-audio base64 +sav application/x-spss base64 +sbml application/sbml+xml base64 +sbs application/x-spss base64 +sc application/vnd.ibm.secure-container base64 +scd application/x-msschedule base64 +scm application/vnd.lotus-screencam base64 +scq application/scvp-cv-request base64 +scs application/scvp-cv-response base64 +scurl text/vnd.curl.scurl quoted-printable +sda application/vnd.stardivision.draw base64 +sdc application/vnd.stardivision.calc base64 +sdd application/vnd.stardivision.impress base64 +sdf application/vnd.Kinar base64 +sdkd application/vnd.solent.sdkm+xml base64 +sdkm application/vnd.solent.sdkm+xml base64 +sdo application/vnd.sealed.doc base64 +sdoc application/vnd.sealed.doc base64 +sdp application/sdp base64 +sds application/vnd.stardivision.chart base64 +sdw application/vnd.stardivision.writer base64 +see application/vnd.seemail base64 +seed application/vnd.fdsn.seed base64 +sem application/vnd.sealed.eml base64 +sema application/vnd.sema base64 +semd application/vnd.semd base64 +semf application/vnd.semf base64 +seml application/vnd.sealed.eml base64 +ser application/java-serialized-object base64 +setpay application/set-payment-initiation base64 +setreg application/set-registration-initiation base64 +sfd-hdstx application/vnd.hydrostatix.sof-data base64 +sfs application/vnd.spotfire.sfs base64 +sfv text/x-sfv quoted-printable +sgi image/sgi base64 +sgl application/vnd.stardivision.writer-global base64 +sgm text/sgml quoted-printable +sgml application/sgml base64 +sh application/x-sh 8bit +shar application/x-shar 8bit +shf application/shf+xml base64 +shtml text/html 8bit +si text/vnd.wap.si quoted-printable +sic application/vnd.wap.sic base64 +sid image/x-mrsid-image base64 +sig application/pgp-signature base64 +sil audio/silk base64 +silo model/mesh base64 +sis application/vnd.symbian.install base64 +sisx application/vnd.symbian.install base64 +sit application/x-stuffit base64 +sitx application/x-stuffitx base64 +siv application/sieve base64 +sj application/javascript 8bit +skd application/vnd.koan base64 +skm application/vnd.koan base64 +skp application/vnd.koan base64 +skt application/vnd.koan base64 +sl text/vnd.wap.sl quoted-printable +slc application/vnd.wap.slc base64 +sldm application/vnd.ms-powerpoint.slide.macroEnabled.12 base64 +sldx application/vnd.openxmlformats-officedocument.presentationml.slide base64 +slt application/vnd.epson.salt base64 +sm application/vnd.stepmania.stepchart base64 +smf application/vnd.stardivision.math base64 +smh application/vnd.sealed.mht base64 +smht application/vnd.sealed.mht base64 +smi application/smil+xml 8bit +smil application/smil+xml 8bit +smo video/vnd.sealedmedia.softseal.mov base64 +smov video/vnd.sealedmedia.softseal.mov base64 +smp audio/vnd.sealedmedia.softseal.mpeg base64 +smp3 audio/vnd.sealedmedia.softseal.mpeg base64 +smpg video/vnd.sealed.mpeg4 base64 +sms application/vnd.3gpp.sms base64 +smv audio/SMV base64 +smzip application/vnd.stepmania.package base64 +snd audio/basic base64 +snf application/x-font-snf base64 +so application/octet-stream base64 +soc application/sgml-open-catalog base64 +spc application/x-pkcs7-certificates base64 +spd application/vnd.sealedmedia.softseal.pdf base64 +spdf application/vnd.sealedmedia.softseal.pdf base64 +spf application/vnd.yamaha.smaf-phrase base64 +spl application/x-futuresplash base64 +spo application/x-spss base64 +spot text/vnd.in3d.spot quoted-printable +spp application/scvp-vp-response base64 +sppt application/vnd.sealed.ppt base64 +spq application/scvp-vp-request base64 +sps application/x-spss base64 +spx audio/ogg base64 +sql application/x-sql base64 +sr2 image/x-sony-sr2 base64 +src application/x-wais-source base64 +srf image/x-sony-srf base64 +srt application/x-subrip base64 +sru application/sru+xml base64 +srx application/sparql-results+xml base64 +ssdl application/ssdl+xml base64 +sse application/vnd.kodak-descriptor base64 +ssf application/vnd.epson.ssf base64 +ssml application/ssml+xml base64 +ssw video/vnd.sealed.swf base64 +sswf video/vnd.sealed.swf base64 +st application/vnd.sailingtracker.track base64 +stc application/vnd.sun.xml.calc.template base64 +std application/vnd.sun.xml.draw.template base64 +stf application/vnd.wt.stf base64 +sti application/vnd.sun.xml.impress.template base64 +stk application/hyperstudio base64 +stl application/vnd.ms-pki.stl base64 +stm application/vnd.sealedmedia.softseal.html base64 +stml application/vnd.sealedmedia.softseal.html base64 +str application/vnd.pg.format base64 +stw application/vnd.sun.xml.writer.template base64 +sub image/vnd.dvb.subtitle base64 +sus application/vnd.sus-calendar base64 +susp application/vnd.sus-calendar base64 +sv4cpio application/x-sv4cpio base64 +sv4crc application/x-sv4crc base64 +svc application/vnd.dvb.service base64 +svd application/vnd.svd base64 +svg image/svg+xml 8bit +svgz image/svg+xml 8bit +swa application/x-director base64 +swf application/x-shockwave-flash base64 +swi application/vnd.aristanetworks.swi base64 +sxc application/vnd.sun.xml.calc base64 +sxd application/vnd.sun.xml.draw base64 +sxg application/vnd.sun.xml.writer.global base64 +sxi application/vnd.sun.xml.impress base64 +sxl application/vnd.sealed.xls base64 +sxls application/vnd.sealed.xls base64 +sxm application/vnd.sun.xml.math base64 +sxw application/vnd.sun.xml.writer base64 +t text/troff 8bit +t3 application/x-t3vm-image base64 +taglet application/vnd.mynfc base64 +tao application/vnd.tao.intent-module-archive base64 +tar application/x-tar base64 +tbk application/x-toolbook base64 +tbz application/x-gtar base64 +tbz2 application/x-gtar base64 +tcap application/vnd.3gpp2.tcap base64 +tcl application/x-tcl 8bit +teacher application/vnd.smart.teacher base64 +tei application/tei+xml base64 +teicorpus application/tei+xml base64 +tex application/x-tex 8bit +texi application/x-texinfo 8bit +texinfo application/x-texinfo 8bit +text text/plain quoted-printable +textile text/plain quoted-printable +tfi application/thraud+xml base64 +tfm application/x-tex-tfm base64 +tga image/x-targa base64 +tgz application/x-gtar base64 +thmx application/vnd.ms-officetheme base64 +tif image/tiff base64 +tiff image/tiff base64 +tmo application/vnd.tmobile-livetv base64 +torrent application/x-bittorrent base64 +tpl application/vnd.groove-tool-template base64 +tpt application/vnd.trid.tpt base64 +tr text/troff 8bit +tra application/vnd.trueapp base64 +trm application/x-msterminal base64 +troff text/troff 8bit +ts video/MP2T base64 +tsd application/timestamped-data base64 +tsv text/tab-separated-values quoted-printable +ttc font/collection base64 +ttf font/ttf base64 +ttl text/turtle quoted-printable +twd application/vnd.SimTech-MindMapper base64 +twds application/vnd.SimTech-MindMapper base64 +txd application/vnd.genomatix.tuxedo base64 +txf application/vnd.Mobius.TXF base64 +txt text/plain quoted-printable +u32 application/x-authorware-bin base64 +udeb application/x-debian-package base64 +ufd application/vnd.ufdl base64 +ufdl application/vnd.ufdl base64 +ulx application/x-glulx base64 +umj application/vnd.umajin base64 +unityweb application/vnd.unity base64 +uoml application/vnd.uoml+xml base64 +upa application/vnd.hbci base64 +uri text/uri-list quoted-printable +uris text/uri-list quoted-printable +urls text/uri-list quoted-printable +ustar application/x-ustar base64 +utz application/vnd.uiq.theme base64 +uu text/x-uuencode quoted-printable +uva audio/vnd.dece.audio base64 +uvd application/vnd.dece.data base64 +uvf application/vnd.dece.data base64 +uvg image/vnd.dece.graphic base64 +uvh video/vnd.dece.hd base64 +uvi image/vnd.dece.graphic base64 +uvm video/vnd.dece.mobile base64 +uvp video/vnd.dece.pd base64 +uvs video/vnd.dece.sd base64 +uvt application/vnd.dece.ttml+xml base64 +uvu video/vnd.uvvu.mp4 base64 +uvv video/vnd.dece.video base64 +uvva audio/vnd.dece.audio base64 +uvvd application/vnd.dece.data base64 +uvvf application/vnd.dece.data base64 +uvvg image/vnd.dece.graphic base64 +uvvh video/vnd.dece.hd base64 +uvvi image/vnd.dece.graphic base64 +uvvm video/vnd.dece.mobile base64 +uvvp video/vnd.dece.pd base64 +uvvs video/vnd.dece.sd base64 +uvvt application/vnd.dece.ttml+xml base64 +uvvu video/vnd.uvvu.mp4 base64 +uvvv video/vnd.dece.video base64 +uvvx application/vnd.dece.unspecified base64 +uvvz application/vnd.dece.zip base64 +uvx application/vnd.dece.unspecified base64 +uvz application/vnd.dece.zip base64 +vbk audio/vnd.nortel.vbk base64 +vbs application/x-msdos-program base64 +vcard text/vcard quoted-printable +vcd application/x-cdlink base64 +vcf text/x-vcard 8bit +vcg application/vnd.groove-vcard base64 +vcs text/x-vcalendar 8bit +vcx application/vnd.vcx base64 +vis application/vnd.visionary base64 +viv video/vnd.vivo base64 +vivo video/vnd.vivo base64 +vob video/x-ms-vob base64 +vor application/vnd.stardivision.writer base64 +vox application/x-authorware-bin base64 +vrml model/vrml base64 +vsc application/vnd.vidsoft.vidconference 8bit +vsd application/vnd.visio base64 +vsf application/vnd.vsf base64 +vss application/vnd.visio base64 +vst application/vnd.visio base64 +vsw application/vnd.visio base64 +vtt text/vtt quoted-printable +vtu model/vnd.vtu base64 +vxml application/voicexml+xml base64 +w3d application/x-director base64 +wad application/x-doom base64 +wasm application/wasm 8bit +wav audio/wav base64 +wax audio/x-ms-wax base64 +wbmp image/vnd.wap.wbmp base64 +wbs application/vnd.criticaltools.wbs+xml base64 +wbxml application/vnd.wap.wbxml base64 +wcm application/vnd.ms-works base64 +wdb application/vnd.ms-works base64 +wdp image/vnd.ms-photo base64 +weba audio/webm base64 +webapp application/x-web-app-manifest+json base64 +webm audio/webm base64 +webmanifest application/manifest+json base64 +webp image/webp base64 +wg application/vnd.pmi.widget base64 +wgt application/widget base64 +wif application/watcherinfo+xml base64 +wk application/x-123 base64 +wks application/vnd.lotus-1-2-3 base64 +wkz application/x-Wingz base64 +wm video/x-ms-wm base64 +wma audio/x-ms-wma base64 +wmd application/x-ms-wmd base64 +wmf application/x-msmetafile base64 +wml text/vnd.wap.wml quoted-printable +wmlc application/vnd.wap.wmlc base64 +wmls text/vnd.wap.wmlscript quoted-printable +wmlsc application/vnd.wap.wmlscriptc base64 +wmv audio/x-ms-wmv base64 +wmx video/x-ms-wmx base64 +wmz application/x-ms-wmz base64 +woff font/woff base64 +woff2 font/woff2 base64 +wp application/wordperfect5.1 base64 +wp5 application/wordperfect5.1 base64 +wp6 application/x-wordperfect6.1 base64 +wpd application/vnd.wordperfect base64 +wpl application/vnd.ms-wpl base64 +wps application/vnd.ms-works base64 +wqd application/vnd.wqd base64 +wrd application/msword base64 +wri application/x-mswrite base64 +wrl model/vrml base64 +wsdl application/wsdl+xml base64 +wspolicy application/wspolicy+xml base64 +wtb application/vnd.webturbo base64 +wv application/vnd.wv.csp+wbxml base64 +wvx video/x-ms-wvx base64 +wz application/x-Wingz base64 +x32 application/x-authorware-bin base64 +x3d model/x3d+xml base64 +x3db model/x3d+binary base64 +x3dbz model/x3d+binary base64 +x3dv model/x3d+vrml base64 +x3dvz model/x3d+vrml base64 +x3dz model/x3d+xml base64 +x3f image/x-sigma-x3f base64 +x_b model/vnd.parasolid.transmit.binary base64 +x_t model/vnd.parasolid.transmit.text quoted-printable +xaml application/xaml+xml base64 +xap application/x-silverlight-app base64 +xar application/vnd.xara base64 +xbap application/x-ms-xbap base64 +xbd application/vnd.fujixerox.docuworks.binder base64 +xbm image/x-xbitmap 7bit +xcf image/x-xcf base64 +xcfbz2 image/x-compressed-xcf base64 +xcfgz image/x-compressed-xcf base64 +xdf application/xcap-diff+xml base64 +xdm application/vnd.syncml.dm+xml base64 +xdp application/vnd.adobe.xdp+xml base64 +xdssc application/dssc+xml base64 +xdw application/vnd.fujixerox.docuworks base64 +xenc application/xenc+xml base64 +xer application/patch-ops-error+xml base64 +xfdf application/vnd.adobe.xfdf base64 +xfdl application/vnd.xfdl base64 +xht application/xhtml+xml 8bit +xhtml application/xhtml+xml 8bit +xhvml application/xv+xml base64 +xif image/vnd.xiff base64 +xla application/vnd.ms-excel base64 +xlam application/vnd.ms-excel.addin.macroEnabled.12 base64 +xlc application/vnd.ms-excel base64 +xlf application/x-xliff+xml base64 +xlm application/vnd.ms-excel base64 +xls application/vnd.ms-excel base64 +xlsb application/vnd.ms-excel.sheet.binary.macroEnabled.12 base64 +xlsm application/vnd.ms-excel.sheet.macroEnabled.12 base64 +xlsx application/vnd.openxmlformats-officedocument.spreadsheetml.sheet base64 +xlt application/vnd.ms-excel base64 +xltm application/vnd.ms-excel.template.macroEnabled.12 base64 +xltx application/vnd.openxmlformats-officedocument.spreadsheetml.template base64 +xlw application/vnd.ms-excel base64 +xm audio/xm base64 +xml application/xml 8bit +xmt_bin model/vnd.parasolid.transmit.binary base64 +xmt_txt model/vnd.parasolid.transmit.text quoted-printable +xo application/vnd.olpc-sugar base64 +xop application/xop+xml base64 +xpi application/x-xpinstall base64 +xpl application/xproc+xml base64 +xpm image/x-xpixmap 8bit +xpr application/vnd.is-xpr base64 +xps application/vnd.ms-xpsdocument 8bit +xpw application/vnd.intercon.formnet base64 +xpx application/vnd.intercon.formnet base64 +xsd text/xml 8bit +xsl application/xml 8bit +xslt application/xslt+xml base64 +xsm application/vnd.syncml+xml base64 +xspf application/xspf+xml base64 +xul application/vnd.mozilla.xul+xml base64 +xvm application/xv+xml base64 +xvml application/xv+xml base64 +xwd image/x-xwindowdump base64 +xyz x-chemical/x-xyz base64 +xz application/x-xz base64 +yaml text/x-yaml 8bit +yang application/yang base64 +yin application/yin+xml base64 +yml text/x-yaml 8bit +z application/x-compressed base64 +z1 application/x-zmachine base64 +z2 application/x-zmachine base64 +z3 application/x-zmachine base64 +z4 application/x-zmachine base64 +z5 application/x-zmachine base64 +z6 application/x-zmachine base64 +z7 application/x-zmachine base64 +z8 application/x-zmachine base64 +zaz application/vnd.zzazz.deck+xml base64 +zip application/zip base64 +zir application/vnd.zul base64 +zirz application/vnd.zul base64 +zmm application/vnd.HandHeld-Entertainment+xml base64 diff --git a/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/lib/mini_mime.rb b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/lib/mini_mime.rb new file mode 100644 index 0000000..eadde55 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/lib/mini_mime.rb @@ -0,0 +1,186 @@ +# frozen_string_literal: true +require "mini_mime/version" +require "thread" + +module MiniMime + def self.lookup_by_filename(filename) + Db.lookup_by_filename(filename) + end + + def self.lookup_by_extension(extension) + Db.lookup_by_extension(extension) + end + + def self.lookup_by_content_type(mime) + Db.lookup_by_content_type(mime) + end + + module Configuration + class << self + attr_accessor :ext_db_path + attr_accessor :content_type_db_path + end + + self.ext_db_path = File.expand_path("../db/ext_mime.db", __FILE__) + self.content_type_db_path = File.expand_path("../db/content_type_mime.db", __FILE__) + end + + class Info + BINARY_ENCODINGS = %w(base64 8bit) + + attr_accessor :extension, :content_type, :encoding + + def initialize(buffer) + @extension, @content_type, @encoding = buffer.split(/\s+/).map!(&:freeze) + end + + def [](idx) + if idx == 0 + @extension + elsif idx == 1 + @content_type + elsif idx == 2 + @encoding + end + end + + def binary? + BINARY_ENCODINGS.include?(encoding) + end + end + + class Db + def self.lookup_by_filename(filename) + extension = File.extname(filename) + return if extension.empty? + extension = extension[1..-1] + lookup_by_extension(extension) + end + + def self.lookup_by_extension(extension) + @db ||= new + @db.lookup_by_extension(extension) || + @db.lookup_by_extension(extension.downcase) + end + + def self.lookup_by_content_type(content_type) + @db ||= new + @db.lookup_by_content_type(content_type) + end + + class Cache + def initialize(size) + @size = size + @hash = {} + end + + def []=(key, val) + rval = @hash[key] = val + @hash.shift if @hash.length > @size + rval + end + + def fetch(key, &blk) + @hash.fetch(key, &blk) + end + end + + if ::File.method_defined?(:pread) + PReadFile = ::File + else + # For Windows support + class PReadFile + def initialize(filename) + @mutex = Mutex.new + # We must open the file in binary mode + # otherwise Ruby's automatic line terminator + # translation will skew the row size + @file = ::File.open(filename, 'rb') + end + + def readline(*args) + @file.readline(*args) + end + + def pread(size, offset) + @mutex.synchronize do + @file.seek(offset, IO::SEEK_SET) + @file.read(size) + end + end + end + end + + class RandomAccessDb + MAX_CACHED = 100 + + def initialize(path, sort_order) + @path = path + @file = PReadFile.new(@path) + + @row_length = @file.readline("\n").length + @file_length = File.size(@path) + @rows = @file_length / @row_length + + @hit_cache = Cache.new(MAX_CACHED) + @miss_cache = Cache.new(MAX_CACHED) + + @sort_order = sort_order + end + + def lookup(val) + @hit_cache.fetch(val) do + @miss_cache.fetch(val) do + data = lookup_uncached(val) + if data + @hit_cache[val] = data + else + @miss_cache[val] = nil + end + + data + end + end + end + + # lifted from marcandre/backports + def lookup_uncached(val) + from = 0 + to = @rows - 1 + result = nil + + while from <= to do + midpoint = from + (to - from).div(2) + current = resolve(midpoint) + data = current[@sort_order] + if data > val + to = midpoint - 1 + elsif data < val + from = midpoint + 1 + else + result = current + break + end + end + result + end + + def resolve(row) + Info.new(@file.pread(@row_length, row * @row_length).force_encoding(Encoding::UTF_8)) + end + end + + def initialize + @ext_db = RandomAccessDb.new(Configuration.ext_db_path, 0) + @content_type_db = RandomAccessDb.new(Configuration.content_type_db_path, 1) + end + + def lookup_by_extension(extension) + @ext_db.lookup(extension) + end + + def lookup_by_content_type(content_type) + @content_type_db.lookup(content_type) + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/lib/mini_mime/version.rb b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/lib/mini_mime/version.rb new file mode 100644 index 0000000..968cf0b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/lib/mini_mime/version.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true +module MiniMime + VERSION = "1.1.5" +end diff --git a/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/mini_mime.gemspec b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/mini_mime.gemspec new file mode 100644 index 0000000..2ab398f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/mini_mime-1.1.5/mini_mime.gemspec @@ -0,0 +1,31 @@ +# coding: utf-8 +# frozen_string_literal: true +lib = File.expand_path('../lib', __FILE__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require 'mini_mime/version' + +Gem::Specification.new do |spec| + spec.name = "mini_mime" + spec.version = MiniMime::VERSION + spec.authors = ["Sam Saffron"] + spec.email = ["sam.saffron@gmail.com"] + + spec.summary = %q{A minimal mime type library} + spec.description = %q{A minimal mime type library} + spec.homepage = "https://github.com/discourse/mini_mime" + spec.license = "MIT" + + spec.files = `git ls-files -z`.split("\x0").reject do |f| + f.match(%r{^(test|spec|features)/}) + end + spec.bindir = "exe" + spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } + spec.require_paths = ["lib"] + spec.required_ruby_version = ">= 2.6.0" + + spec.add_development_dependency "bundler" + spec.add_development_dependency "rake" + spec.add_development_dependency "minitest" + spec.add_development_dependency "rubocop" + spec.add_development_dependency "rubocop-discourse" +end diff --git a/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/.rspec b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/.rspec new file mode 100644 index 0000000..0912718 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/.rspec @@ -0,0 +1,2 @@ +--color +--order random diff --git a/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/.rubocop.yml b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/.rubocop.yml new file mode 100644 index 0000000..5014b23 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/.rubocop.yml @@ -0,0 +1,56 @@ +require: + - standard + +plugins: + - rubocop-performance + - rubocop-rake + - rubocop-rspec + - standard-performance + +AllCops: + NewCops: enable + TargetRubyVersion: 3.2 + +Layout/ArgumentAlignment: + EnforcedStyle: with_fixed_indentation + IndentationWidth: 2 + +Layout/CaseIndentation: + EnforcedStyle: end + +Layout/EndAlignment: + EnforcedStyleAlignWith: start_of_line + +Layout/LineLength: + Max: 140 + +Layout/ParameterAlignment: + EnforcedStyle: with_fixed_indentation + IndentationWidth: 2 + +Layout/SpaceInsideHashLiteralBraces: + EnforcedStyle: no_space + +Metrics/ParameterLists: + CountKeywordArgs: false + +Style/Alias: + EnforcedStyle: prefer_alias_method + +Style/Documentation: + Enabled: false + +Style/FrozenStringLiteralComment: + EnforcedStyle: never + +Style/OpenStructUse: + Enabled: false + +Style/StringLiterals: + EnforcedStyle: double_quotes + +Style/StringLiteralsInInterpolation: + EnforcedStyle: double_quotes + +Style/TernaryParentheses: + EnforcedStyle: require_parentheses diff --git a/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/.yardopts b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/.yardopts new file mode 100644 index 0000000..b7f7711 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/.yardopts @@ -0,0 +1,8 @@ +--no-private +--protected +--markup markdown +- +CHANGELOG.md +CONTRIBUTING.md +LICENSE.md +README.md diff --git a/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/CHANGELOG.md b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/CHANGELOG.md new file mode 100644 index 0000000..b71074b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/CHANGELOG.md @@ -0,0 +1,113 @@ +0.7.2 +----- +* [Drop support for Ruby 3.1](https://github.com/sferik/multi_xml/commit/fab6288edd36c58a2b13e0206d8bed305fcb4a4b) + +0.7.1 +----- +* [Relax required Ruby version constraint to allow installation on Debian stable](https://github.com/sferik/multi_xml/commit/7d18711466a15e158dc71344ca6f6e18838ecc8d) + +0.7.0 +----- +* [Add support for Ruby 3.3](https://github.com/sferik/multi_xml/pull/67) +* [Drop support for Ruby 3.0](https://github.com/sferik/multi_xml/commit/eec72c56307fede3a93f1a61553587cb278b0c8a) [and](https://github.com/sferik/multi_xml/commit/6a6dec80a36c30774a5525b45f71d346fb561e69) [earlier](https://github.com/sferik/multi_xml/commit/e7dad37a0a0be8383a26ffe515c575b5b4d04588) +* [Don't mutate strings](https://github.com/sferik/multi_xml/commit/71be3fff4afb0277a7e1c47c5f1f4b6106a8eb45) + +0.6.0 +----- +* [Duplexed Streams](https://github.com/sferik/multi_xml/pull/45) +* [Support for Oga](https://github.com/sferik/multi_xml/pull/47) +* [Integer unification for Ruby 2.4](https://github.com/sferik/multi_xml/pull/54) + +0.5.5 +----- +* [Fix symbolize_keys function](https://github.com/sferik/multi_xml/commit/a4cae3aeb690999287cd30206399abaa5ce1ae81) +* [Fix Nokogiri parser for the same attr and inner element name](https://github.com/sferik/multi_xml/commit/a28ed86e2d7826b2edeed98552736b4c7ca52726) + +0.5.4 +----- +* [Add option to not cast parsed values](https://github.com/sferik/multi_xml/commit/44fc05fbcfd60cc8b555b75212471fab29fa8cd0) +* [Use message instead of to_s](https://github.com/sferik/multi_xml/commit/b06f0114434ffe1957dd7bc2712cb5b76c1b45fe) + +0.5.3 +----- +* [Add cryptographic signature](https://github.com/sferik/multi_xml/commit/f39f0c74308090737816c622dbb7d7aa28c646c0) + +0.5.2 +----- +* [Remove ability to parse symbols and YAML](https://github.com/sferik/multi_xml/pull/34) + +0.5.1 +----- +* [Revert "Reset @@parser in between specs"](https://github.com/sferik/multi_xml/issues/28) + +0.5.0 +----- +* [Reset @@parser in between specs](https://github.com/sferik/multi_xml/commit/b562bed265918b43ac1c4c638ae3a7ffe95ecd83) +* [Add attributes being passed through on content nodes](https://github.com/sferik/multi_xml/commit/631a8bb3c2253db0024f77f47c16d5a53b8128fd) + +0.4.4 +----- +* [Fix regression in MultiXml.parse](https://github.com/sferik/multi_xml/commit/45ae597d9a35cbd89cc7f5518c85bac30199fc06) + +0.4.3 +----- +* [Make parser a class variable](https://github.com/sferik/multi_xml/commit/6804ffc8680ed6466c66f2472f5e016c412c2c24) +* [Add TYPE_NAMES constant](https://github.com/sferik/multi_xml/commit/72a21f2e86c8e3ac9689cee5f3a62102cfb98028) + +0.4.2 +----- +* [Fix bug in dealing with xml element attributes for both REXML and Ox](https://github.com/sferik/multi_xml/commit/ba3c1ac427ff0268abaf8186fb4bd81100c99559) +* [Make Ox the preferred XML parser](https://github.com/sferik/multi_xml/commit/0a718d740c30fba426f300a929cda9ee8250d238) + +0.4.1 +----- +* [Use the SAX like parser with Ox](https://github.com/sferik/multi_xml/commit/d289d42817a32e48483c00d5361c76fbea62a166) + +0.4.0 +----- +* [Add support for Ox](https://github.com/sferik/multi_xml/pull/14) + +0.3.0 +----- +* [Remove core class monkeypatches](https://github.com/sferik/multi_xml/commit/f7cc3ce4d2924c0e0adc6935d1fba5ec79282938) +* [Sort out some class / singleton class issues](https://github.com/sferik/multi_xml/commit/a5dac06bcf658facaaf7afa295f1291c7be15a44) +* [Have parsers refer to toplevel CONTENT_ROOT instead of defining it](https://github.com/sferik/multi_xml/commit/94e6fa49e69b2a2467a0e6d3558f7d9815cae47e) +* [Move redundant input sanitizing to top-level](https://github.com/sferik/multi_xml/commit/4874148214dbbd2e5a4b877734e2519af42d6132) +* [Refactor libxml and nokogiri parsers to inherit from a common ancestor](https://github.com/sferik/multi_xml/commit/e0fdffcbfe641b6aaa3952ffa0570a893de325c2) + +0.2.2 +----- +* [Respect the global load path](https://github.com/sferik/multi_xml/commit/68eb3011b37f0e0222bb842abd2a78e1285a97c1) + +0.2.1 +----- +* [Add BlueCloth gem as development dependency for Markdown formatting](https://github.com/sferik/multi_xml/commit/18195cd1789176709f68f0d7f8df7fc944fe4d24) +* [Replace BlueCloth with Maruku for JRuby compatibility](https://github.com/sferik/multi_xml/commit/bad5516a5ec5e7ef7fc5a35c411721522357fa19) + +0.2.0 +----- +* [Do not automatically load all library files](https://github.com/sferik/multi_xml/commit/dbd0447e062e8930118573c5453150e9371e5955) + +0.1.4 +----- +* [Preserve backtrace when catching/throwing exceptions](https://github.com/sferik/multi_xml/commit/7475ee90201c2701fddd524082832d16ca62552d) + +0.1.3 +----- +* [Common error handling for all parsers](https://github.com/sferik/multi_xml/commit/5357c28eddc14e921fd1be1f445db602a8dddaf2) + +0.1.2 +----- +* [Make wrap an Array class method](https://github.com/sferik/multi_xml/commit/28307b69bd1d9460353c861466e425c2afadcf56) + +0.1.1 +----- +* [Fix parsing for strings that contain newlines](https://github.com/sferik/multi_xml/commit/68087a4ce50b5d63cfa60d6f1fcbc2f6d689e43f) + +0.1.0 +----- +* [Add support for LibXML and Nokogiri](https://github.com/sferik/multi_xml/commit/856bb17fce66601e0b3d3eb3b64dbeb25aed3bca) + +0.0.1 +----- +* [REXML support](https://github.com/sferik/multi_xml/commit/2a848384a7b90fb3e26b5a8d4dc3fa3e3f2db5fc) diff --git a/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/CONTRIBUTING.md b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/CONTRIBUTING.md new file mode 100644 index 0000000..fdb7416 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/CONTRIBUTING.md @@ -0,0 +1,51 @@ +## Contributing +In the spirit of [free software][free-sw] , **everyone** is encouraged to help +improve this project. + +[free-sw]: http://www.fsf.org/licensing/essays/free-sw.html + +Here are some ways *you* can contribute: + +* by using alpha, beta, and prerelease versions +* by reporting bugs +* by suggesting new features +* by writing or editing documentation +* by writing specifications +* by writing code (**no patch is too small**: fix typos, add comments, clean up + inconsistent whitespace) +* by refactoring code +* by resolving [issues][] +* by reviewing patches +* [financially][gittip] + +[issues]: https://github.com/sferik/multi_xml/issues +[gittip]: https://www.gittip.com/sferik/ + +## Submitting an Issue +We use the [GitHub issue tracker][issues] to track bugs and features. Before +submitting a bug report or feature request, check to make sure it hasn't +already been submitted. When submitting a bug report, please include a [Gist][] +that includes a stack trace and any details that may be necessary to reproduce +the bug, including your gem version, Ruby version, and operating system. +Ideally, a bug report should include a pull request with failing specs. + +[gist]: https://gist.github.com/ + +## Submitting a Pull Request +1. [Fork the repository.][fork] +2. [Create a topic branch.][branch] +3. Add specs for your unimplemented feature or bug fix. +4. Run `bundle exec rake spec`. If your specs pass, return to step 3. +5. Implement your feature or bug fix. +6. Run `bundle exec rake`. If your specs fail, return to step 5. +7. Run `open coverage/index.html`. If your changes are not completely covered + by your tests, return to step 3. +8. Add documentation for your feature or bug fix. +9. Run `bundle exec rake verify_measurements`. If your changes are not 100% + documented, go back to step 8. +10. Add, commit, and push your changes. +11. [Submit a pull request.][pr] + +[fork]: http://help.github.com/fork-a-repo/ +[branch]: http://learn.github.com/p/branching.html +[pr]: http://help.github.com/send-pull-requests/ diff --git a/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/Gemfile b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/Gemfile new file mode 100644 index 0000000..b7164f9 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/Gemfile @@ -0,0 +1,21 @@ +source "https://rubygems.org" + +gem "libxml-ruby", require: nil, platforms: :ruby +gem "nokogiri", require: nil +gem "oga", ">= 2.3", require: nil +gem "ox", require: nil, platforms: :ruby +gem "rexml", require: nil + +gem "rake", ">= 13.2.1" +gem "rspec", ">= 3.12" +gem "rubocop", ">= 1.62.1" +gem "rubocop-performance", ">= 1.20.2" +gem "rubocop-rake", ">= 0.6" +gem "rubocop-rspec", ">= 2.24" +gem "simplecov", ">= 0.22" +gem "standard", ">= 1.35.1" +gem "standard-performance", ">= 1.3.1" +gem "yard", ">= 0.9.36" +gem "yardstick", ">= 0.9.9" + +gemspec diff --git a/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/LICENSE.md b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/LICENSE.md new file mode 100644 index 0000000..7dd9288 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/LICENSE.md @@ -0,0 +1,20 @@ +Copyright (c) 2010-2025 Erik Berlin + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/README.md b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/README.md new file mode 100644 index 0000000..c5b0187 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/README.md @@ -0,0 +1,75 @@ +# MultiXML + +A generic swappable back-end for XML parsing + +## Installation + gem install multi_xml + +## Documentation +[http://rdoc.info/gems/multi_xml][documentation] + +[documentation]: http://rdoc.info/gems/multi_xml + +## Usage Examples +```ruby +require 'multi_xml' + +MultiXml.parser = :ox +MultiXml.parser = MultiXml::Parsers::Ox # Same as above +MultiXml.parse('This is the contents') # Parsed using Ox + +MultiXml.parser = :libxml +MultiXml.parser = MultiXml::Parsers::Libxml # Same as above +MultiXml.parse('This is the contents') # Parsed using LibXML + +MultiXml.parser = :nokogiri +MultiXml.parser = MultiXml::Parsers::Nokogiri # Same as above +MultiXml.parse('This is the contents') # Parsed using Nokogiri + +MultiXml.parser = :rexml +MultiXml.parser = MultiXml::Parsers::Rexml # Same as above +MultiXml.parse('This is the contents') # Parsed using REXML + +MultiXml.parser = :oga +MultiXml.parser = MultiXml::Parsers::Oga # Same as above +MultiXml.parse('This is the contents') # Parsed using Oga +``` +The `parser` setter takes either a symbol or a class (to allow for custom XML +parsers) that responds to `.parse` at the class level. + +MultiXML tries to have intelligent defaulting. That is, if you have any of the +supported parsers already loaded, it will use them before attempting to load +a new one. When loading, libraries are ordered by speed: first Ox, then LibXML, +then Nokogiri, and finally REXML. + +## Supported Ruby Versions +This library aims to support and is tested against the following Ruby +implementations: + +* 3.2 +* 3.3 +* 3.4 +* JRuby 10 + +If something doesn't work on one of these versions, it's a bug. + +This library may inadvertently work (or seem to work) on other Ruby +implementations, however support will only be provided for the versions listed +above. + +If you would like this library to support another Ruby version, you may +volunteer to be a maintainer. Being a maintainer entails making sure all tests +run and pass on that implementation. When something breaks on your +implementation, you will be responsible for providing patches in a timely +fashion. If critical issues for a particular implementation exist at the time +of a major release, support for that Ruby version may be dropped. + +## Inspiration +MultiXML was inspired by [MultiJSON][]. + +[multijson]: https://github.com/intridea/multi_json/ + +## Copyright +Copyright (c) 2010-2025 Erik Berlin. See [LICENSE][] for details. + +[license]: LICENSE.md diff --git a/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/Rakefile b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/Rakefile new file mode 100644 index 0000000..54f21fe --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/Rakefile @@ -0,0 +1,33 @@ +require "bundler" +Bundler::GemHelper.install_tasks + +require "rspec/core/rake_task" +RSpec::Core::RakeTask.new(:spec) + +task test: :spec + +require "rubocop/rake_task" +RuboCop::RakeTask.new + +require "yard" +YARD::Rake::YardocTask.new do |task| + task.files = ["lib/**/*.rb", "-", "LICENSE.md"] + task.options = [ + "--no-private", + "--protected", + "--output-dir", "doc/yard", + "--markup", "markdown" + ] +end + +require "yardstick/rake/measurement" +Yardstick::Rake::Measurement.new do |measurement| + measurement.output = "measurement/report.txt" +end + +require "yardstick/rake/verify" +Yardstick::Rake::Verify.new do |verify| + verify.threshold = 48.8 +end + +task default: %i[spec rubocop verify_measurements] diff --git a/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/lib/multi_xml.rb b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/lib/multi_xml.rb new file mode 100644 index 0000000..87e66d0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/lib/multi_xml.rb @@ -0,0 +1,311 @@ +require "bigdecimal" +require "date" +require "stringio" +require "time" +require "yaml" + +module MultiXml # rubocop:disable Metrics/ModuleLength + class ParseError < StandardError; end + + class NoParserError < StandardError; end + + class DisallowedTypeError < StandardError + def initialize(type) + super("Disallowed type attribute: #{type.inspect}") + end + end + + unless defined?(REQUIREMENT_MAP) + REQUIREMENT_MAP = [ + ["ox", :ox], + ["libxml", :libxml], + ["nokogiri", :nokogiri], + ["rexml/document", :rexml], + ["oga", :oga] + ].freeze + end + + CONTENT_ROOT = "__content__".freeze unless defined?(CONTENT_ROOT) + + unless defined?(PARSING) + float_proc = proc { |float| float.to_f } + datetime_proc = proc { |time| Time.parse(time).utc rescue DateTime.parse(time).utc } # rubocop:disable Style/RescueModifier + + PARSING = { + "symbol" => proc { |symbol| symbol.to_sym }, + "date" => proc { |date| Date.parse(date) }, + "datetime" => datetime_proc, + "dateTime" => datetime_proc, + "integer" => proc { |integer| integer.to_i }, + "float" => float_proc, + "double" => float_proc, + "decimal" => proc { |number| BigDecimal(number) }, + "boolean" => proc { |boolean| !%w[0 false].include?(boolean.strip) }, + "string" => proc { |string| string.to_s }, + "yaml" => proc { |yaml| YAML.load(yaml) rescue yaml }, # rubocop:disable Style/RescueModifier + "base64Binary" => proc { |binary| base64_decode(binary) }, + "binary" => proc { |binary, entity| parse_binary(binary, entity) }, + "file" => proc { |file, entity| parse_file(file, entity) } + }.freeze + end + + unless defined?(TYPE_NAMES) + TYPE_NAMES = { + "Symbol" => "symbol", + "Integer" => "integer", + "BigDecimal" => "decimal", + "Float" => "float", + "TrueClass" => "boolean", + "FalseClass" => "boolean", + "Date" => "date", + "DateTime" => "datetime", + "Time" => "datetime", + "Array" => "array", + "Hash" => "hash" + }.freeze + end + + DISALLOWED_XML_TYPES = %w[symbol yaml].freeze + + DEFAULT_OPTIONS = { + typecast_xml_value: true, + disallowed_types: DISALLOWED_XML_TYPES, + symbolize_keys: false + }.freeze + + class << self + # Get the current parser class. + def parser + return @parser if defined?(@parser) + + self.parser = default_parser + @parser + end + + # The default parser based on what you currently + # have loaded and installed. First checks to see + # if any parsers are already loaded, then checks + # to see which are installed if none are loaded. + def default_parser + return :ox if defined?(::Ox) + return :libxml if defined?(::LibXML) + return :nokogiri if defined?(::Nokogiri) + return :oga if defined?(::Oga) + + REQUIREMENT_MAP.each do |library, parser| + require library + return parser + rescue LoadError + next + end + raise(NoParserError, + "No XML parser detected. If you're using Rubinius and Bundler, try adding an XML parser to your Gemfile (e.g. libxml-ruby, nokogiri, or rubysl-rexml). For more information, see https://github.com/sferik/multi_xml/issues/42.") + end + + # Set the XML parser utilizing a symbol, string, or class. + # Supported by default are: + # + # * :libxml + # * :nokogiri + # * :ox + # * :rexml + # * :oga + def parser=(new_parser) + case new_parser + when String, Symbol + require "multi_xml/parsers/#{new_parser.to_s.downcase}" + @parser = MultiXml::Parsers.const_get(new_parser.to_s.split("_").collect(&:capitalize).join.to_s) + when Class, Module + @parser = new_parser + else + raise("Did not recognize your parser specification. Please specify either a symbol or a class.") + end + end + + # Parse an XML string or IO into Ruby. + # + # Options + # + # :symbolize_keys :: If true, will use symbols instead of strings for the keys. + # + # :disallowed_types :: Types to disallow from being typecasted. Defaults to `['yaml', 'symbol']`. Use `[]` to allow all types. + # + # :typecast_xml_value :: If true, won't typecast values for parsed document + def parse(xml, options = {}) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity + xml ||= "" + + options = DEFAULT_OPTIONS.merge(options) + + xml = xml.strip if xml.respond_to?(:strip) + begin + xml = StringIO.new(xml) unless xml.respond_to?(:read) + + char = xml.getc + return {} if char.nil? + + xml.ungetc(char) + + hash = undasherize_keys(parser.parse(xml) || {}) + hash = typecast_xml_value(hash, options[:disallowed_types]) if options[:typecast_xml_value] + rescue DisallowedTypeError + raise + rescue parser.parse_error => e + raise(ParseError, e.message, e.backtrace) + end + hash = symbolize_keys(hash) if options[:symbolize_keys] + hash + end + + # This module decorates files with the original_filename + # and content_type methods. + module FileLike # :nodoc: + attr_writer :original_filename, :content_type + + def original_filename + @original_filename || "untitled" + end + + def content_type + @content_type || "application/octet-stream" + end + end + + private + + # TODO: Add support for other encodings + def parse_binary(binary, entity) # :nodoc: + case entity["encoding"] + when "base64" + base64_decode(binary) + else + binary + end + end + + def parse_file(file, entity) + f = StringIO.new(base64_decode(file)) + f.extend(FileLike) + f.original_filename = entity["name"] + f.content_type = entity["content_type"] + f + end + + def base64_decode(input) + input.unpack1("m") + end + + def symbolize_keys(params) + case params + when Hash + params.inject({}) do |result, (key, value)| + result.merge(key.to_sym => symbolize_keys(value)) + end + when Array + params.collect { |value| symbolize_keys(value) } + else + params + end + end + + def undasherize_keys(params) + case params + when Hash + params.each_with_object({}) do |(key, value), hash| + hash[key.to_s.tr("-", "_")] = undasherize_keys(value) + hash + end + when Array + params.collect { |value| undasherize_keys(value) } + else + params + end + end + + def typecast_xml_value(value, disallowed_types = nil) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity + disallowed_types ||= DISALLOWED_XML_TYPES + + case value + when Hash + if value.include?("type") && !value["type"].is_a?(Hash) && disallowed_types.include?(value["type"]) + raise(DisallowedTypeError, value["type"]) + end + + if value["type"] == "array" + + # this commented-out suggestion helps to avoid the multiple attribute + # problem, but it breaks when there is only one item in the array. + # + # from: https://github.com/jnunemaker/httparty/issues/102 + # + # _, entries = value.detect { |k, v| k != 'type' && v.is_a?(Array) } + + # This attempt fails to consider the order that the detect method + # retrieves the entries. + # _, entries = value.detect {|key, _| key != 'type'} + + # This approach ignores attribute entries that are not convertable + # to an Array which allows attributes to be ignored. + _, entries = value.detect { |k, v| k != "type" && (v.is_a?(Array) || v.is_a?(Hash)) } + + case entries + when NilClass + [] + when String + [] if entries.strip.empty? + when Array + entries.collect { |entry| typecast_xml_value(entry, disallowed_types) } + when Hash + [typecast_xml_value(entries, disallowed_types)] + else + raise("can't typecast #{entries.class.name}: #{entries.inspect}") + end + + elsif value.key?(CONTENT_ROOT) + content = value[CONTENT_ROOT] + block = PARSING[value["type"]] + if block + if block.arity == 1 + value.delete("type") if PARSING[value["type"]] + if value.keys.size > 1 + value[CONTENT_ROOT] = block.call(content) + value + else + block.call(content) + end + else + block.call(content, value) + end + else + (value.keys.size > 1) ? value : content + end + elsif value["type"] == "string" && value["nil"] != "true" + "" + # blank or nil parsed values are represented by nil + elsif value.empty? || value["nil"] == "true" + nil + # If the type is the only element which makes it then + # this still makes the value nil, except if type is + # a XML node(where type['value'] is a Hash) + elsif value["type"] && value.size == 1 && !value["type"].is_a?(Hash) + nil + else + xml_value = value.each_with_object({}) do |(k, v), hash| + hash[k] = typecast_xml_value(v, disallowed_types) + hash + end + + # Turn {:files => {:file => #} into {:files => #} so it is compatible with + # how multipart uploaded files from HTML appear + (xml_value["file"].is_a?(StringIO)) ? xml_value["file"] : xml_value + end + when Array + value.map! { |i| typecast_xml_value(i, disallowed_types) } + (value.length > 1) ? value : value.first + when String + value + else + raise("can't typecast #{value.class.name}: #{value.inspect}") + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/lib/multi_xml/parsers/libxml.rb b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/lib/multi_xml/parsers/libxml.rb new file mode 100644 index 0000000..79ddc20 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/lib/multi_xml/parsers/libxml.rb @@ -0,0 +1,33 @@ +require "libxml" unless defined?(LibXML) +require "multi_xml/parsers/libxml2_parser" + +module MultiXml + module Parsers + module Libxml # :nodoc: + include Libxml2Parser + extend self + + def parse_error + ::LibXML::XML::Error + end + + def parse(xml) + node_to_hash(LibXML::XML::Parser.io(xml).parse.root) + end + + private + + def each_child(node, &) + node.each_child(&) + end + + def each_attr(node, &) + node.each_attr(&) + end + + def node_name(node) + node.name + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/lib/multi_xml/parsers/libxml2_parser.rb b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/lib/multi_xml/parsers/libxml2_parser.rb new file mode 100644 index 0000000..d94caed --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/lib/multi_xml/parsers/libxml2_parser.rb @@ -0,0 +1,70 @@ +module MultiXml + module Parsers + module Libxml2Parser # :nodoc: + # Convert XML document to hash + # + # node:: + # The XML node object to convert to a hash. + # + # hash:: + # Hash to merge the converted element into. + def node_to_hash(node, hash = {}) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength + node_hash = {MultiXml::CONTENT_ROOT => ""} + + name = node_name(node) + + # Insert node hash into parent hash correctly. + case hash[name] + when Array + hash[name] << node_hash + when Hash + hash[name] = [hash[name], node_hash] + when NilClass + hash[name] = node_hash + end + + # Handle child elements + each_child(node) do |c| + if c.element? + node_to_hash(c, node_hash) + elsif c.text? || c.cdata? + node_hash[MultiXml::CONTENT_ROOT] += c.content + end + end + + # Remove content node if it is empty + node_hash.delete(MultiXml::CONTENT_ROOT) if node_hash[MultiXml::CONTENT_ROOT].strip.empty? + + # Handle attributes + each_attr(node) do |a| + key = node_name(a) + v = node_hash[key] + node_hash[key] = ((v) ? [a.value, v] : a.value) + end + + hash + end + + # Parse an XML Document IO into a simple hash. + # xml:: + # XML Document IO to parse + def parse(_) + raise(NotImplementedError, "inheritor should define #{__method__}") + end + + private + + def each_child(*) + raise(NotImplementedError, "inheritor should define #{__method__}") + end + + def each_attr(*) + raise(NotImplementedError, "inheritor should define #{__method__}") + end + + def node_name(*) + raise(NotImplementedError, "inheritor should define #{__method__}") + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/lib/multi_xml/parsers/nokogiri.rb b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/lib/multi_xml/parsers/nokogiri.rb new file mode 100644 index 0000000..67a02bc --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/lib/multi_xml/parsers/nokogiri.rb @@ -0,0 +1,36 @@ +require "nokogiri" unless defined?(Nokogiri) +require "multi_xml/parsers/libxml2_parser" + +module MultiXml + module Parsers + module Nokogiri # :nodoc: + include Libxml2Parser + extend self + + def parse_error + ::Nokogiri::XML::SyntaxError + end + + def parse(xml) + doc = ::Nokogiri::XML(xml) + raise(doc.errors.first) unless doc.errors.empty? + + node_to_hash(doc.root) + end + + private + + def each_child(node, &) + node.children.each(&) + end + + def each_attr(node, &) + node.attribute_nodes.each(&) + end + + def node_name(node) + node.node_name + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/lib/multi_xml/parsers/oga.rb b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/lib/multi_xml/parsers/oga.rb new file mode 100644 index 0000000..9d30b2a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/lib/multi_xml/parsers/oga.rb @@ -0,0 +1,71 @@ +require "oga" unless defined?(Oga) +require "multi_xml/parsers/libxml2_parser" + +module MultiXml + module Parsers + module Oga # :nodoc: + include Libxml2Parser + extend self + + def parse_error + LL::ParserError + end + + def parse(io) + document = ::Oga.parse_xml(io) + node_to_hash(document.children[0]) + end + + def node_to_hash(node, hash = {}) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength + node_hash = {MultiXml::CONTENT_ROOT => ""} + + name = node_name(node) + + # Insert node hash into parent hash correctly. + case hash[name] + when Array + hash[name] << node_hash + when Hash + hash[name] = [hash[name], node_hash] + when NilClass + hash[name] = node_hash + end + + # Handle child elements + each_child(node) do |c| + if c.is_a?(::Oga::XML::Element) + node_to_hash(c, node_hash) + elsif c.is_a?(::Oga::XML::Text) || c.is_a?(::Oga::XML::Cdata) + node_hash[MultiXml::CONTENT_ROOT] += c.text + end + end + + # Remove content node if it is empty + node_hash.delete(MultiXml::CONTENT_ROOT) if node_hash[MultiXml::CONTENT_ROOT].strip.empty? + + # Handle attributes + each_attr(node) do |a| + key = node_name(a) + v = node_hash[key] + node_hash[key] = ((v) ? [a.value, v] : a.value) + end + + hash + end + + private + + def each_child(node, &) + node.children.each(&) + end + + def each_attr(node, &) + node.attributes.each(&) + end + + def node_name(node) + node.name + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/lib/multi_xml/parsers/ox.rb b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/lib/multi_xml/parsers/ox.rb new file mode 100644 index 0000000..2679a06 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/lib/multi_xml/parsers/ox.rb @@ -0,0 +1,91 @@ +require "ox" unless defined?(Ox) + +# Each MultiXml parser is expected to parse an XML document into a Hash. The +# conversion rules are: +# +# - Each document starts out as an empty Hash. +# +# - Reading an element created an entry in the parent Hash that has a key of +# the element name and a value of a Hash with attributes as key value +# pairs. Children are added as described by this rule. +# +# - Text and CDATE is stored in the parent element Hash with a key of +# MultiXml::CONTENT_ROOT and a value of the text itself. +# +# - If a key already exists in the Hash then the value associated with the key +# is converted to an Array with the old and new value in it. +# +# - Other elements such as the xml prolog, doctype, and comments are ignored. +# + +module MultiXml + module Parsers + module Ox # :nodoc: + module_function + + def parse_error + Exception + end + + def parse(io) + handler = Handler.new + ::Ox.sax_parse(handler, io, convert_special: true, skip: :skip_return) + handler.doc + end + + class Handler + attr_accessor :stack + + def initialize + @stack = [] + end + + def doc + @stack[0] + end + + def attr(name, value) + append(name, value) unless @stack.empty? + end + + def text(value) + append(MultiXml::CONTENT_ROOT, value) + end + + def cdata(value) + append(MultiXml::CONTENT_ROOT, value) + end + + def start_element(name) + @stack.push({}) if @stack.empty? + h = {} + append(name, h) + @stack.push(h) + end + + def end_element(_) + @stack.pop + end + + def error(message, line, column) + raise(StandardError, "#{message} at #{line}:#{column}") + end + + def append(key, value) + key = key.to_s + h = @stack.last + if h.key?(key) + v = h[key] + if v.is_a?(Array) + v << value + else + h[key] = [v, value] + end + else + h[key] = value + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/lib/multi_xml/parsers/rexml.rb b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/lib/multi_xml/parsers/rexml.rb new file mode 100644 index 0000000..2c09fea --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/lib/multi_xml/parsers/rexml.rb @@ -0,0 +1,113 @@ +require "rexml/document" unless defined?(REXML::Document) + +module MultiXml + module Parsers + module Rexml # :nodoc: + extend self + + def parse_error + ::REXML::ParseException + end + + # Parse an XML Document IO into a simple hash using REXML + # + # xml:: + # XML Document IO to parse + def parse(xml) + doc = REXML::Document.new(xml) + raise(REXML::ParseException, "The document #{doc.to_s.inspect} does not have a valid root") unless doc.root + + merge_element!({}, doc.root) + end + + private + + # Convert an XML element and merge into the hash + # + # hash:: + # Hash to merge the converted element into. + # element:: + # XML element to merge into hash + def merge_element!(hash, element) + merge!(hash, element.name, collapse(element)) + end + + # Actually converts an XML document element into a data structure. + # + # element:: + # The document element to be collapsed. + def collapse(element) + hash = get_attributes(element) + + if element.has_elements? + element.each_element { |child| merge_element!(hash, child) } + merge_texts!(hash, element) unless empty_content?(element) + hash + else + merge_texts!(hash, element) + end + end + + # Merge all the texts of an element into the hash + # + # hash:: + # Hash to add the converted element to. + # element:: + # XML element whose texts are to me merged into the hash + def merge_texts!(hash, element) + if element.has_text? + # must use value to prevent double-escaping + texts = element.texts.map(&:value).join + merge!(hash, MultiXml::CONTENT_ROOT, texts) + else + hash + end + end + + # Adds a new key/value pair to an existing Hash. If the key to be added + # already exists and the existing value associated with key is not + # an Array, it will be wrapped in an Array. Then the new value is + # appended to that Array. + # + # hash:: + # Hash to add key/value pair to. + # key:: + # Key to be added. + # value:: + # Value to be associated with key. + def merge!(hash, key, value) + if hash.key?(key) + if hash[key].instance_of?(Array) + hash[key] << value + else + hash[key] = [hash[key], value] + end + elsif value.instance_of?(Array) + hash[key] = [value] + else + hash[key] = value + end + hash + end + + # Converts the attributes array of an XML element into a hash. + # Returns an empty Hash if node has no attributes. + # + # element:: + # XML element to extract attributes from. + def get_attributes(element) + attributes = {} + element.attributes.each { |n, v| attributes[n] = v } + attributes + end + + # Determines if a document element has text content + # + # element:: + # XML element to be checked. + def empty_content?(element) + element.texts.join.strip.empty? + end + end + end +end diff --git a/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/lib/multi_xml/version.rb b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/lib/multi_xml/version.rb new file mode 100644 index 0000000..71d2ab1 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/multi_xml-0.7.2/lib/multi_xml/version.rb @@ -0,0 +1,3 @@ +module MultiXml + VERSION = Gem::Version.create("0.7.2") +end diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/Gemfile b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/Gemfile new file mode 100644 index 0000000..affe3ac --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/Gemfile @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gemspec + +group :development do + # bootstrapping + gem "bundler", "~> 2.3" + gem "rake", "13.2.1" + + # building extensions + gem "rake-compiler", "1.2.8" + gem "rake-compiler-dock", "1.7.0" + + # parser generator + gem "rexical", "1.0.8" + + # tests + gem "minitest", "5.25.4" + gem "minitest-parallel_fork", "2.0.0" + gem "ruby_memcheck", "3.0.0" + gem "rubyzip", "~> 2.3.2" + gem "simplecov", "= 0.21.2" + + # rubocop + unless RUBY_PLATFORM == "java" + gem "standard", "1.43.0" + gem "rubocop-minitest", "0.36.0" + gem "rubocop-packaging", "0.5.2" + gem "rubocop-rake", "0.6.0" + end +end + +# If Psych doesn't build, you can disable this group locally by running +# `bundle config set --local without rdoc` +# Then re-run `bundle install`. +group :rdoc do + gem "rdoc", "6.10.0" unless RUBY_PLATFORM == "java" || ENV["CI"] +end diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/LICENSE-DEPENDENCIES.md b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/LICENSE-DEPENDENCIES.md new file mode 100644 index 0000000..1e950b6 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/LICENSE-DEPENDENCIES.md @@ -0,0 +1,2224 @@ +# Vendored Dependency Licenses + +Nokogiri ships with some third party dependencies, which are listed here along with their licenses. + +Note that this document is broken into multiple sections, each of which describes the dependencies of a different "platform release" of Nokogiri. + + + + + +- [Platform Releases](#platform-releases) + * [Default platform release ("ruby")](#default-platform-release-ruby) + * [Native LinuxⓇ platform releases ("x86_64-linux", "aarch64-linux", and "arm-linux")](#native-linux%E2%93%A1-platform-releases-x86_64-linux-aarch64-linux-and-arm-linux) + * [Native Darwin (macOSⓇ) platform releases ("x86_64-darwin" and "arm64-darwin")](#native-darwin-macos%E2%93%A1-platform-releases-x86_64-darwin-and-arm64-darwin) + * [Native WindowsⓇ platform releases ("x64-mingw-ucrt")](#native-windows%E2%93%A1-platform-releases-x64-mingw-ucrt) + * [JavaⓇ (JRuby) platform release ("java")](#java%E2%93%A1-jruby-platform-release-java) +- [Appendix: Dependencies' License Texts](#appendix-dependencies-license-texts) + * [libgumbo](#libgumbo) + * [libxml2](#libxml2) + * [libxslt](#libxslt) + * [zlib](#zlib) + * [libiconv](#libiconv) + * [isorelax:isorelax](#isorelaxisorelax) + * [net.sf.saxon:Saxon-HE](#netsfsaxonsaxon-he) + * [net.sourceforge.htmlunit:neko-htmlunit](#netsourceforgehtmlunitneko-htmlunit) + * [nu.validator:jing](#nuvalidatorjing) + * [org.nokogiri:nekodtd](#orgnokogirinekodtd) + * [xalan:serializer and xalan:xalan](#xalanserializer-and-xalanxalan) + * [xerces:xercesImpl](#xercesxercesimpl) + * [xml-apis:xml-apis](#xml-apisxml-apis) + + + +Anyone consuming this file via license-tracking software should endeavor to understand which gem file you're downloading and using, so as not to misinterpret the contents of this file and the licenses of the software being distributed. + +You can double-check the dependencies in your gem file by examining the output of `nokogiri -v` after installation, which will emit the complete set of libraries in use (for versions `>= 1.11.0.rc4`). + +In particular, I'm sure somebody's lawyer, somewhere, is going to freak out that the LGPL appears in this file; and so I'd like to take special note that the dependency covered by LGPL, `libiconv`, is only being redistributed in the native Windows and native Darwin platform releases. It's not present in default, JavaⓇ, or native LinuxⓇ releases. + + +## Platform Releases + +### Default platform release ("ruby") + +The default platform release distributes the following dependencies in source form: + +* [libxml2](#libxml2) +* [libxslt](#libxslt) +* [libgumbo](#libgumbo) + +This distribution can be identified by inspecting the included Gem::Specification, which will have the value "ruby" for its "platform" attribute. + + +### Native LinuxⓇ platform releases ("x86_64-linux", "aarch64-linux", and "arm-linux") + +The native LinuxⓇ platform release distributes the following dependencies in source form: + +* [libxml2](#libxml2) +* [libxslt](#libxslt) +* [libgumbo](#libgumbo) +* [zlib](#zlib) + +This distribution can be identified by inspecting the included Gem::Specification, which will have a value similar to "x86_64-linux" or "aarch64-linux" for its "platform.cpu" attribute. + + +### Native Darwin (macOSⓇ) platform releases ("x86_64-darwin" and "arm64-darwin") + +The native Darwin platform release distributes the following dependencies in source form: + +* [libxml2](#libxml2) +* [libxslt](#libxslt) +* [libgumbo](#libgumbo) +* [zlib](#zlib) +* [libiconv](#libiconv) + +This distribution can be identified by inspecting the included Gem::Specification, which will have a value similar to "x86_64-darwin" or "arm64-darwin" for its "platform.cpu" attribute. Darwin is also known more familiarly as "OSX" or "macOSⓇ" and is the operating system for many AppleⓇ computers. + + +### Native WindowsⓇ platform releases ("x64-mingw-ucrt") + +The native WindowsⓇ platform release distributes the following dependencies in source form: + +* [libxml2](#libxml2) +* [libxslt](#libxslt) +* [libgumbo](#libgumbo) +* [zlib](#zlib) +* [libiconv](#libiconv) + +This distribution can be identified by inspecting the included Gem::Specification, which will have a value similar to "x64-mingw-ucrt" for its "platform.cpu" attribute. + + +### JavaⓇ (JRuby) platform release ("java") + +The Java platform release distributes the following dependencies as compiled jar files: + +* [isorelax:isorelax](#isorelaxisorelax) +* [net.sf.saxon:Saxon-HE](#netsfsaxonsaxon-he) +* [net.sourceforge.htmlunit:neko-htmlunit](#netsourceforgehtmlunitneko-htmlunit) +* [nu.validator:jing](#nuvalidatorjing) +* [org.nokogiri:nekodtd](#orgnokogirinekodtd) +* [xalan:serializer and xalan:xalan](#xalanserializer-and-xalanxalan) +* [xerces:xercesImpl](#xercesxercesimpl) +* [xml-apis:xml-apis](#xml-apisxml-apis) + +This distribution can be identified by inspecting the included Gem::Specification, which will have the value "java" for its "platform.os" attribute. + + +## Appendix: Dependencies' License Texts + +This section contains a subsection for each potentially-distributed dependency, which includes the name of the license and the license text. + +Please see previous sections to understand which of these potential dependencies is actually distributed in the gem file you're downloading and using. + + +### libgumbo + +Apache 2.0 + +https://github.com/sparklemotion/nokogiri/blob/main/gumbo-parser/src/README.md + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + +### libxml2 + +MIT + +http://xmlsoft.org/ + + Except where otherwise noted in the source code (e.g. the files hash.c, + list.c and the trio files, which are covered by a similar licence but + with different Copyright notices) all the files are: + + Copyright (C) 1998-2012 Daniel Veillard. All Rights Reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is fur- + nished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- + NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + + +### libxslt + +MIT + +http://xmlsoft.org/libxslt/ + + Licence for libxslt except libexslt + ---------------------------------------------------------------------- + Copyright (C) 2001-2002 Daniel Veillard. All Rights Reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is fur- + nished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- + NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + DANIEL VEILLARD BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- + NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name of Daniel Veillard shall not + be used in advertising or otherwise to promote the sale, use or other deal- + ings in this Software without prior written authorization from him. + + ---------------------------------------------------------------------- + + Licence for libexslt + ---------------------------------------------------------------------- + Copyright (C) 2001-2002 Thomas Broyer, Charlie Bozeman and Daniel Veillard. + All Rights Reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is fur- + nished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- + NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- + NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name of the authors shall not + be used in advertising or otherwise to promote the sale, use or other deal- + ings in this Software without prior written authorization from him. + ---------------------------------------------------------------------- + + +### zlib + +zlib license + +http://www.zlib.net/zlib_license.html + + Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + +### libiconv + +LGPL + +https://www.gnu.org/software/libiconv/ + + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + [This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your + freedom to share and change it. By contrast, the GNU General Public + Licenses are intended to guarantee your freedom to share and change + free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some + specially designated Free Software Foundation software, and to any + other libraries whose authors decide to use it. You can use it for + your libraries, too. + + When we speak of free software, we are referring to freedom, not + price. Our General Public Licenses are designed to make sure that you + have the freedom to distribute copies of free software (and charge for + this service if you wish), that you receive source code or can get it + if you want it, that you can change the software or use pieces of it + in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid + anyone to deny you these rights or to ask you to surrender the rights. + These restrictions translate to certain responsibilities for you if + you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis + or for a fee, you must give the recipients all the rights that we gave + you. You must make sure that they, too, receive or can get the source + code. If you link a program with the library, you must provide + complete object files to the recipients so that they can relink them + with the library, after making changes to the library and recompiling + it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright + the library, and (2) offer you this license which gives you legal + permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain + that everyone understands that there is no warranty for this free + library. If the library is modified by someone else and passed on, we + want its recipients to know that what they have is not the original + version, so that any problems introduced by others will not reflect on + the original authors' reputations. + + Finally, any free program is threatened constantly by software + patents. We wish to avoid the danger that companies distributing free + software will individually obtain patent licenses, thus in effect + transforming the program into proprietary software. To prevent this, + we have made it clear that any patent must be licensed for everyone's + free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary + GNU General Public License, which was designed for utility programs. This + license, the GNU Library General Public License, applies to certain + designated libraries. This license is quite different from the ordinary + one; be sure to read it in full, and don't assume that anything in it is + the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that + they blur the distinction we usually make between modifying or adding to a + program and simply using it. Linking a program with a library, without + changing the library, is in some sense simply using the library, and is + analogous to running a utility program or application program. However, in + a textual and legal sense, the linked executable is a combined work, a + derivative of the original library, and the ordinary General Public License + treats it as such. + + Because of this blurred distinction, using the ordinary General + Public License for libraries did not effectively promote software + sharing, because most developers did not use the libraries. We + concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the + users of those programs of all benefit from the free status of the + libraries themselves. This Library General Public License is intended to + permit developers of non-free programs to use free libraries, while + preserving your freedom as a user of such programs to change the free + libraries that are incorporated in them. (We have not seen how to achieve + this as regards changes in header files, but we have achieved it as regards + changes in the actual functions of the Library.) The hope is that this + will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and + modification follow. Pay close attention to the difference between a + "work based on the library" and a "work that uses the library". The + former contains code derived from the library, while the latter only + works together with the library. + + Note that it is possible for a library to be covered by the ordinary + General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which + contains a notice placed by the copyright holder or other authorized + party saying it may be distributed under the terms of this Library + General Public License (also called "this License"). Each licensee is + addressed as "you". + + A "library" means a collection of software functions and/or data + prepared so as to be conveniently linked with application programs + (which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work + which has been distributed under these terms. A "work based on the + Library" means either the Library or any derivative work under + copyright law: that is to say, a work containing the Library or a + portion of it, either verbatim or with modifications and/or translated + straightforwardly into another language. (Hereinafter, translation is + included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for + making modifications to it. For a library, complete source code means + all the source code for all modules it contains, plus any associated + interface definition files, plus the scripts used to control compilation + and installation of the library. + + Activities other than copying, distribution and modification are not + covered by this License; they are outside its scope. The act of + running a program using the Library is not restricted, and output from + such a program is covered only if its contents constitute a work based + on the Library (independent of the use of the Library in a tool for + writing it). Whether that is true depends on what the Library does + and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's + complete source code as you receive it, in any medium, provided that + you conspicuously and appropriately publish on each copy an + appropriate copyright notice and disclaimer of warranty; keep intact + all the notices that refer to this License and to the absence of any + warranty; and distribute a copy of this License along with the + Library. + + You may charge a fee for the physical act of transferring a copy, + and you may at your option offer warranty protection in exchange for a + fee. + + 2. You may modify your copy or copies of the Library or any portion + of it, thus forming a work based on the Library, and copy and + distribute such modifications or work under the terms of Section 1 + above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + + These requirements apply to the modified work as a whole. If + identifiable sections of that work are not derived from the Library, + and can be reasonably considered independent and separate works in + themselves, then this License, and its terms, do not apply to those + sections when you distribute them as separate works. But when you + distribute the same sections as part of a whole which is a work based + on the Library, the distribution of the whole must be on the terms of + this License, whose permissions for other licensees extend to the + entire whole, and thus to each and every part regardless of who wrote + it. + + Thus, it is not the intent of this section to claim rights or contest + your rights to work written entirely by you; rather, the intent is to + exercise the right to control the distribution of derivative or + collective works based on the Library. + + In addition, mere aggregation of another work not based on the Library + with the Library (or with a work based on the Library) on a volume of + a storage or distribution medium does not bring the other work under + the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public + License instead of this License to a given copy of the Library. To do + this, you must alter all the notices that refer to this License, so + that they refer to the ordinary GNU General Public License, version 2, + instead of to this License. (If a newer version than version 2 of the + ordinary GNU General Public License has appeared, then you can specify + that version instead if you wish.) Do not make any other change in + these notices. + + Once this change is made in a given copy, it is irreversible for + that copy, so the ordinary GNU General Public License applies to all + subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of + the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or + derivative of it, under Section 2) in object code or executable form + under the terms of Sections 1 and 2 above provided that you accompany + it with the complete corresponding machine-readable source code, which + must be distributed under the terms of Sections 1 and 2 above on a + medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy + from a designated place, then offering equivalent access to copy the + source code from the same place satisfies the requirement to + distribute the source code, even though third parties are not + compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the + Library, but is designed to work with the Library by being compiled or + linked with it, is called a "work that uses the Library". Such a + work, in isolation, is not a derivative work of the Library, and + therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library + creates an executable that is a derivative of the Library (because it + contains portions of the Library), rather than a "work that uses the + library". The executable is therefore covered by this License. + Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file + that is part of the Library, the object code for the work may be a + derivative work of the Library even though the source code is not. + Whether this is true is especially significant if the work can be + linked without the Library, or if the work is itself a library. The + threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data + structure layouts and accessors, and small macros and small inline + functions (ten lines or less in length), then the use of the object + file is unrestricted, regardless of whether it is legally a derivative + work. (Executables containing this object code plus portions of the + Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may + distribute the object code for the work under the terms of Section 6. + Any executables containing that work also fall under Section 6, + whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or + link a "work that uses the Library" with the Library to produce a + work containing portions of the Library, and distribute that work + under terms of your choice, provided that the terms permit + modification of the work for the customer's own use and reverse + engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the + Library is used in it and that the Library and its use are covered by + this License. You must supply a copy of this License. If the work + during execution displays copyright notices, you must include the + copyright notice for the Library among them, as well as a reference + directing the user to the copy of this License. Also, you must do one + of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the + Library" must include any data and utility programs needed for + reproducing the executable from it. However, as a special exception, + the source code distributed need not include anything that is normally + distributed (in either source or binary form) with the major + components (compiler, kernel, and so on) of the operating system on + which the executable runs, unless that component itself accompanies + the executable. + + It may happen that this requirement contradicts the license + restrictions of other proprietary libraries that do not normally + accompany the operating system. Such a contradiction means you cannot + use both them and the Library together in an executable that you + distribute. + + 7. You may place library facilities that are a work based on the + Library side-by-side in a single library together with other library + facilities not covered by this License, and distribute such a combined + library, provided that the separate distribution of the work based on + the Library and of the other library facilities is otherwise + permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute + the Library except as expressly provided under this License. Any + attempt otherwise to copy, modify, sublicense, link with, or + distribute the Library is void, and will automatically terminate your + rights under this License. However, parties who have received copies, + or rights, from you under this License will not have their licenses + terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not + signed it. However, nothing else grants you permission to modify or + distribute the Library or its derivative works. These actions are + prohibited by law if you do not accept this License. Therefore, by + modifying or distributing the Library (or any work based on the + Library), you indicate your acceptance of this License to do so, and + all its terms and conditions for copying, distributing or modifying + the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the + Library), the recipient automatically receives a license from the + original licensor to copy, distribute, link with or modify the Library + subject to these terms and conditions. You may not impose any further + restrictions on the recipients' exercise of the rights granted herein. + You are not responsible for enforcing compliance by third parties to + this License. + + 11. If, as a consequence of a court judgment or allegation of patent + infringement or for any other reason (not limited to patent issues), + conditions are imposed on you (whether by court order, agreement or + otherwise) that contradict the conditions of this License, they do not + excuse you from the conditions of this License. If you cannot + distribute so as to satisfy simultaneously your obligations under this + License and any other pertinent obligations, then as a consequence you + may not distribute the Library at all. For example, if a patent + license would not permit royalty-free redistribution of the Library by + all those who receive copies directly or indirectly through you, then + the only way you could satisfy both it and this License would be to + refrain entirely from distribution of the Library. + + If any portion of this section is held invalid or unenforceable under any + particular circumstance, the balance of the section is intended to apply, + and the section as a whole is intended to apply in other circumstances. + + It is not the purpose of this section to induce you to infringe any + patents or other property right claims or to contest validity of any + such claims; this section has the sole purpose of protecting the + integrity of the free software distribution system which is + implemented by public license practices. Many people have made + generous contributions to the wide range of software distributed + through that system in reliance on consistent application of that + system; it is up to the author/donor to decide if he or she is willing + to distribute software through any other system and a licensee cannot + impose that choice. + + This section is intended to make thoroughly clear what is believed to + be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in + certain countries either by patents or by copyrighted interfaces, the + original copyright holder who places the Library under this License may add + an explicit geographical distribution limitation excluding those countries, + so that distribution is permitted only in or among countries not thus + excluded. In such case, this License incorporates the limitation as if + written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new + versions of the Library General Public License from time to time. + Such new versions will be similar in spirit to the present version, + but may differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the Library + specifies a version number of this License which applies to it and + "any later version", you have the option of following the terms and + conditions either of that version or of any later version published by + the Free Software Foundation. If the Library does not specify a + license version number, you may choose any version ever published by + the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free + programs whose distribution conditions are incompatible with these, + write to the author to ask for permission. For software which is + copyrighted by the Free Software Foundation, write to the Free + Software Foundation; we sometimes make exceptions for this. Our + decision will be guided by the two goals of preserving the free status + of all derivatives of our free software and of promoting the sharing + and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO + WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. + EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR + OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE + LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME + THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN + WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY + AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU + FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR + CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE + LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING + RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A + FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF + SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + DAMAGES. + + END OF TERMS AND CONDITIONS + + +### isorelax:isorelax + +MIT + +http://iso-relax.sourceforge.net/ + + Copyright (c) 2001-2002, SourceForge ISO-RELAX Project (ASAMI + Tomoharu, Daisuke Okajima, Kohsuke Kawaguchi, and MURATA Makoto) + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +### net.sf.saxon:Saxon-HE + +MPL 2.0 + +http://www.saxonica.com/ + + Mozilla Public License Version 2.0 + ================================== + + 1. Definitions + -------------- + + 1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + + 1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + + 1.3. "Contribution" + means Covered Software of a particular Contributor. + + 1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + + 1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + + 1.6. "Executable Form" + means any form of the work other than Source Code Form. + + 1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + + 1.8. "License" + means this document. + + 1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + + 1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + + 1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + + 1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + + 1.13. "Source Code Form" + means the form of the work preferred for making modifications. + + 1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + + 2. License Grants and Conditions + -------------------------------- + + 2.1. Grants + + Each Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: + + (a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + + (b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + + 2.2. Effective Date + + The licenses granted in Section 2.1 with respect to any Contribution + become effective for each Contribution on the date the Contributor first + distributes such Contribution. + + 2.3. Limitations on Grant Scope + + The licenses granted in this Section 2 are the only rights granted under + this License. No additional rights or licenses will be implied from the + distribution or licensing of Covered Software under this License. + Notwithstanding Section 2.1(b) above, no patent license is granted by a + Contributor: + + (a) for any code that a Contributor has removed from Covered Software; + or + + (b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + + (c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + + This License does not grant any rights in the trademarks, service marks, + or logos of any Contributor (except as may be necessary to comply with + the notice requirements in Section 3.4). + + 2.4. Subsequent Licenses + + No Contributor makes additional grants as a result of Your choice to + distribute the Covered Software under a subsequent version of this + License (see Section 10.2) or under the terms of a Secondary License (if + permitted under the terms of Section 3.3). + + 2.5. Representation + + Each Contributor represents that the Contributor believes its + Contributions are its original creation(s) or it has sufficient rights + to grant the rights to its Contributions conveyed by this License. + + 2.6. Fair Use + + This License is not intended to limit any rights You have under + applicable copyright doctrines of fair use, fair dealing, or other + equivalents. + + 2.7. Conditions + + Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted + in Section 2.1. + + 3. Responsibilities + ------------------- + + 3.1. Distribution of Source Form + + All distribution of Covered Software in Source Code Form, including any + Modifications that You create or to which You contribute, must be under + the terms of this License. You must inform recipients that the Source + Code Form of the Covered Software is governed by the terms of this + License, and how they can obtain a copy of this License. You may not + attempt to alter or restrict the recipients' rights in the Source Code + Form. + + 3.2. Distribution of Executable Form + + If You distribute Covered Software in Executable Form then: + + (a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + + (b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + + 3.3. Distribution of a Larger Work + + You may create and distribute a Larger Work under terms of Your choice, + provided that You also comply with the requirements of this License for + the Covered Software. If the Larger Work is a combination of Covered + Software with a work governed by one or more Secondary Licenses, and the + Covered Software is not Incompatible With Secondary Licenses, this + License permits You to additionally distribute such Covered Software + under the terms of such Secondary License(s), so that the recipient of + the Larger Work may, at their option, further distribute the Covered + Software under the terms of either this License or such Secondary + License(s). + + 3.4. Notices + + You may not remove or alter the substance of any license notices + (including copyright notices, patent notices, disclaimers of warranty, + or limitations of liability) contained within the Source Code Form of + the Covered Software, except that You may alter any license notices to + the extent required to remedy known factual inaccuracies. + + 3.5. Application of Additional Terms + + You may choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of Covered + Software. However, You may do so only on Your own behalf, and not on + behalf of any Contributor. You must make it absolutely clear that any + such warranty, support, indemnity, or liability obligation is offered by + You alone, and You hereby agree to indemnify every Contributor for any + liability incurred by such Contributor as a result of warranty, support, + indemnity or liability terms You offer. You may include additional + disclaimers of warranty and limitations of liability specific to any + jurisdiction. + + 4. Inability to Comply Due to Statute or Regulation + --------------------------------------------------- + + If it is impossible for You to comply with any of the terms of this + License with respect to some or all of the Covered Software due to + statute, judicial order, or regulation then You must: (a) comply with + the terms of this License to the maximum extent possible; and (b) + describe the limitations and the code they affect. Such description must + be placed in a text file included with all distributions of the Covered + Software under this License. Except to the extent prohibited by statute + or regulation, such description must be sufficiently detailed for a + recipient of ordinary skill to be able to understand it. + + 5. Termination + -------------- + + 5.1. The rights granted under this License will terminate automatically + if You fail to comply with any of its terms. However, if You become + compliant, then the rights granted under this License from a particular + Contributor are reinstated (a) provisionally, unless and until such + Contributor explicitly and finally terminates Your grants, and (b) on an + ongoing basis, if such Contributor fails to notify You of the + non-compliance by some reasonable means prior to 60 days after You have + come back into compliance. Moreover, Your grants from a particular + Contributor are reinstated on an ongoing basis if such Contributor + notifies You of the non-compliance by some reasonable means, this is the + first time You have received notice of non-compliance with this License + from such Contributor, and You become compliant prior to 30 days after + Your receipt of the notice. + + 5.2. If You initiate litigation against any entity by asserting a patent + infringement claim (excluding declaratory judgment actions, + counter-claims, and cross-claims) alleging that a Contributor Version + directly or indirectly infringes any patent, then the rights granted to + You by any and all Contributors for the Covered Software under Section + 2.1 of this License shall terminate. + + 5.3. In the event of termination under Sections 5.1 or 5.2 above, all + end user license agreements (excluding distributors and resellers) which + have been validly granted by You or Your distributors under this License + prior to termination shall survive termination. + + ************************************************************************ + * * + * 6. Disclaimer of Warranty * + * ------------------------- * + * * + * Covered Software is provided under this License on an "as is" * + * basis, without warranty of any kind, either expressed, implied, or * + * statutory, including, without limitation, warranties that the * + * Covered Software is free of defects, merchantable, fit for a * + * particular purpose or non-infringing. The entire risk as to the * + * quality and performance of the Covered Software is with You. * + * Should any Covered Software prove defective in any respect, You * + * (not any Contributor) assume the cost of any necessary servicing, * + * repair, or correction. This disclaimer of warranty constitutes an * + * essential part of this License. No use of any Covered Software is * + * authorized under this License except under this disclaimer. * + * * + ************************************************************************ + + ************************************************************************ + * * + * 7. Limitation of Liability * + * -------------------------- * + * * + * Under no circumstances and under no legal theory, whether tort * + * (including negligence), contract, or otherwise, shall any * + * Contributor, or anyone who distributes Covered Software as * + * permitted above, be liable to You for any direct, indirect, * + * special, incidental, or consequential damages of any character * + * including, without limitation, damages for lost profits, loss of * + * goodwill, work stoppage, computer failure or malfunction, or any * + * and all other commercial damages or losses, even if such party * + * shall have been informed of the possibility of such damages. This * + * limitation of liability shall not apply to liability for death or * + * personal injury resulting from such party's negligence to the * + * extent applicable law prohibits such limitation. Some * + * jurisdictions do not allow the exclusion or limitation of * + * incidental or consequential damages, so this exclusion and * + * limitation may not apply to You. * + * * + ************************************************************************ + + 8. Litigation + ------------- + + Any litigation relating to this License may be brought only in the + courts of a jurisdiction where the defendant maintains its principal + place of business and such litigation shall be governed by laws of that + jurisdiction, without reference to its conflict-of-law provisions. + Nothing in this Section shall prevent a party's ability to bring + cross-claims or counter-claims. + + 9. Miscellaneous + ---------------- + + This License represents the complete agreement concerning the subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. Any law or regulation which provides + that the language of a contract shall be construed against the drafter + shall not be used to construe this License against a Contributor. + + 10. Versions of the License + --------------------------- + + 10.1. New Versions + + Mozilla Foundation is the license steward. Except as provided in Section + 10.3, no one other than the license steward has the right to modify or + publish new versions of this License. Each version will be given a + distinguishing version number. + + 10.2. Effect of New Versions + + You may distribute the Covered Software under the terms of the version + of the License under which You originally received the Covered Software, + or under the terms of any subsequent version published by the license + steward. + + 10.3. Modified Versions + + If you create software not governed by this License, and you want to + create a new license for such software, you may create and use a + modified version of this License if you rename the license and remove + any references to the name of the license steward (except to note that + such modified license differs from this License). + + 10.4. Distributing Source Code Form that is Incompatible With Secondary + Licenses + + If You choose to distribute Source Code Form that is Incompatible With + Secondary Licenses under the terms of this version of the License, the + notice described in Exhibit B of this License must be attached. + + +### net.sourceforge.htmlunit:neko-htmlunit + +Apache 2.0 + +https://github.com/HtmlUnit/htmlunit-neko + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + +### nu.validator:jing + +BSD-3-Clause + +http://www.thaiopensource.com/relaxng/jing.html + + Copyright (c) 2001-2003 Thai Open Source Software Center Ltd + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of the Thai Open Source Software Center Ltd nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + +### org.nokogiri:nekodtd + +Apache 2.0 + +https://github.com/sparklemotion/nekodtd + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + +### xalan:serializer and xalan:xalan + +Apache 2.0 + +https://xml.apache.org/xalan-j/ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + +### xerces:xercesImpl + +Apache 2.0 + +https://xerces.apache.org/xerces2-j/ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + +### xml-apis:xml-apis + +Apache 2.0 + +https://xerces.apache.org/xml-commons/ + + Unless otherwise noted all files in XML Commons are covered under the + Apache License Version 2.0. Please read the LICENSE and NOTICE files. + + XML Commons contains some software and documentation that is covered + under a number of different licenses. This applies particularly to the + xml-commons/java/external/ directory. Most files under + xml-commons/java/external/ are covered under their respective + LICENSE.*.txt files; see the matching README.*.txt files for + descriptions. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/LICENSE.md b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/LICENSE.md new file mode 100644 index 0000000..b649dd8 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/LICENSE.md @@ -0,0 +1,9 @@ +The MIT License + +Copyright 2008 -- 2023 by Mike Dalessio, Aaron Patterson, Yoko Harada, Akinori MUSHA, John Shahid, Karol Bucek, Sam Ruby, Craig Barnes, Stephen Checkoway, Lars Kanis, Sergio Arbeo, Timothy Elliott, Nobuyoshi Nakada, Charles Nutter, Patrick Mahoney. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/README.md b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/README.md new file mode 100644 index 0000000..df466f4 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/README.md @@ -0,0 +1,293 @@ +
+ +# Nokogiri + +Nokogiri (鋸) makes it easy and painless to work with XML and HTML from Ruby. It provides a sensible, easy-to-understand API for [reading](https://nokogiri.org/tutorials/parsing_an_html_xml_document.html), writing, [modifying](https://nokogiri.org/tutorials/modifying_an_html_xml_document.html), and [querying](https://nokogiri.org/tutorials/searching_a_xml_html_document.html) documents. It is fast and standards-compliant by relying on native parsers like libxml2, libgumbo, and xerces. + +## Guiding Principles + +Some guiding principles Nokogiri tries to follow: + +- be secure-by-default by treating all documents as **untrusted** by default +- be a **thin-as-reasonable layer** on top of the underlying parsers, and don't attempt to fix behavioral differences between the parsers + + +## Features Overview + +- DOM Parser for XML, HTML4, and HTML5 +- SAX Parser for XML and HTML4 +- Push Parser for XML and HTML4 +- Document search via XPath 1.0 +- Document search via CSS3 selectors, with some jquery-like extensions +- XSD Schema validation +- XSLT transformation +- "Builder" DSL for XML and HTML documents + + +## Status + +[![Github Actions CI](https://github.com/sparklemotion/nokogiri/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/sparklemotion/nokogiri/actions/workflows/ci.yml) +[![Appveyor CI](https://ci.appveyor.com/api/projects/status/xj2pqwvlxwuwgr06/branch/main?svg=true)](https://ci.appveyor.com/project/flavorjones/nokogiri/branch/main) + +[![Gem Version](https://badge.fury.io/rb/nokogiri.svg)](https://rubygems.org/gems/nokogiri) +[![SemVer compatibility](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=nokogiri&package-manager=bundler&previous-version=1.11.7&new-version=1.12.5)](https://docs.github.com/en/code-security/supply-chain-security/managing-vulnerabilities-in-your-projects-dependencies/about-dependabot-security-updates#about-compatibility-scores) + +[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/5344/badge)](https://bestpractices.coreinfrastructure.org/projects/5344) +[![Tidelift dependencies](https://tidelift.com/badges/package/rubygems/nokogiri)](https://tidelift.com/subscription/pkg/rubygems-nokogiri?utm_source=rubygems-nokogiri&utm_medium=referral&utm_campaign=readme) + + +## Support, Getting Help, and Reporting Issues + +All official documentation is posted at https://nokogiri.org (the source for which is at https://github.com/sparklemotion/nokogiri.org/, and we welcome contributions). + +### Reading + +Your first stops for learning more about Nokogiri should be: + +- [API Documentation](https://nokogiri.org/rdoc/index.html) +- [Tutorials](https://nokogiri.org/tutorials/toc.html) +- An excellent community-maintained [Cheat Sheet](https://github.com/sparklemotion/nokogiri/wiki/Cheat-sheet) + + +### Ask For Help + +There are a few ways to ask exploratory questions: + +- The Nokogiri mailing list is active at https://groups.google.com/group/nokogiri-talk +- Open an issue using the "Help Request" template at https://github.com/sparklemotion/nokogiri/issues +- Open a discussion at https://github.com/sparklemotion/nokogiri/discussions + +Please do not mail the maintainers at their personal addresses. + + +### Report A Bug + +The Nokogiri bug tracker is at https://github.com/sparklemotion/nokogiri/issues + +Please use the "Bug Report" or "Installation Difficulties" templates. + + +### Security and Vulnerability Reporting + +Please report vulnerabilities at https://hackerone.com/nokogiri + +Full information and description of our security policy is in [`SECURITY.md`](SECURITY.md) + + +### Semantic Versioning Policy + +Nokogiri follows [Semantic Versioning](https://semver.org/) (since 2017 or so). [![Dependabot's SemVer compatibility score for Nokogiri](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=nokogiri&package-manager=bundler&previous-version=1.11.7&new-version=1.12.5)](https://docs.github.com/en/code-security/supply-chain-security/managing-vulnerabilities-in-your-projects-dependencies/about-dependabot-security-updates#about-compatibility-scores) + +We bump `Major.Minor.Patch` versions following this guidance: + +`Major`: (we've never done this) + +- Significant backwards-incompatible changes to the public API that would require rewriting existing application code. +- Some examples of backwards-incompatible changes we might someday consider for a Major release are at [`ROADMAP.md`](ROADMAP.md). + +`Minor`: + +- Features and bugfixes. +- Updating packaged libraries for non-security-related reasons. +- Dropping support for EOLed Ruby versions. [Some folks find this objectionable](https://github.com/sparklemotion/nokogiri/issues/1568), but [SemVer says this is OK if the public API hasn't changed](https://semver.org/#what-should-i-do-if-i-update-my-own-dependencies-without-changing-the-public-api). +- Backwards-incompatible changes to internal or private methods and constants. These are detailed in the "Changes" section of each changelog entry. +- Removal of deprecated methods or parameters, after a generous transition period; usually when those methods or parameters are rarely-used or dangerous to the user. Essentially, removals that do not justify a major version bump. + + +`Patch`: + +- Bugfixes. +- Security updates. +- Updating packaged libraries for security-related reasons. + + +### Sponsorship + +You can help sponsor the maintainers of this software through one of these organizations: + +- [github.com/sponsors/flavorjones](https://github.com/sponsors/flavorjones) +- [opencollective.com/nokogiri](https://opencollective.com/nokogiri) +- [tidelift.com/subscription/pkg/rubygems-nokogiri](https://tidelift.com/subscription/pkg/rubygems-nokogiri?utm_source=rubygems-nokogiri&utm_medium=referral&utm_campaign=readme) + + +## Installation + +Requirements: + +- Ruby >= 3.1 +- JRuby >= 9.4.0.0 + +If you are compiling the native extension against a system version of libxml2: + +- libxml2 >= 2.9.2 (recommended >= 2.12.0) + + +### Native Gems: Faster, more reliable installation + +"Native gems" contain pre-compiled libraries for a specific machine architecture. On supported platforms, this removes the need for compiling the C extension and the packaged libraries, or for system dependencies to exist. This results in **much faster installation** and **more reliable installation**, which as you probably know are the biggest headaches for Nokogiri users. + +### Supported Platforms + +Nokogiri ships pre-compiled, "native" gems for the following platforms: + +- Linux: + - `x86_64-linux-gnu`, `aarch64-linux-gnu`, and `arm-linux-gnu` (req: `glibc >= 2.29`) + - `x86_64-linux-musl`, `aarch64-linux-musl`, and `arm-linux-musl` +- Darwin/MacOS: `x86_64-darwin` and `arm64-darwin` +- Windows: `x64-mingw-ucrt` +- Java: any platform running JRuby 9.4 or higher + +To determine whether your system supports one of these gems, look at the output of `bundle platform` or `ruby -e 'puts Gem::Platform.local.to_s'`. + +If you're on a supported platform, either `gem install` or `bundle install` should install a native gem without any additional action on your part. This installation should only take a few seconds, and your output should look something like: + +``` sh +$ gem install nokogiri +Fetching nokogiri-1.11.0-x86_64-linux.gem +Successfully installed nokogiri-1.11.0-x86_64-linux +1 gem installed +``` + + +### Other Installation Options + +Because Nokogiri is a C extension, it requires that you have a C compiler toolchain, Ruby development header files, and some system dependencies installed. + +The following may work for you if you have an appropriately-configured system: + +``` bash +gem install nokogiri +``` + +If you have any issues, please visit [Installing Nokogiri](https://nokogiri.org/tutorials/installing_nokogiri.html) for more complete instructions and troubleshooting. + + +## How To Use Nokogiri + +Nokogiri is a large library, and so it's challenging to briefly summarize it. We've tried to provide long, real-world examples at [Tutorials](https://nokogiri.org/tutorials/toc.html). + +### Parsing and Querying + +Here is example usage for parsing and querying a document: + +```ruby +#! /usr/bin/env ruby + +require 'nokogiri' +require 'open-uri' + +# Fetch and parse HTML document +doc = Nokogiri::HTML(URI.open('https://nokogiri.org/tutorials/installing_nokogiri.html')) + +# Search for nodes by css +doc.css('nav ul.menu li a', 'article h2').each do |link| + puts link.content +end + +# Search for nodes by xpath +doc.xpath('//nav//ul//li/a', '//article//h2').each do |link| + puts link.content +end + +# Or mix and match +doc.search('nav ul.menu li a', '//article//h2').each do |link| + puts link.content +end +``` + + +### Encoding + +Strings are always stored as UTF-8 internally. Methods that return +text values will always return UTF-8 encoded strings. Methods that +return a string containing markup (like `to_xml`, `to_html` and +`inner_html`) will return a string encoded like the source document. + +__WARNING__ + +Some documents declare one encoding, but actually use a different +one. In these cases, which encoding should the parser choose? + +Data is just a stream of bytes. Humans add meaning to that stream. Any +particular set of bytes could be valid characters in multiple +encodings, so detecting encoding with 100% accuracy is not +possible. `libxml2` does its best, but it can't be right all the time. + +If you want Nokogiri to handle the document encoding properly, your +best bet is to explicitly set the encoding. Here is an example of +explicitly setting the encoding to EUC-JP on the parser: + +```ruby + doc = Nokogiri.XML('', nil, 'EUC-JP') +``` + + +## Technical Overview + +### Guiding Principles + +As noted above, two guiding principles of the software are: + +- be secure-by-default by treating all documents as **untrusted** by default +- be a **thin-as-reasonable layer** on top of the underlying parsers, and don't attempt to fix behavioral differences between the parsers + +Notably, despite all parsers being standards-compliant, there are behavioral inconsistencies between the parsers used in the CRuby and JRuby implementations, and Nokogiri does not and should not attempt to remove these inconsistencies. Instead, we surface these differences in the test suite when they are important/semantic; or we intentionally write tests to depend only on the important/semantic bits (omitting whitespace from regex matchers on results, for example). + + +### CRuby + +The Ruby (a.k.a., CRuby, MRI, YARV) implementation is a C extension that depends on libxml2 and libxslt (which in turn depend on zlib and possibly libiconv). + +These dependencies are met by default by Nokogiri's packaged versions of the libxml2 and libxslt source code, but a configuration option `--use-system-libraries` is provided to allow specification of alternative library locations. See [Installing Nokogiri](https://nokogiri.org/tutorials/installing_nokogiri.html) for full documentation. + +We provide native gems by pre-compiling libxml2 and libxslt (and potentially zlib and libiconv) and packaging them into the gem file. In this case, no compilation is necessary at installation time, which leads to faster and more reliable installation. + +See [`LICENSE-DEPENDENCIES.md`](LICENSE-DEPENDENCIES.md) for more information on which dependencies are provided in which native and source gems. + + +### JRuby + +The Java (a.k.a. JRuby) implementation is a Java extension that depends primarily on Xerces and NekoHTML for parsing, though additional dependencies are on `isorelax`, `nekodtd`, `jing`, `serializer`, `xalan-j`, and `xml-apis`. + +These dependencies are provided by pre-compiled jar files packaged in the `java` platform gem. + +See [`LICENSE-DEPENDENCIES.md`](LICENSE-DEPENDENCIES.md) for more information on which dependencies are provided in which native and source gems. + + +## Contributing + +See [`CONTRIBUTING.md`](CONTRIBUTING.md) for an intro guide to developing Nokogiri. + + +## Code of Conduct + +We've adopted the Contributor Covenant code of conduct, which you can read in full in [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md). + + +## License + +This project is licensed under the terms of the MIT license. + +See this license at [`LICENSE.md`](LICENSE.md). + + +### Dependencies + +Some additional libraries may be distributed with your version of Nokogiri. Please see [`LICENSE-DEPENDENCIES.md`](LICENSE-DEPENDENCIES.md) for a discussion of the variations as well as the licenses thereof. + + +## Authors + +- Mike Dalessio +- Aaron Patterson +- Yoko Harada +- Akinori MUSHA +- John Shahid +- Karol Bucek +- Sam Ruby +- Craig Barnes +- Stephen Checkoway +- Lars Kanis +- Sergio Arbeo +- Timothy Elliott +- Nobuyoshi Nakada diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/bin/nokogiri b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/bin/nokogiri new file mode 100755 index 0000000..04a5cea --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/bin/nokogiri @@ -0,0 +1,131 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require "optparse" +require "open-uri" +require "uri" +require "rubygems" +require "nokogiri" +autoload :IRB, "irb" + +parse_class = Nokogiri +encoding = nil + +# This module provides some tunables with the nokogiri CLI for use in +# your ~/.nokogirirc. +module Nokogiri + module CLI + class << self + # Specify the console engine, defaulted to IRB. + # + # call-seq: + # require 'pry' + # Nokogiri::CLI.console = Pry + attr_writer :console + + def console + case @console + when Symbol + Kernel.const_get(@console) + else + @console + end + end + + attr_accessor :rcfile + end + + self.rcfile = File.expand_path("~/.nokogirirc") + self.console = :IRB + end +end + +def safe_read(uri_or_path) + uri = URI.parse(uri_or_path) + case uri + when URI::HTTP + uri.read + when URI::File + File.read(uri.path) + else + File.read(uri_or_path) + end +end + +opts = OptionParser.new do |opts| + opts.banner = "Nokogiri: an HTML, XML, SAX, and Reader parser" + opts.define_head("Usage: nokogiri [options]") + opts.separator("") + opts.separator("Examples:") + opts.separator(" nokogiri https://www.ruby-lang.org/") + opts.separator(" nokogiri ./public/index.html") + opts.separator(" curl -s http://www.nokogiri.org | nokogiri -e'p $_.css(\"h1\").length'") + opts.separator("") + opts.separator("Options:") + + opts.on("--type type", "Parse as type: xml or html (default: auto)", [:xml, :html]) do |v| + parse_class = { xml: Nokogiri::XML, html: Nokogiri::HTML }[v] + end + + opts.on("-C file", "Specifies initialization file to load (default #{Nokogiri::CLI.rcfile})") do |v| + Nokogiri::CLI.rcfile = v + end + + opts.on("-E", "--encoding encoding", "Read as encoding (default: #{encoding || "none"})") do |v| + encoding = v + end + + opts.on("-e command", "Specifies script from command-line.") do |v| + @script = v + end + + opts.on("--rng ", "Validate using this rng file.") do |v| + @rng = Nokogiri::XML::RelaxNG(safe_read(v)) + end + + opts.on_tail("-?", "--help", "Show this message") do + puts opts + exit + end + + opts.on_tail("-v", "--version", "Show version") do + puts Nokogiri::VersionInfo.instance.to_markdown + exit + end +end +opts.parse! + +url = ARGV.shift + +if url.to_s.strip.empty? && $stdin.tty? + puts opts + exit 1 +end + +if File.file?(Nokogiri::CLI.rcfile) + load Nokogiri::CLI.rcfile +end + +@doc = if url || $stdin.tty? + parse_class.parse(safe_read(url), url, encoding) +else + parse_class.parse($stdin, nil, encoding) +end + +$_ = @doc + +if @rng + @rng.validate(@doc).each do |error| + puts error.message + end +elsif @script + begin + eval(@script, binding, "
") # rubocop:disable Security/Eval + rescue Exception => e # rubocop:disable Lint/RescueException + warn("ERROR: Exception raised while evaluating '#{@script}'") + raise e + end +else + puts "Your document is stored in @doc..." + Nokogiri::CLI.console.start +end diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/dependencies.yml b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/dependencies.yml new file mode 100644 index 0000000..a6b5264 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/dependencies.yml @@ -0,0 +1,31 @@ +--- +libxml2: + version: "2.13.9" + sha256: "a2c9ae7b770da34860050c309f903221c67830c86e4a7e760692b803df95143a" + # sha-256 hash provided in https://download.gnome.org/sources/libxml2/2.13/libxml2-2.13.9.sha256sum + +libxslt: + version: "1.1.43" + sha256: "5a3d6b383ca5afc235b171118e90f5ff6aa27e9fea3303065231a6d403f0183a" + # sha-256 hash provided in https://download.gnome.org/sources/libxslt/1.1/libxslt-1.1.43.sha256sum + +zlib: + version: "1.3.1" + sha256: "9a93b2b7dfdac77ceba5a558a580e74667dd6fede4585b91eefb60f03b72df23" + # SHA-256 hash provided on http://zlib.net/ + +libiconv: + # $ gpg --keyserver keyserver.ubuntu.com --recv 9001B85AF9E1B83DF1BDA942F5BE8B267C6A406D + # gpg: key F5BE8B267C6A406D: public key "Bruno Haible (Open Source Development) " imported + # gpg: Total number processed: 1 + # gpg: imported: 1 + # $ gpg --verify libiconv-1.18.tar.gz.sig ports/archives/libiconv-1.18.tar.gz + # gpg: Signature made Sun 15 Dec 2024 07:26:18 AM EST + # gpg: using RSA key 9001B85AF9E1B83DF1BDA942F5BE8B267C6A406D + # gpg: Good signature from "Bruno Haible (Open Source Development) " [expired] + # gpg: Note: This key has expired! + # Primary key fingerprint: 9001 B85A F9E1 B83D F1BD A942 F5BE 8B26 7C6A 406D + # $ sha256sum ports/archives/libiconv-1.18.tar.gz + # 3b08f5f4f9b4eb82f151a7040bfd6fe6c6fb922efe4b1659c66ea933276965e8 ports/archives/libiconv-1.18.tar.gz + version: "1.18" + sha256: "3b08f5f4f9b4eb82f151a7040bfd6fe6c6fb922efe4b1659c66ea933276965e8" diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/depend b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/depend new file mode 100644 index 0000000..24f5908 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/depend @@ -0,0 +1,38 @@ +# -*-makefile-*- +# DO NOT DELETE + +gumbo.o: $(srcdir)/nokogiri.h +html_document.o: $(srcdir)/nokogiri.h +html_element_description.o: $(srcdir)/nokogiri.h +html_entity_lookup.o: $(srcdir)/nokogiri.h +html_sax_parser_context.o: $(srcdir)/nokogiri.h +html_sax_push_parser.o: $(srcdir)/nokogiri.h +libxml2_backwards_compat.o: $(srcdir)/nokogiri.h +nokogiri.o: $(srcdir)/nokogiri.h +test_global_handlers.o: $(srcdir)/nokogiri.h +xml_attr.o: $(srcdir)/nokogiri.h +xml_attribute_decl.o: $(srcdir)/nokogiri.h +xml_cdata.o: $(srcdir)/nokogiri.h +xml_comment.o: $(srcdir)/nokogiri.h +xml_document.o: $(srcdir)/nokogiri.h +xml_document_fragment.o: $(srcdir)/nokogiri.h +xml_dtd.o: $(srcdir)/nokogiri.h +xml_element_content.o: $(srcdir)/nokogiri.h +xml_element_decl.o: $(srcdir)/nokogiri.h +xml_encoding_handler.o: $(srcdir)/nokogiri.h +xml_entity_decl.o: $(srcdir)/nokogiri.h +xml_entity_reference.o: $(srcdir)/nokogiri.h +xml_namespace.o: $(srcdir)/nokogiri.h +xml_node.o: $(srcdir)/nokogiri.h +xml_node_set.o: $(srcdir)/nokogiri.h +xml_processing_instruction.o: $(srcdir)/nokogiri.h +xml_reader.o: $(srcdir)/nokogiri.h +xml_relax_ng.o: $(srcdir)/nokogiri.h +xml_sax_parser.o: $(srcdir)/nokogiri.h +xml_sax_parser_context.o: $(srcdir)/nokogiri.h +xml_sax_push_parser.o: $(srcdir)/nokogiri.h +xml_schema.o: $(srcdir)/nokogiri.h +xml_syntax_error.o: $(srcdir)/nokogiri.h +xml_text.o: $(srcdir)/nokogiri.h +xml_xpath_context.o: $(srcdir)/nokogiri.h +xslt_stylesheet.o: $(srcdir)/nokogiri.h diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/extconf.rb b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/extconf.rb new file mode 100644 index 0000000..2a8ba4e --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/extconf.rb @@ -0,0 +1,1165 @@ +# frozen_string_literal: true + +# rubocop:disable Style/GlobalVars + +ENV["RC_ARCHS"] = "" if RUBY_PLATFORM.include?("darwin") + +require "mkmf" +require "rbconfig" +require "fileutils" +require "shellwords" +require "pathname" + +# helpful constants +PACKAGE_ROOT_DIR = File.expand_path(File.join(File.dirname(__FILE__), "..", "..")) +REQUIRED_LIBXML_VERSION = "2.9.2" +RECOMMENDED_LIBXML_VERSION = "2.12.0" + +REQUIRED_MINI_PORTILE_VERSION = "~> 2.8.2" # keep this version in sync with the one in the gemspec +REQUIRED_PKG_CONFIG_VERSION = "~> 1.1" + +# Keep track of what versions of what libraries we build against +OTHER_LIBRARY_VERSIONS = {} + +NOKOGIRI_HELP_MESSAGE = <<~HELP + USAGE: ruby #{$PROGRAM_NAME} [options] + + Flags that are always valid: + + --use-system-libraries + --enable-system-libraries + Use system libraries instead of building and using the packaged libraries. + + --disable-system-libraries + Use the packaged libraries, and ignore the system libraries. This is the default on most + platforms, and overrides `--use-system-libraries` and the environment variable + `NOKOGIRI_USE_SYSTEM_LIBRARIES`. + + --disable-clean + Do not clean out intermediate files after successful build. + + --prevent-strip + Take steps to prevent stripping the symbol table and debugging info from the shared + library, potentially overriding RbConfig's CFLAGS/LDFLAGS/DLDFLAGS. + + + Flags only used when using system libraries: + + General: + + --with-opt-dir=DIRECTORY + Look for headers and libraries in DIRECTORY. + + --with-opt-lib=DIRECTORY + Look for libraries in DIRECTORY. + + --with-opt-include=DIRECTORY + Look for headers in DIRECTORY. + + + Related to libxml2: + + --with-xml2-dir=DIRECTORY + Look for xml2 headers and library in DIRECTORY. + + --with-xml2-lib=DIRECTORY + Look for xml2 library in DIRECTORY. + + --with-xml2-include=DIRECTORY + Look for xml2 headers in DIRECTORY. + + --with-xml2-source-dir=DIRECTORY + (dev only) Build libxml2 from the source code in DIRECTORY + + --disable-xml2-legacy + Do not build libxml2 with zlib, liblzma, or HTTP support. This will become the default + in a future version of Nokogiri. + + + Related to libxslt: + + --with-xslt-dir=DIRECTORY + Look for xslt headers and library in DIRECTORY. + + --with-xslt-lib=DIRECTORY + Look for xslt library in DIRECTORY. + + --with-xslt-include=DIRECTORY + Look for xslt headers in DIRECTORY. + + --with-xslt-source-dir=DIRECTORY + (dev only) Build libxslt from the source code in DIRECTORY + + + Related to libexslt: + + --with-exslt-dir=DIRECTORY + Look for exslt headers and library in DIRECTORY. + + --with-exslt-lib=DIRECTORY + Look for exslt library in DIRECTORY. + + --with-exslt-include=DIRECTORY + Look for exslt headers in DIRECTORY. + + + Related to iconv: + + --with-iconv-dir=DIRECTORY + Look for iconv headers and library in DIRECTORY. + + --with-iconv-lib=DIRECTORY + Look for iconv library in DIRECTORY. + + --with-iconv-include=DIRECTORY + Look for iconv headers in DIRECTORY. + + + Related to zlib (ignored if `--disable-xml2-legacy` is used): + + --with-zlib-dir=DIRECTORY + Look for zlib headers and library in DIRECTORY. + + --with-zlib-lib=DIRECTORY + Look for zlib library in DIRECTORY. + + --with-zlib-include=DIRECTORY + Look for zlib headers in DIRECTORY. + + + Flags only used when building and using the packaged libraries: + + --disable-static + Do not statically link packaged libraries, instead use shared libraries. + + --enable-cross-build + Enable cross-build mode. (You probably do not want to set this manually.) + + + Environment variables used: + + NOKOGIRI_USE_SYSTEM_LIBRARIES + Equivalent to `--enable-system-libraries` when set, even if nil or blank. + + AR + Use this path to invoke the library archiver instead of `RbConfig::CONFIG['AR']` + + CC + Use this path to invoke the compiler instead of `RbConfig::CONFIG['CC']` + + CPPFLAGS + If this string is accepted by the C preprocessor, add it to the flags passed to the C preprocessor + + CFLAGS + If this string is accepted by the compiler, add it to the flags passed to the compiler + + LD + Use this path to invoke the linker instead of `RbConfig::CONFIG['LD']` + + LDFLAGS + If this string is accepted by the linker, add it to the flags passed to the linker + + LIBS + Add this string to the flags passed to the linker +HELP + +# +# utility functions +# +def config_clean? + enable_config("clean", true) +end + +def config_static? + default_static = !truffle? + enable_config("static", default_static) +end + +def config_cross_build? + enable_config("cross-build") +end + +def config_system_libraries? + enable_config("system-libraries", ENV.key?("NOKOGIRI_USE_SYSTEM_LIBRARIES")) do |_, default| + arg_config("--use-system-libraries", default) + end +end + +def config_with_xml2_legacy? + enable_config("xml2-legacy", true) +end + +def windows? + RbConfig::CONFIG["target_os"].match?(/mingw|mswin/) +end + +def solaris? + RbConfig::CONFIG["target_os"].include?("solaris") +end + +def darwin? + RbConfig::CONFIG["target_os"].include?("darwin") +end + +def openbsd? + RbConfig::CONFIG["target_os"].include?("openbsd") +end + +def aix? + RbConfig::CONFIG["target_os"].include?("aix") +end + +def unix? + !(windows? || solaris? || darwin?) +end + +def nix? + ENV.key?("NIX_CC") +end + +def truffle? + RUBY_ENGINE == "truffleruby" +end + +def concat_flags(*args) + args.compact.join(" ") +end + +def local_have_library(lib, func = nil, headers = nil) + have_library(lib, func, headers) || have_library("lib#{lib}", func, headers) +end + +def zlib_source(version_string) + # As of 2022-12, I'm starting to see failed downloads often enough from zlib.net that I want to + # change the default to github. + if ENV["NOKOGIRI_USE_CANONICAL_ZLIB_SOURCE"] + "https://zlib.net/fossils/zlib-#{version_string}.tar.gz" + else + "https://github.com/madler/zlib/releases/download/v#{version_string}/zlib-#{version_string}.tar.gz" + end +end + +def gnome_source + "https://download.gnome.org" +end + +LOCAL_PACKAGE_RESPONSE = Object.new +def LOCAL_PACKAGE_RESPONSE.%(package) + package ? "yes: #{package}" : "no" +end + +# wrapper around MakeMakefil#pkg_config and the PKGConfig gem +def try_package_configuration(pc) + unless ENV.key?("NOKOGIRI_TEST_PKG_CONFIG_GEM") + # try MakeMakefile#pkg_config, which uses the system utility `pkg-config`. + return if checking_for("#{pc} using `pkg_config`", LOCAL_PACKAGE_RESPONSE) do + pkg_config(pc) + end + end + + # `pkg-config` probably isn't installed, which appears to be the case for lots of freebsd systems. + # let's fall back to the pkg-config gem, which knows how to parse .pc files, and wrap it with the + # same logic as MakeMakefile#pkg_config + begin + require "rubygems" + gem("pkg-config", REQUIRED_PKG_CONFIG_VERSION) + require "pkg-config" + + checking_for("#{pc} using pkg-config gem version #{PKGConfig::VERSION}", LOCAL_PACKAGE_RESPONSE) do + if PKGConfig.have_package(pc) + cflags = PKGConfig.cflags(pc) + ldflags = PKGConfig.libs_only_L(pc) + libs = PKGConfig.libs_only_l(pc) + + Logging.message("pkg-config gem found package configuration for %s\n", pc) + Logging.message("cflags: %s\nldflags: %s\nlibs: %s\n\n", cflags, ldflags, libs) + + [cflags, ldflags, libs] + end + end + rescue LoadError + message("Please install either the `pkg-config` utility or the `pkg-config` rubygem.\n") + end +end + +# set up mkmf to link against the library if we can find it +def have_package_configuration(opt: nil, pc: nil, lib:, func:, headers:) + if opt + dir_config(opt) + dir_config("opt") + end + + # see if we have enough path info to do this without trying any harder + unless ENV.key?("NOKOGIRI_TEST_PKG_CONFIG") + return true if local_have_library(lib, func, headers) + end + + try_package_configuration(pc) if pc + + # verify that we can compile and link against the library + local_have_library(lib, func, headers) +end + +def ensure_package_configuration(opt: nil, pc: nil, lib:, func:, headers:) + have_package_configuration(opt: opt, pc: pc, lib: lib, func: func, headers: headers) || + abort_could_not_find_library(lib) +end + +def ensure_func(func, headers = nil) + have_func(func, headers) || abort_could_not_find_library(func) +end + +def preserving_globals + values = [$arg_config, $INCFLAGS, $CFLAGS, $CPPFLAGS, $LDFLAGS, $DLDFLAGS, $LIBPATH, $libs].map(&:dup) + yield +ensure + $arg_config, $INCFLAGS, $CFLAGS, $CPPFLAGS, $LDFLAGS, $DLDFLAGS, $LIBPATH, $libs = values +end + +def abort_could_not_find_library(lib) + callers = caller(1..2).join("\n") + abort("-----\n#{callers}\n#{lib} is missing. Please locate mkmf.log to investigate how it is failing.\n-----") +end + +def chdir_for_build(&block) + # When using rake-compiler-dock on Windows, the underlying Virtualbox shared + # folders don't support symlinks, but libiconv expects it for a build on + # Linux. We work around this limitation by using the temp dir for cooking. + build_dir = /mingw|mswin|cygwin/.match?(ENV["RCD_HOST_RUBY_PLATFORM"].to_s) ? "/tmp" : "." + Dir.chdir(build_dir, &block) +end + +def sh_export_path(path) + # because libxslt 1.1.29 configure.in uses AC_PATH_TOOL which treats ":" + # as a $PATH separator, we need to convert windows paths from + # + # C:/path/to/foo + # + # to + # + # /C/path/to/foo + # + # which is sh-compatible, in order to find things properly during + # configuration + return path unless windows? + + match = Regexp.new("^([A-Z]):(/.*)").match(path) + if match && match.length == 3 + return File.join("/", match[1], match[2]) + end + + path +end + +def libflag_to_filename(ldflag) + case ldflag + when /\A-l(.+)/ + "lib#{Regexp.last_match(1)}.#{$LIBEXT}" + end +end + +def have_libxml_headers?(version = nil) + source = if version.nil? + <<~SRC + #include + SRC + else + version_int = format("%d%2.2d%2.2d", *version.split(".")) + <<~SRC + #include + #if LIBXML_VERSION < #{version_int} + # error libxml2 is older than #{version} + #endif + SRC + end + + try_cpp(source) +end + +def try_link_iconv(using = nil) + checking_for(using ? "iconv using #{using}" : "iconv") do + ["", "-liconv"].any? do |opt| + preserving_globals do + yield if block_given? + + try_link(<<~SRC, opt) + #include + #include + int main(void) + { + iconv_t cd = iconv_open("", ""); + iconv(cd, NULL, NULL, NULL, NULL); + return EXIT_SUCCESS; + } + SRC + end + end + end +end + +def iconv_configure_flags + # give --with-iconv-dir and --with-opt-dir first priority + ["iconv", "opt"].each do |target| + config = preserving_globals { dir_config(target) } + next unless config.any? && try_link_iconv("--with-#{target}-* flags") { dir_config(target) } + + idirs, ldirs = config.map do |dirs| + Array(dirs).flat_map do |dir| + dir.split(File::PATH_SEPARATOR) + end if dirs + end + + return [ + "--with-iconv=yes", + *("CPPFLAGS=#{idirs.map { |dir| "-I" + dir }.join(" ")}" if idirs), + *("LDFLAGS=#{ldirs.map { |dir| "-L" + dir }.join(" ")}" if ldirs), + ] + end + + if try_link_iconv + return ["--with-iconv=yes"] + end + + config = preserving_globals { pkg_config("libiconv") } + if config && try_link_iconv("pkg-config libiconv") { pkg_config("libiconv") } + cflags, ldflags, libs = config + + return [ + "--with-iconv=yes", + "CPPFLAGS=#{cflags}", + "LDFLAGS=#{ldflags}", + "LIBS=#{libs}", + ] + end + + abort_could_not_find_library("libiconv") +end + +def process_recipe(name, version, static_p, cross_p, cacheable_p = true) + require "rubygems" + gem("mini_portile2", REQUIRED_MINI_PORTILE_VERSION) # gemspec is not respected at install time + require "mini_portile2" + message("Using mini_portile version #{MiniPortile::VERSION}\n") + + unless ["libxml2", "libxslt"].include?(name) + OTHER_LIBRARY_VERSIONS[name] = version + end + + MiniPortile.new(name, version).tap do |recipe| + def recipe.port_path + "#{@target}/#{RUBY_PLATFORM}/#{@name}/#{@version}" + end + + # We use 'host' to set compiler prefix for cross-compiling. Prefer host_alias over host. And + # prefer i686 (what external dev tools use) to i386 (what ruby's configure.ac emits). + recipe.host = RbConfig::CONFIG["host_alias"].empty? ? RbConfig::CONFIG["host"] : RbConfig::CONFIG["host_alias"] + recipe.host = recipe.host.gsub("i386", "i686") + + recipe.target = File.join(PACKAGE_ROOT_DIR, "ports") if cacheable_p + recipe.configure_options << "--libdir=#{File.join(recipe.path, "lib")}" + + yield recipe + + env = Hash.new do |hash, key| + hash[key] = (ENV[key]).to_s + end + + recipe.configure_options.flatten! + + recipe.configure_options.delete_if do |option| + case option + when /\A(\w+)=(.*)\z/ + env[Regexp.last_match(1)] = if env.key?(Regexp.last_match(1)) + concat_flags(env[Regexp.last_match(1)], Regexp.last_match(2)) + else + Regexp.last_match(2) + end + true + else + false + end + end + + if static_p + recipe.configure_options += [ + "--disable-shared", + "--enable-static", + ] + env["CFLAGS"] = concat_flags(env["CFLAGS"], "-fPIC") + else + recipe.configure_options += [ + "--enable-shared", + "--disable-static", + ] + end + + if cross_p + recipe.configure_options += [ + "--target=#{recipe.host}", + "--host=#{recipe.host}", + ] + end + + if RbConfig::CONFIG["target_cpu"] == "universal" + ["CFLAGS", "LDFLAGS"].each do |key| + unless env[key].include?("-arch") + env[key] = concat_flags(env[key], RbConfig::CONFIG["ARCH_FLAG"]) + end + end + end + + recipe.configure_options += env.map do |key, value| + "#{key}=#{value.strip}" + end + + checkpoint = "#{recipe.target}/#{recipe.name}-#{recipe.version}-#{RUBY_PLATFORM}.installed" + if File.exist?(checkpoint) && !recipe.source_directory + message("Building Nokogiri with a packaged version of #{name}-#{version}.\n") + else + message(<<~EOM) + ---------- IMPORTANT NOTICE ---------- + Building Nokogiri with a packaged version of #{name}-#{version}. + Configuration options: #{recipe.configure_options.shelljoin} + EOM + + unless recipe.patch_files.empty? + message("The following patches are being applied:\n") + + recipe.patch_files.each do |patch| + message(format(" - %s\n", File.basename(patch))) + end + end + + message(<<~EOM) if name != "libgumbo" + + The Nokogiri maintainers intend to provide timely security updates, but if + this is a concern for you and want to use your OS/distro system library + instead, then abort this installation process and install nokogiri as + instructed at: + + https://nokogiri.org/tutorials/installing_nokogiri.html#installing-using-standard-system-libraries + + EOM + + message(<<~EOM) if name == "libxml2" + Note, however, that nokogiri cannot guarantee compatibility with every + version of libxml2 that may be provided by OS/package vendors. + + EOM + + chdir_for_build { recipe.cook } + FileUtils.touch(checkpoint) + end + recipe.activate + end +end + +def copy_packaged_libraries_headers(to_path:, from_recipes:) + FileUtils.rm_rf(to_path, secure: true) + FileUtils.mkdir(to_path) + from_recipes.each do |recipe| + FileUtils.cp_r(Dir[File.join(recipe.path, "include/*")], to_path) + end +end + +def do_help + print(NOKOGIRI_HELP_MESSAGE) + exit!(0) +end + +def do_clean + root = Pathname(PACKAGE_ROOT_DIR) + pwd = Pathname(Dir.pwd) + + # Skip if this is a development work tree + unless (root + ".git").exist? + message("Cleaning files only used during build.\n") + + # (root + 'tmp') cannot be removed at this stage because + # nokogiri.so is yet to be copied to lib. + + # clean the ports build directory + Pathname.glob(pwd.join("tmp", "*", "ports")) do |dir| + FileUtils.rm_rf(dir, verbose: true) + end + + if config_static? + # ports installation can be safely removed if statically linked. + FileUtils.rm_rf(root + "ports", verbose: true) + else + FileUtils.rm_rf(root + "ports" + "archives", verbose: true) + end + end + + exit!(0) +end + +# In ruby 3.2, symbol resolution changed on Darwin, to introduce the `-bundle_loader` flag to +# resolve symbols against the ruby binary. +# +# This makes it challenging to build a single extension that works with both a ruby with +# `--enable-shared` and one with `--disable-shared. To work around that, we choose to add +# `-flat_namespace` to the link line (later in this file). +# +# The `-flat_namespace` line introduces its own behavior change, which is that (similar to on +# Linux), any symbols in the extension that are exported may now be resolved by shared libraries +# loaded by the Ruby process. Specifically, that means that libxml2 and libxslt, which are +# statically linked into the nokogiri bundle, will resolve (at runtime) to a system libxml2 loaded +# by Ruby on Darwin. And it appears that often Ruby on Darwin does indeed load the system libxml2, +# and that messes with our assumptions about whether we're running with a patched libxml2 or a +# vanilla libxml2. +# +# We choose to use `-load_hidden` in this case to prevent exporting those symbols from libxml2 and +# libxslt, which ensures that they will be resolved to the static libraries in the bundle. In other +# words, when we use `load_hidden`, what happens in the extension stays in the extension. +# +# See https://github.com/rake-compiler/rake-compiler-dock/issues/87 for more info. +# +# Anyway, this method is the logical bit to tell us when to turn on these workarounds. +def needs_darwin_linker_hack + config_cross_build? && + darwin? && + Gem::Requirement.new("~> 3.2").satisfied_by?(Gem::Version.new(RbConfig::CONFIG["ruby_version"].split("+").first)) +end + +# +# main +# +do_help if arg_config("--help") +do_clean if arg_config("--clean") + +if openbsd? && !config_system_libraries? + unless %x(#{ENV["CC"] || "/usr/bin/cc"} -v 2>&1).include?("clang") + (ENV["CC"] ||= find_executable("egcc")) || + abort("Please install gcc 4.9+ from ports using `pkg_add -v gcc`") + end + append_cppflags "-I/usr/local/include" +end + +if ENV["AR"] + RbConfig::CONFIG["AR"] = RbConfig::MAKEFILE_CONFIG["AR"] = ENV["AR"] +end + +if ENV["CC"] + RbConfig::CONFIG["CC"] = RbConfig::MAKEFILE_CONFIG["CC"] = ENV["CC"] +end + +if ENV["LD"] + RbConfig::CONFIG["LD"] = RbConfig::MAKEFILE_CONFIG["LD"] = ENV["LD"] +end + +# use same toolchain for libxml and libxslt +ENV["AR"] = RbConfig::CONFIG["AR"] +ENV["CC"] = RbConfig::CONFIG["CC"] +ENV["LD"] = RbConfig::CONFIG["LD"] + +if arg_config("--prevent-strip") + old_cflags = $CFLAGS.split.join(" ") + old_ldflags = $LDFLAGS.split.join(" ") + old_dldflags = $DLDFLAGS.split.join(" ") + $CFLAGS = $CFLAGS.split.reject { |flag| flag == "-s" }.join(" ") + $LDFLAGS = $LDFLAGS.split.reject { |flag| flag == "-s" }.join(" ") + $DLDFLAGS = $DLDFLAGS.split.reject { |flag| flag == "-s" }.join(" ") + puts "Prevent stripping by removing '-s' from $CFLAGS" if old_cflags != $CFLAGS + puts "Prevent stripping by removing '-s' from $LDFLAGS" if old_ldflags != $LDFLAGS + puts "Prevent stripping by removing '-s' from $DLDFLAGS" if old_dldflags != $DLDFLAGS +end + +# adopt environment config +append_cflags(ENV["CFLAGS"]) unless ENV["CFLAGS"].nil? +append_cppflags(ENV["CPPFLAGS"]) unless ENV["CPPFLAGS"].nil? +append_ldflags(ENV["LDFLAGS"]) unless ENV["LDFLAGS"].nil? +$LIBS = concat_flags($LIBS, ENV["LIBS"]) + +# libgumbo uses C90/C99 features, see #2302 +append_cflags(["-std=c99", "-Wno-declaration-after-statement"]) + +# gumbo html5 serialization is slower with O3, let's make sure we use O2 +append_cflags("-O2") + +# always include debugging information +append_cflags("-g") + +# we use at least one inline function in the C extension +append_cflags("-Winline") + +# good to have no matter what Ruby was compiled with +append_cflags("-Wmissing-noreturn") + +# check integer loss of precision. this flag won't generally work until Ruby 3.4. +# see https://bugs.ruby-lang.org/issues/20507 +append_cflags("-Wconversion") + +# handle clang variations, see #1101 +if darwin? + append_cflags("-Wno-error=unused-command-line-argument-hard-error-in-future") + append_cflags("-Wno-unknown-warning-option") +end + +# these tend to be noisy, but on occasion useful during development +# append_cflags(["-Wcast-qual", "-Wwrite-strings"]) + +# Add SDK-specific include path for macOS and brew versions before v2.2.12 (2020-04-08) [#1851, #1801] +macos_mojave_sdk_include_path = "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/libxml2" +if config_system_libraries? && darwin? && Dir.exist?(macos_mojave_sdk_include_path) && !nix? + append_cppflags("-I#{macos_mojave_sdk_include_path}") +end + +# Work around a character escaping bug in MSYS by passing an arbitrary double-quoted parameter to gcc. +# See https://sourceforge.net/p/mingw/bugs/2142 +append_cppflags(' "-Idummypath"') if windows? + +if config_system_libraries? + message "Building nokogiri using system libraries.\n" + if config_with_xml2_legacy? + ensure_package_configuration( + opt: "zlib", + pc: "zlib", + lib: "z", + headers: "zlib.h", + func: "gzdopen", + ) + end + ensure_package_configuration( + opt: "xml2", + pc: "libxml-2.0", + lib: "xml2", + headers: "libxml/parser.h", + func: "xmlParseDoc", + ) + ensure_package_configuration( + opt: "xslt", + pc: "libxslt", + lib: "xslt", + headers: "libxslt/xslt.h", + func: "xsltParseStylesheetDoc", + ) + ensure_package_configuration( + opt: "exslt", + pc: "libexslt", + lib: "exslt", + headers: "libexslt/exslt.h", + func: "exsltFuncRegister", + ) + + have_libxml_headers?(REQUIRED_LIBXML_VERSION) || + abort("ERROR: libxml2 version #{REQUIRED_LIBXML_VERSION} or later is required!") + have_libxml_headers?(RECOMMENDED_LIBXML_VERSION) || + warn("WARNING: libxml2 version #{RECOMMENDED_LIBXML_VERSION} or later is highly recommended, but proceeding anyway.") + +else + message "Building nokogiri using packaged libraries.\n" + + static_p = config_static? + message "Static linking is #{static_p ? "enabled" : "disabled"}.\n" + + cross_build_p = config_cross_build? + message "Cross build is #{cross_build_p ? "enabled" : "disabled"}.\n" + + if needs_darwin_linker_hack + append_ldflags("-Wl,-flat_namespace") + end + + require "yaml" + dependencies = YAML.load_file(File.join(PACKAGE_ROOT_DIR, "dependencies.yml")) + + dir_config("zlib") if config_with_xml2_legacy? + + if cross_build_p || windows? + if config_with_xml2_legacy? + zlib_recipe = process_recipe("zlib", dependencies["zlib"]["version"], static_p, cross_build_p) do |recipe| + recipe.files = [{ + url: zlib_source(recipe.version), + sha256: dependencies["zlib"]["sha256"], + }] + if windows? + class << recipe + attr_accessor :cross_build_p + + def configure + Dir.chdir(work_path) do + mk = File.read("win32/Makefile.gcc") + File.open("win32/Makefile.gcc", "wb") do |f| + f.puts "BINARY_PATH = #{path}/bin" + f.puts "LIBRARY_PATH = #{path}/lib" + f.puts "INCLUDE_PATH = #{path}/include" + mk.sub!(/^PREFIX\s*=\s*$/, "PREFIX = #{host}-") if cross_build_p + f.puts mk + end + end + end + + def configured? + Dir.chdir(work_path) do + !!(File.read("win32/Makefile.gcc") =~ /^BINARY_PATH/) + end + end + + def compile + execute("compile", "make -f win32/Makefile.gcc") + end + + def install + execute("install", "make -f win32/Makefile.gcc install") + end + end + recipe.cross_build_p = cross_build_p + else + class << recipe + def configure + env = {} + env["CFLAGS"] = concat_flags(ENV["CFLAGS"], "-fPIC", "-g") + env["CHOST"] = host + execute("configure", ["./configure", "--static", configure_prefix], { env: env }) + if darwin? + # needed as of zlib 1.2.13 + Dir.chdir(work_path) do + makefile = File.read("Makefile").gsub(/^AR=.*$/, "AR=#{host}-libtool") + File.open("Makefile", "w") { |m| m.write(makefile) } + end + end + end + end + end + end + end + + unless unix? + libiconv_recipe = process_recipe( + "libiconv", + dependencies["libiconv"]["version"], + static_p, + cross_build_p, + ) do |recipe| + recipe.files = [{ + url: "https://ftpmirror.gnu.org/gnu/libiconv/#{recipe.name}-#{recipe.version}.tar.gz", + sha256: dependencies["libiconv"]["sha256"], + }] + + # The libiconv configure script doesn't accept "arm64" host string but "aarch64" + recipe.host = recipe.host.gsub("arm64-apple-darwin", "aarch64-apple-darwin") + + cflags = concat_flags(ENV["CFLAGS"], "-O2", "-g") + + recipe.configure_options += [ + "--disable-dependency-tracking", + "CPPFLAGS=-Wall", + "CFLAGS=#{cflags}", + "CXXFLAGS=#{cflags}", + "LDFLAGS=", + ] + end + end + elsif darwin? && !have_header("iconv.h") + abort(<<~EOM.chomp) + ----- + The file "iconv.h" is missing in your build environment, + which means you haven't installed Xcode Command Line Tools properly. + + To install Command Line Tools, try running `xcode-select --install` on + terminal and follow the instructions. If it fails, open Xcode.app, + select from the menu "Xcode" - "Open Developer Tool" - "More Developer + Tools" to open the developer site, download the installer for your OS + version and run it. + ----- + EOM + end + + if zlib_recipe + append_cppflags("-I#{zlib_recipe.path}/include") + $LIBPATH = ["#{zlib_recipe.path}/lib"] | $LIBPATH + ensure_package_configuration( + opt: "zlib", + pc: "zlib", + lib: "z", + headers: "zlib.h", + func: "gzdopen", + ) + end + + if libiconv_recipe + append_cppflags("-I#{libiconv_recipe.path}/include") + $LIBPATH = ["#{libiconv_recipe.path}/lib"] | $LIBPATH + ensure_package_configuration( + opt: "iconv", + pc: "iconv", + lib: "iconv", + headers: "iconv.h", + func: "iconv_open", + ) + end + + libxml2_recipe = process_recipe("libxml2", dependencies["libxml2"]["version"], static_p, cross_build_p) do |recipe| + source_dir = arg_config("--with-xml2-source-dir") + if source_dir + recipe.source_directory = source_dir + else + minor_version = Gem::Version.new(recipe.version).segments.take(2).join(".") + recipe.files = [{ + url: "#{gnome_source}/sources/libxml2/#{minor_version}/#{recipe.name}-#{recipe.version}.tar.xz", + sha256: dependencies["libxml2"]["sha256"], + }] + recipe.patch_files = Dir[File.join(PACKAGE_ROOT_DIR, "patches", "libxml2", "*.patch")].sort + end + + cppflags = concat_flags(ENV["CPPFLAGS"]) + cflags = concat_flags(ENV["CFLAGS"], "-O2", "-g") + + if cross_build_p + cppflags = concat_flags(cppflags, "-DNOKOGIRI_PRECOMPILED_LIBRARIES") + end + + if config_with_xml2_legacy? + recipe.configure_options << "--with-legacy" + end + + if zlib_recipe + recipe.configure_options << "--with-zlib=#{zlib_recipe.path}" + end + + if libiconv_recipe + recipe.configure_options << "--with-iconv=#{libiconv_recipe.path}" + else + recipe.configure_options += iconv_configure_flags + end + + if darwin? && !cross_build_p + recipe.configure_options << "RANLIB=/usr/bin/ranlib" unless ENV.key?("RANLIB") + recipe.configure_options << "AR=/usr/bin/ar" unless ENV.key?("AR") + end + + if windows? + cflags = concat_flags(cflags, "-ULIBXML_STATIC", "-DIN_LIBXML") + end + + recipe.configure_options << if source_dir + "--config-cache" + else + "--disable-dependency-tracking" + end + + recipe.configure_options += [ + "--without-python", + "--without-readline", + "--with-c14n", + "--with-debug", + "--with-threads", + "CPPFLAGS=#{cppflags}", + "CFLAGS=#{cflags}", + ] + end + + libxslt_recipe = process_recipe("libxslt", dependencies["libxslt"]["version"], static_p, cross_build_p) do |recipe| + source_dir = arg_config("--with-xslt-source-dir") + if source_dir + recipe.source_directory = source_dir + else + minor_version = Gem::Version.new(recipe.version).segments.take(2).join(".") + recipe.files = [{ + url: "#{gnome_source}/sources/libxslt/#{minor_version}/#{recipe.name}-#{recipe.version}.tar.xz", + sha256: dependencies["libxslt"]["sha256"], + }] + recipe.patch_files = Dir[File.join(PACKAGE_ROOT_DIR, "patches", "libxslt", "*.patch")].sort + end + + cflags = concat_flags(ENV["CFLAGS"], "-O2", "-g") + + if darwin? && !cross_build_p + recipe.configure_options << "RANLIB=/usr/bin/ranlib" unless ENV.key?("RANLIB") + recipe.configure_options << "AR=/usr/bin/ar" unless ENV.key?("AR") + end + + if windows? + cflags = concat_flags(cflags, "-ULIBXSLT_STATIC", "-DIN_LIBXSLT") + cflags = concat_flags(cflags, "-ULIBEXSLT_STATIC", "-DIN_LIBEXSLT") + end + + recipe.configure_options << if source_dir + "--config-cache" + else + "--disable-dependency-tracking" + end + + recipe.configure_options += [ + "--without-python", + "--without-crypto", + "--with-debug", + "--with-libxml-prefix=#{sh_export_path(libxml2_recipe.path)}", + "CFLAGS=#{cflags}", + ] + end + + append_cppflags("-DNOKOGIRI_PACKAGED_LIBRARIES") + append_cppflags("-DNOKOGIRI_PRECOMPILED_LIBRARIES") if cross_build_p + + $libs = $libs.shellsplit.tap do |libs| + [libxml2_recipe, libxslt_recipe].each do |recipe| + libname = recipe.name[/\Alib(.+)\z/, 1] + config_basename = "#{libname}-config" + File.join(recipe.path, "bin", config_basename).tap do |config| + # call config scripts explicit with 'sh' for compat with Windows + cflags = %x(sh #{config} --cflags).strip + message("#{config_basename} cflags: #{cflags}\n") + $CPPFLAGS = concat_flags(cflags, $CPPFLAGS) # prepend + + %x(sh #{config} --libs).strip.shellsplit.each do |arg| + case arg + when /\A-L(.+)\z/ + # Prioritize ports' directories + $LIBPATH = if Regexp.last_match(1).start_with?(PACKAGE_ROOT_DIR + "/") + [Regexp.last_match(1)] | $LIBPATH + else + $LIBPATH | [Regexp.last_match(1)] + end + when /\A-l./ + libs.unshift(arg) + else + $LDFLAGS << " " << arg.shellescape + end + end + end + + patches_string = recipe.patch_files.map { |path| File.basename(path) }.join(" ") + append_cppflags(%[-DNOKOGIRI_#{recipe.name.upcase}_PATCHES="\\"#{patches_string}\\""]) + + case libname + when "xml2" + # xslt-config --libs or pkg-config libxslt --libs does not include + # -llzma, so we need to add it manually when linking statically. + if static_p && preserving_globals { local_have_library("lzma") } + # Add it at the end; GH #988 + libs << "-llzma" + end + when "xslt" + # xslt-config does not have a flag to emit options including + # -lexslt, so add it manually. + libs.unshift("-lexslt") + end + end + end.shelljoin + + if static_p + static_archive_ld_flag = needs_darwin_linker_hack ? ["-load_hidden"] : [] + $libs = $libs.shellsplit.map do |arg| + case arg + when "-lxml2" + static_archive_ld_flag + [File.join(libxml2_recipe.path, "lib", libflag_to_filename(arg))] + when "-lxslt", "-lexslt" + static_archive_ld_flag + [File.join(libxslt_recipe.path, "lib", libflag_to_filename(arg))] + else + arg + end + end.flatten.shelljoin + end + + ensure_func("xmlParseDoc", "libxml/parser.h") + ensure_func("xsltParseStylesheetDoc", "libxslt/xslt.h") + ensure_func("exsltFuncRegister", "libexslt/exslt.h") +end + +if arg_config("--gumbo-dev") + message("DEV MODE ENABLED: build libgumbo as packaged source") + ext_dir = File.dirname(__FILE__) + Dir.chdir(ext_dir) do + $srcs = Dir["*.c", "../../gumbo-parser/src/*.c"] + $hdrs = Dir["*.h", "../../gumbo-parser/src/*.h"] + end + $INCFLAGS << " -I$(srcdir)/../../gumbo-parser/src" + $VPATH << "$(srcdir)/../../gumbo-parser/src" + find_header("nokogiri_gumbo.h") || abort("nokogiri_gumbo.h not found") +else + libgumbo_recipe = process_recipe("libgumbo", "1.0.0-nokogiri", static_p, cross_build_p, false) do |recipe| + recipe.configure_options = [] + + class << recipe + def downloaded? + true + end + + def extract + target = File.join(tmp_path, "gumbo-parser") + output("Copying gumbo-parser files into #{target}...") + FileUtils.mkdir_p(target) + FileUtils.cp(Dir.glob(File.join(PACKAGE_ROOT_DIR, "gumbo-parser/src/*")), target) + end + + def configured? + true + end + + def install + lib_dir = File.join(port_path, "lib") + inc_dir = File.join(port_path, "include") + FileUtils.mkdir_p([lib_dir, inc_dir]) + FileUtils.cp(File.join(work_path, "libgumbo.a"), lib_dir) + FileUtils.cp(Dir.glob(File.join(work_path, "*.h")), inc_dir) + end + + def compile + cflags = concat_flags(ENV["CFLAGS"], "-fPIC", "-O2", "-g") + + env = { "CC" => gcc_cmd, "CFLAGS" => cflags } + if config_cross_build? + if host.include?("darwin") + env["AR"] = "#{host}-libtool" + env["ARFLAGS"] = "-o" + else + env["AR"] = "#{host}-ar" + end + env["RANLIB"] = "#{host}-ranlib" + if windows? + concat_flags(env["CFLAGS"], "-D_RUBY_UCRT") + end + end + + execute("compile", make_cmd, { env: env }) + end + end + end + append_cppflags("-I#{File.join(libgumbo_recipe.path, "include")}") + $libs = $libs + " " + File.join(libgumbo_recipe.path, "lib", "libgumbo.a") + $LIBPATH = $LIBPATH | [File.join(libgumbo_recipe.path, "lib")] + ensure_func("gumbo_parse_with_options", "nokogiri_gumbo.h") +end + +have_func("xmlCtxtSetOptions") # introduced in libxml2 2.13.0 +have_func("xmlCtxtGetOptions") # introduced in libxml2 2.14.0 +have_func("xmlSwitchEncodingName") # introduced in libxml2 2.13.0 +have_func("rb_category_warning") # introduced in Ruby 3.0 but had trouble resolving this symbol in truffleruby + +other_library_versions_string = OTHER_LIBRARY_VERSIONS.map { |k, v| [k, v].join(":") }.join(",") +append_cppflags(%[-DNOKOGIRI_OTHER_LIBRARY_VERSIONS="\\"#{other_library_versions_string}\\""]) + +unless config_system_libraries? + if cross_build_p + # When precompiling native gems, copy packaged libraries' headers to ext/nokogiri/include + # These are packaged up by the cross-compiling callback in the ExtensionTask + copy_packaged_libraries_headers( + to_path: File.join(PACKAGE_ROOT_DIR, "ext/nokogiri/include"), + from_recipes: [libxml2_recipe, libxslt_recipe], + ) + else + # When compiling during installation, install packaged libraries' header files into ext/nokogiri/include + copy_packaged_libraries_headers( + to_path: "include", + from_recipes: [libxml2_recipe, libxslt_recipe], + ) + $INSTALLFILES << ["include/**/*.h", "$(rubylibdir)"] + end +end + +create_makefile("nokogiri/nokogiri") + +if config_clean? + # Do not clean if run in a development work tree. + File.open("Makefile", "at") do |mk| + mk.print(<<~EOF) + + all: clean-ports + clean-ports: $(TARGET_SO) + \t-$(Q)$(RUBY) $(srcdir)/extconf.rb --clean --#{static_p ? "enable" : "disable"}-static + EOF + end +end + +# rubocop:enable Style/GlobalVars diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/gumbo.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/gumbo.c new file mode 100644 index 0000000..fd938f3 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/gumbo.c @@ -0,0 +1,610 @@ +// +// Copyright 2013-2021 Sam Ruby, Stephen Checkoway +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// +// nokogumbo.c defines the following: +// +// class Nokogumbo +// def parse(utf8_string) # returns Nokogiri::HTML5::Document +// end +// +// Processing starts by calling gumbo_parse_with_options. The resulting document tree +// is then walked, a parallel libxml2 tree is constructed, and the final document is +// then wrapped using noko_xml_document_wrap. This approach reduces memory and CPU +// requirements as Ruby objects are only built when necessary. +// + +#include + +#include "nokogiri_gumbo.h" + +VALUE cNokogiriHtml5Document; + +// Interned symbols +static ID internal_subset; +static ID parent; + +#include +#include +#include + +// URI = system id +// external id = public id +static xmlDocPtr +new_html_doc(const char *dtd_name, const char *system, const char *public) +{ + // These two libxml2 functions take the public and system ids in + // opposite orders. + htmlDocPtr doc = htmlNewDocNoDtD(/* URI */ NULL, /* ExternalID */NULL); + assert(doc); + if (dtd_name) { + xmlCreateIntSubset(doc, (const xmlChar *)dtd_name, (const xmlChar *)public, (const xmlChar *)system); + } + return doc; +} + +static xmlNodePtr +get_parent(xmlNodePtr node) +{ + return node->parent; +} + +static GumboOutput * +perform_parse(const GumboOptions *options, VALUE input) +{ + assert(RTEST(input)); + Check_Type(input, T_STRING); + GumboOutput *output = gumbo_parse_with_options( + options, + RSTRING_PTR(input), + (size_t)RSTRING_LEN(input) + ); + + const char *status_string = gumbo_status_to_string(output->status); + switch (output->status) { + case GUMBO_STATUS_OK: + break; + case GUMBO_STATUS_TOO_MANY_ATTRIBUTES: + case GUMBO_STATUS_TREE_TOO_DEEP: + gumbo_destroy_output(output); + rb_raise(rb_eArgError, "%s", status_string); + case GUMBO_STATUS_OUT_OF_MEMORY: + gumbo_destroy_output(output); + rb_raise(rb_eNoMemError, "%s", status_string); + } + return output; +} + +static xmlNsPtr +lookup_or_add_ns( + xmlDocPtr doc, + xmlNodePtr root, + const char *href, + const char *prefix +) +{ + xmlNsPtr ns = xmlSearchNs(doc, root, (const xmlChar *)prefix); + if (ns) { + return ns; + } + return xmlNewNs(root, (const xmlChar *)href, (const xmlChar *)prefix); +} + +static void +set_line(xmlNodePtr node, size_t line) +{ + // libxml2 uses 65535 to mean look elsewhere for the line number on some + // nodes. + if (line < 65535) { + node->line = (unsigned short)line; + } +} + +// Construct an XML tree rooted at xml_output_node from the Gumbo tree rooted +// at gumbo_node. +static void +build_tree( + xmlDocPtr doc, + xmlNodePtr xml_output_node, + const GumboNode *gumbo_node +) +{ + xmlNodePtr xml_root = NULL; + xmlNodePtr xml_node = xml_output_node; + size_t child_index = 0; + + while (true) { + assert(gumbo_node != NULL); + const GumboVector *children = gumbo_node->type == GUMBO_NODE_DOCUMENT ? + &gumbo_node->v.document.children : &gumbo_node->v.element.children; + if (child_index >= children->length) { + // Move up the tree and to the next child. + if (xml_node == xml_output_node) { + // We've built as much of the tree as we can. + return; + } + child_index = gumbo_node->index_within_parent + 1; + gumbo_node = gumbo_node->parent; + xml_node = get_parent(xml_node); + // Children of fragments don't share the same root, so reset it and + // it'll be set below. In the non-fragment case, this will only happen + // after the html element has been finished at which point there are no + // further elements. + if (xml_node == xml_output_node) { + xml_root = NULL; + } + continue; + } + const GumboNode *gumbo_child = children->data[child_index++]; + xmlNodePtr xml_child; + + switch (gumbo_child->type) { + case GUMBO_NODE_DOCUMENT: + abort(); // Bug in Gumbo. + + case GUMBO_NODE_TEXT: + case GUMBO_NODE_WHITESPACE: + xml_child = xmlNewDocText(doc, (const xmlChar *)gumbo_child->v.text.text); + set_line(xml_child, gumbo_child->v.text.start_pos.line); + xmlAddChild(xml_node, xml_child); + break; + + case GUMBO_NODE_CDATA: + xml_child = xmlNewCDataBlock(doc, (const xmlChar *)gumbo_child->v.text.text, + (int) strlen(gumbo_child->v.text.text)); + set_line(xml_child, gumbo_child->v.text.start_pos.line); + xmlAddChild(xml_node, xml_child); + break; + + case GUMBO_NODE_COMMENT: + xml_child = xmlNewDocComment(doc, (const xmlChar *)gumbo_child->v.text.text); + set_line(xml_child, gumbo_child->v.text.start_pos.line); + xmlAddChild(xml_node, xml_child); + break; + + case GUMBO_NODE_TEMPLATE: + // XXX: Should create a template element and a new DocumentFragment + case GUMBO_NODE_ELEMENT: { + xml_child = xmlNewDocNode(doc, NULL, (const xmlChar *)gumbo_child->v.element.name, NULL); + set_line(xml_child, gumbo_child->v.element.start_pos.line); + if (xml_root == NULL) { + xml_root = xml_child; + } + xmlNsPtr ns = NULL; + switch (gumbo_child->v.element.tag_namespace) { + case GUMBO_NAMESPACE_HTML: + break; + case GUMBO_NAMESPACE_SVG: + ns = lookup_or_add_ns(doc, xml_root, "http://www.w3.org/2000/svg", "svg"); + break; + case GUMBO_NAMESPACE_MATHML: + ns = lookup_or_add_ns(doc, xml_root, "http://www.w3.org/1998/Math/MathML", "math"); + break; + } + if (ns != NULL) { + xmlSetNs(xml_child, ns); + } + xmlAddChild(xml_node, xml_child); + + // Add the attributes. + const GumboVector *attrs = &gumbo_child->v.element.attributes; + for (size_t i = 0; i < attrs->length; i++) { + const GumboAttribute *attr = attrs->data[i]; + + switch (attr->attr_namespace) { + case GUMBO_ATTR_NAMESPACE_XLINK: + ns = lookup_or_add_ns(doc, xml_root, "http://www.w3.org/1999/xlink", "xlink"); + break; + + case GUMBO_ATTR_NAMESPACE_XML: + ns = lookup_or_add_ns(doc, xml_root, "http://www.w3.org/XML/1998/namespace", "xml"); + break; + + case GUMBO_ATTR_NAMESPACE_XMLNS: + ns = lookup_or_add_ns(doc, xml_root, "http://www.w3.org/2000/xmlns/", "xmlns"); + break; + + default: + ns = NULL; + } + xmlNewNsProp(xml_child, ns, (const xmlChar *)attr->name, (const xmlChar *)attr->value); + } + + // Add children for this element. + child_index = 0; + gumbo_node = gumbo_child; + xml_node = xml_child; + } + } + } +} + +static void +add_errors(const GumboOutput *output, VALUE rdoc, VALUE input, VALUE url) +{ + const char *input_str = RSTRING_PTR(input); + size_t input_len = (size_t)RSTRING_LEN(input); + + // Add parse errors to rdoc. + if (output->errors.length) { + const GumboVector *errors = &output->errors; + VALUE rerrors = rb_ary_new2(errors->length); + + for (size_t i = 0; i < errors->length; i++) { + GumboError *err = errors->data[i]; + GumboSourcePosition position = gumbo_error_position(err); + char *msg; + size_t size = gumbo_caret_diagnostic_to_string(err, input_str, input_len, &msg); + VALUE err_str = rb_utf8_str_new(msg, (int)size); + free(msg); + VALUE syntax_error = rb_class_new_instance(1, &err_str, cNokogiriXmlSyntaxError); + const char *error_code = gumbo_error_code(err); + VALUE str1 = error_code ? rb_utf8_str_new_static(error_code, (int)strlen(error_code)) : Qnil; + rb_iv_set(syntax_error, "@domain", INT2NUM(1)); // XML_FROM_PARSER + rb_iv_set(syntax_error, "@code", INT2NUM(1)); // XML_ERR_INTERNAL_ERROR + rb_iv_set(syntax_error, "@level", INT2NUM(2)); // XML_ERR_ERROR + rb_iv_set(syntax_error, "@file", url); + rb_iv_set(syntax_error, "@line", SIZET2NUM(position.line)); + rb_iv_set(syntax_error, "@str1", str1); + rb_iv_set(syntax_error, "@str2", Qnil); + rb_iv_set(syntax_error, "@str3", Qnil); + rb_iv_set(syntax_error, "@int1", INT2NUM(0)); + rb_iv_set(syntax_error, "@column", SIZET2NUM(position.column)); + rb_ary_push(rerrors, syntax_error); + } + rb_iv_set(rdoc, "@errors", rerrors); + } +} + +typedef struct { + GumboOutput *output; + VALUE input; + VALUE url_or_frag; + VALUE klass; + xmlDocPtr doc; +} ParseArgs; + +static VALUE +parse_cleanup(VALUE parse_args) +{ + ParseArgs *args = (ParseArgs *)parse_args; + gumbo_destroy_output(args->output); + // Make sure garbage collection doesn't mark the objects as being live based + // on references from the ParseArgs. This may be unnecessary. + args->input = Qnil; + args->url_or_frag = Qnil; + if (args->doc != NULL) { + xmlFreeDoc(args->doc); + } + return Qnil; +} + +// Scan the keyword arguments for options common to the document and fragment +// parse. +static GumboOptions +common_options(VALUE kwargs) +{ + // The order of the keywords determines the order of the values below. + // If this order is changed, then setting the options below must change as + // well. + ID keywords[] = { + // Required keywords. + rb_intern_const("max_attributes"), + rb_intern_const("max_errors"), + rb_intern_const("max_tree_depth"), + + // Optional keywords. + rb_intern_const("parse_noscript_content_as_text"), + }; + VALUE values[sizeof keywords / sizeof keywords[0]]; + + // Extract the values coresponding to the required keywords. Raise an error + // if required arguments are missing. + rb_get_kwargs(kwargs, keywords, 3, 1, values); + + GumboOptions options = kGumboDefaultOptions; + options.max_attributes = NUM2INT(values[0]); + options.max_errors = NUM2INT(values[1]); + + // handle negative values + int depth = NUM2INT(values[2]); + options.max_tree_depth = depth < 0 ? UINT_MAX : (unsigned int)depth; + + options.parse_noscript_content_as_text = values[3] != Qundef && RTEST(values[3]); + + return options; +} + +static VALUE parse_continue(VALUE parse_args); + +/* + * @!visibility protected + */ +static VALUE +noko_gumbo_s_parse(int argc, VALUE *argv, VALUE _self) +{ + VALUE input, url, klass, kwargs; + + rb_scan_args(argc, argv, "3:", &input, &url, &klass, &kwargs); + if (NIL_P(kwargs)) { + kwargs = rb_hash_new(); + } + + GumboOptions options = common_options(kwargs); + + GumboOutput *output = perform_parse(&options, input); + ParseArgs args = { + .output = output, + .input = input, + .url_or_frag = url, + .klass = klass, + .doc = NULL, + }; + + return rb_ensure(parse_continue, (VALUE)(&args), parse_cleanup, (VALUE)(&args)); +} + +static VALUE +parse_continue(VALUE parse_args) +{ + ParseArgs *args = (ParseArgs *)parse_args; + GumboOutput *output = args->output; + xmlDocPtr doc; + if (output->document->v.document.has_doctype) { + const char *name = output->document->v.document.name; + const char *public = output->document->v.document.public_identifier; + const char *system = output->document->v.document.system_identifier; + public = public[0] ? public : NULL; + system = system[0] ? system : NULL; + doc = new_html_doc(name, system, public); + } else { + doc = new_html_doc(NULL, NULL, NULL); + } + args->doc = doc; // Make sure doc gets cleaned up if an error is thrown. + build_tree(doc, (xmlNodePtr)doc, output->document); + VALUE rdoc = noko_xml_document_wrap(args->klass, doc); + rb_iv_set(rdoc, "@url", args->url_or_frag); + rb_iv_set(rdoc, "@quirks_mode", INT2NUM(output->document->v.document.doc_type_quirks_mode)); + args->doc = NULL; // The Ruby runtime now owns doc so don't delete it. + add_errors(output, rdoc, args->input, args->url_or_frag); + return rdoc; +} + +static int +lookup_namespace(VALUE node, bool require_known_ns) +{ + ID namespace, href; + CONST_ID(namespace, "namespace"); + CONST_ID(href, "href"); + VALUE ns = rb_funcall(node, namespace, 0); + + if (NIL_P(ns)) { + return GUMBO_NAMESPACE_HTML; + } + ns = rb_funcall(ns, href, 0); + assert(RTEST(ns)); + Check_Type(ns, T_STRING); + + const char *href_ptr = RSTRING_PTR(ns); + size_t href_len = (size_t)RSTRING_LEN(ns); +#define NAMESPACE_P(uri) (href_len == sizeof uri - 1 && !memcmp(href_ptr, uri, href_len)) + if (NAMESPACE_P("http://www.w3.org/1999/xhtml")) { + return GUMBO_NAMESPACE_HTML; + } + if (NAMESPACE_P("http://www.w3.org/1998/Math/MathML")) { + return GUMBO_NAMESPACE_MATHML; + } + if (NAMESPACE_P("http://www.w3.org/2000/svg")) { + return GUMBO_NAMESPACE_SVG; + } +#undef NAMESPACE_P + if (require_known_ns) { + rb_raise(rb_eArgError, "Unexpected namespace URI \"%*s\"", (int)href_len, href_ptr); + } + return -1; +} + +static xmlNodePtr +extract_xml_node(VALUE node) +{ + xmlNodePtr xml_node; + Noko_Node_Get_Struct(node, xmlNode, xml_node); + return xml_node; +} + +static VALUE fragment_continue(VALUE parse_args); + +/* + * @!visibility protected + */ +static VALUE +noko_gumbo_s_fragment(int argc, VALUE *argv, VALUE _self) +{ + VALUE doc_fragment; + VALUE tags; + VALUE ctx; + VALUE kwargs; + ID name = rb_intern_const("name"); + const char *ctx_tag; + GumboNamespaceEnum ctx_ns; + GumboQuirksModeEnum quirks_mode; + bool form = false; + const char *encoding = NULL; + + rb_scan_args(argc, argv, "3:", &doc_fragment, &tags, &ctx, &kwargs); + if (NIL_P(kwargs)) { + kwargs = rb_hash_new(); + } + + GumboOptions options = common_options(kwargs); + + if (NIL_P(ctx)) { + ctx_tag = "body"; + ctx_ns = GUMBO_NAMESPACE_HTML; + } else if (TYPE(ctx) == T_STRING) { + ctx_tag = StringValueCStr(ctx); + ctx_ns = GUMBO_NAMESPACE_HTML; + size_t len = (size_t)RSTRING_LEN(ctx); + const char *colon = memchr(ctx_tag, ':', len); + if (colon) { + switch (colon - ctx_tag) { + case 3: + if (st_strncasecmp(ctx_tag, "svg", 3) != 0) { + goto error; + } + ctx_ns = GUMBO_NAMESPACE_SVG; + break; + case 4: + if (st_strncasecmp(ctx_tag, "html", 4) == 0) { + ctx_ns = GUMBO_NAMESPACE_HTML; + } else if (st_strncasecmp(ctx_tag, "math", 4) == 0) { + ctx_ns = GUMBO_NAMESPACE_MATHML; + } else { + goto error; + } + break; + default: +error: + rb_raise(rb_eArgError, "Invalid context namespace '%*s'", (int)(colon - ctx_tag), ctx_tag); + } + ctx_tag = colon + 1; + } else { + // For convenience, put 'svg' and 'math' in their namespaces. + if (len == 3 && st_strncasecmp(ctx_tag, "svg", 3) == 0) { + ctx_ns = GUMBO_NAMESPACE_SVG; + } else if (len == 4 && st_strncasecmp(ctx_tag, "math", 4) == 0) { + ctx_ns = GUMBO_NAMESPACE_MATHML; + } + } + + // Check if it's a form. + form = ctx_ns == GUMBO_NAMESPACE_HTML && st_strcasecmp(ctx_tag, "form") == 0; + } else { + ID element_ = rb_intern_const("element?"); + + // Context fragment name. + VALUE tag_name = rb_funcall(ctx, name, 0); + assert(RTEST(tag_name)); + Check_Type(tag_name, T_STRING); + ctx_tag = StringValueCStr(tag_name); + + // Context fragment namespace. + ctx_ns = lookup_namespace(ctx, true); + + // Check for a form ancestor, including self. + for (VALUE node = ctx; + !NIL_P(node); + node = rb_respond_to(node, parent) ? rb_funcall(node, parent, 0) : Qnil) { + if (!RTEST(rb_funcall(node, element_, 0))) { + continue; + } + VALUE element_name = rb_funcall(node, name, 0); + if (RSTRING_LEN(element_name) == 4 + && !st_strcasecmp(RSTRING_PTR(element_name), "form") + && lookup_namespace(node, false) == GUMBO_NAMESPACE_HTML) { + form = true; + break; + } + } + + // Encoding. + if (ctx_ns == GUMBO_NAMESPACE_MATHML + && RSTRING_LEN(tag_name) == 14 + && !st_strcasecmp(ctx_tag, "annotation-xml")) { + VALUE enc = rb_funcall(ctx, rb_intern_const("[]"), + 1, + rb_utf8_str_new_static("encoding", 8)); + if (RTEST(enc)) { + Check_Type(enc, T_STRING); + encoding = StringValueCStr(enc); + } + } + } + + // Quirks mode. + VALUE doc = rb_funcall(doc_fragment, rb_intern_const("document"), 0); + VALUE dtd = rb_funcall(doc, internal_subset, 0); + VALUE doc_quirks_mode = rb_iv_get(doc, "@quirks_mode"); + if (NIL_P(ctx) || (TYPE(ctx) == T_STRING) || NIL_P(doc_quirks_mode)) { + quirks_mode = GUMBO_DOCTYPE_NO_QUIRKS; + } else if (NIL_P(dtd)) { + quirks_mode = GUMBO_DOCTYPE_QUIRKS; + } else { + VALUE dtd_name = rb_funcall(dtd, name, 0); + VALUE pubid = rb_funcall(dtd, rb_intern_const("external_id"), 0); + VALUE sysid = rb_funcall(dtd, rb_intern_const("system_id"), 0); + quirks_mode = gumbo_compute_quirks_mode( + NIL_P(dtd_name) ? NULL : StringValueCStr(dtd_name), + NIL_P(pubid) ? NULL : StringValueCStr(pubid), + NIL_P(sysid) ? NULL : StringValueCStr(sysid) + ); + } + + // Perform a fragment parse. + options.fragment_context = ctx_tag; + options.fragment_namespace = ctx_ns; + options.fragment_encoding = encoding; + options.quirks_mode = quirks_mode; + options.fragment_context_has_form_ancestor = form; + + // Add one to the max tree depth to account for the HTML element. + if (options.max_tree_depth < UINT_MAX) { options.max_tree_depth++; } + + GumboOutput *output = perform_parse(&options, tags); + ParseArgs args = { + .output = output, + .input = tags, + .url_or_frag = doc_fragment, + .doc = (xmlDocPtr)extract_xml_node(doc), + }; + rb_ensure(fragment_continue, (VALUE)(&args), parse_cleanup, (VALUE)(&args)); + return Qnil; +} + +static VALUE +fragment_continue(VALUE parse_args) +{ + ParseArgs *args = (ParseArgs *)parse_args; + GumboOutput *output = args->output; + VALUE doc_fragment = args->url_or_frag; + xmlDocPtr xml_doc = args->doc; + + args->doc = NULL; // The Ruby runtime owns doc so make sure we don't delete it. + xmlNodePtr xml_frag = extract_xml_node(doc_fragment); + build_tree(xml_doc, xml_frag, output->root); + rb_iv_set(doc_fragment, "@quirks_mode", INT2NUM(output->document->v.document.doc_type_quirks_mode)); + add_errors(output, doc_fragment, args->input, rb_utf8_str_new_static("#fragment", 9)); + return Qnil; +} + +// Initialize the Nokogumbo class and fetch constants we will use later. +void +noko_init_gumbo(void) +{ + // Class constants. + cNokogiriHtml5Document = rb_define_class_under(mNokogiriHtml5, "Document", cNokogiriHtml4Document); + rb_gc_register_mark_object(cNokogiriHtml5Document); + + // Interned symbols. + internal_subset = rb_intern_const("internal_subset"); + parent = rb_intern_const("parent"); + + // Define Nokogumbo module with parse and fragment methods. + rb_define_singleton_method(mNokogiriGumbo, "parse", noko_gumbo_s_parse, -1); + rb_define_singleton_method(mNokogiriGumbo, "fragment", noko_gumbo_s_fragment, -1); +} + +// vim: set shiftwidth=2 softtabstop=2 tabstop=8 expandtab: diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/html4_document.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/html4_document.c new file mode 100644 index 0000000..e3e0ee0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/html4_document.c @@ -0,0 +1,171 @@ +#include + +VALUE cNokogiriHtml4Document ; + +static ID id_encoding_found; +static ID id_to_s; + +/* + * call-seq: + * new(uri=nil, external_id=nil) → HTML4::Document + * + * Create a new empty document with base URI +uri+ and external ID +external_id+. + */ +static VALUE +rb_html_document_s_new(int argc, VALUE *argv, VALUE klass) +{ + VALUE uri, external_id, rest, rb_doc; + htmlDocPtr doc; + + rb_scan_args(argc, argv, "0*", &rest); + uri = rb_ary_entry(rest, (long)0); + external_id = rb_ary_entry(rest, (long)1); + + doc = htmlNewDoc( + RTEST(uri) ? (const xmlChar *)StringValueCStr(uri) : NULL, + RTEST(external_id) ? (const xmlChar *)StringValueCStr(external_id) : NULL + ); + rb_doc = noko_xml_document_wrap_with_init_args(klass, doc, argc, argv); + return rb_doc ; +} + +/* + * call-seq: + * read_io(io, url, encoding, options) + * + * Read the HTML document from +io+ with given +url+, +encoding+, + * and +options+. See Nokogiri::HTML4.parse + */ +static VALUE +rb_html_document_s_read_io(VALUE klass, VALUE rb_io, VALUE rb_url, VALUE rb_encoding, VALUE rb_options) +{ + VALUE rb_doc; + VALUE rb_error_list = rb_ary_new(); + htmlDocPtr c_doc; + const char *c_url = NIL_P(rb_url) ? NULL : StringValueCStr(rb_url); + const char *c_encoding = NIL_P(rb_encoding) ? NULL : StringValueCStr(rb_encoding); + int options = NUM2INT(rb_options); + + xmlSetStructuredErrorFunc((void *)rb_error_list, noko__error_array_pusher); + + c_doc = htmlReadIO(noko_io_read, noko_io_close, (void *)rb_io, c_url, c_encoding, options); + + xmlSetStructuredErrorFunc(NULL, NULL); + + /* + * If EncodingFound has occurred in EncodingReader, make sure to do + * a cleanup and propagate the error. + */ + if (rb_respond_to(rb_io, id_encoding_found)) { + VALUE encoding_found = rb_funcall(rb_io, id_encoding_found, 0); + if (!NIL_P(encoding_found)) { + xmlFreeDoc(c_doc); + rb_exc_raise(encoding_found); + } + } + + if ((c_doc == NULL) || (!(options & XML_PARSE_RECOVER) && (RARRAY_LEN(rb_error_list) > 0))) { + VALUE rb_error ; + + xmlFreeDoc(c_doc); + + rb_error = rb_ary_entry(rb_error_list, 0); + if (rb_error == Qnil) { + rb_raise(rb_eRuntimeError, "Could not parse document"); + } else { + VALUE exception_message = rb_funcall(rb_error, id_to_s, 0); + exception_message = rb_str_concat(rb_str_new2("Parser without recover option encountered error or warning: "), + exception_message); + rb_exc_raise(rb_class_new_instance(1, &exception_message, cNokogiriXmlSyntaxError)); + } + + return Qnil; + } + + rb_doc = noko_xml_document_wrap(klass, c_doc); + rb_iv_set(rb_doc, "@errors", rb_error_list); + return rb_doc; +} + +/* + * call-seq: + * read_memory(string, url, encoding, options) + * + * Read the HTML document contained in +string+ with given +url+, +encoding+, + * and +options+. See Nokogiri::HTML4.parse + */ +static VALUE +rb_html_document_s_read_memory(VALUE klass, VALUE rb_html, VALUE rb_url, VALUE rb_encoding, VALUE rb_options) +{ + VALUE rb_doc; + VALUE rb_error_list = rb_ary_new(); + htmlDocPtr c_doc; + const char *c_buffer = StringValuePtr(rb_html); + const char *c_url = NIL_P(rb_url) ? NULL : StringValueCStr(rb_url); + const char *c_encoding = NIL_P(rb_encoding) ? NULL : StringValueCStr(rb_encoding); + int html_len = (int)RSTRING_LEN(rb_html); + int options = NUM2INT(rb_options); + + xmlSetStructuredErrorFunc((void *)rb_error_list, noko__error_array_pusher); + + c_doc = htmlReadMemory(c_buffer, html_len, c_url, c_encoding, options); + + xmlSetStructuredErrorFunc(NULL, NULL); + + if ((c_doc == NULL) || (!(options & XML_PARSE_RECOVER) && (RARRAY_LEN(rb_error_list) > 0))) { + VALUE rb_error ; + + xmlFreeDoc(c_doc); + + rb_error = rb_ary_entry(rb_error_list, 0); + if (rb_error == Qnil) { + rb_raise(rb_eRuntimeError, "Could not parse document"); + } else { + VALUE exception_message = rb_funcall(rb_error, id_to_s, 0); + exception_message = rb_str_concat(rb_str_new2("Parser without recover option encountered error or warning: "), + exception_message); + rb_exc_raise(rb_class_new_instance(1, &exception_message, cNokogiriXmlSyntaxError)); + } + + return Qnil; + } + + rb_doc = noko_xml_document_wrap(klass, c_doc); + rb_iv_set(rb_doc, "@errors", rb_error_list); + return rb_doc; +} + +/* + * call-seq: + * type + * + * The type for this document + */ +static VALUE +rb_html_document_type(VALUE self) +{ + htmlDocPtr doc = noko_xml_document_unwrap(self); + return INT2NUM(doc->type); +} + +void +noko_init_html_document(void) +{ + /* this is here so that rdoc doesn't ignore this file. */ + /* + mNokogiri = rb_define_module("Nokogiri"); + mNokogiriHtml4 = rb_define_module_under(mNokogiri, "HTML4"); + */ + + assert(cNokogiriXmlDocument); + cNokogiriHtml4Document = rb_define_class_under(mNokogiriHtml4, "Document", cNokogiriXmlDocument); + + rb_define_singleton_method(cNokogiriHtml4Document, "read_memory", rb_html_document_s_read_memory, 4); + rb_define_singleton_method(cNokogiriHtml4Document, "read_io", rb_html_document_s_read_io, 4); + rb_define_singleton_method(cNokogiriHtml4Document, "new", rb_html_document_s_new, -1); + + rb_define_method(cNokogiriHtml4Document, "type", rb_html_document_type, 0); + + id_encoding_found = rb_intern("encoding_found"); + id_to_s = rb_intern("to_s"); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/html4_element_description.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/html4_element_description.c new file mode 100644 index 0000000..bd345d1 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/html4_element_description.c @@ -0,0 +1,299 @@ +#include + +static const rb_data_type_t html_elem_desc_type = { + .wrap_struct_name = "htmlElemDesc", + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +VALUE cNokogiriHtml4ElementDescription ; + +/* + * call-seq: + * required_attributes + * + * A list of required attributes for this element + */ +static VALUE +required_attributes(VALUE self) +{ + const htmlElemDesc *description; + VALUE list; + int i; + + TypedData_Get_Struct(self, htmlElemDesc, &html_elem_desc_type, description); + + list = rb_ary_new(); + + if (NULL == description->attrs_req) { return list; } + + for (i = 0; description->attrs_depr[i]; i++) { + rb_ary_push(list, NOKOGIRI_STR_NEW2(description->attrs_req[i])); + } + + return list; +} + +/* + * call-seq: + * deprecated_attributes + * + * A list of deprecated attributes for this element + */ +static VALUE +deprecated_attributes(VALUE self) +{ + const htmlElemDesc *description; + VALUE list; + int i; + + TypedData_Get_Struct(self, htmlElemDesc, &html_elem_desc_type, description); + + list = rb_ary_new(); + + if (NULL == description->attrs_depr) { return list; } + + for (i = 0; description->attrs_depr[i]; i++) { + rb_ary_push(list, NOKOGIRI_STR_NEW2(description->attrs_depr[i])); + } + + return list; +} + +/* + * call-seq: + * optional_attributes + * + * A list of optional attributes for this element + */ +static VALUE +optional_attributes(VALUE self) +{ + const htmlElemDesc *description; + VALUE list; + int i; + + TypedData_Get_Struct(self, htmlElemDesc, &html_elem_desc_type, description); + + list = rb_ary_new(); + + if (NULL == description->attrs_opt) { return list; } + + for (i = 0; description->attrs_opt[i]; i++) { + rb_ary_push(list, NOKOGIRI_STR_NEW2(description->attrs_opt[i])); + } + + return list; +} + +/* + * call-seq: + * default_sub_element + * + * The default sub element for this element + */ +static VALUE +default_sub_element(VALUE self) +{ + const htmlElemDesc *description; + TypedData_Get_Struct(self, htmlElemDesc, &html_elem_desc_type, description); + + if (description->defaultsubelt) { + return NOKOGIRI_STR_NEW2(description->defaultsubelt); + } + + return Qnil; +} + +/* + * call-seq: + * sub_elements + * + * A list of allowed sub elements for this element. + */ +static VALUE +sub_elements(VALUE self) +{ + const htmlElemDesc *description; + VALUE list; + int i; + + TypedData_Get_Struct(self, htmlElemDesc, &html_elem_desc_type, description); + + list = rb_ary_new(); + + if (NULL == description->subelts) { return list; } + + for (i = 0; description->subelts[i]; i++) { + rb_ary_push(list, NOKOGIRI_STR_NEW2(description->subelts[i])); + } + + return list; +} + +/* + * call-seq: + * description + * + * The description for this element + */ +static VALUE +description(VALUE self) +{ + const htmlElemDesc *description; + TypedData_Get_Struct(self, htmlElemDesc, &html_elem_desc_type, description); + + return NOKOGIRI_STR_NEW2(description->desc); +} + +/* + * call-seq: + * inline? + * + * Is this element an inline element? + */ +static VALUE +inline_eh(VALUE self) +{ + const htmlElemDesc *description; + TypedData_Get_Struct(self, htmlElemDesc, &html_elem_desc_type, description); + + if (description->isinline) { return Qtrue; } + return Qfalse; +} + +/* + * call-seq: + * deprecated? + * + * Is this element deprecated? + */ +static VALUE +deprecated_eh(VALUE self) +{ + const htmlElemDesc *description; + TypedData_Get_Struct(self, htmlElemDesc, &html_elem_desc_type, description); + + if (description->depr) { return Qtrue; } + return Qfalse; +} + +/* + * call-seq: + * empty? + * + * Is this an empty element? + */ +static VALUE +empty_eh(VALUE self) +{ + const htmlElemDesc *description; + TypedData_Get_Struct(self, htmlElemDesc, &html_elem_desc_type, description); + + if (description->empty) { return Qtrue; } + return Qfalse; +} + +/* + * call-seq: + * save_end_tag? + * + * Should the end tag be saved? + */ +static VALUE +save_end_tag_eh(VALUE self) +{ + const htmlElemDesc *description; + TypedData_Get_Struct(self, htmlElemDesc, &html_elem_desc_type, description); + + if (description->saveEndTag) { return Qtrue; } + return Qfalse; +} + +/* + * call-seq: + * implied_end_tag? + * + * Can the end tag be implied for this tag? + */ +static VALUE +implied_end_tag_eh(VALUE self) +{ + const htmlElemDesc *description; + TypedData_Get_Struct(self, htmlElemDesc, &html_elem_desc_type, description); + + if (description->endTag) { return Qtrue; } + return Qfalse; +} + +/* + * call-seq: + * implied_start_tag? + * + * Can the start tag be implied for this tag? + */ +static VALUE +implied_start_tag_eh(VALUE self) +{ + const htmlElemDesc *description; + TypedData_Get_Struct(self, htmlElemDesc, &html_elem_desc_type, description); + + if (description->startTag) { return Qtrue; } + return Qfalse; +} + +/* + * call-seq: + * name + * + * Get the tag name for this ElementDescription + */ +static VALUE +name(VALUE self) +{ + const htmlElemDesc *description; + TypedData_Get_Struct(self, htmlElemDesc, &html_elem_desc_type, description); + + if (NULL == description->name) { return Qnil; } + return NOKOGIRI_STR_NEW2(description->name); +} + +/* + * call-seq: + * [](tag_name) + * + * Get ElementDescription for +tag_name+ + */ +static VALUE +get_description(VALUE klass, VALUE tag_name) +{ + const htmlElemDesc *description = htmlTagLookup( + (const xmlChar *)StringValueCStr(tag_name) + ); + + if (NULL == description) { return Qnil; } + return TypedData_Wrap_Struct(klass, &html_elem_desc_type, DISCARD_CONST_QUAL(void *, description)); +} + +void +noko_init_html_element_description(void) +{ + cNokogiriHtml4ElementDescription = rb_define_class_under(mNokogiriHtml4, "ElementDescription", rb_cObject); + + rb_undef_alloc_func(cNokogiriHtml4ElementDescription); + + rb_define_singleton_method(cNokogiriHtml4ElementDescription, "[]", get_description, 1); + + rb_define_method(cNokogiriHtml4ElementDescription, "name", name, 0); + rb_define_method(cNokogiriHtml4ElementDescription, "implied_start_tag?", implied_start_tag_eh, 0); + rb_define_method(cNokogiriHtml4ElementDescription, "implied_end_tag?", implied_end_tag_eh, 0); + rb_define_method(cNokogiriHtml4ElementDescription, "save_end_tag?", save_end_tag_eh, 0); + rb_define_method(cNokogiriHtml4ElementDescription, "empty?", empty_eh, 0); + rb_define_method(cNokogiriHtml4ElementDescription, "deprecated?", deprecated_eh, 0); + rb_define_method(cNokogiriHtml4ElementDescription, "inline?", inline_eh, 0); + rb_define_method(cNokogiriHtml4ElementDescription, "description", description, 0); + rb_define_method(cNokogiriHtml4ElementDescription, "sub_elements", sub_elements, 0); + rb_define_method(cNokogiriHtml4ElementDescription, "default_sub_element", default_sub_element, 0); + rb_define_method(cNokogiriHtml4ElementDescription, "optional_attributes", optional_attributes, 0); + rb_define_method(cNokogiriHtml4ElementDescription, "deprecated_attributes", deprecated_attributes, 0); + rb_define_method(cNokogiriHtml4ElementDescription, "required_attributes", required_attributes, 0); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/html4_entity_lookup.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/html4_entity_lookup.c new file mode 100644 index 0000000..85ad384 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/html4_entity_lookup.c @@ -0,0 +1,37 @@ +#include + +static VALUE cNokogiriHtml4EntityLookup; + +/* + * call-seq: + * get(key) + * + * Get the HTML4::EntityDescription for +key+ + */ +static VALUE +get(VALUE _, VALUE rb_entity_name) +{ + VALUE cNokogiriHtml4EntityDescription; + const htmlEntityDesc *c_entity_desc; + VALUE rb_constructor_args[3]; + + c_entity_desc = htmlEntityLookup((const xmlChar *)StringValueCStr(rb_entity_name)); + if (NULL == c_entity_desc) { + return Qnil; + } + + rb_constructor_args[0] = UINT2NUM(c_entity_desc->value); + rb_constructor_args[1] = NOKOGIRI_STR_NEW2(c_entity_desc->name); + rb_constructor_args[2] = NOKOGIRI_STR_NEW2(c_entity_desc->desc); + + cNokogiriHtml4EntityDescription = rb_const_get_at(mNokogiriHtml4, rb_intern("EntityDescription")); + return rb_class_new_instance(3, rb_constructor_args, cNokogiriHtml4EntityDescription); +} + +void +noko_init_html_entity_lookup(void) +{ + cNokogiriHtml4EntityLookup = rb_define_class_under(mNokogiriHtml4, "EntityLookup", rb_cObject); + + rb_define_method(cNokogiriHtml4EntityLookup, "get", get, 1); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/html4_sax_parser.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/html4_sax_parser.c new file mode 100644 index 0000000..2316ec2 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/html4_sax_parser.c @@ -0,0 +1,40 @@ +#include + +VALUE cNokogiriHtml4SaxParser; + +static ID id_start_document; + +static void +noko_html4_sax_parser_start_document(void *ctx) +{ + xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr)ctx; + VALUE self = (VALUE)ctxt->_private; + VALUE doc = rb_iv_get(self, "@document"); + + xmlSAX2StartDocument(ctx); + + rb_funcall(doc, id_start_document, 0); +} + +static VALUE +noko_html4_sax_parser_initialize(VALUE self) +{ + xmlSAXHandlerPtr handler = noko_xml_sax_parser_unwrap(self); + + rb_call_super(0, NULL); + + handler->startDocument = noko_html4_sax_parser_start_document; + + return self; +} + +void +noko_init_html4_sax_parser(void) +{ + cNokogiriHtml4SaxParser = rb_define_class_under(mNokogiriHtml4Sax, "Parser", cNokogiriXmlSaxParser); + + rb_define_private_method(cNokogiriHtml4SaxParser, "initialize_native", + noko_html4_sax_parser_initialize, 0); + + id_start_document = rb_intern("start_document"); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/html4_sax_parser_context.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/html4_sax_parser_context.c new file mode 100644 index 0000000..6f971d1 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/html4_sax_parser_context.c @@ -0,0 +1,98 @@ +#include + +VALUE cNokogiriHtml4SaxParserContext ; + +/* :nodoc: */ +static VALUE +noko_html4_sax_parser_context_s_native_memory(VALUE rb_class, VALUE rb_input, VALUE rb_encoding) +{ + Check_Type(rb_input, T_STRING); + if (!(int)RSTRING_LEN(rb_input)) { + rb_raise(rb_eRuntimeError, "input string cannot be empty"); + } + + if (!NIL_P(rb_encoding) && !rb_obj_is_kind_of(rb_encoding, rb_cEncoding)) { + rb_raise(rb_eTypeError, "argument must be an Encoding object"); + } + + htmlParserCtxtPtr c_context = + htmlCreateMemoryParserCtxt(StringValuePtr(rb_input), (int)RSTRING_LEN(rb_input)); + if (!c_context) { + rb_raise(rb_eRuntimeError, "failed to create xml sax parser context"); + } + + noko_xml_sax_parser_context_set_encoding(c_context, rb_encoding); + + if (c_context->sax) { + xmlFree(c_context->sax); + c_context->sax = NULL; + } + + return noko_xml_sax_parser_context_wrap(rb_class, c_context); +} + +/* :nodoc: */ +static VALUE +noko_html4_sax_parser_context_s_native_file(VALUE rb_class, VALUE rb_filename, VALUE rb_encoding) +{ + if (!NIL_P(rb_encoding) && !rb_obj_is_kind_of(rb_encoding, rb_cEncoding)) { + rb_raise(rb_eTypeError, "argument must be an Encoding object"); + } + + htmlParserCtxtPtr c_context = htmlCreateFileParserCtxt(StringValueCStr(rb_filename), NULL); + if (!c_context) { + rb_raise(rb_eRuntimeError, "failed to create xml sax parser context"); + } + + noko_xml_sax_parser_context_set_encoding(c_context, rb_encoding); + + if (c_context->sax) { + xmlFree(c_context->sax); + c_context->sax = NULL; + } + + return noko_xml_sax_parser_context_wrap(rb_class, c_context); +} + +static VALUE +noko_html4_sax_parser_context__parse_with(VALUE rb_context, VALUE rb_sax_parser) +{ + htmlParserCtxtPtr ctxt; + htmlSAXHandlerPtr sax; + + if (!rb_obj_is_kind_of(rb_sax_parser, cNokogiriXmlSaxParser)) { + rb_raise(rb_eArgError, "argument must be a Nokogiri::XML::SAX::Parser"); + } + + ctxt = noko_xml_sax_parser_context_unwrap(rb_context); + sax = noko_xml_sax_parser_unwrap(rb_sax_parser); + + ctxt->sax = sax; + ctxt->userData = ctxt; /* so we can use libxml2/SAX2.c handlers if we want to */ + ctxt->_private = (void *)rb_sax_parser; + + xmlSetStructuredErrorFunc(NULL, NULL); + + /* although we're calling back into Ruby here, we don't need to worry about exceptions, because we + * don't have any cleanup to do. The only memory we need to free is handled by + * xml_sax_parser_context_type_free */ + htmlParseDocument(ctxt); + + return Qnil; +} + +void +noko_init_html_sax_parser_context(void) +{ + assert(cNokogiriXmlSaxParserContext); + cNokogiriHtml4SaxParserContext = rb_define_class_under(mNokogiriHtml4Sax, "ParserContext", + cNokogiriXmlSaxParserContext); + + rb_define_singleton_method(cNokogiriHtml4SaxParserContext, "native_memory", + noko_html4_sax_parser_context_s_native_memory, 2); + rb_define_singleton_method(cNokogiriHtml4SaxParserContext, "native_file", + noko_html4_sax_parser_context_s_native_file, 2); + + rb_define_method(cNokogiriHtml4SaxParserContext, "parse_with", + noko_html4_sax_parser_context__parse_with, 1); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/html4_sax_push_parser.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/html4_sax_push_parser.c new file mode 100644 index 0000000..845baf0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/html4_sax_push_parser.c @@ -0,0 +1,96 @@ +#include + +VALUE cNokogiriHtml4SaxPushParser; + +/* + * Write +chunk+ to PushParser. +last_chunk+ triggers the end_document handle + */ +static VALUE +noko_html4_sax_push_parser__native_write(VALUE self, VALUE rb_chunk, VALUE rb_last_chunk) +{ + xmlParserCtxtPtr ctx; + const char *chunk = NULL; + int size = 0; + int status = 0; + libxmlStructuredErrorHandlerState handler_state; + + ctx = noko_xml_sax_push_parser_unwrap(self); + + if (Qnil != rb_chunk) { + chunk = StringValuePtr(rb_chunk); + size = (int)RSTRING_LEN(rb_chunk); + } + + noko__structured_error_func_save_and_set(&handler_state, NULL, NULL); + + status = htmlParseChunk(ctx, chunk, size, Qtrue == rb_last_chunk ? 1 : 0); + + noko__structured_error_func_restore(&handler_state); + + if ((status != 0) && !(xmlCtxtGetOptions(ctx) & XML_PARSE_RECOVER)) { + // TODO: there appear to be no tests for this block + xmlErrorConstPtr e = xmlCtxtGetLastError(ctx); + noko__error_raise(NULL, e); + } + + return self; +} + +/* + * Initialize the push parser with +xml_sax+ using +filename+ + */ +static VALUE +noko_html4_sax_push_parser__initialize_native( + VALUE self, + VALUE rb_xml_sax, + VALUE rb_filename, + VALUE encoding +) +{ + htmlSAXHandlerPtr sax; + const char *filename = NULL; + htmlParserCtxtPtr ctx; + xmlCharEncoding enc = XML_CHAR_ENCODING_NONE; + + sax = noko_xml_sax_parser_unwrap(rb_xml_sax); + + if (rb_filename != Qnil) { filename = StringValueCStr(rb_filename); } + + if (!NIL_P(encoding)) { + enc = xmlParseCharEncoding(StringValueCStr(encoding)); + if (enc == XML_CHAR_ENCODING_ERROR) { + rb_raise(rb_eArgError, "Unsupported Encoding"); + } + } + + ctx = htmlCreatePushParserCtxt( + sax, + NULL, + NULL, + 0, + filename, + enc + ); + if (ctx == NULL) { + rb_raise(rb_eRuntimeError, "Could not create a parser context"); + } + + ctx->userData = ctx; + ctx->_private = (void *)rb_xml_sax; + + DATA_PTR(self) = ctx; + return self; +} + +void +noko_init_html_sax_push_parser(void) +{ + assert(cNokogiriXmlSaxPushParser); + cNokogiriHtml4SaxPushParser = + rb_define_class_under(mNokogiriHtml4Sax, "PushParser", cNokogiriXmlSaxPushParser); + + rb_define_private_method(cNokogiriHtml4SaxPushParser, "initialize_native", + noko_html4_sax_push_parser__initialize_native, 3); + rb_define_private_method(cNokogiriHtml4SaxPushParser, "native_write", + noko_html4_sax_push_parser__native_write, 2); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libexslt/exslt.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libexslt/exslt.h new file mode 100644 index 0000000..dfbd09b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libexslt/exslt.h @@ -0,0 +1,108 @@ +/* + * Summary: main header file + * + * Copy: See Copyright for the status of this software. + */ + + +#ifndef __EXSLT_H__ +#define __EXSLT_H__ + +#include +#include +#include "exsltexports.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +EXSLTPUBVAR const char *exsltLibraryVersion; +EXSLTPUBVAR const int exsltLibexsltVersion; +EXSLTPUBVAR const int exsltLibxsltVersion; +EXSLTPUBVAR const int exsltLibxmlVersion; + +/** + * EXSLT_COMMON_NAMESPACE: + * + * Namespace for EXSLT common functions + */ +#define EXSLT_COMMON_NAMESPACE ((const xmlChar *) "http://exslt.org/common") +/** + * EXSLT_CRYPTO_NAMESPACE: + * + * Namespace for EXSLT crypto functions + */ +#define EXSLT_CRYPTO_NAMESPACE ((const xmlChar *) "http://exslt.org/crypto") +/** + * EXSLT_MATH_NAMESPACE: + * + * Namespace for EXSLT math functions + */ +#define EXSLT_MATH_NAMESPACE ((const xmlChar *) "http://exslt.org/math") +/** + * EXSLT_SETS_NAMESPACE: + * + * Namespace for EXSLT set functions + */ +#define EXSLT_SETS_NAMESPACE ((const xmlChar *) "http://exslt.org/sets") +/** + * EXSLT_FUNCTIONS_NAMESPACE: + * + * Namespace for EXSLT functions extension functions + */ +#define EXSLT_FUNCTIONS_NAMESPACE ((const xmlChar *) "http://exslt.org/functions") +/** + * EXSLT_STRINGS_NAMESPACE: + * + * Namespace for EXSLT strings functions + */ +#define EXSLT_STRINGS_NAMESPACE ((const xmlChar *) "http://exslt.org/strings") +/** + * EXSLT_DATE_NAMESPACE: + * + * Namespace for EXSLT date functions + */ +#define EXSLT_DATE_NAMESPACE ((const xmlChar *) "http://exslt.org/dates-and-times") +/** + * EXSLT_DYNAMIC_NAMESPACE: + * + * Namespace for EXSLT dynamic functions + */ +#define EXSLT_DYNAMIC_NAMESPACE ((const xmlChar *) "http://exslt.org/dynamic") + +/** + * SAXON_NAMESPACE: + * + * Namespace for SAXON extensions functions + */ +#define SAXON_NAMESPACE ((const xmlChar *) "http://icl.com/saxon") + +EXSLTPUBFUN void EXSLTCALL exsltCommonRegister (void); +#ifdef EXSLT_CRYPTO_ENABLED +EXSLTPUBFUN void EXSLTCALL exsltCryptoRegister (void); +#endif +EXSLTPUBFUN void EXSLTCALL exsltMathRegister (void); +EXSLTPUBFUN void EXSLTCALL exsltSetsRegister (void); +EXSLTPUBFUN void EXSLTCALL exsltFuncRegister (void); +EXSLTPUBFUN void EXSLTCALL exsltStrRegister (void); +EXSLTPUBFUN void EXSLTCALL exsltDateRegister (void); +EXSLTPUBFUN void EXSLTCALL exsltSaxonRegister (void); +EXSLTPUBFUN void EXSLTCALL exsltDynRegister(void); + +EXSLTPUBFUN void EXSLTCALL exsltRegisterAll (void); + +EXSLTPUBFUN int EXSLTCALL exsltDateXpathCtxtRegister (xmlXPathContextPtr ctxt, + const xmlChar *prefix); +EXSLTPUBFUN int EXSLTCALL exsltMathXpathCtxtRegister (xmlXPathContextPtr ctxt, + const xmlChar *prefix); +EXSLTPUBFUN int EXSLTCALL exsltSetsXpathCtxtRegister (xmlXPathContextPtr ctxt, + const xmlChar *prefix); +EXSLTPUBFUN int EXSLTCALL exsltStrXpathCtxtRegister (xmlXPathContextPtr ctxt, + const xmlChar *prefix); + +#ifdef __cplusplus +} +#endif +#endif /* __EXSLT_H__ */ + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libexslt/exsltconfig.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libexslt/exsltconfig.h new file mode 100644 index 0000000..10e43b0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libexslt/exsltconfig.h @@ -0,0 +1,70 @@ +/* + * exsltconfig.h: compile-time version information for the EXSLT library + * + * See Copyright for the status of this software. + * + * daniel@veillard.com + */ + +#ifndef __XML_EXSLTCONFIG_H__ +#define __XML_EXSLTCONFIG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * LIBEXSLT_DOTTED_VERSION: + * + * the version string like "1.2.3" + */ +#define LIBEXSLT_DOTTED_VERSION "0.8.24" + +/** + * LIBEXSLT_VERSION: + * + * the version number: 1.2.3 value is 10203 + */ +#define LIBEXSLT_VERSION 824 + +/** + * LIBEXSLT_VERSION_STRING: + * + * the version number string, 1.2.3 value is "10203" + */ +#define LIBEXSLT_VERSION_STRING "824" + +/** + * LIBEXSLT_VERSION_EXTRA: + * + * extra version information, used to show a Git commit description + */ +#define LIBEXSLT_VERSION_EXTRA "" + +/** + * WITH_CRYPTO: + * + * Whether crypto support is configured into exslt + */ +#if 0 +#define EXSLT_CRYPTO_ENABLED +#endif + +/** + * ATTRIBUTE_UNUSED: + * + * This macro is used to flag unused function parameters to GCC + */ +#ifdef __GNUC__ +#ifndef ATTRIBUTE_UNUSED +#define ATTRIBUTE_UNUSED __attribute__((unused)) +#endif +#else +#define ATTRIBUTE_UNUSED +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __XML_EXSLTCONFIG_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libexslt/exsltexports.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libexslt/exsltexports.h new file mode 100644 index 0000000..ee79ec7 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libexslt/exsltexports.h @@ -0,0 +1,63 @@ +/* + * Summary: macros for marking symbols as exportable/importable. + * + * Copy: See Copyright for the status of this software. + */ + +#ifndef __EXSLT_EXPORTS_H__ +#define __EXSLT_EXPORTS_H__ + +#if defined(_WIN32) || defined(__CYGWIN__) +/** DOC_DISABLE */ + +#ifdef LIBEXSLT_STATIC + #define EXSLTPUBLIC +#elif defined(IN_LIBEXSLT) + #define EXSLTPUBLIC __declspec(dllexport) +#else + #define EXSLTPUBLIC __declspec(dllimport) +#endif + +#define EXSLTCALL __cdecl + +/** DOC_ENABLE */ +#else /* not Windows */ + +/** + * EXSLTPUBLIC: + * + * Macro which declares a public symbol + */ +#define EXSLTPUBLIC + +/** + * EXSLTCALL: + * + * Macro which declares the calling convention for exported functions + */ +#define EXSLTCALL + +#endif /* platform switch */ + +/* + * EXSLTPUBFUN: + * + * Macro which declares an exportable function + */ +#define EXSLTPUBFUN EXSLTPUBLIC + +/** + * EXSLTPUBVAR: + * + * Macro which declares an exportable variable + */ +#define EXSLTPUBVAR EXSLTPUBLIC extern + +/* Compatibility */ +#if !defined(LIBEXSLT_PUBLIC) +#define LIBEXSLT_PUBLIC EXSLTPUBVAR +#endif + +#endif /* __EXSLT_EXPORTS_H__ */ + + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/HTMLparser.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/HTMLparser.h new file mode 100644 index 0000000..7be3d2b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/HTMLparser.h @@ -0,0 +1,336 @@ +/* + * Summary: interface for an HTML 4.0 non-verifying parser + * Description: this module implements an HTML 4.0 non-verifying parser + * with API compatible with the XML parser ones. It should + * be able to parse "real world" HTML, even if severely + * broken from a specification point of view. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __HTML_PARSER_H__ +#define __HTML_PARSER_H__ +#include +#include + +#ifdef LIBXML_HTML_ENABLED + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Most of the back-end structures from XML and HTML are shared. + */ +typedef xmlParserCtxt htmlParserCtxt; +typedef xmlParserCtxtPtr htmlParserCtxtPtr; +typedef xmlParserNodeInfo htmlParserNodeInfo; +typedef xmlSAXHandler htmlSAXHandler; +typedef xmlSAXHandlerPtr htmlSAXHandlerPtr; +typedef xmlParserInput htmlParserInput; +typedef xmlParserInputPtr htmlParserInputPtr; +typedef xmlDocPtr htmlDocPtr; +typedef xmlNodePtr htmlNodePtr; + +/* + * Internal description of an HTML element, representing HTML 4.01 + * and XHTML 1.0 (which share the same structure). + */ +typedef struct _htmlElemDesc htmlElemDesc; +typedef htmlElemDesc *htmlElemDescPtr; +struct _htmlElemDesc { + const char *name; /* The tag name */ + char startTag; /* Whether the start tag can be implied */ + char endTag; /* Whether the end tag can be implied */ + char saveEndTag; /* Whether the end tag should be saved */ + char empty; /* Is this an empty element ? */ + char depr; /* Is this a deprecated element ? */ + char dtd; /* 1: only in Loose DTD, 2: only Frameset one */ + char isinline; /* is this a block 0 or inline 1 element */ + const char *desc; /* the description */ + +/* NRK Jan.2003 + * New fields encapsulating HTML structure + * + * Bugs: + * This is a very limited representation. It fails to tell us when + * an element *requires* subelements (we only have whether they're + * allowed or not), and it doesn't tell us where CDATA and PCDATA + * are allowed. Some element relationships are not fully represented: + * these are flagged with the word MODIFIER + */ + const char** subelts; /* allowed sub-elements of this element */ + const char* defaultsubelt; /* subelement for suggested auto-repair + if necessary or NULL */ + const char** attrs_opt; /* Optional Attributes */ + const char** attrs_depr; /* Additional deprecated attributes */ + const char** attrs_req; /* Required attributes */ +}; + +/* + * Internal description of an HTML entity. + */ +typedef struct _htmlEntityDesc htmlEntityDesc; +typedef htmlEntityDesc *htmlEntityDescPtr; +struct _htmlEntityDesc { + unsigned int value; /* the UNICODE value for the character */ + const char *name; /* The entity name */ + const char *desc; /* the description */ +}; + +#ifdef LIBXML_SAX1_ENABLED + +XML_DEPRECATED +XMLPUBVAR const xmlSAXHandlerV1 htmlDefaultSAXHandler; + +#ifdef LIBXML_THREAD_ENABLED +XML_DEPRECATED +XMLPUBFUN const xmlSAXHandlerV1 *__htmlDefaultSAXHandler(void); +#endif + +#endif /* LIBXML_SAX1_ENABLED */ + +/* + * There is only few public functions. + */ +XML_DEPRECATED +XMLPUBFUN void + htmlInitAutoClose (void); +XMLPUBFUN const htmlElemDesc * + htmlTagLookup (const xmlChar *tag); +XMLPUBFUN const htmlEntityDesc * + htmlEntityLookup(const xmlChar *name); +XMLPUBFUN const htmlEntityDesc * + htmlEntityValueLookup(unsigned int value); + +XMLPUBFUN int + htmlIsAutoClosed(htmlDocPtr doc, + htmlNodePtr elem); +XMLPUBFUN int + htmlAutoCloseTag(htmlDocPtr doc, + const xmlChar *name, + htmlNodePtr elem); +XML_DEPRECATED +XMLPUBFUN const htmlEntityDesc * + htmlParseEntityRef(htmlParserCtxtPtr ctxt, + const xmlChar **str); +XML_DEPRECATED +XMLPUBFUN int + htmlParseCharRef(htmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN void + htmlParseElement(htmlParserCtxtPtr ctxt); + +XMLPUBFUN htmlParserCtxtPtr + htmlNewParserCtxt(void); +XMLPUBFUN htmlParserCtxtPtr + htmlNewSAXParserCtxt(const htmlSAXHandler *sax, + void *userData); + +XMLPUBFUN htmlParserCtxtPtr + htmlCreateMemoryParserCtxt(const char *buffer, + int size); + +XMLPUBFUN int + htmlParseDocument(htmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN htmlDocPtr + htmlSAXParseDoc (const xmlChar *cur, + const char *encoding, + htmlSAXHandlerPtr sax, + void *userData); +XMLPUBFUN htmlDocPtr + htmlParseDoc (const xmlChar *cur, + const char *encoding); +XMLPUBFUN htmlParserCtxtPtr + htmlCreateFileParserCtxt(const char *filename, + const char *encoding); +XML_DEPRECATED +XMLPUBFUN htmlDocPtr + htmlSAXParseFile(const char *filename, + const char *encoding, + htmlSAXHandlerPtr sax, + void *userData); +XMLPUBFUN htmlDocPtr + htmlParseFile (const char *filename, + const char *encoding); +XMLPUBFUN int + UTF8ToHtml (unsigned char *out, + int *outlen, + const unsigned char *in, + int *inlen); +XMLPUBFUN int + htmlEncodeEntities(unsigned char *out, + int *outlen, + const unsigned char *in, + int *inlen, int quoteChar); +XMLPUBFUN int + htmlIsScriptAttribute(const xmlChar *name); +XML_DEPRECATED +XMLPUBFUN int + htmlHandleOmittedElem(int val); + +#ifdef LIBXML_PUSH_ENABLED +/** + * Interfaces for the Push mode. + */ +XMLPUBFUN htmlParserCtxtPtr + htmlCreatePushParserCtxt(htmlSAXHandlerPtr sax, + void *user_data, + const char *chunk, + int size, + const char *filename, + xmlCharEncoding enc); +XMLPUBFUN int + htmlParseChunk (htmlParserCtxtPtr ctxt, + const char *chunk, + int size, + int terminate); +#endif /* LIBXML_PUSH_ENABLED */ + +XMLPUBFUN void + htmlFreeParserCtxt (htmlParserCtxtPtr ctxt); + +/* + * New set of simpler/more flexible APIs + */ +/** + * xmlParserOption: + * + * This is the set of XML parser options that can be passed down + * to the xmlReadDoc() and similar calls. + */ +typedef enum { + HTML_PARSE_RECOVER = 1<<0, /* Relaxed parsing */ + HTML_PARSE_NODEFDTD = 1<<2, /* do not default a doctype if not found */ + HTML_PARSE_NOERROR = 1<<5, /* suppress error reports */ + HTML_PARSE_NOWARNING= 1<<6, /* suppress warning reports */ + HTML_PARSE_PEDANTIC = 1<<7, /* pedantic error reporting */ + HTML_PARSE_NOBLANKS = 1<<8, /* remove blank nodes */ + HTML_PARSE_NONET = 1<<11,/* Forbid network access */ + HTML_PARSE_NOIMPLIED= 1<<13,/* Do not add implied html/body... elements */ + HTML_PARSE_COMPACT = 1<<16,/* compact small text nodes */ + HTML_PARSE_IGNORE_ENC=1<<21 /* ignore internal document encoding hint */ +} htmlParserOption; + +XMLPUBFUN void + htmlCtxtReset (htmlParserCtxtPtr ctxt); +XMLPUBFUN int + htmlCtxtUseOptions (htmlParserCtxtPtr ctxt, + int options); +XMLPUBFUN htmlDocPtr + htmlReadDoc (const xmlChar *cur, + const char *URL, + const char *encoding, + int options); +XMLPUBFUN htmlDocPtr + htmlReadFile (const char *URL, + const char *encoding, + int options); +XMLPUBFUN htmlDocPtr + htmlReadMemory (const char *buffer, + int size, + const char *URL, + const char *encoding, + int options); +XMLPUBFUN htmlDocPtr + htmlReadFd (int fd, + const char *URL, + const char *encoding, + int options); +XMLPUBFUN htmlDocPtr + htmlReadIO (xmlInputReadCallback ioread, + xmlInputCloseCallback ioclose, + void *ioctx, + const char *URL, + const char *encoding, + int options); +XMLPUBFUN htmlDocPtr + htmlCtxtParseDocument (htmlParserCtxtPtr ctxt, + xmlParserInputPtr input); +XMLPUBFUN htmlDocPtr + htmlCtxtReadDoc (xmlParserCtxtPtr ctxt, + const xmlChar *cur, + const char *URL, + const char *encoding, + int options); +XMLPUBFUN htmlDocPtr + htmlCtxtReadFile (xmlParserCtxtPtr ctxt, + const char *filename, + const char *encoding, + int options); +XMLPUBFUN htmlDocPtr + htmlCtxtReadMemory (xmlParserCtxtPtr ctxt, + const char *buffer, + int size, + const char *URL, + const char *encoding, + int options); +XMLPUBFUN htmlDocPtr + htmlCtxtReadFd (xmlParserCtxtPtr ctxt, + int fd, + const char *URL, + const char *encoding, + int options); +XMLPUBFUN htmlDocPtr + htmlCtxtReadIO (xmlParserCtxtPtr ctxt, + xmlInputReadCallback ioread, + xmlInputCloseCallback ioclose, + void *ioctx, + const char *URL, + const char *encoding, + int options); + +/* NRK/Jan2003: further knowledge of HTML structure + */ +typedef enum { + HTML_NA = 0 , /* something we don't check at all */ + HTML_INVALID = 0x1 , + HTML_DEPRECATED = 0x2 , + HTML_VALID = 0x4 , + HTML_REQUIRED = 0xc /* VALID bit set so ( & HTML_VALID ) is TRUE */ +} htmlStatus ; + +/* Using htmlElemDesc rather than name here, to emphasise the fact + that otherwise there's a lookup overhead +*/ +XMLPUBFUN htmlStatus htmlAttrAllowed(const htmlElemDesc*, const xmlChar*, int) ; +XMLPUBFUN int htmlElementAllowedHere(const htmlElemDesc*, const xmlChar*) ; +XMLPUBFUN htmlStatus htmlElementStatusHere(const htmlElemDesc*, const htmlElemDesc*) ; +XMLPUBFUN htmlStatus htmlNodeStatus(htmlNodePtr, int) ; +/** + * htmlDefaultSubelement: + * @elt: HTML element + * + * Returns the default subelement for this element + */ +#define htmlDefaultSubelement(elt) elt->defaultsubelt +/** + * htmlElementAllowedHereDesc: + * @parent: HTML parent element + * @elt: HTML element + * + * Checks whether an HTML element description may be a + * direct child of the specified element. + * + * Returns 1 if allowed; 0 otherwise. + */ +#define htmlElementAllowedHereDesc(parent,elt) \ + htmlElementAllowedHere((parent), (elt)->name) +/** + * htmlRequiredAttrs: + * @elt: HTML element + * + * Returns the attributes required for the specified element. + */ +#define htmlRequiredAttrs(elt) (elt)->attrs_req + + +#ifdef __cplusplus +} +#endif + +#endif /* LIBXML_HTML_ENABLED */ +#endif /* __HTML_PARSER_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/HTMLtree.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/HTMLtree.h new file mode 100644 index 0000000..8e1ba90 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/HTMLtree.h @@ -0,0 +1,147 @@ +/* + * Summary: specific APIs to process HTML tree, especially serialization + * Description: this module implements a few function needed to process + * tree in an HTML specific way. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __HTML_TREE_H__ +#define __HTML_TREE_H__ + +#include +#include +#include +#include + +#ifdef LIBXML_HTML_ENABLED + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * HTML_TEXT_NODE: + * + * Macro. A text node in a HTML document is really implemented + * the same way as a text node in an XML document. + */ +#define HTML_TEXT_NODE XML_TEXT_NODE +/** + * HTML_ENTITY_REF_NODE: + * + * Macro. An entity reference in a HTML document is really implemented + * the same way as an entity reference in an XML document. + */ +#define HTML_ENTITY_REF_NODE XML_ENTITY_REF_NODE +/** + * HTML_COMMENT_NODE: + * + * Macro. A comment in a HTML document is really implemented + * the same way as a comment in an XML document. + */ +#define HTML_COMMENT_NODE XML_COMMENT_NODE +/** + * HTML_PRESERVE_NODE: + * + * Macro. A preserved node in a HTML document is really implemented + * the same way as a CDATA section in an XML document. + */ +#define HTML_PRESERVE_NODE XML_CDATA_SECTION_NODE +/** + * HTML_PI_NODE: + * + * Macro. A processing instruction in a HTML document is really implemented + * the same way as a processing instruction in an XML document. + */ +#define HTML_PI_NODE XML_PI_NODE + +XMLPUBFUN htmlDocPtr + htmlNewDoc (const xmlChar *URI, + const xmlChar *ExternalID); +XMLPUBFUN htmlDocPtr + htmlNewDocNoDtD (const xmlChar *URI, + const xmlChar *ExternalID); +XMLPUBFUN const xmlChar * + htmlGetMetaEncoding (htmlDocPtr doc); +XMLPUBFUN int + htmlSetMetaEncoding (htmlDocPtr doc, + const xmlChar *encoding); +#ifdef LIBXML_OUTPUT_ENABLED +XMLPUBFUN void + htmlDocDumpMemory (xmlDocPtr cur, + xmlChar **mem, + int *size); +XMLPUBFUN void + htmlDocDumpMemoryFormat (xmlDocPtr cur, + xmlChar **mem, + int *size, + int format); +XMLPUBFUN int + htmlDocDump (FILE *f, + xmlDocPtr cur); +XMLPUBFUN int + htmlSaveFile (const char *filename, + xmlDocPtr cur); +XMLPUBFUN int + htmlNodeDump (xmlBufferPtr buf, + xmlDocPtr doc, + xmlNodePtr cur); +XMLPUBFUN void + htmlNodeDumpFile (FILE *out, + xmlDocPtr doc, + xmlNodePtr cur); +XMLPUBFUN int + htmlNodeDumpFileFormat (FILE *out, + xmlDocPtr doc, + xmlNodePtr cur, + const char *encoding, + int format); +XMLPUBFUN int + htmlSaveFileEnc (const char *filename, + xmlDocPtr cur, + const char *encoding); +XMLPUBFUN int + htmlSaveFileFormat (const char *filename, + xmlDocPtr cur, + const char *encoding, + int format); + +XMLPUBFUN void + htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, + xmlDocPtr doc, + xmlNodePtr cur, + const char *encoding, + int format); +XMLPUBFUN void + htmlDocContentDumpOutput(xmlOutputBufferPtr buf, + xmlDocPtr cur, + const char *encoding); +XMLPUBFUN void + htmlDocContentDumpFormatOutput(xmlOutputBufferPtr buf, + xmlDocPtr cur, + const char *encoding, + int format); +XMLPUBFUN void + htmlNodeDumpOutput (xmlOutputBufferPtr buf, + xmlDocPtr doc, + xmlNodePtr cur, + const char *encoding); + +#endif /* LIBXML_OUTPUT_ENABLED */ + +XMLPUBFUN int + htmlIsBooleanAttr (const xmlChar *name); + + +#ifdef __cplusplus +} +#endif + +#endif /* LIBXML_HTML_ENABLED */ + +#endif /* __HTML_TREE_H__ */ + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/SAX.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/SAX.h new file mode 100644 index 0000000..eea1057 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/SAX.h @@ -0,0 +1,202 @@ +/* + * Summary: Old SAX version 1 handler, deprecated + * Description: DEPRECATED set of SAX version 1 interfaces used to + * build the DOM tree. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + + +#ifndef __XML_SAX_H__ +#define __XML_SAX_H__ + +#include +#include + +#ifdef LIBXML_LEGACY_ENABLED + +#ifdef __cplusplus +extern "C" { +#endif +XML_DEPRECATED +XMLPUBFUN const xmlChar * + getPublicId (void *ctx); +XML_DEPRECATED +XMLPUBFUN const xmlChar * + getSystemId (void *ctx); +XML_DEPRECATED +XMLPUBFUN void + setDocumentLocator (void *ctx, + xmlSAXLocatorPtr loc); + +XML_DEPRECATED +XMLPUBFUN int + getLineNumber (void *ctx); +XML_DEPRECATED +XMLPUBFUN int + getColumnNumber (void *ctx); + +XML_DEPRECATED +XMLPUBFUN int + isStandalone (void *ctx); +XML_DEPRECATED +XMLPUBFUN int + hasInternalSubset (void *ctx); +XML_DEPRECATED +XMLPUBFUN int + hasExternalSubset (void *ctx); + +XML_DEPRECATED +XMLPUBFUN void + internalSubset (void *ctx, + const xmlChar *name, + const xmlChar *ExternalID, + const xmlChar *SystemID); +XML_DEPRECATED +XMLPUBFUN void + externalSubset (void *ctx, + const xmlChar *name, + const xmlChar *ExternalID, + const xmlChar *SystemID); +XML_DEPRECATED +XMLPUBFUN xmlEntityPtr + getEntity (void *ctx, + const xmlChar *name); +XML_DEPRECATED +XMLPUBFUN xmlEntityPtr + getParameterEntity (void *ctx, + const xmlChar *name); +XML_DEPRECATED +XMLPUBFUN xmlParserInputPtr + resolveEntity (void *ctx, + const xmlChar *publicId, + const xmlChar *systemId); + +XML_DEPRECATED +XMLPUBFUN void + entityDecl (void *ctx, + const xmlChar *name, + int type, + const xmlChar *publicId, + const xmlChar *systemId, + xmlChar *content); +XML_DEPRECATED +XMLPUBFUN void + attributeDecl (void *ctx, + const xmlChar *elem, + const xmlChar *fullname, + int type, + int def, + const xmlChar *defaultValue, + xmlEnumerationPtr tree); +XML_DEPRECATED +XMLPUBFUN void + elementDecl (void *ctx, + const xmlChar *name, + int type, + xmlElementContentPtr content); +XML_DEPRECATED +XMLPUBFUN void + notationDecl (void *ctx, + const xmlChar *name, + const xmlChar *publicId, + const xmlChar *systemId); +XML_DEPRECATED +XMLPUBFUN void + unparsedEntityDecl (void *ctx, + const xmlChar *name, + const xmlChar *publicId, + const xmlChar *systemId, + const xmlChar *notationName); + +XML_DEPRECATED +XMLPUBFUN void + startDocument (void *ctx); +XML_DEPRECATED +XMLPUBFUN void + endDocument (void *ctx); +XML_DEPRECATED +XMLPUBFUN void + attribute (void *ctx, + const xmlChar *fullname, + const xmlChar *value); +XML_DEPRECATED +XMLPUBFUN void + startElement (void *ctx, + const xmlChar *fullname, + const xmlChar **atts); +XML_DEPRECATED +XMLPUBFUN void + endElement (void *ctx, + const xmlChar *name); +XML_DEPRECATED +XMLPUBFUN void + reference (void *ctx, + const xmlChar *name); +XML_DEPRECATED +XMLPUBFUN void + characters (void *ctx, + const xmlChar *ch, + int len); +XML_DEPRECATED +XMLPUBFUN void + ignorableWhitespace (void *ctx, + const xmlChar *ch, + int len); +XML_DEPRECATED +XMLPUBFUN void + processingInstruction (void *ctx, + const xmlChar *target, + const xmlChar *data); +XML_DEPRECATED +XMLPUBFUN void + globalNamespace (void *ctx, + const xmlChar *href, + const xmlChar *prefix); +XML_DEPRECATED +XMLPUBFUN void + setNamespace (void *ctx, + const xmlChar *name); +XML_DEPRECATED +XMLPUBFUN xmlNsPtr + getNamespace (void *ctx); +XML_DEPRECATED +XMLPUBFUN int + checkNamespace (void *ctx, + xmlChar *nameSpace); +XML_DEPRECATED +XMLPUBFUN void + namespaceDecl (void *ctx, + const xmlChar *href, + const xmlChar *prefix); +XML_DEPRECATED +XMLPUBFUN void + comment (void *ctx, + const xmlChar *value); +XML_DEPRECATED +XMLPUBFUN void + cdataBlock (void *ctx, + const xmlChar *value, + int len); + +#ifdef LIBXML_SAX1_ENABLED +XML_DEPRECATED +XMLPUBFUN void + initxmlDefaultSAXHandler (xmlSAXHandlerV1 *hdlr, + int warning); +#ifdef LIBXML_HTML_ENABLED +XML_DEPRECATED +XMLPUBFUN void + inithtmlDefaultSAXHandler (xmlSAXHandlerV1 *hdlr); +#endif +#endif /* LIBXML_SAX1_ENABLED */ + +#ifdef __cplusplus +} +#endif + +#endif /* LIBXML_LEGACY_ENABLED */ + +#endif /* __XML_SAX_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/SAX2.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/SAX2.h new file mode 100644 index 0000000..4c4ecce --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/SAX2.h @@ -0,0 +1,171 @@ +/* + * Summary: SAX2 parser interface used to build the DOM tree + * Description: those are the default SAX2 interfaces used by + * the library when building DOM tree. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + + +#ifndef __XML_SAX2_H__ +#define __XML_SAX2_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +XMLPUBFUN const xmlChar * + xmlSAX2GetPublicId (void *ctx); +XMLPUBFUN const xmlChar * + xmlSAX2GetSystemId (void *ctx); +XMLPUBFUN void + xmlSAX2SetDocumentLocator (void *ctx, + xmlSAXLocatorPtr loc); + +XMLPUBFUN int + xmlSAX2GetLineNumber (void *ctx); +XMLPUBFUN int + xmlSAX2GetColumnNumber (void *ctx); + +XMLPUBFUN int + xmlSAX2IsStandalone (void *ctx); +XMLPUBFUN int + xmlSAX2HasInternalSubset (void *ctx); +XMLPUBFUN int + xmlSAX2HasExternalSubset (void *ctx); + +XMLPUBFUN void + xmlSAX2InternalSubset (void *ctx, + const xmlChar *name, + const xmlChar *ExternalID, + const xmlChar *SystemID); +XMLPUBFUN void + xmlSAX2ExternalSubset (void *ctx, + const xmlChar *name, + const xmlChar *ExternalID, + const xmlChar *SystemID); +XMLPUBFUN xmlEntityPtr + xmlSAX2GetEntity (void *ctx, + const xmlChar *name); +XMLPUBFUN xmlEntityPtr + xmlSAX2GetParameterEntity (void *ctx, + const xmlChar *name); +XMLPUBFUN xmlParserInputPtr + xmlSAX2ResolveEntity (void *ctx, + const xmlChar *publicId, + const xmlChar *systemId); + +XMLPUBFUN void + xmlSAX2EntityDecl (void *ctx, + const xmlChar *name, + int type, + const xmlChar *publicId, + const xmlChar *systemId, + xmlChar *content); +XMLPUBFUN void + xmlSAX2AttributeDecl (void *ctx, + const xmlChar *elem, + const xmlChar *fullname, + int type, + int def, + const xmlChar *defaultValue, + xmlEnumerationPtr tree); +XMLPUBFUN void + xmlSAX2ElementDecl (void *ctx, + const xmlChar *name, + int type, + xmlElementContentPtr content); +XMLPUBFUN void + xmlSAX2NotationDecl (void *ctx, + const xmlChar *name, + const xmlChar *publicId, + const xmlChar *systemId); +XMLPUBFUN void + xmlSAX2UnparsedEntityDecl (void *ctx, + const xmlChar *name, + const xmlChar *publicId, + const xmlChar *systemId, + const xmlChar *notationName); + +XMLPUBFUN void + xmlSAX2StartDocument (void *ctx); +XMLPUBFUN void + xmlSAX2EndDocument (void *ctx); +#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || \ + defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_LEGACY_ENABLED) +XMLPUBFUN void + xmlSAX2StartElement (void *ctx, + const xmlChar *fullname, + const xmlChar **atts); +XMLPUBFUN void + xmlSAX2EndElement (void *ctx, + const xmlChar *name); +#endif /* LIBXML_SAX1_ENABLED or LIBXML_HTML_ENABLED or LIBXML_LEGACY_ENABLED */ +XMLPUBFUN void + xmlSAX2StartElementNs (void *ctx, + const xmlChar *localname, + const xmlChar *prefix, + const xmlChar *URI, + int nb_namespaces, + const xmlChar **namespaces, + int nb_attributes, + int nb_defaulted, + const xmlChar **attributes); +XMLPUBFUN void + xmlSAX2EndElementNs (void *ctx, + const xmlChar *localname, + const xmlChar *prefix, + const xmlChar *URI); +XMLPUBFUN void + xmlSAX2Reference (void *ctx, + const xmlChar *name); +XMLPUBFUN void + xmlSAX2Characters (void *ctx, + const xmlChar *ch, + int len); +XMLPUBFUN void + xmlSAX2IgnorableWhitespace (void *ctx, + const xmlChar *ch, + int len); +XMLPUBFUN void + xmlSAX2ProcessingInstruction (void *ctx, + const xmlChar *target, + const xmlChar *data); +XMLPUBFUN void + xmlSAX2Comment (void *ctx, + const xmlChar *value); +XMLPUBFUN void + xmlSAX2CDataBlock (void *ctx, + const xmlChar *value, + int len); + +#ifdef LIBXML_SAX1_ENABLED +XML_DEPRECATED +XMLPUBFUN int + xmlSAXDefaultVersion (int version); +#endif /* LIBXML_SAX1_ENABLED */ + +XMLPUBFUN int + xmlSAXVersion (xmlSAXHandler *hdlr, + int version); +XMLPUBFUN void + xmlSAX2InitDefaultSAXHandler (xmlSAXHandler *hdlr, + int warning); +#ifdef LIBXML_HTML_ENABLED +XMLPUBFUN void + xmlSAX2InitHtmlDefaultSAXHandler(xmlSAXHandler *hdlr); +XML_DEPRECATED +XMLPUBFUN void + htmlDefaultSAXHandlerInit (void); +#endif +XML_DEPRECATED +XMLPUBFUN void + xmlDefaultSAXHandlerInit (void); +#ifdef __cplusplus +} +#endif +#endif /* __XML_SAX2_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/c14n.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/c14n.h new file mode 100644 index 0000000..8ccd1ce --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/c14n.h @@ -0,0 +1,115 @@ +/* + * Summary: Provide Canonical XML and Exclusive XML Canonicalization + * Description: the c14n modules provides a + * + * "Canonical XML" implementation + * http://www.w3.org/TR/xml-c14n + * + * and an + * + * "Exclusive XML Canonicalization" implementation + * http://www.w3.org/TR/xml-exc-c14n + + * Copy: See Copyright for the status of this software. + * + * Author: Aleksey Sanin + */ +#ifndef __XML_C14N_H__ +#define __XML_C14N_H__ + +#include + +#ifdef LIBXML_C14N_ENABLED + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * XML Canonicalization + * http://www.w3.org/TR/xml-c14n + * + * Exclusive XML Canonicalization + * http://www.w3.org/TR/xml-exc-c14n + * + * Canonical form of an XML document could be created if and only if + * a) default attributes (if any) are added to all nodes + * b) all character and parsed entity references are resolved + * In order to achieve this in libxml2 the document MUST be loaded with + * following options: XML_PARSE_DTDATTR | XML_PARSE_NOENT + */ + +/* + * xmlC14NMode: + * + * Predefined values for C14N modes + * + */ +typedef enum { + XML_C14N_1_0 = 0, /* Original C14N 1.0 spec */ + XML_C14N_EXCLUSIVE_1_0 = 1, /* Exclusive C14N 1.0 spec */ + XML_C14N_1_1 = 2 /* C14N 1.1 spec */ +} xmlC14NMode; + +XMLPUBFUN int + xmlC14NDocSaveTo (xmlDocPtr doc, + xmlNodeSetPtr nodes, + int mode, /* a xmlC14NMode */ + xmlChar **inclusive_ns_prefixes, + int with_comments, + xmlOutputBufferPtr buf); + +XMLPUBFUN int + xmlC14NDocDumpMemory (xmlDocPtr doc, + xmlNodeSetPtr nodes, + int mode, /* a xmlC14NMode */ + xmlChar **inclusive_ns_prefixes, + int with_comments, + xmlChar **doc_txt_ptr); + +XMLPUBFUN int + xmlC14NDocSave (xmlDocPtr doc, + xmlNodeSetPtr nodes, + int mode, /* a xmlC14NMode */ + xmlChar **inclusive_ns_prefixes, + int with_comments, + const char* filename, + int compression); + + +/** + * This is the core C14N function + */ +/** + * xmlC14NIsVisibleCallback: + * @user_data: user data + * @node: the current node + * @parent: the parent node + * + * Signature for a C14N callback on visible nodes + * + * Returns 1 if the node should be included + */ +typedef int (*xmlC14NIsVisibleCallback) (void* user_data, + xmlNodePtr node, + xmlNodePtr parent); + +XMLPUBFUN int + xmlC14NExecute (xmlDocPtr doc, + xmlC14NIsVisibleCallback is_visible_callback, + void* user_data, + int mode, /* a xmlC14NMode */ + xmlChar **inclusive_ns_prefixes, + int with_comments, + xmlOutputBufferPtr buf); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LIBXML_C14N_ENABLED */ +#endif /* __XML_C14N_H__ */ + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/catalog.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/catalog.h new file mode 100644 index 0000000..02fa7ab --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/catalog.h @@ -0,0 +1,182 @@ +/** + * Summary: interfaces to the Catalog handling system + * Description: the catalog module implements the support for + * XML Catalogs and SGML catalogs + * + * SGML Open Technical Resolution TR9401:1997. + * http://www.jclark.com/sp/catalog.htm + * + * XML Catalogs Working Draft 06 August 2001 + * http://www.oasis-open.org/committees/entity/spec-2001-08-06.html + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_CATALOG_H__ +#define __XML_CATALOG_H__ + +#include + +#include +#include +#include + +#ifdef LIBXML_CATALOG_ENABLED + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * XML_CATALOGS_NAMESPACE: + * + * The namespace for the XML Catalogs elements. + */ +#define XML_CATALOGS_NAMESPACE \ + (const xmlChar *) "urn:oasis:names:tc:entity:xmlns:xml:catalog" +/** + * XML_CATALOG_PI: + * + * The specific XML Catalog Processing Instruction name. + */ +#define XML_CATALOG_PI \ + (const xmlChar *) "oasis-xml-catalog" + +/* + * The API is voluntarily limited to general cataloging. + */ +typedef enum { + XML_CATA_PREFER_NONE = 0, + XML_CATA_PREFER_PUBLIC = 1, + XML_CATA_PREFER_SYSTEM +} xmlCatalogPrefer; + +typedef enum { + XML_CATA_ALLOW_NONE = 0, + XML_CATA_ALLOW_GLOBAL = 1, + XML_CATA_ALLOW_DOCUMENT = 2, + XML_CATA_ALLOW_ALL = 3 +} xmlCatalogAllow; + +typedef struct _xmlCatalog xmlCatalog; +typedef xmlCatalog *xmlCatalogPtr; + +/* + * Operations on a given catalog. + */ +XMLPUBFUN xmlCatalogPtr + xmlNewCatalog (int sgml); +XMLPUBFUN xmlCatalogPtr + xmlLoadACatalog (const char *filename); +XMLPUBFUN xmlCatalogPtr + xmlLoadSGMLSuperCatalog (const char *filename); +XMLPUBFUN int + xmlConvertSGMLCatalog (xmlCatalogPtr catal); +XMLPUBFUN int + xmlACatalogAdd (xmlCatalogPtr catal, + const xmlChar *type, + const xmlChar *orig, + const xmlChar *replace); +XMLPUBFUN int + xmlACatalogRemove (xmlCatalogPtr catal, + const xmlChar *value); +XMLPUBFUN xmlChar * + xmlACatalogResolve (xmlCatalogPtr catal, + const xmlChar *pubID, + const xmlChar *sysID); +XMLPUBFUN xmlChar * + xmlACatalogResolveSystem(xmlCatalogPtr catal, + const xmlChar *sysID); +XMLPUBFUN xmlChar * + xmlACatalogResolvePublic(xmlCatalogPtr catal, + const xmlChar *pubID); +XMLPUBFUN xmlChar * + xmlACatalogResolveURI (xmlCatalogPtr catal, + const xmlChar *URI); +#ifdef LIBXML_OUTPUT_ENABLED +XMLPUBFUN void + xmlACatalogDump (xmlCatalogPtr catal, + FILE *out); +#endif /* LIBXML_OUTPUT_ENABLED */ +XMLPUBFUN void + xmlFreeCatalog (xmlCatalogPtr catal); +XMLPUBFUN int + xmlCatalogIsEmpty (xmlCatalogPtr catal); + +/* + * Global operations. + */ +XMLPUBFUN void + xmlInitializeCatalog (void); +XMLPUBFUN int + xmlLoadCatalog (const char *filename); +XMLPUBFUN void + xmlLoadCatalogs (const char *paths); +XMLPUBFUN void + xmlCatalogCleanup (void); +#ifdef LIBXML_OUTPUT_ENABLED +XMLPUBFUN void + xmlCatalogDump (FILE *out); +#endif /* LIBXML_OUTPUT_ENABLED */ +XMLPUBFUN xmlChar * + xmlCatalogResolve (const xmlChar *pubID, + const xmlChar *sysID); +XMLPUBFUN xmlChar * + xmlCatalogResolveSystem (const xmlChar *sysID); +XMLPUBFUN xmlChar * + xmlCatalogResolvePublic (const xmlChar *pubID); +XMLPUBFUN xmlChar * + xmlCatalogResolveURI (const xmlChar *URI); +XMLPUBFUN int + xmlCatalogAdd (const xmlChar *type, + const xmlChar *orig, + const xmlChar *replace); +XMLPUBFUN int + xmlCatalogRemove (const xmlChar *value); +XMLPUBFUN xmlDocPtr + xmlParseCatalogFile (const char *filename); +XMLPUBFUN int + xmlCatalogConvert (void); + +/* + * Strictly minimal interfaces for per-document catalogs used + * by the parser. + */ +XMLPUBFUN void + xmlCatalogFreeLocal (void *catalogs); +XMLPUBFUN void * + xmlCatalogAddLocal (void *catalogs, + const xmlChar *URL); +XMLPUBFUN xmlChar * + xmlCatalogLocalResolve (void *catalogs, + const xmlChar *pubID, + const xmlChar *sysID); +XMLPUBFUN xmlChar * + xmlCatalogLocalResolveURI(void *catalogs, + const xmlChar *URI); +/* + * Preference settings. + */ +XMLPUBFUN int + xmlCatalogSetDebug (int level); +XMLPUBFUN xmlCatalogPrefer + xmlCatalogSetDefaultPrefer(xmlCatalogPrefer prefer); +XMLPUBFUN void + xmlCatalogSetDefaults (xmlCatalogAllow allow); +XMLPUBFUN xmlCatalogAllow + xmlCatalogGetDefaults (void); + + +/* DEPRECATED interfaces */ +XMLPUBFUN const xmlChar * + xmlCatalogGetSystem (const xmlChar *sysID); +XMLPUBFUN const xmlChar * + xmlCatalogGetPublic (const xmlChar *pubID); + +#ifdef __cplusplus +} +#endif +#endif /* LIBXML_CATALOG_ENABLED */ +#endif /* __XML_CATALOG_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/chvalid.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/chvalid.h new file mode 100644 index 0000000..8225c95 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/chvalid.h @@ -0,0 +1,230 @@ +/* + * Summary: Unicode character range checking + * Description: this module exports interfaces for the character + * range validation APIs + * + * This file is automatically generated from the cvs source + * definition files using the genChRanges.py Python script + * + * Generation date: Mon Mar 27 11:09:48 2006 + * Sources: chvalid.def + * Author: William Brack + */ + +#ifndef __XML_CHVALID_H__ +#define __XML_CHVALID_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Define our typedefs and structures + * + */ +typedef struct _xmlChSRange xmlChSRange; +typedef xmlChSRange *xmlChSRangePtr; +struct _xmlChSRange { + unsigned short low; + unsigned short high; +}; + +typedef struct _xmlChLRange xmlChLRange; +typedef xmlChLRange *xmlChLRangePtr; +struct _xmlChLRange { + unsigned int low; + unsigned int high; +}; + +typedef struct _xmlChRangeGroup xmlChRangeGroup; +typedef xmlChRangeGroup *xmlChRangeGroupPtr; +struct _xmlChRangeGroup { + int nbShortRange; + int nbLongRange; + const xmlChSRange *shortRange; /* points to an array of ranges */ + const xmlChLRange *longRange; +}; + +/** + * Range checking routine + */ +XMLPUBFUN int + xmlCharInRange(unsigned int val, const xmlChRangeGroup *group); + + +/** + * xmlIsBaseChar_ch: + * @c: char to validate + * + * Automatically generated by genChRanges.py + */ +#define xmlIsBaseChar_ch(c) (((0x41 <= (c)) && ((c) <= 0x5a)) || \ + ((0x61 <= (c)) && ((c) <= 0x7a)) || \ + ((0xc0 <= (c)) && ((c) <= 0xd6)) || \ + ((0xd8 <= (c)) && ((c) <= 0xf6)) || \ + (0xf8 <= (c))) + +/** + * xmlIsBaseCharQ: + * @c: char to validate + * + * Automatically generated by genChRanges.py + */ +#define xmlIsBaseCharQ(c) (((c) < 0x100) ? \ + xmlIsBaseChar_ch((c)) : \ + xmlCharInRange((c), &xmlIsBaseCharGroup)) + +XMLPUBVAR const xmlChRangeGroup xmlIsBaseCharGroup; + +/** + * xmlIsBlank_ch: + * @c: char to validate + * + * Automatically generated by genChRanges.py + */ +#define xmlIsBlank_ch(c) (((c) == 0x20) || \ + ((0x9 <= (c)) && ((c) <= 0xa)) || \ + ((c) == 0xd)) + +/** + * xmlIsBlankQ: + * @c: char to validate + * + * Automatically generated by genChRanges.py + */ +#define xmlIsBlankQ(c) (((c) < 0x100) ? \ + xmlIsBlank_ch((c)) : 0) + + +/** + * xmlIsChar_ch: + * @c: char to validate + * + * Automatically generated by genChRanges.py + */ +#define xmlIsChar_ch(c) (((0x9 <= (c)) && ((c) <= 0xa)) || \ + ((c) == 0xd) || \ + (0x20 <= (c))) + +/** + * xmlIsCharQ: + * @c: char to validate + * + * Automatically generated by genChRanges.py + */ +#define xmlIsCharQ(c) (((c) < 0x100) ? \ + xmlIsChar_ch((c)) :\ + (((0x100 <= (c)) && ((c) <= 0xd7ff)) || \ + ((0xe000 <= (c)) && ((c) <= 0xfffd)) || \ + ((0x10000 <= (c)) && ((c) <= 0x10ffff)))) + +XMLPUBVAR const xmlChRangeGroup xmlIsCharGroup; + +/** + * xmlIsCombiningQ: + * @c: char to validate + * + * Automatically generated by genChRanges.py + */ +#define xmlIsCombiningQ(c) (((c) < 0x100) ? \ + 0 : \ + xmlCharInRange((c), &xmlIsCombiningGroup)) + +XMLPUBVAR const xmlChRangeGroup xmlIsCombiningGroup; + +/** + * xmlIsDigit_ch: + * @c: char to validate + * + * Automatically generated by genChRanges.py + */ +#define xmlIsDigit_ch(c) (((0x30 <= (c)) && ((c) <= 0x39))) + +/** + * xmlIsDigitQ: + * @c: char to validate + * + * Automatically generated by genChRanges.py + */ +#define xmlIsDigitQ(c) (((c) < 0x100) ? \ + xmlIsDigit_ch((c)) : \ + xmlCharInRange((c), &xmlIsDigitGroup)) + +XMLPUBVAR const xmlChRangeGroup xmlIsDigitGroup; + +/** + * xmlIsExtender_ch: + * @c: char to validate + * + * Automatically generated by genChRanges.py + */ +#define xmlIsExtender_ch(c) (((c) == 0xb7)) + +/** + * xmlIsExtenderQ: + * @c: char to validate + * + * Automatically generated by genChRanges.py + */ +#define xmlIsExtenderQ(c) (((c) < 0x100) ? \ + xmlIsExtender_ch((c)) : \ + xmlCharInRange((c), &xmlIsExtenderGroup)) + +XMLPUBVAR const xmlChRangeGroup xmlIsExtenderGroup; + +/** + * xmlIsIdeographicQ: + * @c: char to validate + * + * Automatically generated by genChRanges.py + */ +#define xmlIsIdeographicQ(c) (((c) < 0x100) ? \ + 0 :\ + (((0x4e00 <= (c)) && ((c) <= 0x9fa5)) || \ + ((c) == 0x3007) || \ + ((0x3021 <= (c)) && ((c) <= 0x3029)))) + +XMLPUBVAR const xmlChRangeGroup xmlIsIdeographicGroup; +XMLPUBVAR const unsigned char xmlIsPubidChar_tab[256]; + +/** + * xmlIsPubidChar_ch: + * @c: char to validate + * + * Automatically generated by genChRanges.py + */ +#define xmlIsPubidChar_ch(c) (xmlIsPubidChar_tab[(c)]) + +/** + * xmlIsPubidCharQ: + * @c: char to validate + * + * Automatically generated by genChRanges.py + */ +#define xmlIsPubidCharQ(c) (((c) < 0x100) ? \ + xmlIsPubidChar_ch((c)) : 0) + +XMLPUBFUN int + xmlIsBaseChar(unsigned int ch); +XMLPUBFUN int + xmlIsBlank(unsigned int ch); +XMLPUBFUN int + xmlIsChar(unsigned int ch); +XMLPUBFUN int + xmlIsCombining(unsigned int ch); +XMLPUBFUN int + xmlIsDigit(unsigned int ch); +XMLPUBFUN int + xmlIsExtender(unsigned int ch); +XMLPUBFUN int + xmlIsIdeographic(unsigned int ch); +XMLPUBFUN int + xmlIsPubidChar(unsigned int ch); + +#ifdef __cplusplus +} +#endif +#endif /* __XML_CHVALID_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/debugXML.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/debugXML.h new file mode 100644 index 0000000..1332dd7 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/debugXML.h @@ -0,0 +1,217 @@ +/* + * Summary: Tree debugging APIs + * Description: Interfaces to a set of routines used for debugging the tree + * produced by the XML parser. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __DEBUG_XML__ +#define __DEBUG_XML__ +#include +#include +#include + +#ifdef LIBXML_DEBUG_ENABLED + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The standard Dump routines. + */ +XMLPUBFUN void + xmlDebugDumpString (FILE *output, + const xmlChar *str); +XMLPUBFUN void + xmlDebugDumpAttr (FILE *output, + xmlAttrPtr attr, + int depth); +XMLPUBFUN void + xmlDebugDumpAttrList (FILE *output, + xmlAttrPtr attr, + int depth); +XMLPUBFUN void + xmlDebugDumpOneNode (FILE *output, + xmlNodePtr node, + int depth); +XMLPUBFUN void + xmlDebugDumpNode (FILE *output, + xmlNodePtr node, + int depth); +XMLPUBFUN void + xmlDebugDumpNodeList (FILE *output, + xmlNodePtr node, + int depth); +XMLPUBFUN void + xmlDebugDumpDocumentHead(FILE *output, + xmlDocPtr doc); +XMLPUBFUN void + xmlDebugDumpDocument (FILE *output, + xmlDocPtr doc); +XMLPUBFUN void + xmlDebugDumpDTD (FILE *output, + xmlDtdPtr dtd); +XMLPUBFUN void + xmlDebugDumpEntities (FILE *output, + xmlDocPtr doc); + +/**************************************************************** + * * + * Checking routines * + * * + ****************************************************************/ + +XMLPUBFUN int + xmlDebugCheckDocument (FILE * output, + xmlDocPtr doc); + +/**************************************************************** + * * + * XML shell helpers * + * * + ****************************************************************/ + +XMLPUBFUN void + xmlLsOneNode (FILE *output, xmlNodePtr node); +XMLPUBFUN int + xmlLsCountNode (xmlNodePtr node); + +XMLPUBFUN const char * + xmlBoolToText (int boolval); + +/**************************************************************** + * * + * The XML shell related structures and functions * + * * + ****************************************************************/ + +#ifdef LIBXML_XPATH_ENABLED +/** + * xmlShellReadlineFunc: + * @prompt: a string prompt + * + * This is a generic signature for the XML shell input function. + * + * Returns a string which will be freed by the Shell. + */ +typedef char * (* xmlShellReadlineFunc)(char *prompt); + +/** + * xmlShellCtxt: + * + * A debugging shell context. + * TODO: add the defined function tables. + */ +typedef struct _xmlShellCtxt xmlShellCtxt; +typedef xmlShellCtxt *xmlShellCtxtPtr; +struct _xmlShellCtxt { + char *filename; + xmlDocPtr doc; + xmlNodePtr node; + xmlXPathContextPtr pctxt; + int loaded; + FILE *output; + xmlShellReadlineFunc input; +}; + +/** + * xmlShellCmd: + * @ctxt: a shell context + * @arg: a string argument + * @node: a first node + * @node2: a second node + * + * This is a generic signature for the XML shell functions. + * + * Returns an int, negative returns indicating errors. + */ +typedef int (* xmlShellCmd) (xmlShellCtxtPtr ctxt, + char *arg, + xmlNodePtr node, + xmlNodePtr node2); + +XMLPUBFUN void + xmlShellPrintXPathError (int errorType, + const char *arg); +XMLPUBFUN void + xmlShellPrintXPathResult(xmlXPathObjectPtr list); +XMLPUBFUN int + xmlShellList (xmlShellCtxtPtr ctxt, + char *arg, + xmlNodePtr node, + xmlNodePtr node2); +XMLPUBFUN int + xmlShellBase (xmlShellCtxtPtr ctxt, + char *arg, + xmlNodePtr node, + xmlNodePtr node2); +XMLPUBFUN int + xmlShellDir (xmlShellCtxtPtr ctxt, + char *arg, + xmlNodePtr node, + xmlNodePtr node2); +XMLPUBFUN int + xmlShellLoad (xmlShellCtxtPtr ctxt, + char *filename, + xmlNodePtr node, + xmlNodePtr node2); +#ifdef LIBXML_OUTPUT_ENABLED +XMLPUBFUN void + xmlShellPrintNode (xmlNodePtr node); +XMLPUBFUN int + xmlShellCat (xmlShellCtxtPtr ctxt, + char *arg, + xmlNodePtr node, + xmlNodePtr node2); +XMLPUBFUN int + xmlShellWrite (xmlShellCtxtPtr ctxt, + char *filename, + xmlNodePtr node, + xmlNodePtr node2); +XMLPUBFUN int + xmlShellSave (xmlShellCtxtPtr ctxt, + char *filename, + xmlNodePtr node, + xmlNodePtr node2); +#endif /* LIBXML_OUTPUT_ENABLED */ +#ifdef LIBXML_VALID_ENABLED +XMLPUBFUN int + xmlShellValidate (xmlShellCtxtPtr ctxt, + char *dtd, + xmlNodePtr node, + xmlNodePtr node2); +#endif /* LIBXML_VALID_ENABLED */ +XMLPUBFUN int + xmlShellDu (xmlShellCtxtPtr ctxt, + char *arg, + xmlNodePtr tree, + xmlNodePtr node2); +XMLPUBFUN int + xmlShellPwd (xmlShellCtxtPtr ctxt, + char *buffer, + xmlNodePtr node, + xmlNodePtr node2); + +/* + * The Shell interface. + */ +XMLPUBFUN void + xmlShell (xmlDocPtr doc, + const char *filename, + xmlShellReadlineFunc input, + FILE *output); + +#endif /* LIBXML_XPATH_ENABLED */ + +#ifdef __cplusplus +} +#endif + +#endif /* LIBXML_DEBUG_ENABLED */ +#endif /* __DEBUG_XML__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/dict.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/dict.h new file mode 100644 index 0000000..22aa3d9 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/dict.h @@ -0,0 +1,82 @@ +/* + * Summary: string dictionary + * Description: dictionary of reusable strings, just used to avoid allocation + * and freeing operations. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_DICT_H__ +#define __XML_DICT_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The dictionary. + */ +typedef struct _xmlDict xmlDict; +typedef xmlDict *xmlDictPtr; + +/* + * Initializer + */ +XML_DEPRECATED +XMLPUBFUN int xmlInitializeDict(void); + +/* + * Constructor and destructor. + */ +XMLPUBFUN xmlDictPtr + xmlDictCreate (void); +XMLPUBFUN size_t + xmlDictSetLimit (xmlDictPtr dict, + size_t limit); +XMLPUBFUN size_t + xmlDictGetUsage (xmlDictPtr dict); +XMLPUBFUN xmlDictPtr + xmlDictCreateSub(xmlDictPtr sub); +XMLPUBFUN int + xmlDictReference(xmlDictPtr dict); +XMLPUBFUN void + xmlDictFree (xmlDictPtr dict); + +/* + * Lookup of entry in the dictionary. + */ +XMLPUBFUN const xmlChar * + xmlDictLookup (xmlDictPtr dict, + const xmlChar *name, + int len); +XMLPUBFUN const xmlChar * + xmlDictExists (xmlDictPtr dict, + const xmlChar *name, + int len); +XMLPUBFUN const xmlChar * + xmlDictQLookup (xmlDictPtr dict, + const xmlChar *prefix, + const xmlChar *name); +XMLPUBFUN int + xmlDictOwns (xmlDictPtr dict, + const xmlChar *str); +XMLPUBFUN int + xmlDictSize (xmlDictPtr dict); + +/* + * Cleanup function + */ +XML_DEPRECATED +XMLPUBFUN void + xmlDictCleanup (void); + +#ifdef __cplusplus +} +#endif +#endif /* ! __XML_DICT_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/encoding.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/encoding.h new file mode 100644 index 0000000..599a03e --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/encoding.h @@ -0,0 +1,244 @@ +/* + * Summary: interface for the encoding conversion functions + * Description: interface for the encoding conversion functions needed for + * XML basic encoding and iconv() support. + * + * Related specs are + * rfc2044 (UTF-8 and UTF-16) F. Yergeau Alis Technologies + * [ISO-10646] UTF-8 and UTF-16 in Annexes + * [ISO-8859-1] ISO Latin-1 characters codes. + * [UNICODE] The Unicode Consortium, "The Unicode Standard -- + * Worldwide Character Encoding -- Version 1.0", Addison- + * Wesley, Volume 1, 1991, Volume 2, 1992. UTF-8 is + * described in Unicode Technical Report #4. + * [US-ASCII] Coded Character Set--7-bit American Standard Code for + * Information Interchange, ANSI X3.4-1986. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_CHAR_ENCODING_H__ +#define __XML_CHAR_ENCODING_H__ + +#include + +#ifdef LIBXML_ICONV_ENABLED +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + XML_ENC_ERR_SUCCESS = 0, + XML_ENC_ERR_SPACE = -1, + XML_ENC_ERR_INPUT = -2, + XML_ENC_ERR_PARTIAL = -3, + XML_ENC_ERR_INTERNAL = -4, + XML_ENC_ERR_MEMORY = -5 +} xmlCharEncError; + +/* + * xmlCharEncoding: + * + * Predefined values for some standard encodings. + * Libxml does not do beforehand translation on UTF8 and ISOLatinX. + * It also supports ASCII, ISO-8859-1, and UTF16 (LE and BE) by default. + * + * Anything else would have to be translated to UTF8 before being + * given to the parser itself. The BOM for UTF16 and the encoding + * declaration are looked at and a converter is looked for at that + * point. If not found the parser stops here as asked by the XML REC. A + * converter can be registered by the user using xmlRegisterCharEncodingHandler + * but the current form doesn't allow stateful transcoding (a serious + * problem agreed !). If iconv has been found it will be used + * automatically and allow stateful transcoding, the simplest is then + * to be sure to enable iconv and to provide iconv libs for the encoding + * support needed. + * + * Note that the generic "UTF-16" is not a predefined value. Instead, only + * the specific UTF-16LE and UTF-16BE are present. + */ +typedef enum { + XML_CHAR_ENCODING_ERROR= -1, /* No char encoding detected */ + XML_CHAR_ENCODING_NONE= 0, /* No char encoding detected */ + XML_CHAR_ENCODING_UTF8= 1, /* UTF-8 */ + XML_CHAR_ENCODING_UTF16LE= 2, /* UTF-16 little endian */ + XML_CHAR_ENCODING_UTF16BE= 3, /* UTF-16 big endian */ + XML_CHAR_ENCODING_UCS4LE= 4, /* UCS-4 little endian */ + XML_CHAR_ENCODING_UCS4BE= 5, /* UCS-4 big endian */ + XML_CHAR_ENCODING_EBCDIC= 6, /* EBCDIC uh! */ + XML_CHAR_ENCODING_UCS4_2143=7, /* UCS-4 unusual ordering */ + XML_CHAR_ENCODING_UCS4_3412=8, /* UCS-4 unusual ordering */ + XML_CHAR_ENCODING_UCS2= 9, /* UCS-2 */ + XML_CHAR_ENCODING_8859_1= 10,/* ISO-8859-1 ISO Latin 1 */ + XML_CHAR_ENCODING_8859_2= 11,/* ISO-8859-2 ISO Latin 2 */ + XML_CHAR_ENCODING_8859_3= 12,/* ISO-8859-3 */ + XML_CHAR_ENCODING_8859_4= 13,/* ISO-8859-4 */ + XML_CHAR_ENCODING_8859_5= 14,/* ISO-8859-5 */ + XML_CHAR_ENCODING_8859_6= 15,/* ISO-8859-6 */ + XML_CHAR_ENCODING_8859_7= 16,/* ISO-8859-7 */ + XML_CHAR_ENCODING_8859_8= 17,/* ISO-8859-8 */ + XML_CHAR_ENCODING_8859_9= 18,/* ISO-8859-9 */ + XML_CHAR_ENCODING_2022_JP= 19,/* ISO-2022-JP */ + XML_CHAR_ENCODING_SHIFT_JIS=20,/* Shift_JIS */ + XML_CHAR_ENCODING_EUC_JP= 21,/* EUC-JP */ + XML_CHAR_ENCODING_ASCII= 22 /* pure ASCII */ +} xmlCharEncoding; + +/** + * xmlCharEncodingInputFunc: + * @out: a pointer to an array of bytes to store the UTF-8 result + * @outlen: the length of @out + * @in: a pointer to an array of chars in the original encoding + * @inlen: the length of @in + * + * Take a block of chars in the original encoding and try to convert + * it to an UTF-8 block of chars out. + * + * Returns the number of bytes written, -1 if lack of space, or -2 + * if the transcoding failed. + * The value of @inlen after return is the number of octets consumed + * if the return value is positive, else unpredictiable. + * The value of @outlen after return is the number of octets consumed. + */ +typedef int (* xmlCharEncodingInputFunc)(unsigned char *out, int *outlen, + const unsigned char *in, int *inlen); + + +/** + * xmlCharEncodingOutputFunc: + * @out: a pointer to an array of bytes to store the result + * @outlen: the length of @out + * @in: a pointer to an array of UTF-8 chars + * @inlen: the length of @in + * + * Take a block of UTF-8 chars in and try to convert it to another + * encoding. + * Note: a first call designed to produce heading info is called with + * in = NULL. If stateful this should also initialize the encoder state. + * + * Returns the number of bytes written, -1 if lack of space, or -2 + * if the transcoding failed. + * The value of @inlen after return is the number of octets consumed + * if the return value is positive, else unpredictiable. + * The value of @outlen after return is the number of octets produced. + */ +typedef int (* xmlCharEncodingOutputFunc)(unsigned char *out, int *outlen, + const unsigned char *in, int *inlen); + + +/* + * Block defining the handlers for non UTF-8 encodings. + * If iconv is supported, there are two extra fields. + */ +typedef struct _xmlCharEncodingHandler xmlCharEncodingHandler; +typedef xmlCharEncodingHandler *xmlCharEncodingHandlerPtr; +struct _xmlCharEncodingHandler { + char *name; + xmlCharEncodingInputFunc input; + xmlCharEncodingOutputFunc output; +#ifdef LIBXML_ICONV_ENABLED + iconv_t iconv_in; + iconv_t iconv_out; +#endif /* LIBXML_ICONV_ENABLED */ +#ifdef LIBXML_ICU_ENABLED + struct _uconv_t *uconv_in; + struct _uconv_t *uconv_out; +#endif /* LIBXML_ICU_ENABLED */ +}; + +/* + * Interfaces for encoding handlers. + */ +XML_DEPRECATED +XMLPUBFUN void + xmlInitCharEncodingHandlers (void); +XML_DEPRECATED +XMLPUBFUN void + xmlCleanupCharEncodingHandlers (void); +XMLPUBFUN void + xmlRegisterCharEncodingHandler (xmlCharEncodingHandlerPtr handler); +XMLPUBFUN int + xmlLookupCharEncodingHandler (xmlCharEncoding enc, + xmlCharEncodingHandlerPtr *out); +XMLPUBFUN int + xmlOpenCharEncodingHandler (const char *name, + int output, + xmlCharEncodingHandlerPtr *out); +XMLPUBFUN xmlCharEncodingHandlerPtr + xmlGetCharEncodingHandler (xmlCharEncoding enc); +XMLPUBFUN xmlCharEncodingHandlerPtr + xmlFindCharEncodingHandler (const char *name); +XMLPUBFUN xmlCharEncodingHandlerPtr + xmlNewCharEncodingHandler (const char *name, + xmlCharEncodingInputFunc input, + xmlCharEncodingOutputFunc output); + +/* + * Interfaces for encoding names and aliases. + */ +XMLPUBFUN int + xmlAddEncodingAlias (const char *name, + const char *alias); +XMLPUBFUN int + xmlDelEncodingAlias (const char *alias); +XMLPUBFUN const char * + xmlGetEncodingAlias (const char *alias); +XMLPUBFUN void + xmlCleanupEncodingAliases (void); +XMLPUBFUN xmlCharEncoding + xmlParseCharEncoding (const char *name); +XMLPUBFUN const char * + xmlGetCharEncodingName (xmlCharEncoding enc); + +/* + * Interfaces directly used by the parsers. + */ +XMLPUBFUN xmlCharEncoding + xmlDetectCharEncoding (const unsigned char *in, + int len); + +/** DOC_DISABLE */ +struct _xmlBuffer; +/** DOC_ENABLE */ +XMLPUBFUN int + xmlCharEncOutFunc (xmlCharEncodingHandler *handler, + struct _xmlBuffer *out, + struct _xmlBuffer *in); + +XMLPUBFUN int + xmlCharEncInFunc (xmlCharEncodingHandler *handler, + struct _xmlBuffer *out, + struct _xmlBuffer *in); +XML_DEPRECATED +XMLPUBFUN int + xmlCharEncFirstLine (xmlCharEncodingHandler *handler, + struct _xmlBuffer *out, + struct _xmlBuffer *in); +XMLPUBFUN int + xmlCharEncCloseFunc (xmlCharEncodingHandler *handler); + +/* + * Export a few useful functions + */ +#ifdef LIBXML_OUTPUT_ENABLED +XMLPUBFUN int + UTF8Toisolat1 (unsigned char *out, + int *outlen, + const unsigned char *in, + int *inlen); +#endif /* LIBXML_OUTPUT_ENABLED */ +XMLPUBFUN int + isolat1ToUTF8 (unsigned char *out, + int *outlen, + const unsigned char *in, + int *inlen); +#ifdef __cplusplus +} +#endif + +#endif /* __XML_CHAR_ENCODING_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/entities.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/entities.h new file mode 100644 index 0000000..a0cfca8 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/entities.h @@ -0,0 +1,166 @@ +/* + * Summary: interface for the XML entities handling + * Description: this module provides some of the entity API needed + * for the parser and applications. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_ENTITIES_H__ +#define __XML_ENTITIES_H__ + +/** DOC_DISABLE */ +#include +#define XML_TREE_INTERNALS +#include +#undef XML_TREE_INTERNALS +/** DOC_ENABLE */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The different valid entity types. + */ +typedef enum { + XML_INTERNAL_GENERAL_ENTITY = 1, + XML_EXTERNAL_GENERAL_PARSED_ENTITY = 2, + XML_EXTERNAL_GENERAL_UNPARSED_ENTITY = 3, + XML_INTERNAL_PARAMETER_ENTITY = 4, + XML_EXTERNAL_PARAMETER_ENTITY = 5, + XML_INTERNAL_PREDEFINED_ENTITY = 6 +} xmlEntityType; + +/* + * An unit of storage for an entity, contains the string, the value + * and the linkind data needed for the linking in the hash table. + */ + +struct _xmlEntity { + void *_private; /* application data */ + xmlElementType type; /* XML_ENTITY_DECL, must be second ! */ + const xmlChar *name; /* Entity name */ + struct _xmlNode *children; /* First child link */ + struct _xmlNode *last; /* Last child link */ + struct _xmlDtd *parent; /* -> DTD */ + struct _xmlNode *next; /* next sibling link */ + struct _xmlNode *prev; /* previous sibling link */ + struct _xmlDoc *doc; /* the containing document */ + + xmlChar *orig; /* content without ref substitution */ + xmlChar *content; /* content or ndata if unparsed */ + int length; /* the content length */ + xmlEntityType etype; /* The entity type */ + const xmlChar *ExternalID; /* External identifier for PUBLIC */ + const xmlChar *SystemID; /* URI for a SYSTEM or PUBLIC Entity */ + + struct _xmlEntity *nexte; /* unused */ + const xmlChar *URI; /* the full URI as computed */ + int owner; /* unused */ + int flags; /* various flags */ + unsigned long expandedSize; /* expanded size */ +}; + +/* + * All entities are stored in an hash table. + * There is 2 separate hash tables for global and parameter entities. + */ + +typedef struct _xmlHashTable xmlEntitiesTable; +typedef xmlEntitiesTable *xmlEntitiesTablePtr; + +/* + * External functions: + */ + +#ifdef LIBXML_LEGACY_ENABLED +XML_DEPRECATED +XMLPUBFUN void + xmlInitializePredefinedEntities (void); +#endif /* LIBXML_LEGACY_ENABLED */ + +XMLPUBFUN xmlEntityPtr + xmlNewEntity (xmlDocPtr doc, + const xmlChar *name, + int type, + const xmlChar *ExternalID, + const xmlChar *SystemID, + const xmlChar *content); +XMLPUBFUN void + xmlFreeEntity (xmlEntityPtr entity); +XMLPUBFUN int + xmlAddEntity (xmlDocPtr doc, + int extSubset, + const xmlChar *name, + int type, + const xmlChar *ExternalID, + const xmlChar *SystemID, + const xmlChar *content, + xmlEntityPtr *out); +XMLPUBFUN xmlEntityPtr + xmlAddDocEntity (xmlDocPtr doc, + const xmlChar *name, + int type, + const xmlChar *ExternalID, + const xmlChar *SystemID, + const xmlChar *content); +XMLPUBFUN xmlEntityPtr + xmlAddDtdEntity (xmlDocPtr doc, + const xmlChar *name, + int type, + const xmlChar *ExternalID, + const xmlChar *SystemID, + const xmlChar *content); +XMLPUBFUN xmlEntityPtr + xmlGetPredefinedEntity (const xmlChar *name); +XMLPUBFUN xmlEntityPtr + xmlGetDocEntity (const xmlDoc *doc, + const xmlChar *name); +XMLPUBFUN xmlEntityPtr + xmlGetDtdEntity (xmlDocPtr doc, + const xmlChar *name); +XMLPUBFUN xmlEntityPtr + xmlGetParameterEntity (xmlDocPtr doc, + const xmlChar *name); +#ifdef LIBXML_LEGACY_ENABLED +XML_DEPRECATED +XMLPUBFUN const xmlChar * + xmlEncodeEntities (xmlDocPtr doc, + const xmlChar *input); +#endif /* LIBXML_LEGACY_ENABLED */ +XMLPUBFUN xmlChar * + xmlEncodeEntitiesReentrant(xmlDocPtr doc, + const xmlChar *input); +XMLPUBFUN xmlChar * + xmlEncodeSpecialChars (const xmlDoc *doc, + const xmlChar *input); +XMLPUBFUN xmlEntitiesTablePtr + xmlCreateEntitiesTable (void); +#ifdef LIBXML_TREE_ENABLED +XMLPUBFUN xmlEntitiesTablePtr + xmlCopyEntitiesTable (xmlEntitiesTablePtr table); +#endif /* LIBXML_TREE_ENABLED */ +XMLPUBFUN void + xmlFreeEntitiesTable (xmlEntitiesTablePtr table); +#ifdef LIBXML_OUTPUT_ENABLED +XMLPUBFUN void + xmlDumpEntitiesTable (xmlBufferPtr buf, + xmlEntitiesTablePtr table); +XMLPUBFUN void + xmlDumpEntityDecl (xmlBufferPtr buf, + xmlEntityPtr ent); +#endif /* LIBXML_OUTPUT_ENABLED */ +#ifdef LIBXML_LEGACY_ENABLED +XMLPUBFUN void + xmlCleanupPredefinedEntities(void); +#endif /* LIBXML_LEGACY_ENABLED */ + + +#ifdef __cplusplus +} +#endif + +# endif /* __XML_ENTITIES_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/globals.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/globals.h new file mode 100644 index 0000000..92f4131 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/globals.h @@ -0,0 +1,41 @@ +/* + * Summary: interface for all global variables of the library + * Description: Deprecated, don't use + * + * Copy: See Copyright for the status of this software. + */ + +#ifndef __XML_GLOBALS_H +#define __XML_GLOBALS_H + +#include + +/* + * This file was required to access global variables until version v2.12.0. + * + * These includes are for backward compatibility. + */ +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _xmlGlobalState xmlGlobalState; +typedef xmlGlobalState *xmlGlobalStatePtr; + +XML_DEPRECATED XMLPUBFUN void +xmlInitializeGlobalState(xmlGlobalStatePtr gs); +XML_DEPRECATED XMLPUBFUN +xmlGlobalStatePtr xmlGetGlobalState(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __XML_GLOBALS_H */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/hash.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/hash.h new file mode 100644 index 0000000..135b696 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/hash.h @@ -0,0 +1,251 @@ +/* + * Summary: Chained hash tables + * Description: This module implements the hash table support used in + * various places in the library. + * + * Copy: See Copyright for the status of this software. + * + * Author: Bjorn Reese + */ + +#ifndef __XML_HASH_H__ +#define __XML_HASH_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The hash table. + */ +typedef struct _xmlHashTable xmlHashTable; +typedef xmlHashTable *xmlHashTablePtr; + +/* + * Recent version of gcc produce a warning when a function pointer is assigned + * to an object pointer, or vice versa. The following macro is a dirty hack + * to allow suppression of the warning. If your architecture has function + * pointers which are a different size than a void pointer, there may be some + * serious trouble within the library. + */ +/** + * XML_CAST_FPTR: + * @fptr: pointer to a function + * + * Macro to do a casting from an object pointer to a + * function pointer without encountering a warning from + * gcc + * + * #define XML_CAST_FPTR(fptr) (*(void **)(&fptr)) + * This macro violated ISO C aliasing rules (gcc4 on s390 broke) + * so it is disabled now + */ + +#define XML_CAST_FPTR(fptr) fptr + +/* + * function types: + */ +/** + * xmlHashDeallocator: + * @payload: the data in the hash + * @name: the name associated + * + * Callback to free data from a hash. + */ +typedef void (*xmlHashDeallocator)(void *payload, const xmlChar *name); +/** + * xmlHashCopier: + * @payload: the data in the hash + * @name: the name associated + * + * Callback to copy data from a hash. + * + * Returns a copy of the data or NULL in case of error. + */ +typedef void *(*xmlHashCopier)(void *payload, const xmlChar *name); +/** + * xmlHashScanner: + * @payload: the data in the hash + * @data: extra scanner data + * @name: the name associated + * + * Callback when scanning data in a hash with the simple scanner. + */ +typedef void (*xmlHashScanner)(void *payload, void *data, const xmlChar *name); +/** + * xmlHashScannerFull: + * @payload: the data in the hash + * @data: extra scanner data + * @name: the name associated + * @name2: the second name associated + * @name3: the third name associated + * + * Callback when scanning data in a hash with the full scanner. + */ +typedef void (*xmlHashScannerFull)(void *payload, void *data, + const xmlChar *name, const xmlChar *name2, + const xmlChar *name3); + +/* + * Constructor and destructor. + */ +XMLPUBFUN xmlHashTablePtr + xmlHashCreate (int size); +XMLPUBFUN xmlHashTablePtr + xmlHashCreateDict (int size, + xmlDictPtr dict); +XMLPUBFUN void + xmlHashFree (xmlHashTablePtr hash, + xmlHashDeallocator dealloc); +XMLPUBFUN void + xmlHashDefaultDeallocator(void *entry, + const xmlChar *name); + +/* + * Add a new entry to the hash table. + */ +XMLPUBFUN int + xmlHashAdd (xmlHashTablePtr hash, + const xmlChar *name, + void *userdata); +XMLPUBFUN int + xmlHashAddEntry (xmlHashTablePtr hash, + const xmlChar *name, + void *userdata); +XMLPUBFUN int + xmlHashUpdateEntry (xmlHashTablePtr hash, + const xmlChar *name, + void *userdata, + xmlHashDeallocator dealloc); +XMLPUBFUN int + xmlHashAdd2 (xmlHashTablePtr hash, + const xmlChar *name, + const xmlChar *name2, + void *userdata); +XMLPUBFUN int + xmlHashAddEntry2 (xmlHashTablePtr hash, + const xmlChar *name, + const xmlChar *name2, + void *userdata); +XMLPUBFUN int + xmlHashUpdateEntry2 (xmlHashTablePtr hash, + const xmlChar *name, + const xmlChar *name2, + void *userdata, + xmlHashDeallocator dealloc); +XMLPUBFUN int + xmlHashAdd3 (xmlHashTablePtr hash, + const xmlChar *name, + const xmlChar *name2, + const xmlChar *name3, + void *userdata); +XMLPUBFUN int + xmlHashAddEntry3 (xmlHashTablePtr hash, + const xmlChar *name, + const xmlChar *name2, + const xmlChar *name3, + void *userdata); +XMLPUBFUN int + xmlHashUpdateEntry3 (xmlHashTablePtr hash, + const xmlChar *name, + const xmlChar *name2, + const xmlChar *name3, + void *userdata, + xmlHashDeallocator dealloc); + +/* + * Remove an entry from the hash table. + */ +XMLPUBFUN int + xmlHashRemoveEntry (xmlHashTablePtr hash, + const xmlChar *name, + xmlHashDeallocator dealloc); +XMLPUBFUN int + xmlHashRemoveEntry2 (xmlHashTablePtr hash, + const xmlChar *name, + const xmlChar *name2, + xmlHashDeallocator dealloc); +XMLPUBFUN int + xmlHashRemoveEntry3 (xmlHashTablePtr hash, + const xmlChar *name, + const xmlChar *name2, + const xmlChar *name3, + xmlHashDeallocator dealloc); + +/* + * Retrieve the payload. + */ +XMLPUBFUN void * + xmlHashLookup (xmlHashTablePtr hash, + const xmlChar *name); +XMLPUBFUN void * + xmlHashLookup2 (xmlHashTablePtr hash, + const xmlChar *name, + const xmlChar *name2); +XMLPUBFUN void * + xmlHashLookup3 (xmlHashTablePtr hash, + const xmlChar *name, + const xmlChar *name2, + const xmlChar *name3); +XMLPUBFUN void * + xmlHashQLookup (xmlHashTablePtr hash, + const xmlChar *prefix, + const xmlChar *name); +XMLPUBFUN void * + xmlHashQLookup2 (xmlHashTablePtr hash, + const xmlChar *prefix, + const xmlChar *name, + const xmlChar *prefix2, + const xmlChar *name2); +XMLPUBFUN void * + xmlHashQLookup3 (xmlHashTablePtr hash, + const xmlChar *prefix, + const xmlChar *name, + const xmlChar *prefix2, + const xmlChar *name2, + const xmlChar *prefix3, + const xmlChar *name3); + +/* + * Helpers. + */ +XMLPUBFUN xmlHashTablePtr + xmlHashCopySafe (xmlHashTablePtr hash, + xmlHashCopier copy, + xmlHashDeallocator dealloc); +XMLPUBFUN xmlHashTablePtr + xmlHashCopy (xmlHashTablePtr hash, + xmlHashCopier copy); +XMLPUBFUN int + xmlHashSize (xmlHashTablePtr hash); +XMLPUBFUN void + xmlHashScan (xmlHashTablePtr hash, + xmlHashScanner scan, + void *data); +XMLPUBFUN void + xmlHashScan3 (xmlHashTablePtr hash, + const xmlChar *name, + const xmlChar *name2, + const xmlChar *name3, + xmlHashScanner scan, + void *data); +XMLPUBFUN void + xmlHashScanFull (xmlHashTablePtr hash, + xmlHashScannerFull scan, + void *data); +XMLPUBFUN void + xmlHashScanFull3 (xmlHashTablePtr hash, + const xmlChar *name, + const xmlChar *name2, + const xmlChar *name3, + xmlHashScannerFull scan, + void *data); +#ifdef __cplusplus +} +#endif +#endif /* ! __XML_HASH_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/list.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/list.h new file mode 100644 index 0000000..1fa76af --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/list.h @@ -0,0 +1,137 @@ +/* + * Summary: lists interfaces + * Description: this module implement the list support used in + * various place in the library. + * + * Copy: See Copyright for the status of this software. + * + * Author: Gary Pennington + */ + +#ifndef __XML_LINK_INCLUDE__ +#define __XML_LINK_INCLUDE__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _xmlLink xmlLink; +typedef xmlLink *xmlLinkPtr; + +typedef struct _xmlList xmlList; +typedef xmlList *xmlListPtr; + +/** + * xmlListDeallocator: + * @lk: the data to deallocate + * + * Callback function used to free data from a list. + */ +typedef void (*xmlListDeallocator) (xmlLinkPtr lk); +/** + * xmlListDataCompare: + * @data0: the first data + * @data1: the second data + * + * Callback function used to compare 2 data. + * + * Returns 0 is equality, -1 or 1 otherwise depending on the ordering. + */ +typedef int (*xmlListDataCompare) (const void *data0, const void *data1); +/** + * xmlListWalker: + * @data: the data found in the list + * @user: extra user provided data to the walker + * + * Callback function used when walking a list with xmlListWalk(). + * + * Returns 0 to stop walking the list, 1 otherwise. + */ +typedef int (*xmlListWalker) (const void *data, void *user); + +/* Creation/Deletion */ +XMLPUBFUN xmlListPtr + xmlListCreate (xmlListDeallocator deallocator, + xmlListDataCompare compare); +XMLPUBFUN void + xmlListDelete (xmlListPtr l); + +/* Basic Operators */ +XMLPUBFUN void * + xmlListSearch (xmlListPtr l, + void *data); +XMLPUBFUN void * + xmlListReverseSearch (xmlListPtr l, + void *data); +XMLPUBFUN int + xmlListInsert (xmlListPtr l, + void *data) ; +XMLPUBFUN int + xmlListAppend (xmlListPtr l, + void *data) ; +XMLPUBFUN int + xmlListRemoveFirst (xmlListPtr l, + void *data); +XMLPUBFUN int + xmlListRemoveLast (xmlListPtr l, + void *data); +XMLPUBFUN int + xmlListRemoveAll (xmlListPtr l, + void *data); +XMLPUBFUN void + xmlListClear (xmlListPtr l); +XMLPUBFUN int + xmlListEmpty (xmlListPtr l); +XMLPUBFUN xmlLinkPtr + xmlListFront (xmlListPtr l); +XMLPUBFUN xmlLinkPtr + xmlListEnd (xmlListPtr l); +XMLPUBFUN int + xmlListSize (xmlListPtr l); + +XMLPUBFUN void + xmlListPopFront (xmlListPtr l); +XMLPUBFUN void + xmlListPopBack (xmlListPtr l); +XMLPUBFUN int + xmlListPushFront (xmlListPtr l, + void *data); +XMLPUBFUN int + xmlListPushBack (xmlListPtr l, + void *data); + +/* Advanced Operators */ +XMLPUBFUN void + xmlListReverse (xmlListPtr l); +XMLPUBFUN void + xmlListSort (xmlListPtr l); +XMLPUBFUN void + xmlListWalk (xmlListPtr l, + xmlListWalker walker, + void *user); +XMLPUBFUN void + xmlListReverseWalk (xmlListPtr l, + xmlListWalker walker, + void *user); +XMLPUBFUN void + xmlListMerge (xmlListPtr l1, + xmlListPtr l2); +XMLPUBFUN xmlListPtr + xmlListDup (xmlListPtr old); +XMLPUBFUN int + xmlListCopy (xmlListPtr cur, + xmlListPtr old); +/* Link operators */ +XMLPUBFUN void * + xmlLinkGetData (xmlLinkPtr lk); + +/* xmlListUnique() */ +/* xmlListSwap */ + +#ifdef __cplusplus +} +#endif + +#endif /* __XML_LINK_INCLUDE__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/nanoftp.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/nanoftp.h new file mode 100644 index 0000000..ed3ac4f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/nanoftp.h @@ -0,0 +1,186 @@ +/* + * Summary: minimal FTP implementation + * Description: minimal FTP implementation allowing to fetch resources + * like external subset. This module is DEPRECATED, do not + * use any of its functions. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __NANO_FTP_H__ +#define __NANO_FTP_H__ + +#include + +#if defined(LIBXML_FTP_ENABLED) + +/* Needed for portability to Windows 64 bits */ +#if defined(_WIN32) +#include +#else +/** + * SOCKET: + * + * macro used to provide portability of code to windows sockets + */ +#define SOCKET int +/** + * INVALID_SOCKET: + * + * macro used to provide portability of code to windows sockets + * the value to be used when the socket is not valid + */ +#undef INVALID_SOCKET +#define INVALID_SOCKET (-1) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * ftpListCallback: + * @userData: user provided data for the callback + * @filename: the file name (including "->" when links are shown) + * @attrib: the attribute string + * @owner: the owner string + * @group: the group string + * @size: the file size + * @links: the link count + * @year: the year + * @month: the month + * @day: the day + * @hour: the hour + * @minute: the minute + * + * A callback for the xmlNanoFTPList command. + * Note that only one of year and day:minute are specified. + */ +typedef void (*ftpListCallback) (void *userData, + const char *filename, const char *attrib, + const char *owner, const char *group, + unsigned long size, int links, int year, + const char *month, int day, int hour, + int minute); +/** + * ftpDataCallback: + * @userData: the user provided context + * @data: the data received + * @len: its size in bytes + * + * A callback for the xmlNanoFTPGet command. + */ +typedef void (*ftpDataCallback) (void *userData, + const char *data, + int len); + +/* + * Init + */ +XML_DEPRECATED +XMLPUBFUN void + xmlNanoFTPInit (void); +XML_DEPRECATED +XMLPUBFUN void + xmlNanoFTPCleanup (void); + +/* + * Creating/freeing contexts. + */ +XML_DEPRECATED +XMLPUBFUN void * + xmlNanoFTPNewCtxt (const char *URL); +XML_DEPRECATED +XMLPUBFUN void + xmlNanoFTPFreeCtxt (void * ctx); +XML_DEPRECATED +XMLPUBFUN void * + xmlNanoFTPConnectTo (const char *server, + int port); +/* + * Opening/closing session connections. + */ +XML_DEPRECATED +XMLPUBFUN void * + xmlNanoFTPOpen (const char *URL); +XML_DEPRECATED +XMLPUBFUN int + xmlNanoFTPConnect (void *ctx); +XML_DEPRECATED +XMLPUBFUN int + xmlNanoFTPClose (void *ctx); +XML_DEPRECATED +XMLPUBFUN int + xmlNanoFTPQuit (void *ctx); +XML_DEPRECATED +XMLPUBFUN void + xmlNanoFTPScanProxy (const char *URL); +XML_DEPRECATED +XMLPUBFUN void + xmlNanoFTPProxy (const char *host, + int port, + const char *user, + const char *passwd, + int type); +XML_DEPRECATED +XMLPUBFUN int + xmlNanoFTPUpdateURL (void *ctx, + const char *URL); + +/* + * Rather internal commands. + */ +XML_DEPRECATED +XMLPUBFUN int + xmlNanoFTPGetResponse (void *ctx); +XML_DEPRECATED +XMLPUBFUN int + xmlNanoFTPCheckResponse (void *ctx); + +/* + * CD/DIR/GET handlers. + */ +XML_DEPRECATED +XMLPUBFUN int + xmlNanoFTPCwd (void *ctx, + const char *directory); +XML_DEPRECATED +XMLPUBFUN int + xmlNanoFTPDele (void *ctx, + const char *file); + +XML_DEPRECATED +XMLPUBFUN SOCKET + xmlNanoFTPGetConnection (void *ctx); +XML_DEPRECATED +XMLPUBFUN int + xmlNanoFTPCloseConnection(void *ctx); +XML_DEPRECATED +XMLPUBFUN int + xmlNanoFTPList (void *ctx, + ftpListCallback callback, + void *userData, + const char *filename); +XML_DEPRECATED +XMLPUBFUN SOCKET + xmlNanoFTPGetSocket (void *ctx, + const char *filename); +XML_DEPRECATED +XMLPUBFUN int + xmlNanoFTPGet (void *ctx, + ftpDataCallback callback, + void *userData, + const char *filename); +XML_DEPRECATED +XMLPUBFUN int + xmlNanoFTPRead (void *ctx, + void *dest, + int len); + +#ifdef __cplusplus +} +#endif +#endif /* defined(LIBXML_FTP_ENABLED) || defined(LIBXML_LEGACY_ENABLED) */ +#endif /* __NANO_FTP_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/nanohttp.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/nanohttp.h new file mode 100644 index 0000000..c70d1c2 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/nanohttp.h @@ -0,0 +1,98 @@ +/* + * Summary: minimal HTTP implementation + * Description: minimal HTTP implementation allowing to fetch resources + * like external subset. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __NANO_HTTP_H__ +#define __NANO_HTTP_H__ + +#include + +#ifdef LIBXML_HTTP_ENABLED + +#ifdef __cplusplus +extern "C" { +#endif +XML_DEPRECATED +XMLPUBFUN void + xmlNanoHTTPInit (void); +XML_DEPRECATED +XMLPUBFUN void + xmlNanoHTTPCleanup (void); +XML_DEPRECATED +XMLPUBFUN void + xmlNanoHTTPScanProxy (const char *URL); +XML_DEPRECATED +XMLPUBFUN int + xmlNanoHTTPFetch (const char *URL, + const char *filename, + char **contentType); +XML_DEPRECATED +XMLPUBFUN void * + xmlNanoHTTPMethod (const char *URL, + const char *method, + const char *input, + char **contentType, + const char *headers, + int ilen); +XML_DEPRECATED +XMLPUBFUN void * + xmlNanoHTTPMethodRedir (const char *URL, + const char *method, + const char *input, + char **contentType, + char **redir, + const char *headers, + int ilen); +XML_DEPRECATED +XMLPUBFUN void * + xmlNanoHTTPOpen (const char *URL, + char **contentType); +XML_DEPRECATED +XMLPUBFUN void * + xmlNanoHTTPOpenRedir (const char *URL, + char **contentType, + char **redir); +XML_DEPRECATED +XMLPUBFUN int + xmlNanoHTTPReturnCode (void *ctx); +XML_DEPRECATED +XMLPUBFUN const char * + xmlNanoHTTPAuthHeader (void *ctx); +XML_DEPRECATED +XMLPUBFUN const char * + xmlNanoHTTPRedir (void *ctx); +XML_DEPRECATED +XMLPUBFUN int + xmlNanoHTTPContentLength( void * ctx ); +XML_DEPRECATED +XMLPUBFUN const char * + xmlNanoHTTPEncoding (void *ctx); +XML_DEPRECATED +XMLPUBFUN const char * + xmlNanoHTTPMimeType (void *ctx); +XML_DEPRECATED +XMLPUBFUN int + xmlNanoHTTPRead (void *ctx, + void *dest, + int len); +#ifdef LIBXML_OUTPUT_ENABLED +XML_DEPRECATED +XMLPUBFUN int + xmlNanoHTTPSave (void *ctxt, + const char *filename); +#endif /* LIBXML_OUTPUT_ENABLED */ +XML_DEPRECATED +XMLPUBFUN void + xmlNanoHTTPClose (void *ctx); +#ifdef __cplusplus +} +#endif + +#endif /* LIBXML_HTTP_ENABLED */ +#endif /* __NANO_HTTP_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/parser.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/parser.h new file mode 100644 index 0000000..78d29ca --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/parser.h @@ -0,0 +1,1390 @@ +/* + * Summary: the core parser module + * Description: Interfaces, constants and types related to the XML parser + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_PARSER_H__ +#define __XML_PARSER_H__ + +/** DOC_DISABLE */ +#include +#define XML_TREE_INTERNALS +#include +#undef XML_TREE_INTERNALS +#include +#include +#include +#include +#include +#include +#include +#include +#include +/* for compatibility */ +#include +#include +/** DOC_ENABLE */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * XML_DEFAULT_VERSION: + * + * The default version of XML used: 1.0 + */ +#define XML_DEFAULT_VERSION "1.0" + +/** + * xmlParserInput: + * + * An xmlParserInput is an input flow for the XML processor. + * Each entity parsed is associated an xmlParserInput (except the + * few predefined ones). This is the case both for internal entities + * - in which case the flow is already completely in memory - or + * external entities - in which case we use the buf structure for + * progressive reading and I18N conversions to the internal UTF-8 format. + */ + +/** + * xmlParserInputDeallocate: + * @str: the string to deallocate + * + * Callback for freeing some parser input allocations. + */ +typedef void (* xmlParserInputDeallocate)(xmlChar *str); + +struct _xmlParserInput { + /* Input buffer */ + xmlParserInputBufferPtr buf; /* UTF-8 encoded buffer */ + + const char *filename; /* The file analyzed, if any */ + const char *directory; /* unused */ + const xmlChar *base; /* Base of the array to parse */ + const xmlChar *cur; /* Current char being parsed */ + const xmlChar *end; /* end of the array to parse */ + int length; /* unused */ + int line; /* Current line */ + int col; /* Current column */ + unsigned long consumed; /* How many xmlChars already consumed */ + xmlParserInputDeallocate free; /* function to deallocate the base */ + const xmlChar *encoding; /* unused */ + const xmlChar *version; /* the version string for entity */ + int flags; /* Flags */ + int id; /* an unique identifier for the entity */ + unsigned long parentConsumed; /* unused */ + xmlEntityPtr entity; /* entity, if any */ +}; + +/** + * xmlParserNodeInfo: + * + * The parser can be asked to collect Node information, i.e. at what + * place in the file they were detected. + * NOTE: This is off by default and not very well tested. + */ +typedef struct _xmlParserNodeInfo xmlParserNodeInfo; +typedef xmlParserNodeInfo *xmlParserNodeInfoPtr; + +struct _xmlParserNodeInfo { + const struct _xmlNode* node; + /* Position & line # that text that created the node begins & ends on */ + unsigned long begin_pos; + unsigned long begin_line; + unsigned long end_pos; + unsigned long end_line; +}; + +typedef struct _xmlParserNodeInfoSeq xmlParserNodeInfoSeq; +typedef xmlParserNodeInfoSeq *xmlParserNodeInfoSeqPtr; +struct _xmlParserNodeInfoSeq { + unsigned long maximum; + unsigned long length; + xmlParserNodeInfo* buffer; +}; + +/** + * xmlParserInputState: + * + * The parser is now working also as a state based parser. + * The recursive one use the state info for entities processing. + */ +typedef enum { + XML_PARSER_EOF = -1, /* nothing is to be parsed */ + XML_PARSER_START = 0, /* nothing has been parsed */ + XML_PARSER_MISC, /* Misc* before int subset */ + XML_PARSER_PI, /* Within a processing instruction */ + XML_PARSER_DTD, /* within some DTD content */ + XML_PARSER_PROLOG, /* Misc* after internal subset */ + XML_PARSER_COMMENT, /* within a comment */ + XML_PARSER_START_TAG, /* within a start tag */ + XML_PARSER_CONTENT, /* within the content */ + XML_PARSER_CDATA_SECTION, /* within a CDATA section */ + XML_PARSER_END_TAG, /* within a closing tag */ + XML_PARSER_ENTITY_DECL, /* within an entity declaration */ + XML_PARSER_ENTITY_VALUE, /* within an entity value in a decl */ + XML_PARSER_ATTRIBUTE_VALUE, /* within an attribute value */ + XML_PARSER_SYSTEM_LITERAL, /* within a SYSTEM value */ + XML_PARSER_EPILOG, /* the Misc* after the last end tag */ + XML_PARSER_IGNORE, /* within an IGNORED section */ + XML_PARSER_PUBLIC_LITERAL, /* within a PUBLIC value */ + XML_PARSER_XML_DECL /* before XML decl (but after BOM) */ +} xmlParserInputState; + +/** DOC_DISABLE */ +/* + * Internal bits in the 'loadsubset' context member + */ +#define XML_DETECT_IDS 2 +#define XML_COMPLETE_ATTRS 4 +#define XML_SKIP_IDS 8 +/** DOC_ENABLE */ + +/** + * xmlParserMode: + * + * A parser can operate in various modes + */ +typedef enum { + XML_PARSE_UNKNOWN = 0, + XML_PARSE_DOM = 1, + XML_PARSE_SAX = 2, + XML_PARSE_PUSH_DOM = 3, + XML_PARSE_PUSH_SAX = 4, + XML_PARSE_READER = 5 +} xmlParserMode; + +typedef struct _xmlStartTag xmlStartTag; +typedef struct _xmlParserNsData xmlParserNsData; +typedef struct _xmlAttrHashBucket xmlAttrHashBucket; + +/** + * xmlParserCtxt: + * + * The parser context. + * NOTE This doesn't completely define the parser state, the (current ?) + * design of the parser uses recursive function calls since this allow + * and easy mapping from the production rules of the specification + * to the actual code. The drawback is that the actual function call + * also reflect the parser state. However most of the parsing routines + * takes as the only argument the parser context pointer, so migrating + * to a state based parser for progressive parsing shouldn't be too hard. + */ +struct _xmlParserCtxt { + struct _xmlSAXHandler *sax; /* The SAX handler */ + void *userData; /* For SAX interface only, used by DOM build */ + xmlDocPtr myDoc; /* the document being built */ + int wellFormed; /* is the document well formed */ + int replaceEntities; /* shall we replace entities ? */ + const xmlChar *version; /* the XML version string */ + const xmlChar *encoding; /* the declared encoding, if any */ + int standalone; /* standalone document */ + int html; /* an HTML(1) document + * 3 is HTML after + * 10 is HTML after + */ + + /* Input stream stack */ + xmlParserInputPtr input; /* Current input stream */ + int inputNr; /* Number of current input streams */ + int inputMax; /* Max number of input streams */ + xmlParserInputPtr *inputTab; /* stack of inputs */ + + /* Node analysis stack only used for DOM building */ + xmlNodePtr node; /* Current parsed Node */ + int nodeNr; /* Depth of the parsing stack */ + int nodeMax; /* Max depth of the parsing stack */ + xmlNodePtr *nodeTab; /* array of nodes */ + + int record_info; /* Whether node info should be kept */ + xmlParserNodeInfoSeq node_seq; /* info about each node parsed */ + + int errNo; /* error code */ + + int hasExternalSubset; /* reference and external subset */ + int hasPErefs; /* the internal subset has PE refs */ + int external; /* unused */ + + int valid; /* is the document valid */ + int validate; /* shall we try to validate ? */ + xmlValidCtxt vctxt; /* The validity context */ + + xmlParserInputState instate; /* push parser state */ + int token; /* unused */ + + char *directory; /* unused */ + + /* Node name stack */ + const xmlChar *name; /* Current parsed Node */ + int nameNr; /* Depth of the parsing stack */ + int nameMax; /* Max depth of the parsing stack */ + const xmlChar * *nameTab; /* array of nodes */ + + long nbChars; /* unused */ + long checkIndex; /* used by progressive parsing lookup */ + int keepBlanks; /* ugly but ... */ + int disableSAX; /* SAX callbacks are disabled */ + int inSubset; /* Parsing is in int 1/ext 2 subset */ + const xmlChar * intSubName; /* name of subset */ + xmlChar * extSubURI; /* URI of external subset */ + xmlChar * extSubSystem; /* SYSTEM ID of external subset */ + + /* xml:space values */ + int * space; /* Should the parser preserve spaces */ + int spaceNr; /* Depth of the parsing stack */ + int spaceMax; /* Max depth of the parsing stack */ + int * spaceTab; /* array of space infos */ + + int depth; /* to prevent entity substitution loops */ + xmlParserInputPtr entity; /* unused */ + int charset; /* unused */ + int nodelen; /* Those two fields are there to */ + int nodemem; /* Speed up large node parsing */ + int pedantic; /* signal pedantic warnings */ + void *_private; /* For user data, libxml won't touch it */ + + int loadsubset; /* should the external subset be loaded */ + int linenumbers; /* set line number in element content */ + void *catalogs; /* document's own catalog */ + int recovery; /* run in recovery mode */ + int progressive; /* unused */ + xmlDictPtr dict; /* dictionary for the parser */ + const xmlChar * *atts; /* array for the attributes callbacks */ + int maxatts; /* the size of the array */ + int docdict; /* unused */ + + /* + * pre-interned strings + */ + const xmlChar *str_xml; + const xmlChar *str_xmlns; + const xmlChar *str_xml_ns; + + /* + * Everything below is used only by the new SAX mode + */ + int sax2; /* operating in the new SAX mode */ + int nsNr; /* the number of inherited namespaces */ + int nsMax; /* the size of the arrays */ + const xmlChar * *nsTab; /* the array of prefix/namespace name */ + unsigned *attallocs; /* which attribute were allocated */ + xmlStartTag *pushTab; /* array of data for push */ + xmlHashTablePtr attsDefault; /* defaulted attributes if any */ + xmlHashTablePtr attsSpecial; /* non-CDATA attributes if any */ + int nsWellFormed; /* is the document XML Namespace okay */ + int options; /* Extra options */ + + /* + * Those fields are needed only for streaming parsing so far + */ + int dictNames; /* Use dictionary names for the tree */ + int freeElemsNr; /* number of freed element nodes */ + xmlNodePtr freeElems; /* List of freed element nodes */ + int freeAttrsNr; /* number of freed attributes nodes */ + xmlAttrPtr freeAttrs; /* List of freed attributes nodes */ + + /* + * the complete error information for the last error. + */ + xmlError lastError; + xmlParserMode parseMode; /* the parser mode */ + unsigned long nbentities; /* unused */ + unsigned long sizeentities; /* size of external entities */ + + /* for use by HTML non-recursive parser */ + xmlParserNodeInfo *nodeInfo; /* Current NodeInfo */ + int nodeInfoNr; /* Depth of the parsing stack */ + int nodeInfoMax; /* Max depth of the parsing stack */ + xmlParserNodeInfo *nodeInfoTab; /* array of nodeInfos */ + + int input_id; /* we need to label inputs */ + unsigned long sizeentcopy; /* volume of entity copy */ + + int endCheckState; /* quote state for push parser */ + unsigned short nbErrors; /* number of errors */ + unsigned short nbWarnings; /* number of warnings */ + unsigned maxAmpl; /* maximum amplification factor */ + + xmlParserNsData *nsdb; /* namespace database */ + unsigned attrHashMax; /* allocated size */ + xmlAttrHashBucket *attrHash; /* atttribute hash table */ + + xmlStructuredErrorFunc errorHandler; + void *errorCtxt; +}; + +/** + * xmlSAXLocator: + * + * A SAX Locator. + */ +struct _xmlSAXLocator { + const xmlChar *(*getPublicId)(void *ctx); + const xmlChar *(*getSystemId)(void *ctx); + int (*getLineNumber)(void *ctx); + int (*getColumnNumber)(void *ctx); +}; + +/** + * xmlSAXHandler: + * + * A SAX handler is bunch of callbacks called by the parser when processing + * of the input generate data or structure information. + */ + +/** + * resolveEntitySAXFunc: + * @ctx: the user data (XML parser context) + * @publicId: The public ID of the entity + * @systemId: The system ID of the entity + * + * Callback: + * The entity loader, to control the loading of external entities, + * the application can either: + * - override this resolveEntity() callback in the SAX block + * - or better use the xmlSetExternalEntityLoader() function to + * set up it's own entity resolution routine + * + * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour. + */ +typedef xmlParserInputPtr (*resolveEntitySAXFunc) (void *ctx, + const xmlChar *publicId, + const xmlChar *systemId); +/** + * internalSubsetSAXFunc: + * @ctx: the user data (XML parser context) + * @name: the root element name + * @ExternalID: the external ID + * @SystemID: the SYSTEM ID (e.g. filename or URL) + * + * Callback on internal subset declaration. + */ +typedef void (*internalSubsetSAXFunc) (void *ctx, + const xmlChar *name, + const xmlChar *ExternalID, + const xmlChar *SystemID); +/** + * externalSubsetSAXFunc: + * @ctx: the user data (XML parser context) + * @name: the root element name + * @ExternalID: the external ID + * @SystemID: the SYSTEM ID (e.g. filename or URL) + * + * Callback on external subset declaration. + */ +typedef void (*externalSubsetSAXFunc) (void *ctx, + const xmlChar *name, + const xmlChar *ExternalID, + const xmlChar *SystemID); +/** + * getEntitySAXFunc: + * @ctx: the user data (XML parser context) + * @name: The entity name + * + * Get an entity by name. + * + * Returns the xmlEntityPtr if found. + */ +typedef xmlEntityPtr (*getEntitySAXFunc) (void *ctx, + const xmlChar *name); +/** + * getParameterEntitySAXFunc: + * @ctx: the user data (XML parser context) + * @name: The entity name + * + * Get a parameter entity by name. + * + * Returns the xmlEntityPtr if found. + */ +typedef xmlEntityPtr (*getParameterEntitySAXFunc) (void *ctx, + const xmlChar *name); +/** + * entityDeclSAXFunc: + * @ctx: the user data (XML parser context) + * @name: the entity name + * @type: the entity type + * @publicId: The public ID of the entity + * @systemId: The system ID of the entity + * @content: the entity value (without processing). + * + * An entity definition has been parsed. + */ +typedef void (*entityDeclSAXFunc) (void *ctx, + const xmlChar *name, + int type, + const xmlChar *publicId, + const xmlChar *systemId, + xmlChar *content); +/** + * notationDeclSAXFunc: + * @ctx: the user data (XML parser context) + * @name: The name of the notation + * @publicId: The public ID of the entity + * @systemId: The system ID of the entity + * + * What to do when a notation declaration has been parsed. + */ +typedef void (*notationDeclSAXFunc)(void *ctx, + const xmlChar *name, + const xmlChar *publicId, + const xmlChar *systemId); +/** + * attributeDeclSAXFunc: + * @ctx: the user data (XML parser context) + * @elem: the name of the element + * @fullname: the attribute name + * @type: the attribute type + * @def: the type of default value + * @defaultValue: the attribute default value + * @tree: the tree of enumerated value set + * + * An attribute definition has been parsed. + */ +typedef void (*attributeDeclSAXFunc)(void *ctx, + const xmlChar *elem, + const xmlChar *fullname, + int type, + int def, + const xmlChar *defaultValue, + xmlEnumerationPtr tree); +/** + * elementDeclSAXFunc: + * @ctx: the user data (XML parser context) + * @name: the element name + * @type: the element type + * @content: the element value tree + * + * An element definition has been parsed. + */ +typedef void (*elementDeclSAXFunc)(void *ctx, + const xmlChar *name, + int type, + xmlElementContentPtr content); +/** + * unparsedEntityDeclSAXFunc: + * @ctx: the user data (XML parser context) + * @name: The name of the entity + * @publicId: The public ID of the entity + * @systemId: The system ID of the entity + * @notationName: the name of the notation + * + * What to do when an unparsed entity declaration is parsed. + */ +typedef void (*unparsedEntityDeclSAXFunc)(void *ctx, + const xmlChar *name, + const xmlChar *publicId, + const xmlChar *systemId, + const xmlChar *notationName); +/** + * setDocumentLocatorSAXFunc: + * @ctx: the user data (XML parser context) + * @loc: A SAX Locator + * + * Receive the document locator at startup, actually xmlDefaultSAXLocator. + * Everything is available on the context, so this is useless in our case. + */ +typedef void (*setDocumentLocatorSAXFunc) (void *ctx, + xmlSAXLocatorPtr loc); +/** + * startDocumentSAXFunc: + * @ctx: the user data (XML parser context) + * + * Called when the document start being processed. + */ +typedef void (*startDocumentSAXFunc) (void *ctx); +/** + * endDocumentSAXFunc: + * @ctx: the user data (XML parser context) + * + * Called when the document end has been detected. + */ +typedef void (*endDocumentSAXFunc) (void *ctx); +/** + * startElementSAXFunc: + * @ctx: the user data (XML parser context) + * @name: The element name, including namespace prefix + * @atts: An array of name/value attributes pairs, NULL terminated + * + * Called when an opening tag has been processed. + */ +typedef void (*startElementSAXFunc) (void *ctx, + const xmlChar *name, + const xmlChar **atts); +/** + * endElementSAXFunc: + * @ctx: the user data (XML parser context) + * @name: The element name + * + * Called when the end of an element has been detected. + */ +typedef void (*endElementSAXFunc) (void *ctx, + const xmlChar *name); +/** + * attributeSAXFunc: + * @ctx: the user data (XML parser context) + * @name: The attribute name, including namespace prefix + * @value: The attribute value + * + * Handle an attribute that has been read by the parser. + * The default handling is to convert the attribute into an + * DOM subtree and past it in a new xmlAttr element added to + * the element. + */ +typedef void (*attributeSAXFunc) (void *ctx, + const xmlChar *name, + const xmlChar *value); +/** + * referenceSAXFunc: + * @ctx: the user data (XML parser context) + * @name: The entity name + * + * Called when an entity reference is detected. + */ +typedef void (*referenceSAXFunc) (void *ctx, + const xmlChar *name); +/** + * charactersSAXFunc: + * @ctx: the user data (XML parser context) + * @ch: a xmlChar string + * @len: the number of xmlChar + * + * Receiving some chars from the parser. + */ +typedef void (*charactersSAXFunc) (void *ctx, + const xmlChar *ch, + int len); +/** + * ignorableWhitespaceSAXFunc: + * @ctx: the user data (XML parser context) + * @ch: a xmlChar string + * @len: the number of xmlChar + * + * Receiving some ignorable whitespaces from the parser. + * UNUSED: by default the DOM building will use characters. + */ +typedef void (*ignorableWhitespaceSAXFunc) (void *ctx, + const xmlChar *ch, + int len); +/** + * processingInstructionSAXFunc: + * @ctx: the user data (XML parser context) + * @target: the target name + * @data: the PI data's + * + * A processing instruction has been parsed. + */ +typedef void (*processingInstructionSAXFunc) (void *ctx, + const xmlChar *target, + const xmlChar *data); +/** + * commentSAXFunc: + * @ctx: the user data (XML parser context) + * @value: the comment content + * + * A comment has been parsed. + */ +typedef void (*commentSAXFunc) (void *ctx, + const xmlChar *value); +/** + * cdataBlockSAXFunc: + * @ctx: the user data (XML parser context) + * @value: The pcdata content + * @len: the block length + * + * Called when a pcdata block has been parsed. + */ +typedef void (*cdataBlockSAXFunc) ( + void *ctx, + const xmlChar *value, + int len); +/** + * warningSAXFunc: + * @ctx: an XML parser context + * @msg: the message to display/transmit + * @...: extra parameters for the message display + * + * Display and format a warning messages, callback. + */ +typedef void (*warningSAXFunc) (void *ctx, + const char *msg, ...) LIBXML_ATTR_FORMAT(2,3); +/** + * errorSAXFunc: + * @ctx: an XML parser context + * @msg: the message to display/transmit + * @...: extra parameters for the message display + * + * Display and format an error messages, callback. + */ +typedef void (*errorSAXFunc) (void *ctx, + const char *msg, ...) LIBXML_ATTR_FORMAT(2,3); +/** + * fatalErrorSAXFunc: + * @ctx: an XML parser context + * @msg: the message to display/transmit + * @...: extra parameters for the message display + * + * Display and format fatal error messages, callback. + * Note: so far fatalError() SAX callbacks are not used, error() + * get all the callbacks for errors. + */ +typedef void (*fatalErrorSAXFunc) (void *ctx, + const char *msg, ...) LIBXML_ATTR_FORMAT(2,3); +/** + * isStandaloneSAXFunc: + * @ctx: the user data (XML parser context) + * + * Is this document tagged standalone? + * + * Returns 1 if true + */ +typedef int (*isStandaloneSAXFunc) (void *ctx); +/** + * hasInternalSubsetSAXFunc: + * @ctx: the user data (XML parser context) + * + * Does this document has an internal subset. + * + * Returns 1 if true + */ +typedef int (*hasInternalSubsetSAXFunc) (void *ctx); + +/** + * hasExternalSubsetSAXFunc: + * @ctx: the user data (XML parser context) + * + * Does this document has an external subset? + * + * Returns 1 if true + */ +typedef int (*hasExternalSubsetSAXFunc) (void *ctx); + +/************************************************************************ + * * + * The SAX version 2 API extensions * + * * + ************************************************************************/ +/** + * XML_SAX2_MAGIC: + * + * Special constant found in SAX2 blocks initialized fields + */ +#define XML_SAX2_MAGIC 0xDEEDBEAF + +/** + * startElementNsSAX2Func: + * @ctx: the user data (XML parser context) + * @localname: the local name of the element + * @prefix: the element namespace prefix if available + * @URI: the element namespace name if available + * @nb_namespaces: number of namespace definitions on that node + * @namespaces: pointer to the array of prefix/URI pairs namespace definitions + * @nb_attributes: the number of attributes on that node + * @nb_defaulted: the number of defaulted attributes. The defaulted + * ones are at the end of the array + * @attributes: pointer to the array of (localname/prefix/URI/value/end) + * attribute values. + * + * SAX2 callback when an element start has been detected by the parser. + * It provides the namespace information for the element, as well as + * the new namespace declarations on the element. + */ + +typedef void (*startElementNsSAX2Func) (void *ctx, + const xmlChar *localname, + const xmlChar *prefix, + const xmlChar *URI, + int nb_namespaces, + const xmlChar **namespaces, + int nb_attributes, + int nb_defaulted, + const xmlChar **attributes); + +/** + * endElementNsSAX2Func: + * @ctx: the user data (XML parser context) + * @localname: the local name of the element + * @prefix: the element namespace prefix if available + * @URI: the element namespace name if available + * + * SAX2 callback when an element end has been detected by the parser. + * It provides the namespace information for the element. + */ + +typedef void (*endElementNsSAX2Func) (void *ctx, + const xmlChar *localname, + const xmlChar *prefix, + const xmlChar *URI); + + +struct _xmlSAXHandler { + internalSubsetSAXFunc internalSubset; + isStandaloneSAXFunc isStandalone; + hasInternalSubsetSAXFunc hasInternalSubset; + hasExternalSubsetSAXFunc hasExternalSubset; + resolveEntitySAXFunc resolveEntity; + getEntitySAXFunc getEntity; + entityDeclSAXFunc entityDecl; + notationDeclSAXFunc notationDecl; + attributeDeclSAXFunc attributeDecl; + elementDeclSAXFunc elementDecl; + unparsedEntityDeclSAXFunc unparsedEntityDecl; + setDocumentLocatorSAXFunc setDocumentLocator; + startDocumentSAXFunc startDocument; + endDocumentSAXFunc endDocument; + /* + * `startElement` and `endElement` are only used by the legacy SAX1 + * interface and should not be used in new software. If you really + * have to enable SAX1, the preferred way is set the `initialized` + * member to 1 instead of XML_SAX2_MAGIC. + * + * For backward compatibility, it's also possible to set the + * `startElementNs` and `endElementNs` handlers to NULL. + * + * You can also set the XML_PARSE_SAX1 parser option, but versions + * older than 2.12.0 will probably crash if this option is provided + * together with custom SAX callbacks. + */ + startElementSAXFunc startElement; + endElementSAXFunc endElement; + referenceSAXFunc reference; + charactersSAXFunc characters; + ignorableWhitespaceSAXFunc ignorableWhitespace; + processingInstructionSAXFunc processingInstruction; + commentSAXFunc comment; + warningSAXFunc warning; + errorSAXFunc error; + fatalErrorSAXFunc fatalError; /* unused error() get all the errors */ + getParameterEntitySAXFunc getParameterEntity; + cdataBlockSAXFunc cdataBlock; + externalSubsetSAXFunc externalSubset; + /* + * `initialized` should always be set to XML_SAX2_MAGIC to enable the + * modern SAX2 interface. + */ + unsigned int initialized; + /* + * The following members are only used by the SAX2 interface. + */ + void *_private; + startElementNsSAX2Func startElementNs; + endElementNsSAX2Func endElementNs; + xmlStructuredErrorFunc serror; +}; + +/* + * SAX Version 1 + */ +typedef struct _xmlSAXHandlerV1 xmlSAXHandlerV1; +typedef xmlSAXHandlerV1 *xmlSAXHandlerV1Ptr; +struct _xmlSAXHandlerV1 { + internalSubsetSAXFunc internalSubset; + isStandaloneSAXFunc isStandalone; + hasInternalSubsetSAXFunc hasInternalSubset; + hasExternalSubsetSAXFunc hasExternalSubset; + resolveEntitySAXFunc resolveEntity; + getEntitySAXFunc getEntity; + entityDeclSAXFunc entityDecl; + notationDeclSAXFunc notationDecl; + attributeDeclSAXFunc attributeDecl; + elementDeclSAXFunc elementDecl; + unparsedEntityDeclSAXFunc unparsedEntityDecl; + setDocumentLocatorSAXFunc setDocumentLocator; + startDocumentSAXFunc startDocument; + endDocumentSAXFunc endDocument; + startElementSAXFunc startElement; + endElementSAXFunc endElement; + referenceSAXFunc reference; + charactersSAXFunc characters; + ignorableWhitespaceSAXFunc ignorableWhitespace; + processingInstructionSAXFunc processingInstruction; + commentSAXFunc comment; + warningSAXFunc warning; + errorSAXFunc error; + fatalErrorSAXFunc fatalError; /* unused error() get all the errors */ + getParameterEntitySAXFunc getParameterEntity; + cdataBlockSAXFunc cdataBlock; + externalSubsetSAXFunc externalSubset; + unsigned int initialized; +}; + + +/** + * xmlExternalEntityLoader: + * @URL: The System ID of the resource requested + * @ID: The Public ID of the resource requested + * @context: the XML parser context + * + * External entity loaders types. + * + * Returns the entity input parser. + */ +typedef xmlParserInputPtr (*xmlExternalEntityLoader) (const char *URL, + const char *ID, + xmlParserCtxtPtr context); + +/* + * Variables + */ + +XMLPUBVAR const char *const xmlParserVersion; +XML_DEPRECATED +XMLPUBVAR const int oldXMLWDcompatibility; +XML_DEPRECATED +XMLPUBVAR const int xmlParserDebugEntities; +XML_DEPRECATED +XMLPUBVAR const xmlSAXLocator xmlDefaultSAXLocator; +#ifdef LIBXML_SAX1_ENABLED +XML_DEPRECATED +XMLPUBVAR const xmlSAXHandlerV1 xmlDefaultSAXHandler; +#endif + +#ifdef LIBXML_THREAD_ENABLED +/* backward compatibility */ +XMLPUBFUN const char *const *__xmlParserVersion(void); +XML_DEPRECATED +XMLPUBFUN const int *__oldXMLWDcompatibility(void); +XML_DEPRECATED +XMLPUBFUN const int *__xmlParserDebugEntities(void); +XML_DEPRECATED +XMLPUBFUN const xmlSAXLocator *__xmlDefaultSAXLocator(void); +#ifdef LIBXML_SAX1_ENABLED +XML_DEPRECATED +XMLPUBFUN const xmlSAXHandlerV1 *__xmlDefaultSAXHandler(void); +#endif +#endif + +/** DOC_DISABLE */ +#define XML_GLOBALS_PARSER_CORE \ + XML_OP(xmlDoValidityCheckingDefaultValue, int, XML_DEPRECATED) \ + XML_OP(xmlGetWarningsDefaultValue, int, XML_DEPRECATED) \ + XML_OP(xmlKeepBlanksDefaultValue, int, XML_DEPRECATED) \ + XML_OP(xmlLineNumbersDefaultValue, int, XML_DEPRECATED) \ + XML_OP(xmlLoadExtDtdDefaultValue, int, XML_DEPRECATED) \ + XML_OP(xmlPedanticParserDefaultValue, int, XML_DEPRECATED) \ + XML_OP(xmlSubstituteEntitiesDefaultValue, int, XML_DEPRECATED) + +#ifdef LIBXML_OUTPUT_ENABLED + #define XML_GLOBALS_PARSER_OUTPUT \ + XML_OP(xmlIndentTreeOutput, int, XML_NO_ATTR) \ + XML_OP(xmlTreeIndentString, const char *, XML_NO_ATTR) \ + XML_OP(xmlSaveNoEmptyTags, int, XML_NO_ATTR) +#else + #define XML_GLOBALS_PARSER_OUTPUT +#endif + +#define XML_GLOBALS_PARSER \ + XML_GLOBALS_PARSER_CORE \ + XML_GLOBALS_PARSER_OUTPUT + +#define XML_OP XML_DECLARE_GLOBAL +XML_GLOBALS_PARSER +#undef XML_OP + +#if defined(LIBXML_THREAD_ENABLED) && !defined(XML_GLOBALS_NO_REDEFINITION) + #define xmlDoValidityCheckingDefaultValue \ + XML_GLOBAL_MACRO(xmlDoValidityCheckingDefaultValue) + #define xmlGetWarningsDefaultValue \ + XML_GLOBAL_MACRO(xmlGetWarningsDefaultValue) + #define xmlKeepBlanksDefaultValue XML_GLOBAL_MACRO(xmlKeepBlanksDefaultValue) + #define xmlLineNumbersDefaultValue \ + XML_GLOBAL_MACRO(xmlLineNumbersDefaultValue) + #define xmlLoadExtDtdDefaultValue XML_GLOBAL_MACRO(xmlLoadExtDtdDefaultValue) + #define xmlPedanticParserDefaultValue \ + XML_GLOBAL_MACRO(xmlPedanticParserDefaultValue) + #define xmlSubstituteEntitiesDefaultValue \ + XML_GLOBAL_MACRO(xmlSubstituteEntitiesDefaultValue) + #ifdef LIBXML_OUTPUT_ENABLED + #define xmlIndentTreeOutput XML_GLOBAL_MACRO(xmlIndentTreeOutput) + #define xmlTreeIndentString XML_GLOBAL_MACRO(xmlTreeIndentString) + #define xmlSaveNoEmptyTags XML_GLOBAL_MACRO(xmlSaveNoEmptyTags) + #endif +#endif +/** DOC_ENABLE */ + +/* + * Init/Cleanup + */ +XMLPUBFUN void + xmlInitParser (void); +XMLPUBFUN void + xmlCleanupParser (void); +XML_DEPRECATED +XMLPUBFUN void + xmlInitGlobals (void); +XML_DEPRECATED +XMLPUBFUN void + xmlCleanupGlobals (void); + +/* + * Input functions + */ +XML_DEPRECATED +XMLPUBFUN int + xmlParserInputRead (xmlParserInputPtr in, + int len); +XML_DEPRECATED +XMLPUBFUN int + xmlParserInputGrow (xmlParserInputPtr in, + int len); + +/* + * Basic parsing Interfaces + */ +#ifdef LIBXML_SAX1_ENABLED +XMLPUBFUN xmlDocPtr + xmlParseDoc (const xmlChar *cur); +XMLPUBFUN xmlDocPtr + xmlParseFile (const char *filename); +XMLPUBFUN xmlDocPtr + xmlParseMemory (const char *buffer, + int size); +#endif /* LIBXML_SAX1_ENABLED */ +XML_DEPRECATED XMLPUBFUN int + xmlSubstituteEntitiesDefault(int val); +XML_DEPRECATED XMLPUBFUN int + xmlThrDefSubstituteEntitiesDefaultValue(int v); +XMLPUBFUN int + xmlKeepBlanksDefault (int val); +XML_DEPRECATED XMLPUBFUN int + xmlThrDefKeepBlanksDefaultValue(int v); +XMLPUBFUN void + xmlStopParser (xmlParserCtxtPtr ctxt); +XML_DEPRECATED XMLPUBFUN int + xmlPedanticParserDefault(int val); +XML_DEPRECATED XMLPUBFUN int + xmlThrDefPedanticParserDefaultValue(int v); +XML_DEPRECATED XMLPUBFUN int + xmlLineNumbersDefault (int val); +XML_DEPRECATED XMLPUBFUN int + xmlThrDefLineNumbersDefaultValue(int v); +XML_DEPRECATED XMLPUBFUN int + xmlThrDefDoValidityCheckingDefaultValue(int v); +XML_DEPRECATED XMLPUBFUN int + xmlThrDefGetWarningsDefaultValue(int v); +XML_DEPRECATED XMLPUBFUN int + xmlThrDefLoadExtDtdDefaultValue(int v); +XML_DEPRECATED XMLPUBFUN int + xmlThrDefParserDebugEntities(int v); + +#ifdef LIBXML_SAX1_ENABLED +/* + * Recovery mode + */ +XML_DEPRECATED +XMLPUBFUN xmlDocPtr + xmlRecoverDoc (const xmlChar *cur); +XML_DEPRECATED +XMLPUBFUN xmlDocPtr + xmlRecoverMemory (const char *buffer, + int size); +XML_DEPRECATED +XMLPUBFUN xmlDocPtr + xmlRecoverFile (const char *filename); +#endif /* LIBXML_SAX1_ENABLED */ + +/* + * Less common routines and SAX interfaces + */ +XMLPUBFUN int + xmlParseDocument (xmlParserCtxtPtr ctxt); +XMLPUBFUN int + xmlParseExtParsedEnt (xmlParserCtxtPtr ctxt); +#ifdef LIBXML_SAX1_ENABLED +XML_DEPRECATED +XMLPUBFUN int + xmlSAXUserParseFile (xmlSAXHandlerPtr sax, + void *user_data, + const char *filename); +XML_DEPRECATED +XMLPUBFUN int + xmlSAXUserParseMemory (xmlSAXHandlerPtr sax, + void *user_data, + const char *buffer, + int size); +XML_DEPRECATED +XMLPUBFUN xmlDocPtr + xmlSAXParseDoc (xmlSAXHandlerPtr sax, + const xmlChar *cur, + int recovery); +XML_DEPRECATED +XMLPUBFUN xmlDocPtr + xmlSAXParseMemory (xmlSAXHandlerPtr sax, + const char *buffer, + int size, + int recovery); +XML_DEPRECATED +XMLPUBFUN xmlDocPtr + xmlSAXParseMemoryWithData (xmlSAXHandlerPtr sax, + const char *buffer, + int size, + int recovery, + void *data); +XML_DEPRECATED +XMLPUBFUN xmlDocPtr + xmlSAXParseFile (xmlSAXHandlerPtr sax, + const char *filename, + int recovery); +XML_DEPRECATED +XMLPUBFUN xmlDocPtr + xmlSAXParseFileWithData (xmlSAXHandlerPtr sax, + const char *filename, + int recovery, + void *data); +XML_DEPRECATED +XMLPUBFUN xmlDocPtr + xmlSAXParseEntity (xmlSAXHandlerPtr sax, + const char *filename); +XML_DEPRECATED +XMLPUBFUN xmlDocPtr + xmlParseEntity (const char *filename); +#endif /* LIBXML_SAX1_ENABLED */ + +#ifdef LIBXML_VALID_ENABLED +XML_DEPRECATED +XMLPUBFUN xmlDtdPtr + xmlSAXParseDTD (xmlSAXHandlerPtr sax, + const xmlChar *ExternalID, + const xmlChar *SystemID); +XMLPUBFUN xmlDtdPtr + xmlParseDTD (const xmlChar *ExternalID, + const xmlChar *SystemID); +XMLPUBFUN xmlDtdPtr + xmlIOParseDTD (xmlSAXHandlerPtr sax, + xmlParserInputBufferPtr input, + xmlCharEncoding enc); +#endif /* LIBXML_VALID_ENABLE */ +#ifdef LIBXML_SAX1_ENABLED +XMLPUBFUN int + xmlParseBalancedChunkMemory(xmlDocPtr doc, + xmlSAXHandlerPtr sax, + void *user_data, + int depth, + const xmlChar *string, + xmlNodePtr *lst); +#endif /* LIBXML_SAX1_ENABLED */ +XMLPUBFUN xmlParserErrors + xmlParseInNodeContext (xmlNodePtr node, + const char *data, + int datalen, + int options, + xmlNodePtr *lst); +#ifdef LIBXML_SAX1_ENABLED +XMLPUBFUN int + xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, + xmlSAXHandlerPtr sax, + void *user_data, + int depth, + const xmlChar *string, + xmlNodePtr *lst, + int recover); +XML_DEPRECATED +XMLPUBFUN int + xmlParseExternalEntity (xmlDocPtr doc, + xmlSAXHandlerPtr sax, + void *user_data, + int depth, + const xmlChar *URL, + const xmlChar *ID, + xmlNodePtr *lst); +#endif /* LIBXML_SAX1_ENABLED */ +XMLPUBFUN int + xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, + const xmlChar *URL, + const xmlChar *ID, + xmlNodePtr *lst); + +/* + * Parser contexts handling. + */ +XMLPUBFUN xmlParserCtxtPtr + xmlNewParserCtxt (void); +XMLPUBFUN xmlParserCtxtPtr + xmlNewSAXParserCtxt (const xmlSAXHandler *sax, + void *userData); +XMLPUBFUN int + xmlInitParserCtxt (xmlParserCtxtPtr ctxt); +XMLPUBFUN void + xmlClearParserCtxt (xmlParserCtxtPtr ctxt); +XMLPUBFUN void + xmlFreeParserCtxt (xmlParserCtxtPtr ctxt); +#ifdef LIBXML_SAX1_ENABLED +XML_DEPRECATED +XMLPUBFUN void + xmlSetupParserForBuffer (xmlParserCtxtPtr ctxt, + const xmlChar* buffer, + const char *filename); +#endif /* LIBXML_SAX1_ENABLED */ +XMLPUBFUN xmlParserCtxtPtr + xmlCreateDocParserCtxt (const xmlChar *cur); + +#ifdef LIBXML_LEGACY_ENABLED +/* + * Reading/setting optional parsing features. + */ +XML_DEPRECATED +XMLPUBFUN int + xmlGetFeaturesList (int *len, + const char **result); +XML_DEPRECATED +XMLPUBFUN int + xmlGetFeature (xmlParserCtxtPtr ctxt, + const char *name, + void *result); +XML_DEPRECATED +XMLPUBFUN int + xmlSetFeature (xmlParserCtxtPtr ctxt, + const char *name, + void *value); +#endif /* LIBXML_LEGACY_ENABLED */ + +#ifdef LIBXML_PUSH_ENABLED +/* + * Interfaces for the Push mode. + */ +XMLPUBFUN xmlParserCtxtPtr + xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, + void *user_data, + const char *chunk, + int size, + const char *filename); +XMLPUBFUN int + xmlParseChunk (xmlParserCtxtPtr ctxt, + const char *chunk, + int size, + int terminate); +#endif /* LIBXML_PUSH_ENABLED */ + +/* + * Special I/O mode. + */ + +XMLPUBFUN xmlParserCtxtPtr + xmlCreateIOParserCtxt (xmlSAXHandlerPtr sax, + void *user_data, + xmlInputReadCallback ioread, + xmlInputCloseCallback ioclose, + void *ioctx, + xmlCharEncoding enc); + +XMLPUBFUN xmlParserInputPtr + xmlNewIOInputStream (xmlParserCtxtPtr ctxt, + xmlParserInputBufferPtr input, + xmlCharEncoding enc); + +/* + * Node infos. + */ +XMLPUBFUN const xmlParserNodeInfo* + xmlParserFindNodeInfo (xmlParserCtxtPtr ctxt, + xmlNodePtr node); +XMLPUBFUN void + xmlInitNodeInfoSeq (xmlParserNodeInfoSeqPtr seq); +XMLPUBFUN void + xmlClearNodeInfoSeq (xmlParserNodeInfoSeqPtr seq); +XMLPUBFUN unsigned long + xmlParserFindNodeInfoIndex(xmlParserNodeInfoSeqPtr seq, + xmlNodePtr node); +XMLPUBFUN void + xmlParserAddNodeInfo (xmlParserCtxtPtr ctxt, + xmlParserNodeInfoPtr info); + +/* + * External entities handling actually implemented in xmlIO. + */ + +XMLPUBFUN void + xmlSetExternalEntityLoader(xmlExternalEntityLoader f); +XMLPUBFUN xmlExternalEntityLoader + xmlGetExternalEntityLoader(void); +XMLPUBFUN xmlParserInputPtr + xmlLoadExternalEntity (const char *URL, + const char *ID, + xmlParserCtxtPtr ctxt); + +/* + * Index lookup, actually implemented in the encoding module + */ +XMLPUBFUN long + xmlByteConsumed (xmlParserCtxtPtr ctxt); + +/* + * New set of simpler/more flexible APIs + */ +/** + * xmlParserOption: + * + * This is the set of XML parser options that can be passed down + * to the xmlReadDoc() and similar calls. + */ +typedef enum { + XML_PARSE_RECOVER = 1<<0, /* recover on errors */ + XML_PARSE_NOENT = 1<<1, /* substitute entities */ + XML_PARSE_DTDLOAD = 1<<2, /* load the external subset */ + XML_PARSE_DTDATTR = 1<<3, /* default DTD attributes */ + XML_PARSE_DTDVALID = 1<<4, /* validate with the DTD */ + XML_PARSE_NOERROR = 1<<5, /* suppress error reports */ + XML_PARSE_NOWARNING = 1<<6, /* suppress warning reports */ + XML_PARSE_PEDANTIC = 1<<7, /* pedantic error reporting */ + XML_PARSE_NOBLANKS = 1<<8, /* remove blank nodes */ + XML_PARSE_SAX1 = 1<<9, /* use the SAX1 interface internally */ + XML_PARSE_XINCLUDE = 1<<10,/* Implement XInclude substitution */ + XML_PARSE_NONET = 1<<11,/* Forbid network access */ + XML_PARSE_NODICT = 1<<12,/* Do not reuse the context dictionary */ + XML_PARSE_NSCLEAN = 1<<13,/* remove redundant namespaces declarations */ + XML_PARSE_NOCDATA = 1<<14,/* merge CDATA as text nodes */ + XML_PARSE_NOXINCNODE= 1<<15,/* do not generate XINCLUDE START/END nodes */ + XML_PARSE_COMPACT = 1<<16,/* compact small text nodes; no modification of + the tree allowed afterwards (will possibly + crash if you try to modify the tree) */ + XML_PARSE_OLD10 = 1<<17,/* parse using XML-1.0 before update 5 */ + XML_PARSE_NOBASEFIX = 1<<18,/* do not fixup XINCLUDE xml:base uris */ + XML_PARSE_HUGE = 1<<19,/* relax any hardcoded limit from the parser */ + XML_PARSE_OLDSAX = 1<<20,/* parse using SAX2 interface before 2.7.0 */ + XML_PARSE_IGNORE_ENC= 1<<21,/* ignore internal document encoding hint */ + XML_PARSE_BIG_LINES = 1<<22,/* Store big lines numbers in text PSVI field */ + XML_PARSE_NO_XXE = 1<<23 /* disable loading of external content */ +} xmlParserOption; + +XMLPUBFUN void + xmlCtxtReset (xmlParserCtxtPtr ctxt); +XMLPUBFUN int + xmlCtxtResetPush (xmlParserCtxtPtr ctxt, + const char *chunk, + int size, + const char *filename, + const char *encoding); +XMLPUBFUN int + xmlCtxtSetOptions (xmlParserCtxtPtr ctxt, + int options); +XMLPUBFUN int + xmlCtxtUseOptions (xmlParserCtxtPtr ctxt, + int options); +XMLPUBFUN void + xmlCtxtSetErrorHandler (xmlParserCtxtPtr ctxt, + xmlStructuredErrorFunc handler, + void *data); +XMLPUBFUN void + xmlCtxtSetMaxAmplification(xmlParserCtxtPtr ctxt, + unsigned maxAmpl); +XMLPUBFUN xmlDocPtr + xmlReadDoc (const xmlChar *cur, + const char *URL, + const char *encoding, + int options); +XMLPUBFUN xmlDocPtr + xmlReadFile (const char *URL, + const char *encoding, + int options); +XMLPUBFUN xmlDocPtr + xmlReadMemory (const char *buffer, + int size, + const char *URL, + const char *encoding, + int options); +XMLPUBFUN xmlDocPtr + xmlReadFd (int fd, + const char *URL, + const char *encoding, + int options); +XMLPUBFUN xmlDocPtr + xmlReadIO (xmlInputReadCallback ioread, + xmlInputCloseCallback ioclose, + void *ioctx, + const char *URL, + const char *encoding, + int options); +XMLPUBFUN xmlDocPtr + xmlCtxtParseDocument (xmlParserCtxtPtr ctxt, + xmlParserInputPtr input); +XMLPUBFUN xmlDocPtr + xmlCtxtReadDoc (xmlParserCtxtPtr ctxt, + const xmlChar *cur, + const char *URL, + const char *encoding, + int options); +XMLPUBFUN xmlDocPtr + xmlCtxtReadFile (xmlParserCtxtPtr ctxt, + const char *filename, + const char *encoding, + int options); +XMLPUBFUN xmlDocPtr + xmlCtxtReadMemory (xmlParserCtxtPtr ctxt, + const char *buffer, + int size, + const char *URL, + const char *encoding, + int options); +XMLPUBFUN xmlDocPtr + xmlCtxtReadFd (xmlParserCtxtPtr ctxt, + int fd, + const char *URL, + const char *encoding, + int options); +XMLPUBFUN xmlDocPtr + xmlCtxtReadIO (xmlParserCtxtPtr ctxt, + xmlInputReadCallback ioread, + xmlInputCloseCallback ioclose, + void *ioctx, + const char *URL, + const char *encoding, + int options); + +/* + * Library wide options + */ +/** + * xmlFeature: + * + * Used to examine the existence of features that can be enabled + * or disabled at compile-time. + * They used to be called XML_FEATURE_xxx but this clashed with Expat + */ +typedef enum { + XML_WITH_THREAD = 1, + XML_WITH_TREE = 2, + XML_WITH_OUTPUT = 3, + XML_WITH_PUSH = 4, + XML_WITH_READER = 5, + XML_WITH_PATTERN = 6, + XML_WITH_WRITER = 7, + XML_WITH_SAX1 = 8, + XML_WITH_FTP = 9, + XML_WITH_HTTP = 10, + XML_WITH_VALID = 11, + XML_WITH_HTML = 12, + XML_WITH_LEGACY = 13, + XML_WITH_C14N = 14, + XML_WITH_CATALOG = 15, + XML_WITH_XPATH = 16, + XML_WITH_XPTR = 17, + XML_WITH_XINCLUDE = 18, + XML_WITH_ICONV = 19, + XML_WITH_ISO8859X = 20, + XML_WITH_UNICODE = 21, + XML_WITH_REGEXP = 22, + XML_WITH_AUTOMATA = 23, + XML_WITH_EXPR = 24, + XML_WITH_SCHEMAS = 25, + XML_WITH_SCHEMATRON = 26, + XML_WITH_MODULES = 27, + XML_WITH_DEBUG = 28, + XML_WITH_DEBUG_MEM = 29, + XML_WITH_DEBUG_RUN = 30, /* unused */ + XML_WITH_ZLIB = 31, + XML_WITH_ICU = 32, + XML_WITH_LZMA = 33, + XML_WITH_NONE = 99999 /* just to be sure of allocation size */ +} xmlFeature; + +XMLPUBFUN int + xmlHasFeature (xmlFeature feature); + +#ifdef __cplusplus +} +#endif +#endif /* __XML_PARSER_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/parserInternals.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/parserInternals.h new file mode 100644 index 0000000..c4d4363 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/parserInternals.h @@ -0,0 +1,671 @@ +/* + * Summary: internals routines and limits exported by the parser. + * Description: this module exports a number of internal parsing routines + * they are not really all intended for applications but + * can prove useful doing low level processing. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_PARSER_INTERNALS_H__ +#define __XML_PARSER_INTERNALS_H__ + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * xmlParserMaxDepth: + * + * DEPRECATED: has no effect + * + * arbitrary depth limit for the XML documents that we allow to + * process. This is not a limitation of the parser but a safety + * boundary feature, use XML_PARSE_HUGE option to override it. + */ +XML_DEPRECATED +XMLPUBVAR const unsigned int xmlParserMaxDepth; + +/** + * XML_MAX_TEXT_LENGTH: + * + * Maximum size allowed for a single text node when building a tree. + * This is not a limitation of the parser but a safety boundary feature, + * use XML_PARSE_HUGE option to override it. + * Introduced in 2.9.0 + */ +#define XML_MAX_TEXT_LENGTH 10000000 + +/** + * XML_MAX_HUGE_LENGTH: + * + * Maximum size allowed when XML_PARSE_HUGE is set. + */ +#define XML_MAX_HUGE_LENGTH 1000000000 + +/** + * XML_MAX_NAME_LENGTH: + * + * Maximum size allowed for a markup identifier. + * This is not a limitation of the parser but a safety boundary feature, + * use XML_PARSE_HUGE option to override it. + * Note that with the use of parsing dictionaries overriding the limit + * may result in more runtime memory usage in face of "unfriendly' content + * Introduced in 2.9.0 + */ +#define XML_MAX_NAME_LENGTH 50000 + +/** + * XML_MAX_DICTIONARY_LIMIT: + * + * Maximum size allowed by the parser for a dictionary by default + * This is not a limitation of the parser but a safety boundary feature, + * use XML_PARSE_HUGE option to override it. + * Introduced in 2.9.0 + */ +#define XML_MAX_DICTIONARY_LIMIT 10000000 + +/** + * XML_MAX_LOOKUP_LIMIT: + * + * Maximum size allowed by the parser for ahead lookup + * This is an upper boundary enforced by the parser to avoid bad + * behaviour on "unfriendly' content + * Introduced in 2.9.0 + */ +#define XML_MAX_LOOKUP_LIMIT 10000000 + +/** + * XML_MAX_NAMELEN: + * + * Identifiers can be longer, but this will be more costly + * at runtime. + */ +#define XML_MAX_NAMELEN 100 + +/** + * INPUT_CHUNK: + * + * The parser tries to always have that amount of input ready. + * One of the point is providing context when reporting errors. + */ +#define INPUT_CHUNK 250 + +/************************************************************************ + * * + * UNICODE version of the macros. * + * * + ************************************************************************/ +/** + * IS_BYTE_CHAR: + * @c: an byte value (int) + * + * Macro to check the following production in the XML spec: + * + * [2] Char ::= #x9 | #xA | #xD | [#x20...] + * any byte character in the accepted range + */ +#define IS_BYTE_CHAR(c) xmlIsChar_ch(c) + +/** + * IS_CHAR: + * @c: an UNICODE value (int) + * + * Macro to check the following production in the XML spec: + * + * [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] + * | [#x10000-#x10FFFF] + * any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. + */ +#define IS_CHAR(c) xmlIsCharQ(c) + +/** + * IS_CHAR_CH: + * @c: an xmlChar (usually an unsigned char) + * + * Behaves like IS_CHAR on single-byte value + */ +#define IS_CHAR_CH(c) xmlIsChar_ch(c) + +/** + * IS_BLANK: + * @c: an UNICODE value (int) + * + * Macro to check the following production in the XML spec: + * + * [3] S ::= (#x20 | #x9 | #xD | #xA)+ + */ +#define IS_BLANK(c) xmlIsBlankQ(c) + +/** + * IS_BLANK_CH: + * @c: an xmlChar value (normally unsigned char) + * + * Behaviour same as IS_BLANK + */ +#define IS_BLANK_CH(c) xmlIsBlank_ch(c) + +/** + * IS_BASECHAR: + * @c: an UNICODE value (int) + * + * Macro to check the following production in the XML spec: + * + * [85] BaseChar ::= ... long list see REC ... + */ +#define IS_BASECHAR(c) xmlIsBaseCharQ(c) + +/** + * IS_DIGIT: + * @c: an UNICODE value (int) + * + * Macro to check the following production in the XML spec: + * + * [88] Digit ::= ... long list see REC ... + */ +#define IS_DIGIT(c) xmlIsDigitQ(c) + +/** + * IS_DIGIT_CH: + * @c: an xmlChar value (usually an unsigned char) + * + * Behaves like IS_DIGIT but with a single byte argument + */ +#define IS_DIGIT_CH(c) xmlIsDigit_ch(c) + +/** + * IS_COMBINING: + * @c: an UNICODE value (int) + * + * Macro to check the following production in the XML spec: + * + * [87] CombiningChar ::= ... long list see REC ... + */ +#define IS_COMBINING(c) xmlIsCombiningQ(c) + +/** + * IS_COMBINING_CH: + * @c: an xmlChar (usually an unsigned char) + * + * Always false (all combining chars > 0xff) + */ +#define IS_COMBINING_CH(c) 0 + +/** + * IS_EXTENDER: + * @c: an UNICODE value (int) + * + * Macro to check the following production in the XML spec: + * + * + * [89] Extender ::= #x00B7 | #x02D0 | #x02D1 | #x0387 | #x0640 | + * #x0E46 | #x0EC6 | #x3005 | [#x3031-#x3035] | + * [#x309D-#x309E] | [#x30FC-#x30FE] + */ +#define IS_EXTENDER(c) xmlIsExtenderQ(c) + +/** + * IS_EXTENDER_CH: + * @c: an xmlChar value (usually an unsigned char) + * + * Behaves like IS_EXTENDER but with a single-byte argument + */ +#define IS_EXTENDER_CH(c) xmlIsExtender_ch(c) + +/** + * IS_IDEOGRAPHIC: + * @c: an UNICODE value (int) + * + * Macro to check the following production in the XML spec: + * + * + * [86] Ideographic ::= [#x4E00-#x9FA5] | #x3007 | [#x3021-#x3029] + */ +#define IS_IDEOGRAPHIC(c) xmlIsIdeographicQ(c) + +/** + * IS_LETTER: + * @c: an UNICODE value (int) + * + * Macro to check the following production in the XML spec: + * + * + * [84] Letter ::= BaseChar | Ideographic + */ +#define IS_LETTER(c) (IS_BASECHAR(c) || IS_IDEOGRAPHIC(c)) + +/** + * IS_LETTER_CH: + * @c: an xmlChar value (normally unsigned char) + * + * Macro behaves like IS_LETTER, but only check base chars + * + */ +#define IS_LETTER_CH(c) xmlIsBaseChar_ch(c) + +/** + * IS_ASCII_LETTER: + * @c: an xmlChar value + * + * Macro to check [a-zA-Z] + * + */ +#define IS_ASCII_LETTER(c) (((0x41 <= (c)) && ((c) <= 0x5a)) || \ + ((0x61 <= (c)) && ((c) <= 0x7a))) + +/** + * IS_ASCII_DIGIT: + * @c: an xmlChar value + * + * Macro to check [0-9] + * + */ +#define IS_ASCII_DIGIT(c) ((0x30 <= (c)) && ((c) <= 0x39)) + +/** + * IS_PUBIDCHAR: + * @c: an UNICODE value (int) + * + * Macro to check the following production in the XML spec: + * + * + * [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%] + */ +#define IS_PUBIDCHAR(c) xmlIsPubidCharQ(c) + +/** + * IS_PUBIDCHAR_CH: + * @c: an xmlChar value (normally unsigned char) + * + * Same as IS_PUBIDCHAR but for single-byte value + */ +#define IS_PUBIDCHAR_CH(c) xmlIsPubidChar_ch(c) + +/** + * Global variables used for predefined strings. + */ +XMLPUBVAR const xmlChar xmlStringText[]; +XMLPUBVAR const xmlChar xmlStringTextNoenc[]; +XMLPUBVAR const xmlChar xmlStringComment[]; + +/* + * Function to finish the work of the macros where needed. + */ +XMLPUBFUN int xmlIsLetter (int c); + +/** + * Parser context. + */ +XMLPUBFUN xmlParserCtxtPtr + xmlCreateFileParserCtxt (const char *filename); +XMLPUBFUN xmlParserCtxtPtr + xmlCreateURLParserCtxt (const char *filename, + int options); +XMLPUBFUN xmlParserCtxtPtr + xmlCreateMemoryParserCtxt(const char *buffer, + int size); +XMLPUBFUN xmlParserCtxtPtr + xmlCreateEntityParserCtxt(const xmlChar *URL, + const xmlChar *ID, + const xmlChar *base); +XMLPUBFUN void + xmlCtxtErrMemory (xmlParserCtxtPtr ctxt); +XMLPUBFUN int + xmlSwitchEncoding (xmlParserCtxtPtr ctxt, + xmlCharEncoding enc); +XMLPUBFUN int + xmlSwitchEncodingName (xmlParserCtxtPtr ctxt, + const char *encoding); +XMLPUBFUN int + xmlSwitchToEncoding (xmlParserCtxtPtr ctxt, + xmlCharEncodingHandlerPtr handler); +XML_DEPRECATED +XMLPUBFUN int + xmlSwitchInputEncoding (xmlParserCtxtPtr ctxt, + xmlParserInputPtr input, + xmlCharEncodingHandlerPtr handler); + +/** + * Input Streams. + */ +XMLPUBFUN xmlParserInputPtr + xmlNewStringInputStream (xmlParserCtxtPtr ctxt, + const xmlChar *buffer); +XML_DEPRECATED +XMLPUBFUN xmlParserInputPtr + xmlNewEntityInputStream (xmlParserCtxtPtr ctxt, + xmlEntityPtr entity); +XMLPUBFUN int + xmlPushInput (xmlParserCtxtPtr ctxt, + xmlParserInputPtr input); +XMLPUBFUN xmlChar + xmlPopInput (xmlParserCtxtPtr ctxt); +XMLPUBFUN void + xmlFreeInputStream (xmlParserInputPtr input); +XMLPUBFUN xmlParserInputPtr + xmlNewInputFromFile (xmlParserCtxtPtr ctxt, + const char *filename); +XMLPUBFUN xmlParserInputPtr + xmlNewInputStream (xmlParserCtxtPtr ctxt); + +/** + * Namespaces. + */ +XMLPUBFUN xmlChar * + xmlSplitQName (xmlParserCtxtPtr ctxt, + const xmlChar *name, + xmlChar **prefix); + +/** + * Generic production rules. + */ +XML_DEPRECATED +XMLPUBFUN const xmlChar * + xmlParseName (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN xmlChar * + xmlParseNmtoken (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN xmlChar * + xmlParseEntityValue (xmlParserCtxtPtr ctxt, + xmlChar **orig); +XML_DEPRECATED +XMLPUBFUN xmlChar * + xmlParseAttValue (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN xmlChar * + xmlParseSystemLiteral (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN xmlChar * + xmlParsePubidLiteral (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN void + xmlParseCharData (xmlParserCtxtPtr ctxt, + int cdata); +XML_DEPRECATED +XMLPUBFUN xmlChar * + xmlParseExternalID (xmlParserCtxtPtr ctxt, + xmlChar **publicID, + int strict); +XML_DEPRECATED +XMLPUBFUN void + xmlParseComment (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN const xmlChar * + xmlParsePITarget (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN void + xmlParsePI (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN void + xmlParseNotationDecl (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN void + xmlParseEntityDecl (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN int + xmlParseDefaultDecl (xmlParserCtxtPtr ctxt, + xmlChar **value); +XML_DEPRECATED +XMLPUBFUN xmlEnumerationPtr + xmlParseNotationType (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN xmlEnumerationPtr + xmlParseEnumerationType (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN int + xmlParseEnumeratedType (xmlParserCtxtPtr ctxt, + xmlEnumerationPtr *tree); +XML_DEPRECATED +XMLPUBFUN int + xmlParseAttributeType (xmlParserCtxtPtr ctxt, + xmlEnumerationPtr *tree); +XML_DEPRECATED +XMLPUBFUN void + xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN xmlElementContentPtr + xmlParseElementMixedContentDecl + (xmlParserCtxtPtr ctxt, + int inputchk); +XML_DEPRECATED +XMLPUBFUN xmlElementContentPtr + xmlParseElementChildrenContentDecl + (xmlParserCtxtPtr ctxt, + int inputchk); +XML_DEPRECATED +XMLPUBFUN int + xmlParseElementContentDecl(xmlParserCtxtPtr ctxt, + const xmlChar *name, + xmlElementContentPtr *result); +XML_DEPRECATED +XMLPUBFUN int + xmlParseElementDecl (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN void + xmlParseMarkupDecl (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN int + xmlParseCharRef (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN xmlEntityPtr + xmlParseEntityRef (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN void + xmlParseReference (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN void + xmlParsePEReference (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN void + xmlParseDocTypeDecl (xmlParserCtxtPtr ctxt); +#ifdef LIBXML_SAX1_ENABLED +XML_DEPRECATED +XMLPUBFUN const xmlChar * + xmlParseAttribute (xmlParserCtxtPtr ctxt, + xmlChar **value); +XML_DEPRECATED +XMLPUBFUN const xmlChar * + xmlParseStartTag (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN void + xmlParseEndTag (xmlParserCtxtPtr ctxt); +#endif /* LIBXML_SAX1_ENABLED */ +XML_DEPRECATED +XMLPUBFUN void + xmlParseCDSect (xmlParserCtxtPtr ctxt); +XMLPUBFUN void + xmlParseContent (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN void + xmlParseElement (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN xmlChar * + xmlParseVersionNum (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN xmlChar * + xmlParseVersionInfo (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN xmlChar * + xmlParseEncName (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN const xmlChar * + xmlParseEncodingDecl (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN int + xmlParseSDDecl (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN void + xmlParseXMLDecl (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN void + xmlParseTextDecl (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN void + xmlParseMisc (xmlParserCtxtPtr ctxt); +XMLPUBFUN void + xmlParseExternalSubset (xmlParserCtxtPtr ctxt, + const xmlChar *ExternalID, + const xmlChar *SystemID); +/** + * XML_SUBSTITUTE_NONE: + * + * If no entities need to be substituted. + */ +#define XML_SUBSTITUTE_NONE 0 +/** + * XML_SUBSTITUTE_REF: + * + * Whether general entities need to be substituted. + */ +#define XML_SUBSTITUTE_REF 1 +/** + * XML_SUBSTITUTE_PEREF: + * + * Whether parameter entities need to be substituted. + */ +#define XML_SUBSTITUTE_PEREF 2 +/** + * XML_SUBSTITUTE_BOTH: + * + * Both general and parameter entities need to be substituted. + */ +#define XML_SUBSTITUTE_BOTH 3 + +XML_DEPRECATED +XMLPUBFUN xmlChar * + xmlStringDecodeEntities (xmlParserCtxtPtr ctxt, + const xmlChar *str, + int what, + xmlChar end, + xmlChar end2, + xmlChar end3); +XML_DEPRECATED +XMLPUBFUN xmlChar * + xmlStringLenDecodeEntities (xmlParserCtxtPtr ctxt, + const xmlChar *str, + int len, + int what, + xmlChar end, + xmlChar end2, + xmlChar end3); + +/* + * Generated by MACROS on top of parser.c c.f. PUSH_AND_POP. + */ +XML_DEPRECATED +XMLPUBFUN int nodePush (xmlParserCtxtPtr ctxt, + xmlNodePtr value); +XML_DEPRECATED +XMLPUBFUN xmlNodePtr nodePop (xmlParserCtxtPtr ctxt); +XMLPUBFUN int inputPush (xmlParserCtxtPtr ctxt, + xmlParserInputPtr value); +XMLPUBFUN xmlParserInputPtr inputPop (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN const xmlChar * namePop (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN int namePush (xmlParserCtxtPtr ctxt, + const xmlChar *value); + +/* + * other commodities shared between parser.c and parserInternals. + */ +XML_DEPRECATED +XMLPUBFUN int xmlSkipBlankChars (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN int xmlStringCurrentChar (xmlParserCtxtPtr ctxt, + const xmlChar *cur, + int *len); +XML_DEPRECATED +XMLPUBFUN void xmlParserHandlePEReference(xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN int xmlCheckLanguageID (const xmlChar *lang); + +/* + * Really core function shared with HTML parser. + */ +XML_DEPRECATED +XMLPUBFUN int xmlCurrentChar (xmlParserCtxtPtr ctxt, + int *len); +XMLPUBFUN int xmlCopyCharMultiByte (xmlChar *out, + int val); +XMLPUBFUN int xmlCopyChar (int len, + xmlChar *out, + int val); +XML_DEPRECATED +XMLPUBFUN void xmlNextChar (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN void xmlParserInputShrink (xmlParserInputPtr in); + +/* + * Specific function to keep track of entities references + * and used by the XSLT debugger. + */ +#ifdef LIBXML_LEGACY_ENABLED +/** + * xmlEntityReferenceFunc: + * @ent: the entity + * @firstNode: the fist node in the chunk + * @lastNode: the last nod in the chunk + * + * Callback function used when one needs to be able to track back the + * provenance of a chunk of nodes inherited from an entity replacement. + */ +typedef void (*xmlEntityReferenceFunc) (xmlEntityPtr ent, + xmlNodePtr firstNode, + xmlNodePtr lastNode); + +XML_DEPRECATED +XMLPUBFUN void xmlSetEntityReferenceFunc (xmlEntityReferenceFunc func); + +XML_DEPRECATED +XMLPUBFUN xmlChar * + xmlParseQuotedString (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN void + xmlParseNamespace (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN xmlChar * + xmlNamespaceParseNSDef (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN xmlChar * + xmlScanName (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN xmlChar * + xmlNamespaceParseNCName (xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN void xmlParserHandleReference(xmlParserCtxtPtr ctxt); +XML_DEPRECATED +XMLPUBFUN xmlChar * + xmlNamespaceParseQName (xmlParserCtxtPtr ctxt, + xmlChar **prefix); +/** + * Entities + */ +XML_DEPRECATED +XMLPUBFUN xmlChar * + xmlDecodeEntities (xmlParserCtxtPtr ctxt, + int len, + int what, + xmlChar end, + xmlChar end2, + xmlChar end3); +XML_DEPRECATED +XMLPUBFUN void + xmlHandleEntity (xmlParserCtxtPtr ctxt, + xmlEntityPtr entity); + +#endif /* LIBXML_LEGACY_ENABLED */ + +#ifdef __cplusplus +} +#endif +#endif /* __XML_PARSER_INTERNALS_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/pattern.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/pattern.h new file mode 100644 index 0000000..947f090 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/pattern.h @@ -0,0 +1,106 @@ +/* + * Summary: pattern expression handling + * Description: allows to compile and test pattern expressions for nodes + * either in a tree or based on a parser state. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_PATTERN_H__ +#define __XML_PATTERN_H__ + +#include +#include +#include + +#ifdef LIBXML_PATTERN_ENABLED + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * xmlPattern: + * + * A compiled (XPath based) pattern to select nodes + */ +typedef struct _xmlPattern xmlPattern; +typedef xmlPattern *xmlPatternPtr; + +/** + * xmlPatternFlags: + * + * This is the set of options affecting the behaviour of pattern + * matching with this module + * + */ +typedef enum { + XML_PATTERN_DEFAULT = 0, /* simple pattern match */ + XML_PATTERN_XPATH = 1<<0, /* standard XPath pattern */ + XML_PATTERN_XSSEL = 1<<1, /* XPath subset for schema selector */ + XML_PATTERN_XSFIELD = 1<<2 /* XPath subset for schema field */ +} xmlPatternFlags; + +XMLPUBFUN void + xmlFreePattern (xmlPatternPtr comp); + +XMLPUBFUN void + xmlFreePatternList (xmlPatternPtr comp); + +XMLPUBFUN xmlPatternPtr + xmlPatterncompile (const xmlChar *pattern, + xmlDict *dict, + int flags, + const xmlChar **namespaces); +XMLPUBFUN int + xmlPatternCompileSafe (const xmlChar *pattern, + xmlDict *dict, + int flags, + const xmlChar **namespaces, + xmlPatternPtr *patternOut); +XMLPUBFUN int + xmlPatternMatch (xmlPatternPtr comp, + xmlNodePtr node); + +/* streaming interfaces */ +typedef struct _xmlStreamCtxt xmlStreamCtxt; +typedef xmlStreamCtxt *xmlStreamCtxtPtr; + +XMLPUBFUN int + xmlPatternStreamable (xmlPatternPtr comp); +XMLPUBFUN int + xmlPatternMaxDepth (xmlPatternPtr comp); +XMLPUBFUN int + xmlPatternMinDepth (xmlPatternPtr comp); +XMLPUBFUN int + xmlPatternFromRoot (xmlPatternPtr comp); +XMLPUBFUN xmlStreamCtxtPtr + xmlPatternGetStreamCtxt (xmlPatternPtr comp); +XMLPUBFUN void + xmlFreeStreamCtxt (xmlStreamCtxtPtr stream); +XMLPUBFUN int + xmlStreamPushNode (xmlStreamCtxtPtr stream, + const xmlChar *name, + const xmlChar *ns, + int nodeType); +XMLPUBFUN int + xmlStreamPush (xmlStreamCtxtPtr stream, + const xmlChar *name, + const xmlChar *ns); +XMLPUBFUN int + xmlStreamPushAttr (xmlStreamCtxtPtr stream, + const xmlChar *name, + const xmlChar *ns); +XMLPUBFUN int + xmlStreamPop (xmlStreamCtxtPtr stream); +XMLPUBFUN int + xmlStreamWantsAnyNode (xmlStreamCtxtPtr stream); +#ifdef __cplusplus +} +#endif + +#endif /* LIBXML_PATTERN_ENABLED */ + +#endif /* __XML_PATTERN_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/relaxng.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/relaxng.h new file mode 100644 index 0000000..079b7f1 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/relaxng.h @@ -0,0 +1,219 @@ +/* + * Summary: implementation of the Relax-NG validation + * Description: implementation of the Relax-NG validation + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_RELAX_NG__ +#define __XML_RELAX_NG__ + +#include +#include +#include +#include + +#ifdef LIBXML_SCHEMAS_ENABLED + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _xmlRelaxNG xmlRelaxNG; +typedef xmlRelaxNG *xmlRelaxNGPtr; + + +/** + * xmlRelaxNGValidityErrorFunc: + * @ctx: the validation context + * @msg: the message + * @...: extra arguments + * + * Signature of an error callback from a Relax-NG validation + */ +typedef void (*xmlRelaxNGValidityErrorFunc) (void *ctx, + const char *msg, + ...) LIBXML_ATTR_FORMAT(2,3); + +/** + * xmlRelaxNGValidityWarningFunc: + * @ctx: the validation context + * @msg: the message + * @...: extra arguments + * + * Signature of a warning callback from a Relax-NG validation + */ +typedef void (*xmlRelaxNGValidityWarningFunc) (void *ctx, + const char *msg, + ...) LIBXML_ATTR_FORMAT(2,3); + +/** + * A schemas validation context + */ +typedef struct _xmlRelaxNGParserCtxt xmlRelaxNGParserCtxt; +typedef xmlRelaxNGParserCtxt *xmlRelaxNGParserCtxtPtr; + +typedef struct _xmlRelaxNGValidCtxt xmlRelaxNGValidCtxt; +typedef xmlRelaxNGValidCtxt *xmlRelaxNGValidCtxtPtr; + +/* + * xmlRelaxNGValidErr: + * + * List of possible Relax NG validation errors + */ +typedef enum { + XML_RELAXNG_OK = 0, + XML_RELAXNG_ERR_MEMORY, + XML_RELAXNG_ERR_TYPE, + XML_RELAXNG_ERR_TYPEVAL, + XML_RELAXNG_ERR_DUPID, + XML_RELAXNG_ERR_TYPECMP, + XML_RELAXNG_ERR_NOSTATE, + XML_RELAXNG_ERR_NODEFINE, + XML_RELAXNG_ERR_LISTEXTRA, + XML_RELAXNG_ERR_LISTEMPTY, + XML_RELAXNG_ERR_INTERNODATA, + XML_RELAXNG_ERR_INTERSEQ, + XML_RELAXNG_ERR_INTEREXTRA, + XML_RELAXNG_ERR_ELEMNAME, + XML_RELAXNG_ERR_ATTRNAME, + XML_RELAXNG_ERR_ELEMNONS, + XML_RELAXNG_ERR_ATTRNONS, + XML_RELAXNG_ERR_ELEMWRONGNS, + XML_RELAXNG_ERR_ATTRWRONGNS, + XML_RELAXNG_ERR_ELEMEXTRANS, + XML_RELAXNG_ERR_ATTREXTRANS, + XML_RELAXNG_ERR_ELEMNOTEMPTY, + XML_RELAXNG_ERR_NOELEM, + XML_RELAXNG_ERR_NOTELEM, + XML_RELAXNG_ERR_ATTRVALID, + XML_RELAXNG_ERR_CONTENTVALID, + XML_RELAXNG_ERR_EXTRACONTENT, + XML_RELAXNG_ERR_INVALIDATTR, + XML_RELAXNG_ERR_DATAELEM, + XML_RELAXNG_ERR_VALELEM, + XML_RELAXNG_ERR_LISTELEM, + XML_RELAXNG_ERR_DATATYPE, + XML_RELAXNG_ERR_VALUE, + XML_RELAXNG_ERR_LIST, + XML_RELAXNG_ERR_NOGRAMMAR, + XML_RELAXNG_ERR_EXTRADATA, + XML_RELAXNG_ERR_LACKDATA, + XML_RELAXNG_ERR_INTERNAL, + XML_RELAXNG_ERR_ELEMWRONG, + XML_RELAXNG_ERR_TEXTWRONG +} xmlRelaxNGValidErr; + +/* + * xmlRelaxNGParserFlags: + * + * List of possible Relax NG Parser flags + */ +typedef enum { + XML_RELAXNGP_NONE = 0, + XML_RELAXNGP_FREE_DOC = 1, + XML_RELAXNGP_CRNG = 2 +} xmlRelaxNGParserFlag; + +XMLPUBFUN int + xmlRelaxNGInitTypes (void); +XML_DEPRECATED +XMLPUBFUN void + xmlRelaxNGCleanupTypes (void); + +/* + * Interfaces for parsing. + */ +XMLPUBFUN xmlRelaxNGParserCtxtPtr + xmlRelaxNGNewParserCtxt (const char *URL); +XMLPUBFUN xmlRelaxNGParserCtxtPtr + xmlRelaxNGNewMemParserCtxt (const char *buffer, + int size); +XMLPUBFUN xmlRelaxNGParserCtxtPtr + xmlRelaxNGNewDocParserCtxt (xmlDocPtr doc); + +XMLPUBFUN int + xmlRelaxParserSetFlag (xmlRelaxNGParserCtxtPtr ctxt, + int flag); + +XMLPUBFUN void + xmlRelaxNGFreeParserCtxt (xmlRelaxNGParserCtxtPtr ctxt); +XMLPUBFUN void + xmlRelaxNGSetParserErrors(xmlRelaxNGParserCtxtPtr ctxt, + xmlRelaxNGValidityErrorFunc err, + xmlRelaxNGValidityWarningFunc warn, + void *ctx); +XMLPUBFUN int + xmlRelaxNGGetParserErrors(xmlRelaxNGParserCtxtPtr ctxt, + xmlRelaxNGValidityErrorFunc *err, + xmlRelaxNGValidityWarningFunc *warn, + void **ctx); +XMLPUBFUN void + xmlRelaxNGSetParserStructuredErrors( + xmlRelaxNGParserCtxtPtr ctxt, + xmlStructuredErrorFunc serror, + void *ctx); +XMLPUBFUN xmlRelaxNGPtr + xmlRelaxNGParse (xmlRelaxNGParserCtxtPtr ctxt); +XMLPUBFUN void + xmlRelaxNGFree (xmlRelaxNGPtr schema); +#ifdef LIBXML_OUTPUT_ENABLED +XMLPUBFUN void + xmlRelaxNGDump (FILE *output, + xmlRelaxNGPtr schema); +XMLPUBFUN void + xmlRelaxNGDumpTree (FILE * output, + xmlRelaxNGPtr schema); +#endif /* LIBXML_OUTPUT_ENABLED */ +/* + * Interfaces for validating + */ +XMLPUBFUN void + xmlRelaxNGSetValidErrors(xmlRelaxNGValidCtxtPtr ctxt, + xmlRelaxNGValidityErrorFunc err, + xmlRelaxNGValidityWarningFunc warn, + void *ctx); +XMLPUBFUN int + xmlRelaxNGGetValidErrors(xmlRelaxNGValidCtxtPtr ctxt, + xmlRelaxNGValidityErrorFunc *err, + xmlRelaxNGValidityWarningFunc *warn, + void **ctx); +XMLPUBFUN void + xmlRelaxNGSetValidStructuredErrors(xmlRelaxNGValidCtxtPtr ctxt, + xmlStructuredErrorFunc serror, void *ctx); +XMLPUBFUN xmlRelaxNGValidCtxtPtr + xmlRelaxNGNewValidCtxt (xmlRelaxNGPtr schema); +XMLPUBFUN void + xmlRelaxNGFreeValidCtxt (xmlRelaxNGValidCtxtPtr ctxt); +XMLPUBFUN int + xmlRelaxNGValidateDoc (xmlRelaxNGValidCtxtPtr ctxt, + xmlDocPtr doc); +/* + * Interfaces for progressive validation when possible + */ +XMLPUBFUN int + xmlRelaxNGValidatePushElement (xmlRelaxNGValidCtxtPtr ctxt, + xmlDocPtr doc, + xmlNodePtr elem); +XMLPUBFUN int + xmlRelaxNGValidatePushCData (xmlRelaxNGValidCtxtPtr ctxt, + const xmlChar *data, + int len); +XMLPUBFUN int + xmlRelaxNGValidatePopElement (xmlRelaxNGValidCtxtPtr ctxt, + xmlDocPtr doc, + xmlNodePtr elem); +XMLPUBFUN int + xmlRelaxNGValidateFullElement (xmlRelaxNGValidCtxtPtr ctxt, + xmlDocPtr doc, + xmlNodePtr elem); + +#ifdef __cplusplus +} +#endif + +#endif /* LIBXML_SCHEMAS_ENABLED */ + +#endif /* __XML_RELAX_NG__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/schemasInternals.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/schemasInternals.h new file mode 100644 index 0000000..e9d3b3c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/schemasInternals.h @@ -0,0 +1,959 @@ +/* + * Summary: internal interfaces for XML Schemas + * Description: internal interfaces for the XML Schemas handling + * and schema validity checking + * The Schemas development is a Work In Progress. + * Some of those interfaces are not guaranteed to be API or ABI stable ! + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + + +#ifndef __XML_SCHEMA_INTERNALS_H__ +#define __XML_SCHEMA_INTERNALS_H__ + +#include + +#ifdef LIBXML_SCHEMAS_ENABLED + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + XML_SCHEMAS_UNKNOWN = 0, + XML_SCHEMAS_STRING = 1, + XML_SCHEMAS_NORMSTRING = 2, + XML_SCHEMAS_DECIMAL = 3, + XML_SCHEMAS_TIME = 4, + XML_SCHEMAS_GDAY = 5, + XML_SCHEMAS_GMONTH = 6, + XML_SCHEMAS_GMONTHDAY = 7, + XML_SCHEMAS_GYEAR = 8, + XML_SCHEMAS_GYEARMONTH = 9, + XML_SCHEMAS_DATE = 10, + XML_SCHEMAS_DATETIME = 11, + XML_SCHEMAS_DURATION = 12, + XML_SCHEMAS_FLOAT = 13, + XML_SCHEMAS_DOUBLE = 14, + XML_SCHEMAS_BOOLEAN = 15, + XML_SCHEMAS_TOKEN = 16, + XML_SCHEMAS_LANGUAGE = 17, + XML_SCHEMAS_NMTOKEN = 18, + XML_SCHEMAS_NMTOKENS = 19, + XML_SCHEMAS_NAME = 20, + XML_SCHEMAS_QNAME = 21, + XML_SCHEMAS_NCNAME = 22, + XML_SCHEMAS_ID = 23, + XML_SCHEMAS_IDREF = 24, + XML_SCHEMAS_IDREFS = 25, + XML_SCHEMAS_ENTITY = 26, + XML_SCHEMAS_ENTITIES = 27, + XML_SCHEMAS_NOTATION = 28, + XML_SCHEMAS_ANYURI = 29, + XML_SCHEMAS_INTEGER = 30, + XML_SCHEMAS_NPINTEGER = 31, + XML_SCHEMAS_NINTEGER = 32, + XML_SCHEMAS_NNINTEGER = 33, + XML_SCHEMAS_PINTEGER = 34, + XML_SCHEMAS_INT = 35, + XML_SCHEMAS_UINT = 36, + XML_SCHEMAS_LONG = 37, + XML_SCHEMAS_ULONG = 38, + XML_SCHEMAS_SHORT = 39, + XML_SCHEMAS_USHORT = 40, + XML_SCHEMAS_BYTE = 41, + XML_SCHEMAS_UBYTE = 42, + XML_SCHEMAS_HEXBINARY = 43, + XML_SCHEMAS_BASE64BINARY = 44, + XML_SCHEMAS_ANYTYPE = 45, + XML_SCHEMAS_ANYSIMPLETYPE = 46 +} xmlSchemaValType; + +/* + * XML Schemas defines multiple type of types. + */ +typedef enum { + XML_SCHEMA_TYPE_BASIC = 1, /* A built-in datatype */ + XML_SCHEMA_TYPE_ANY, + XML_SCHEMA_TYPE_FACET, + XML_SCHEMA_TYPE_SIMPLE, + XML_SCHEMA_TYPE_COMPLEX, + XML_SCHEMA_TYPE_SEQUENCE = 6, + XML_SCHEMA_TYPE_CHOICE, + XML_SCHEMA_TYPE_ALL, + XML_SCHEMA_TYPE_SIMPLE_CONTENT, + XML_SCHEMA_TYPE_COMPLEX_CONTENT, + XML_SCHEMA_TYPE_UR, + XML_SCHEMA_TYPE_RESTRICTION, + XML_SCHEMA_TYPE_EXTENSION, + XML_SCHEMA_TYPE_ELEMENT, + XML_SCHEMA_TYPE_ATTRIBUTE, + XML_SCHEMA_TYPE_ATTRIBUTEGROUP, + XML_SCHEMA_TYPE_GROUP, + XML_SCHEMA_TYPE_NOTATION, + XML_SCHEMA_TYPE_LIST, + XML_SCHEMA_TYPE_UNION, + XML_SCHEMA_TYPE_ANY_ATTRIBUTE, + XML_SCHEMA_TYPE_IDC_UNIQUE, + XML_SCHEMA_TYPE_IDC_KEY, + XML_SCHEMA_TYPE_IDC_KEYREF, + XML_SCHEMA_TYPE_PARTICLE = 25, + XML_SCHEMA_TYPE_ATTRIBUTE_USE, + XML_SCHEMA_FACET_MININCLUSIVE = 1000, + XML_SCHEMA_FACET_MINEXCLUSIVE, + XML_SCHEMA_FACET_MAXINCLUSIVE, + XML_SCHEMA_FACET_MAXEXCLUSIVE, + XML_SCHEMA_FACET_TOTALDIGITS, + XML_SCHEMA_FACET_FRACTIONDIGITS, + XML_SCHEMA_FACET_PATTERN, + XML_SCHEMA_FACET_ENUMERATION, + XML_SCHEMA_FACET_WHITESPACE, + XML_SCHEMA_FACET_LENGTH, + XML_SCHEMA_FACET_MAXLENGTH, + XML_SCHEMA_FACET_MINLENGTH, + XML_SCHEMA_EXTRA_QNAMEREF = 2000, + XML_SCHEMA_EXTRA_ATTR_USE_PROHIB +} xmlSchemaTypeType; + +typedef enum { + XML_SCHEMA_CONTENT_UNKNOWN = 0, + XML_SCHEMA_CONTENT_EMPTY = 1, + XML_SCHEMA_CONTENT_ELEMENTS, + XML_SCHEMA_CONTENT_MIXED, + XML_SCHEMA_CONTENT_SIMPLE, + XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS, /* Obsolete */ + XML_SCHEMA_CONTENT_BASIC, + XML_SCHEMA_CONTENT_ANY +} xmlSchemaContentType; + +typedef struct _xmlSchemaVal xmlSchemaVal; +typedef xmlSchemaVal *xmlSchemaValPtr; + +typedef struct _xmlSchemaType xmlSchemaType; +typedef xmlSchemaType *xmlSchemaTypePtr; + +typedef struct _xmlSchemaFacet xmlSchemaFacet; +typedef xmlSchemaFacet *xmlSchemaFacetPtr; + +/** + * Annotation + */ +typedef struct _xmlSchemaAnnot xmlSchemaAnnot; +typedef xmlSchemaAnnot *xmlSchemaAnnotPtr; +struct _xmlSchemaAnnot { + struct _xmlSchemaAnnot *next; + xmlNodePtr content; /* the annotation */ +}; + +/** + * XML_SCHEMAS_ANYATTR_SKIP: + * + * Skip unknown attribute from validation + * Obsolete, not used anymore. + */ +#define XML_SCHEMAS_ANYATTR_SKIP 1 +/** + * XML_SCHEMAS_ANYATTR_LAX: + * + * Ignore validation non definition on attributes + * Obsolete, not used anymore. + */ +#define XML_SCHEMAS_ANYATTR_LAX 2 +/** + * XML_SCHEMAS_ANYATTR_STRICT: + * + * Apply strict validation rules on attributes + * Obsolete, not used anymore. + */ +#define XML_SCHEMAS_ANYATTR_STRICT 3 +/** + * XML_SCHEMAS_ANY_SKIP: + * + * Skip unknown attribute from validation + */ +#define XML_SCHEMAS_ANY_SKIP 1 +/** + * XML_SCHEMAS_ANY_LAX: + * + * Used by wildcards. + * Validate if type found, don't worry if not found + */ +#define XML_SCHEMAS_ANY_LAX 2 +/** + * XML_SCHEMAS_ANY_STRICT: + * + * Used by wildcards. + * Apply strict validation rules + */ +#define XML_SCHEMAS_ANY_STRICT 3 +/** + * XML_SCHEMAS_ATTR_USE_PROHIBITED: + * + * Used by wildcards. + * The attribute is prohibited. + */ +#define XML_SCHEMAS_ATTR_USE_PROHIBITED 0 +/** + * XML_SCHEMAS_ATTR_USE_REQUIRED: + * + * The attribute is required. + */ +#define XML_SCHEMAS_ATTR_USE_REQUIRED 1 +/** + * XML_SCHEMAS_ATTR_USE_OPTIONAL: + * + * The attribute is optional. + */ +#define XML_SCHEMAS_ATTR_USE_OPTIONAL 2 +/** + * XML_SCHEMAS_ATTR_GLOBAL: + * + * allow elements in no namespace + */ +#define XML_SCHEMAS_ATTR_GLOBAL 1 << 0 +/** + * XML_SCHEMAS_ATTR_NSDEFAULT: + * + * allow elements in no namespace + */ +#define XML_SCHEMAS_ATTR_NSDEFAULT 1 << 7 +/** + * XML_SCHEMAS_ATTR_INTERNAL_RESOLVED: + * + * this is set when the "type" and "ref" references + * have been resolved. + */ +#define XML_SCHEMAS_ATTR_INTERNAL_RESOLVED 1 << 8 +/** + * XML_SCHEMAS_ATTR_FIXED: + * + * the attribute has a fixed value + */ +#define XML_SCHEMAS_ATTR_FIXED 1 << 9 + +/** + * xmlSchemaAttribute: + * An attribute definition. + */ + +typedef struct _xmlSchemaAttribute xmlSchemaAttribute; +typedef xmlSchemaAttribute *xmlSchemaAttributePtr; +struct _xmlSchemaAttribute { + xmlSchemaTypeType type; + struct _xmlSchemaAttribute *next; /* the next attribute (not used?) */ + const xmlChar *name; /* the name of the declaration */ + const xmlChar *id; /* Deprecated; not used */ + const xmlChar *ref; /* Deprecated; not used */ + const xmlChar *refNs; /* Deprecated; not used */ + const xmlChar *typeName; /* the local name of the type definition */ + const xmlChar *typeNs; /* the ns URI of the type definition */ + xmlSchemaAnnotPtr annot; + + xmlSchemaTypePtr base; /* Deprecated; not used */ + int occurs; /* Deprecated; not used */ + const xmlChar *defValue; /* The initial value of the value constraint */ + xmlSchemaTypePtr subtypes; /* the type definition */ + xmlNodePtr node; + const xmlChar *targetNamespace; + int flags; + const xmlChar *refPrefix; /* Deprecated; not used */ + xmlSchemaValPtr defVal; /* The compiled value constraint */ + xmlSchemaAttributePtr refDecl; /* Deprecated; not used */ +}; + +/** + * xmlSchemaAttributeLink: + * Used to build a list of attribute uses on complexType definitions. + * WARNING: Deprecated; not used. + */ +typedef struct _xmlSchemaAttributeLink xmlSchemaAttributeLink; +typedef xmlSchemaAttributeLink *xmlSchemaAttributeLinkPtr; +struct _xmlSchemaAttributeLink { + struct _xmlSchemaAttributeLink *next;/* the next attribute link ... */ + struct _xmlSchemaAttribute *attr;/* the linked attribute */ +}; + +/** + * XML_SCHEMAS_WILDCARD_COMPLETE: + * + * If the wildcard is complete. + */ +#define XML_SCHEMAS_WILDCARD_COMPLETE 1 << 0 + +/** + * xmlSchemaCharValueLink: + * Used to build a list of namespaces on wildcards. + */ +typedef struct _xmlSchemaWildcardNs xmlSchemaWildcardNs; +typedef xmlSchemaWildcardNs *xmlSchemaWildcardNsPtr; +struct _xmlSchemaWildcardNs { + struct _xmlSchemaWildcardNs *next;/* the next constraint link ... */ + const xmlChar *value;/* the value */ +}; + +/** + * xmlSchemaWildcard. + * A wildcard. + */ +typedef struct _xmlSchemaWildcard xmlSchemaWildcard; +typedef xmlSchemaWildcard *xmlSchemaWildcardPtr; +struct _xmlSchemaWildcard { + xmlSchemaTypeType type; /* The kind of type */ + const xmlChar *id; /* Deprecated; not used */ + xmlSchemaAnnotPtr annot; + xmlNodePtr node; + int minOccurs; /* Deprecated; not used */ + int maxOccurs; /* Deprecated; not used */ + int processContents; + int any; /* Indicates if the ns constraint is of ##any */ + xmlSchemaWildcardNsPtr nsSet; /* The list of allowed namespaces */ + xmlSchemaWildcardNsPtr negNsSet; /* The negated namespace */ + int flags; +}; + +/** + * XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED: + * + * The attribute wildcard has been built. + */ +#define XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED 1 << 0 +/** + * XML_SCHEMAS_ATTRGROUP_GLOBAL: + * + * The attribute group has been defined. + */ +#define XML_SCHEMAS_ATTRGROUP_GLOBAL 1 << 1 +/** + * XML_SCHEMAS_ATTRGROUP_MARKED: + * + * Marks the attr group as marked; used for circular checks. + */ +#define XML_SCHEMAS_ATTRGROUP_MARKED 1 << 2 + +/** + * XML_SCHEMAS_ATTRGROUP_REDEFINED: + * + * The attr group was redefined. + */ +#define XML_SCHEMAS_ATTRGROUP_REDEFINED 1 << 3 +/** + * XML_SCHEMAS_ATTRGROUP_HAS_REFS: + * + * Whether this attr. group contains attr. group references. + */ +#define XML_SCHEMAS_ATTRGROUP_HAS_REFS 1 << 4 + +/** + * An attribute group definition. + * + * xmlSchemaAttribute and xmlSchemaAttributeGroup start of structures + * must be kept similar + */ +typedef struct _xmlSchemaAttributeGroup xmlSchemaAttributeGroup; +typedef xmlSchemaAttributeGroup *xmlSchemaAttributeGroupPtr; +struct _xmlSchemaAttributeGroup { + xmlSchemaTypeType type; /* The kind of type */ + struct _xmlSchemaAttribute *next;/* the next attribute if in a group ... */ + const xmlChar *name; + const xmlChar *id; + const xmlChar *ref; /* Deprecated; not used */ + const xmlChar *refNs; /* Deprecated; not used */ + xmlSchemaAnnotPtr annot; + + xmlSchemaAttributePtr attributes; /* Deprecated; not used */ + xmlNodePtr node; + int flags; + xmlSchemaWildcardPtr attributeWildcard; + const xmlChar *refPrefix; /* Deprecated; not used */ + xmlSchemaAttributeGroupPtr refItem; /* Deprecated; not used */ + const xmlChar *targetNamespace; + void *attrUses; +}; + +/** + * xmlSchemaTypeLink: + * Used to build a list of types (e.g. member types of + * simpleType with variety "union"). + */ +typedef struct _xmlSchemaTypeLink xmlSchemaTypeLink; +typedef xmlSchemaTypeLink *xmlSchemaTypeLinkPtr; +struct _xmlSchemaTypeLink { + struct _xmlSchemaTypeLink *next;/* the next type link ... */ + xmlSchemaTypePtr type;/* the linked type */ +}; + +/** + * xmlSchemaFacetLink: + * Used to build a list of facets. + */ +typedef struct _xmlSchemaFacetLink xmlSchemaFacetLink; +typedef xmlSchemaFacetLink *xmlSchemaFacetLinkPtr; +struct _xmlSchemaFacetLink { + struct _xmlSchemaFacetLink *next;/* the next facet link ... */ + xmlSchemaFacetPtr facet;/* the linked facet */ +}; + +/** + * XML_SCHEMAS_TYPE_MIXED: + * + * the element content type is mixed + */ +#define XML_SCHEMAS_TYPE_MIXED 1 << 0 +/** + * XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION: + * + * the simple or complex type has a derivation method of "extension". + */ +#define XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION 1 << 1 +/** + * XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION: + * + * the simple or complex type has a derivation method of "restriction". + */ +#define XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION 1 << 2 +/** + * XML_SCHEMAS_TYPE_GLOBAL: + * + * the type is global + */ +#define XML_SCHEMAS_TYPE_GLOBAL 1 << 3 +/** + * XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD: + * + * the complexType owns an attribute wildcard, i.e. + * it can be freed by the complexType + */ +#define XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD 1 << 4 /* Obsolete. */ +/** + * XML_SCHEMAS_TYPE_VARIETY_ABSENT: + * + * the simpleType has a variety of "absent". + * TODO: Actually not necessary :-/, since if + * none of the variety flags occur then it's + * automatically absent. + */ +#define XML_SCHEMAS_TYPE_VARIETY_ABSENT 1 << 5 +/** + * XML_SCHEMAS_TYPE_VARIETY_LIST: + * + * the simpleType has a variety of "list". + */ +#define XML_SCHEMAS_TYPE_VARIETY_LIST 1 << 6 +/** + * XML_SCHEMAS_TYPE_VARIETY_UNION: + * + * the simpleType has a variety of "union". + */ +#define XML_SCHEMAS_TYPE_VARIETY_UNION 1 << 7 +/** + * XML_SCHEMAS_TYPE_VARIETY_ATOMIC: + * + * the simpleType has a variety of "union". + */ +#define XML_SCHEMAS_TYPE_VARIETY_ATOMIC 1 << 8 +/** + * XML_SCHEMAS_TYPE_FINAL_EXTENSION: + * + * the complexType has a final of "extension". + */ +#define XML_SCHEMAS_TYPE_FINAL_EXTENSION 1 << 9 +/** + * XML_SCHEMAS_TYPE_FINAL_RESTRICTION: + * + * the simpleType/complexType has a final of "restriction". + */ +#define XML_SCHEMAS_TYPE_FINAL_RESTRICTION 1 << 10 +/** + * XML_SCHEMAS_TYPE_FINAL_LIST: + * + * the simpleType has a final of "list". + */ +#define XML_SCHEMAS_TYPE_FINAL_LIST 1 << 11 +/** + * XML_SCHEMAS_TYPE_FINAL_UNION: + * + * the simpleType has a final of "union". + */ +#define XML_SCHEMAS_TYPE_FINAL_UNION 1 << 12 +/** + * XML_SCHEMAS_TYPE_FINAL_DEFAULT: + * + * the simpleType has a final of "default". + */ +#define XML_SCHEMAS_TYPE_FINAL_DEFAULT 1 << 13 +/** + * XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE: + * + * Marks the item as a builtin primitive. + */ +#define XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE 1 << 14 +/** + * XML_SCHEMAS_TYPE_MARKED: + * + * Marks the item as marked; used for circular checks. + */ +#define XML_SCHEMAS_TYPE_MARKED 1 << 16 +/** + * XML_SCHEMAS_TYPE_BLOCK_DEFAULT: + * + * the complexType did not specify 'block' so use the default of the + * item. + */ +#define XML_SCHEMAS_TYPE_BLOCK_DEFAULT 1 << 17 +/** + * XML_SCHEMAS_TYPE_BLOCK_EXTENSION: + * + * the complexType has a 'block' of "extension". + */ +#define XML_SCHEMAS_TYPE_BLOCK_EXTENSION 1 << 18 +/** + * XML_SCHEMAS_TYPE_BLOCK_RESTRICTION: + * + * the complexType has a 'block' of "restriction". + */ +#define XML_SCHEMAS_TYPE_BLOCK_RESTRICTION 1 << 19 +/** + * XML_SCHEMAS_TYPE_ABSTRACT: + * + * the simple/complexType is abstract. + */ +#define XML_SCHEMAS_TYPE_ABSTRACT 1 << 20 +/** + * XML_SCHEMAS_TYPE_FACETSNEEDVALUE: + * + * indicates if the facets need a computed value + */ +#define XML_SCHEMAS_TYPE_FACETSNEEDVALUE 1 << 21 +/** + * XML_SCHEMAS_TYPE_INTERNAL_RESOLVED: + * + * indicates that the type was typefixed + */ +#define XML_SCHEMAS_TYPE_INTERNAL_RESOLVED 1 << 22 +/** + * XML_SCHEMAS_TYPE_INTERNAL_INVALID: + * + * indicates that the type is invalid + */ +#define XML_SCHEMAS_TYPE_INTERNAL_INVALID 1 << 23 +/** + * XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE: + * + * a whitespace-facet value of "preserve" + */ +#define XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE 1 << 24 +/** + * XML_SCHEMAS_TYPE_WHITESPACE_REPLACE: + * + * a whitespace-facet value of "replace" + */ +#define XML_SCHEMAS_TYPE_WHITESPACE_REPLACE 1 << 25 +/** + * XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE: + * + * a whitespace-facet value of "collapse" + */ +#define XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE 1 << 26 +/** + * XML_SCHEMAS_TYPE_HAS_FACETS: + * + * has facets + */ +#define XML_SCHEMAS_TYPE_HAS_FACETS 1 << 27 +/** + * XML_SCHEMAS_TYPE_NORMVALUENEEDED: + * + * indicates if the facets (pattern) need a normalized value + */ +#define XML_SCHEMAS_TYPE_NORMVALUENEEDED 1 << 28 + +/** + * XML_SCHEMAS_TYPE_FIXUP_1: + * + * First stage of fixup was done. + */ +#define XML_SCHEMAS_TYPE_FIXUP_1 1 << 29 + +/** + * XML_SCHEMAS_TYPE_REDEFINED: + * + * The type was redefined. + */ +#define XML_SCHEMAS_TYPE_REDEFINED 1 << 30 +/** + * XML_SCHEMAS_TYPE_REDEFINING: + * + * The type redefines an other type. + */ +/* #define XML_SCHEMAS_TYPE_REDEFINING 1 << 31 */ + +/** + * _xmlSchemaType: + * + * Schemas type definition. + */ +struct _xmlSchemaType { + xmlSchemaTypeType type; /* The kind of type */ + struct _xmlSchemaType *next; /* the next type if in a sequence ... */ + const xmlChar *name; + const xmlChar *id ; /* Deprecated; not used */ + const xmlChar *ref; /* Deprecated; not used */ + const xmlChar *refNs; /* Deprecated; not used */ + xmlSchemaAnnotPtr annot; + xmlSchemaTypePtr subtypes; + xmlSchemaAttributePtr attributes; /* Deprecated; not used */ + xmlNodePtr node; + int minOccurs; /* Deprecated; not used */ + int maxOccurs; /* Deprecated; not used */ + + int flags; + xmlSchemaContentType contentType; + const xmlChar *base; /* Base type's local name */ + const xmlChar *baseNs; /* Base type's target namespace */ + xmlSchemaTypePtr baseType; /* The base type component */ + xmlSchemaFacetPtr facets; /* Local facets */ + struct _xmlSchemaType *redef; /* Deprecated; not used */ + int recurse; /* Obsolete */ + xmlSchemaAttributeLinkPtr *attributeUses; /* Deprecated; not used */ + xmlSchemaWildcardPtr attributeWildcard; + int builtInType; /* Type of built-in types. */ + xmlSchemaTypeLinkPtr memberTypes; /* member-types if a union type. */ + xmlSchemaFacetLinkPtr facetSet; /* All facets (incl. inherited) */ + const xmlChar *refPrefix; /* Deprecated; not used */ + xmlSchemaTypePtr contentTypeDef; /* Used for the simple content of complex types. + Could we use @subtypes for this? */ + xmlRegexpPtr contModel; /* Holds the automaton of the content model */ + const xmlChar *targetNamespace; + void *attrUses; +}; + +/* + * xmlSchemaElement: + * An element definition. + * + * xmlSchemaType, xmlSchemaFacet and xmlSchemaElement start of + * structures must be kept similar + */ +/** + * XML_SCHEMAS_ELEM_NILLABLE: + * + * the element is nillable + */ +#define XML_SCHEMAS_ELEM_NILLABLE 1 << 0 +/** + * XML_SCHEMAS_ELEM_GLOBAL: + * + * the element is global + */ +#define XML_SCHEMAS_ELEM_GLOBAL 1 << 1 +/** + * XML_SCHEMAS_ELEM_DEFAULT: + * + * the element has a default value + */ +#define XML_SCHEMAS_ELEM_DEFAULT 1 << 2 +/** + * XML_SCHEMAS_ELEM_FIXED: + * + * the element has a fixed value + */ +#define XML_SCHEMAS_ELEM_FIXED 1 << 3 +/** + * XML_SCHEMAS_ELEM_ABSTRACT: + * + * the element is abstract + */ +#define XML_SCHEMAS_ELEM_ABSTRACT 1 << 4 +/** + * XML_SCHEMAS_ELEM_TOPLEVEL: + * + * the element is top level + * obsolete: use XML_SCHEMAS_ELEM_GLOBAL instead + */ +#define XML_SCHEMAS_ELEM_TOPLEVEL 1 << 5 +/** + * XML_SCHEMAS_ELEM_REF: + * + * the element is a reference to a type + */ +#define XML_SCHEMAS_ELEM_REF 1 << 6 +/** + * XML_SCHEMAS_ELEM_NSDEFAULT: + * + * allow elements in no namespace + * Obsolete, not used anymore. + */ +#define XML_SCHEMAS_ELEM_NSDEFAULT 1 << 7 +/** + * XML_SCHEMAS_ELEM_INTERNAL_RESOLVED: + * + * this is set when "type", "ref", "substitutionGroup" + * references have been resolved. + */ +#define XML_SCHEMAS_ELEM_INTERNAL_RESOLVED 1 << 8 + /** + * XML_SCHEMAS_ELEM_CIRCULAR: + * + * a helper flag for the search of circular references. + */ +#define XML_SCHEMAS_ELEM_CIRCULAR 1 << 9 +/** + * XML_SCHEMAS_ELEM_BLOCK_ABSENT: + * + * the "block" attribute is absent + */ +#define XML_SCHEMAS_ELEM_BLOCK_ABSENT 1 << 10 +/** + * XML_SCHEMAS_ELEM_BLOCK_EXTENSION: + * + * disallowed substitutions are absent + */ +#define XML_SCHEMAS_ELEM_BLOCK_EXTENSION 1 << 11 +/** + * XML_SCHEMAS_ELEM_BLOCK_RESTRICTION: + * + * disallowed substitutions: "restriction" + */ +#define XML_SCHEMAS_ELEM_BLOCK_RESTRICTION 1 << 12 +/** + * XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION: + * + * disallowed substitutions: "substitution" + */ +#define XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION 1 << 13 +/** + * XML_SCHEMAS_ELEM_FINAL_ABSENT: + * + * substitution group exclusions are absent + */ +#define XML_SCHEMAS_ELEM_FINAL_ABSENT 1 << 14 +/** + * XML_SCHEMAS_ELEM_FINAL_EXTENSION: + * + * substitution group exclusions: "extension" + */ +#define XML_SCHEMAS_ELEM_FINAL_EXTENSION 1 << 15 +/** + * XML_SCHEMAS_ELEM_FINAL_RESTRICTION: + * + * substitution group exclusions: "restriction" + */ +#define XML_SCHEMAS_ELEM_FINAL_RESTRICTION 1 << 16 +/** + * XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD: + * + * the declaration is a substitution group head + */ +#define XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD 1 << 17 +/** + * XML_SCHEMAS_ELEM_INTERNAL_CHECKED: + * + * this is set when the elem decl has been checked against + * all constraints + */ +#define XML_SCHEMAS_ELEM_INTERNAL_CHECKED 1 << 18 + +typedef struct _xmlSchemaElement xmlSchemaElement; +typedef xmlSchemaElement *xmlSchemaElementPtr; +struct _xmlSchemaElement { + xmlSchemaTypeType type; /* The kind of type */ + struct _xmlSchemaType *next; /* Not used? */ + const xmlChar *name; + const xmlChar *id; /* Deprecated; not used */ + const xmlChar *ref; /* Deprecated; not used */ + const xmlChar *refNs; /* Deprecated; not used */ + xmlSchemaAnnotPtr annot; + xmlSchemaTypePtr subtypes; /* the type definition */ + xmlSchemaAttributePtr attributes; + xmlNodePtr node; + int minOccurs; /* Deprecated; not used */ + int maxOccurs; /* Deprecated; not used */ + + int flags; + const xmlChar *targetNamespace; + const xmlChar *namedType; + const xmlChar *namedTypeNs; + const xmlChar *substGroup; + const xmlChar *substGroupNs; + const xmlChar *scope; + const xmlChar *value; /* The original value of the value constraint. */ + struct _xmlSchemaElement *refDecl; /* This will now be used for the + substitution group affiliation */ + xmlRegexpPtr contModel; /* Obsolete for WXS, maybe used for RelaxNG */ + xmlSchemaContentType contentType; + const xmlChar *refPrefix; /* Deprecated; not used */ + xmlSchemaValPtr defVal; /* The compiled value constraint. */ + void *idcs; /* The identity-constraint defs */ +}; + +/* + * XML_SCHEMAS_FACET_UNKNOWN: + * + * unknown facet handling + */ +#define XML_SCHEMAS_FACET_UNKNOWN 0 +/* + * XML_SCHEMAS_FACET_PRESERVE: + * + * preserve the type of the facet + */ +#define XML_SCHEMAS_FACET_PRESERVE 1 +/* + * XML_SCHEMAS_FACET_REPLACE: + * + * replace the type of the facet + */ +#define XML_SCHEMAS_FACET_REPLACE 2 +/* + * XML_SCHEMAS_FACET_COLLAPSE: + * + * collapse the types of the facet + */ +#define XML_SCHEMAS_FACET_COLLAPSE 3 +/** + * A facet definition. + */ +struct _xmlSchemaFacet { + xmlSchemaTypeType type; /* The kind of type */ + struct _xmlSchemaFacet *next;/* the next type if in a sequence ... */ + const xmlChar *value; /* The original value */ + const xmlChar *id; /* Obsolete */ + xmlSchemaAnnotPtr annot; + xmlNodePtr node; + int fixed; /* XML_SCHEMAS_FACET_PRESERVE, etc. */ + int whitespace; + xmlSchemaValPtr val; /* The compiled value */ + xmlRegexpPtr regexp; /* The regex for patterns */ +}; + +/** + * A notation definition. + */ +typedef struct _xmlSchemaNotation xmlSchemaNotation; +typedef xmlSchemaNotation *xmlSchemaNotationPtr; +struct _xmlSchemaNotation { + xmlSchemaTypeType type; /* The kind of type */ + const xmlChar *name; + xmlSchemaAnnotPtr annot; + const xmlChar *identifier; + const xmlChar *targetNamespace; +}; + +/* +* TODO: Actually all those flags used for the schema should sit +* on the schema parser context, since they are used only +* during parsing an XML schema document, and not available +* on the component level as per spec. +*/ +/** + * XML_SCHEMAS_QUALIF_ELEM: + * + * Reflects elementFormDefault == qualified in + * an XML schema document. + */ +#define XML_SCHEMAS_QUALIF_ELEM 1 << 0 +/** + * XML_SCHEMAS_QUALIF_ATTR: + * + * Reflects attributeFormDefault == qualified in + * an XML schema document. + */ +#define XML_SCHEMAS_QUALIF_ATTR 1 << 1 +/** + * XML_SCHEMAS_FINAL_DEFAULT_EXTENSION: + * + * the schema has "extension" in the set of finalDefault. + */ +#define XML_SCHEMAS_FINAL_DEFAULT_EXTENSION 1 << 2 +/** + * XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION: + * + * the schema has "restriction" in the set of finalDefault. + */ +#define XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION 1 << 3 +/** + * XML_SCHEMAS_FINAL_DEFAULT_LIST: + * + * the schema has "list" in the set of finalDefault. + */ +#define XML_SCHEMAS_FINAL_DEFAULT_LIST 1 << 4 +/** + * XML_SCHEMAS_FINAL_DEFAULT_UNION: + * + * the schema has "union" in the set of finalDefault. + */ +#define XML_SCHEMAS_FINAL_DEFAULT_UNION 1 << 5 +/** + * XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION: + * + * the schema has "extension" in the set of blockDefault. + */ +#define XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION 1 << 6 +/** + * XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION: + * + * the schema has "restriction" in the set of blockDefault. + */ +#define XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION 1 << 7 +/** + * XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION: + * + * the schema has "substitution" in the set of blockDefault. + */ +#define XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION 1 << 8 +/** + * XML_SCHEMAS_INCLUDING_CONVERT_NS: + * + * the schema is currently including an other schema with + * no target namespace. + */ +#define XML_SCHEMAS_INCLUDING_CONVERT_NS 1 << 9 +/** + * _xmlSchema: + * + * A Schemas definition + */ +struct _xmlSchema { + const xmlChar *name; /* schema name */ + const xmlChar *targetNamespace; /* the target namespace */ + const xmlChar *version; + const xmlChar *id; /* Obsolete */ + xmlDocPtr doc; + xmlSchemaAnnotPtr annot; + int flags; + + xmlHashTablePtr typeDecl; + xmlHashTablePtr attrDecl; + xmlHashTablePtr attrgrpDecl; + xmlHashTablePtr elemDecl; + xmlHashTablePtr notaDecl; + + xmlHashTablePtr schemasImports; + + void *_private; /* unused by the library for users or bindings */ + xmlHashTablePtr groupDecl; + xmlDictPtr dict; + void *includes; /* the includes, this is opaque for now */ + int preserve; /* whether to free the document */ + int counter; /* used to give anonymous components unique names */ + xmlHashTablePtr idcDef; /* All identity-constraint defs. */ + void *volatiles; /* Obsolete */ +}; + +XMLPUBFUN void xmlSchemaFreeType (xmlSchemaTypePtr type); +XMLPUBFUN void xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard); + +#ifdef __cplusplus +} +#endif + +#endif /* LIBXML_SCHEMAS_ENABLED */ +#endif /* __XML_SCHEMA_INTERNALS_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/schematron.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/schematron.h new file mode 100644 index 0000000..8dd8d25 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/schematron.h @@ -0,0 +1,143 @@ +/* + * Summary: XML Schematron implementation + * Description: interface to the XML Schematron validity checking. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + + +#ifndef __XML_SCHEMATRON_H__ +#define __XML_SCHEMATRON_H__ + +#include + +#ifdef LIBXML_SCHEMATRON_ENABLED + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + XML_SCHEMATRON_OUT_QUIET = 1 << 0, /* quiet no report */ + XML_SCHEMATRON_OUT_TEXT = 1 << 1, /* build a textual report */ + XML_SCHEMATRON_OUT_XML = 1 << 2, /* output SVRL */ + XML_SCHEMATRON_OUT_ERROR = 1 << 3, /* output via xmlStructuredErrorFunc */ + XML_SCHEMATRON_OUT_FILE = 1 << 8, /* output to a file descriptor */ + XML_SCHEMATRON_OUT_BUFFER = 1 << 9, /* output to a buffer */ + XML_SCHEMATRON_OUT_IO = 1 << 10 /* output to I/O mechanism */ +} xmlSchematronValidOptions; + +/** + * The schemas related types are kept internal + */ +typedef struct _xmlSchematron xmlSchematron; +typedef xmlSchematron *xmlSchematronPtr; + +/** + * xmlSchematronValidityErrorFunc: + * @ctx: the validation context + * @msg: the message + * @...: extra arguments + * + * Signature of an error callback from a Schematron validation + */ +typedef void (*xmlSchematronValidityErrorFunc) (void *ctx, const char *msg, ...); + +/** + * xmlSchematronValidityWarningFunc: + * @ctx: the validation context + * @msg: the message + * @...: extra arguments + * + * Signature of a warning callback from a Schematron validation + */ +typedef void (*xmlSchematronValidityWarningFunc) (void *ctx, const char *msg, ...); + +/** + * A schemas validation context + */ +typedef struct _xmlSchematronParserCtxt xmlSchematronParserCtxt; +typedef xmlSchematronParserCtxt *xmlSchematronParserCtxtPtr; + +typedef struct _xmlSchematronValidCtxt xmlSchematronValidCtxt; +typedef xmlSchematronValidCtxt *xmlSchematronValidCtxtPtr; + +/* + * Interfaces for parsing. + */ +XMLPUBFUN xmlSchematronParserCtxtPtr + xmlSchematronNewParserCtxt (const char *URL); +XMLPUBFUN xmlSchematronParserCtxtPtr + xmlSchematronNewMemParserCtxt(const char *buffer, + int size); +XMLPUBFUN xmlSchematronParserCtxtPtr + xmlSchematronNewDocParserCtxt(xmlDocPtr doc); +XMLPUBFUN void + xmlSchematronFreeParserCtxt (xmlSchematronParserCtxtPtr ctxt); +/***** +XMLPUBFUN void + xmlSchematronSetParserErrors(xmlSchematronParserCtxtPtr ctxt, + xmlSchematronValidityErrorFunc err, + xmlSchematronValidityWarningFunc warn, + void *ctx); +XMLPUBFUN int + xmlSchematronGetParserErrors(xmlSchematronParserCtxtPtr ctxt, + xmlSchematronValidityErrorFunc * err, + xmlSchematronValidityWarningFunc * warn, + void **ctx); +XMLPUBFUN int + xmlSchematronIsValid (xmlSchematronValidCtxtPtr ctxt); + *****/ +XMLPUBFUN xmlSchematronPtr + xmlSchematronParse (xmlSchematronParserCtxtPtr ctxt); +XMLPUBFUN void + xmlSchematronFree (xmlSchematronPtr schema); +/* + * Interfaces for validating + */ +XMLPUBFUN void + xmlSchematronSetValidStructuredErrors( + xmlSchematronValidCtxtPtr ctxt, + xmlStructuredErrorFunc serror, + void *ctx); +/****** +XMLPUBFUN void + xmlSchematronSetValidErrors (xmlSchematronValidCtxtPtr ctxt, + xmlSchematronValidityErrorFunc err, + xmlSchematronValidityWarningFunc warn, + void *ctx); +XMLPUBFUN int + xmlSchematronGetValidErrors (xmlSchematronValidCtxtPtr ctxt, + xmlSchematronValidityErrorFunc *err, + xmlSchematronValidityWarningFunc *warn, + void **ctx); +XMLPUBFUN int + xmlSchematronSetValidOptions(xmlSchematronValidCtxtPtr ctxt, + int options); +XMLPUBFUN int + xmlSchematronValidCtxtGetOptions(xmlSchematronValidCtxtPtr ctxt); +XMLPUBFUN int + xmlSchematronValidateOneElement (xmlSchematronValidCtxtPtr ctxt, + xmlNodePtr elem); + *******/ + +XMLPUBFUN xmlSchematronValidCtxtPtr + xmlSchematronNewValidCtxt (xmlSchematronPtr schema, + int options); +XMLPUBFUN void + xmlSchematronFreeValidCtxt (xmlSchematronValidCtxtPtr ctxt); +XMLPUBFUN int + xmlSchematronValidateDoc (xmlSchematronValidCtxtPtr ctxt, + xmlDocPtr instance); + +#ifdef __cplusplus +} +#endif + +#endif /* LIBXML_SCHEMATRON_ENABLED */ +#endif /* __XML_SCHEMATRON_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/threads.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/threads.h new file mode 100644 index 0000000..8f4b6e1 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/threads.h @@ -0,0 +1,87 @@ +/** + * Summary: interfaces for thread handling + * Description: set of generic threading related routines + * should work with pthreads, Windows native or TLS threads + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_THREADS_H__ +#define __XML_THREADS_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * xmlMutex are a simple mutual exception locks. + */ +typedef struct _xmlMutex xmlMutex; +typedef xmlMutex *xmlMutexPtr; + +/* + * xmlRMutex are reentrant mutual exception locks. + */ +typedef struct _xmlRMutex xmlRMutex; +typedef xmlRMutex *xmlRMutexPtr; + +XMLPUBFUN int + xmlCheckThreadLocalStorage(void); + +XMLPUBFUN xmlMutexPtr + xmlNewMutex (void); +XMLPUBFUN void + xmlMutexLock (xmlMutexPtr tok); +XMLPUBFUN void + xmlMutexUnlock (xmlMutexPtr tok); +XMLPUBFUN void + xmlFreeMutex (xmlMutexPtr tok); + +XMLPUBFUN xmlRMutexPtr + xmlNewRMutex (void); +XMLPUBFUN void + xmlRMutexLock (xmlRMutexPtr tok); +XMLPUBFUN void + xmlRMutexUnlock (xmlRMutexPtr tok); +XMLPUBFUN void + xmlFreeRMutex (xmlRMutexPtr tok); + +/* + * Library wide APIs. + */ +XML_DEPRECATED +XMLPUBFUN void + xmlInitThreads (void); +XMLPUBFUN void + xmlLockLibrary (void); +XMLPUBFUN void + xmlUnlockLibrary(void); +XML_DEPRECATED +XMLPUBFUN int + xmlGetThreadId (void); +XML_DEPRECATED +XMLPUBFUN int + xmlIsMainThread (void); +XML_DEPRECATED +XMLPUBFUN void + xmlCleanupThreads(void); + +/** DOC_DISABLE */ +#if defined(LIBXML_THREAD_ENABLED) && defined(_WIN32) && \ + defined(LIBXML_STATIC_FOR_DLL) +int +xmlDllMain(void *hinstDLL, unsigned long fdwReason, + void *lpvReserved); +#endif +/** DOC_ENABLE */ + +#ifdef __cplusplus +} +#endif + + +#endif /* __XML_THREADS_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/tree.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/tree.h new file mode 100644 index 0000000..4070375 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/tree.h @@ -0,0 +1,1382 @@ +/* + * Summary: interfaces for tree manipulation + * Description: this module describes the structures found in an tree resulting + * from an XML or HTML parsing, as well as the API provided for + * various processing on that tree + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef XML_TREE_INTERNALS + +/* + * Emulate circular dependency for backward compatibility + */ +#include + +#else /* XML_TREE_INTERNALS */ + +#ifndef __XML_TREE_H__ +#define __XML_TREE_H__ + +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Some of the basic types pointer to structures: + */ +/* xmlIO.h */ +typedef struct _xmlParserInputBuffer xmlParserInputBuffer; +typedef xmlParserInputBuffer *xmlParserInputBufferPtr; + +typedef struct _xmlOutputBuffer xmlOutputBuffer; +typedef xmlOutputBuffer *xmlOutputBufferPtr; + +/* parser.h */ +typedef struct _xmlParserInput xmlParserInput; +typedef xmlParserInput *xmlParserInputPtr; + +typedef struct _xmlParserCtxt xmlParserCtxt; +typedef xmlParserCtxt *xmlParserCtxtPtr; + +typedef struct _xmlSAXLocator xmlSAXLocator; +typedef xmlSAXLocator *xmlSAXLocatorPtr; + +typedef struct _xmlSAXHandler xmlSAXHandler; +typedef xmlSAXHandler *xmlSAXHandlerPtr; + +/* entities.h */ +typedef struct _xmlEntity xmlEntity; +typedef xmlEntity *xmlEntityPtr; + +/** + * BASE_BUFFER_SIZE: + * + * default buffer size 4000. + */ +#define BASE_BUFFER_SIZE 4096 + +/** + * LIBXML_NAMESPACE_DICT: + * + * Defines experimental behaviour: + * 1) xmlNs gets an additional field @context (a xmlDoc) + * 2) when creating a tree, xmlNs->href is stored in the dict of xmlDoc. + */ +/* #define LIBXML_NAMESPACE_DICT */ + +/** + * xmlBufferAllocationScheme: + * + * A buffer allocation scheme can be defined to either match exactly the + * need or double it's allocated size each time it is found too small. + */ + +typedef enum { + XML_BUFFER_ALLOC_DOUBLEIT, /* double each time one need to grow */ + XML_BUFFER_ALLOC_EXACT, /* grow only to the minimal size */ + XML_BUFFER_ALLOC_IMMUTABLE, /* immutable buffer, deprecated */ + XML_BUFFER_ALLOC_IO, /* special allocation scheme used for I/O */ + XML_BUFFER_ALLOC_HYBRID, /* exact up to a threshold, and doubleit thereafter */ + XML_BUFFER_ALLOC_BOUNDED /* limit the upper size of the buffer */ +} xmlBufferAllocationScheme; + +/** + * xmlBuffer: + * + * A buffer structure, this old construct is limited to 2GB and + * is being deprecated, use API with xmlBuf instead + */ +typedef struct _xmlBuffer xmlBuffer; +typedef xmlBuffer *xmlBufferPtr; +struct _xmlBuffer { + xmlChar *content; /* The buffer content UTF8 */ + unsigned int use; /* The buffer size used */ + unsigned int size; /* The buffer size */ + xmlBufferAllocationScheme alloc; /* The realloc method */ + xmlChar *contentIO; /* in IO mode we may have a different base */ +}; + +/** + * xmlBuf: + * + * A buffer structure, new one, the actual structure internals are not public + */ + +typedef struct _xmlBuf xmlBuf; + +/** + * xmlBufPtr: + * + * A pointer to a buffer structure, the actual structure internals are not + * public + */ + +typedef xmlBuf *xmlBufPtr; + +/* + * A few public routines for xmlBuf. As those are expected to be used + * mostly internally the bulk of the routines are internal in buf.h + */ +XMLPUBFUN xmlChar* xmlBufContent (const xmlBuf* buf); +XMLPUBFUN xmlChar* xmlBufEnd (xmlBufPtr buf); +XMLPUBFUN size_t xmlBufUse (const xmlBufPtr buf); +XMLPUBFUN size_t xmlBufShrink (xmlBufPtr buf, size_t len); + +/* + * LIBXML2_NEW_BUFFER: + * + * Macro used to express that the API use the new buffers for + * xmlParserInputBuffer and xmlOutputBuffer. The change was + * introduced in 2.9.0. + */ +#define LIBXML2_NEW_BUFFER + +/** + * XML_XML_NAMESPACE: + * + * This is the namespace for the special xml: prefix predefined in the + * XML Namespace specification. + */ +#define XML_XML_NAMESPACE \ + (const xmlChar *) "http://www.w3.org/XML/1998/namespace" + +/** + * XML_XML_ID: + * + * This is the name for the special xml:id attribute + */ +#define XML_XML_ID (const xmlChar *) "xml:id" + +/* + * The different element types carried by an XML tree. + * + * NOTE: This is synchronized with DOM Level1 values + * See http://www.w3.org/TR/REC-DOM-Level-1/ + * + * Actually this had diverged a bit, and now XML_DOCUMENT_TYPE_NODE should + * be deprecated to use an XML_DTD_NODE. + */ +typedef enum { + XML_ELEMENT_NODE= 1, + XML_ATTRIBUTE_NODE= 2, + XML_TEXT_NODE= 3, + XML_CDATA_SECTION_NODE= 4, + XML_ENTITY_REF_NODE= 5, + XML_ENTITY_NODE= 6, /* unused */ + XML_PI_NODE= 7, + XML_COMMENT_NODE= 8, + XML_DOCUMENT_NODE= 9, + XML_DOCUMENT_TYPE_NODE= 10, /* unused */ + XML_DOCUMENT_FRAG_NODE= 11, + XML_NOTATION_NODE= 12, /* unused */ + XML_HTML_DOCUMENT_NODE= 13, + XML_DTD_NODE= 14, + XML_ELEMENT_DECL= 15, + XML_ATTRIBUTE_DECL= 16, + XML_ENTITY_DECL= 17, + XML_NAMESPACE_DECL= 18, + XML_XINCLUDE_START= 19, + XML_XINCLUDE_END= 20 + /* XML_DOCB_DOCUMENT_NODE= 21 */ /* removed */ +} xmlElementType; + +/** DOC_DISABLE */ +/* For backward compatibility */ +#define XML_DOCB_DOCUMENT_NODE 21 +/** DOC_ENABLE */ + +/** + * xmlNotation: + * + * A DTD Notation definition. + */ + +typedef struct _xmlNotation xmlNotation; +typedef xmlNotation *xmlNotationPtr; +struct _xmlNotation { + const xmlChar *name; /* Notation name */ + const xmlChar *PublicID; /* Public identifier, if any */ + const xmlChar *SystemID; /* System identifier, if any */ +}; + +/** + * xmlAttributeType: + * + * A DTD Attribute type definition. + */ + +typedef enum { + XML_ATTRIBUTE_CDATA = 1, + XML_ATTRIBUTE_ID, + XML_ATTRIBUTE_IDREF , + XML_ATTRIBUTE_IDREFS, + XML_ATTRIBUTE_ENTITY, + XML_ATTRIBUTE_ENTITIES, + XML_ATTRIBUTE_NMTOKEN, + XML_ATTRIBUTE_NMTOKENS, + XML_ATTRIBUTE_ENUMERATION, + XML_ATTRIBUTE_NOTATION +} xmlAttributeType; + +/** + * xmlAttributeDefault: + * + * A DTD Attribute default definition. + */ + +typedef enum { + XML_ATTRIBUTE_NONE = 1, + XML_ATTRIBUTE_REQUIRED, + XML_ATTRIBUTE_IMPLIED, + XML_ATTRIBUTE_FIXED +} xmlAttributeDefault; + +/** + * xmlEnumeration: + * + * List structure used when there is an enumeration in DTDs. + */ + +typedef struct _xmlEnumeration xmlEnumeration; +typedef xmlEnumeration *xmlEnumerationPtr; +struct _xmlEnumeration { + struct _xmlEnumeration *next; /* next one */ + const xmlChar *name; /* Enumeration name */ +}; + +/** + * xmlAttribute: + * + * An Attribute declaration in a DTD. + */ + +typedef struct _xmlAttribute xmlAttribute; +typedef xmlAttribute *xmlAttributePtr; +struct _xmlAttribute { + void *_private; /* application data */ + xmlElementType type; /* XML_ATTRIBUTE_DECL, must be second ! */ + const xmlChar *name; /* Attribute name */ + struct _xmlNode *children; /* NULL */ + struct _xmlNode *last; /* NULL */ + struct _xmlDtd *parent; /* -> DTD */ + struct _xmlNode *next; /* next sibling link */ + struct _xmlNode *prev; /* previous sibling link */ + struct _xmlDoc *doc; /* the containing document */ + + struct _xmlAttribute *nexth; /* next in hash table */ + xmlAttributeType atype; /* The attribute type */ + xmlAttributeDefault def; /* the default */ + const xmlChar *defaultValue; /* or the default value */ + xmlEnumerationPtr tree; /* or the enumeration tree if any */ + const xmlChar *prefix; /* the namespace prefix if any */ + const xmlChar *elem; /* Element holding the attribute */ +}; + +/** + * xmlElementContentType: + * + * Possible definitions of element content types. + */ +typedef enum { + XML_ELEMENT_CONTENT_PCDATA = 1, + XML_ELEMENT_CONTENT_ELEMENT, + XML_ELEMENT_CONTENT_SEQ, + XML_ELEMENT_CONTENT_OR +} xmlElementContentType; + +/** + * xmlElementContentOccur: + * + * Possible definitions of element content occurrences. + */ +typedef enum { + XML_ELEMENT_CONTENT_ONCE = 1, + XML_ELEMENT_CONTENT_OPT, + XML_ELEMENT_CONTENT_MULT, + XML_ELEMENT_CONTENT_PLUS +} xmlElementContentOccur; + +/** + * xmlElementContent: + * + * An XML Element content as stored after parsing an element definition + * in a DTD. + */ + +typedef struct _xmlElementContent xmlElementContent; +typedef xmlElementContent *xmlElementContentPtr; +struct _xmlElementContent { + xmlElementContentType type; /* PCDATA, ELEMENT, SEQ or OR */ + xmlElementContentOccur ocur; /* ONCE, OPT, MULT or PLUS */ + const xmlChar *name; /* Element name */ + struct _xmlElementContent *c1; /* first child */ + struct _xmlElementContent *c2; /* second child */ + struct _xmlElementContent *parent; /* parent */ + const xmlChar *prefix; /* Namespace prefix */ +}; + +/** + * xmlElementTypeVal: + * + * The different possibilities for an element content type. + */ + +typedef enum { + XML_ELEMENT_TYPE_UNDEFINED = 0, + XML_ELEMENT_TYPE_EMPTY = 1, + XML_ELEMENT_TYPE_ANY, + XML_ELEMENT_TYPE_MIXED, + XML_ELEMENT_TYPE_ELEMENT +} xmlElementTypeVal; + +/** + * xmlElement: + * + * An XML Element declaration from a DTD. + */ + +typedef struct _xmlElement xmlElement; +typedef xmlElement *xmlElementPtr; +struct _xmlElement { + void *_private; /* application data */ + xmlElementType type; /* XML_ELEMENT_DECL, must be second ! */ + const xmlChar *name; /* Element name */ + struct _xmlNode *children; /* NULL */ + struct _xmlNode *last; /* NULL */ + struct _xmlDtd *parent; /* -> DTD */ + struct _xmlNode *next; /* next sibling link */ + struct _xmlNode *prev; /* previous sibling link */ + struct _xmlDoc *doc; /* the containing document */ + + xmlElementTypeVal etype; /* The type */ + xmlElementContentPtr content; /* the allowed element content */ + xmlAttributePtr attributes; /* List of the declared attributes */ + const xmlChar *prefix; /* the namespace prefix if any */ +#ifdef LIBXML_REGEXP_ENABLED + xmlRegexpPtr contModel; /* the validating regexp */ +#else + void *contModel; +#endif +}; + + +/** + * XML_LOCAL_NAMESPACE: + * + * A namespace declaration node. + */ +#define XML_LOCAL_NAMESPACE XML_NAMESPACE_DECL +typedef xmlElementType xmlNsType; + +/** + * xmlNs: + * + * An XML namespace. + * Note that prefix == NULL is valid, it defines the default namespace + * within the subtree (until overridden). + * + * xmlNsType is unified with xmlElementType. + */ + +typedef struct _xmlNs xmlNs; +typedef xmlNs *xmlNsPtr; +struct _xmlNs { + struct _xmlNs *next; /* next Ns link for this node */ + xmlNsType type; /* global or local */ + const xmlChar *href; /* URL for the namespace */ + const xmlChar *prefix; /* prefix for the namespace */ + void *_private; /* application data */ + struct _xmlDoc *context; /* normally an xmlDoc */ +}; + +/** + * xmlDtd: + * + * An XML DTD, as defined by parent link */ + struct _xmlNode *next; /* next sibling link */ + struct _xmlNode *prev; /* previous sibling link */ + struct _xmlDoc *doc; /* the containing document */ + + /* End of common part */ + void *notations; /* Hash table for notations if any */ + void *elements; /* Hash table for elements if any */ + void *attributes; /* Hash table for attributes if any */ + void *entities; /* Hash table for entities if any */ + const xmlChar *ExternalID; /* External identifier for PUBLIC DTD */ + const xmlChar *SystemID; /* URI for a SYSTEM or PUBLIC DTD */ + void *pentities; /* Hash table for param entities if any */ +}; + +/** + * xmlAttr: + * + * An attribute on an XML node. + */ +typedef struct _xmlAttr xmlAttr; +typedef xmlAttr *xmlAttrPtr; +struct _xmlAttr { + void *_private; /* application data */ + xmlElementType type; /* XML_ATTRIBUTE_NODE, must be second ! */ + const xmlChar *name; /* the name of the property */ + struct _xmlNode *children; /* the value of the property */ + struct _xmlNode *last; /* NULL */ + struct _xmlNode *parent; /* child->parent link */ + struct _xmlAttr *next; /* next sibling link */ + struct _xmlAttr *prev; /* previous sibling link */ + struct _xmlDoc *doc; /* the containing document */ + xmlNs *ns; /* pointer to the associated namespace */ + xmlAttributeType atype; /* the attribute type if validating */ + void *psvi; /* for type/PSVI information */ + struct _xmlID *id; /* the ID struct */ +}; + +/** + * xmlID: + * + * An XML ID instance. + */ + +typedef struct _xmlID xmlID; +typedef xmlID *xmlIDPtr; +struct _xmlID { + struct _xmlID *next; /* next ID */ + const xmlChar *value; /* The ID name */ + xmlAttrPtr attr; /* The attribute holding it */ + const xmlChar *name; /* The attribute if attr is not available */ + int lineno; /* The line number if attr is not available */ + struct _xmlDoc *doc; /* The document holding the ID */ +}; + +/** + * xmlRef: + * + * An XML IDREF instance. + */ + +typedef struct _xmlRef xmlRef; +typedef xmlRef *xmlRefPtr; +struct _xmlRef { + struct _xmlRef *next; /* next Ref */ + const xmlChar *value; /* The Ref name */ + xmlAttrPtr attr; /* The attribute holding it */ + const xmlChar *name; /* The attribute if attr is not available */ + int lineno; /* The line number if attr is not available */ +}; + +/** + * xmlNode: + * + * A node in an XML tree. + */ +typedef struct _xmlNode xmlNode; +typedef xmlNode *xmlNodePtr; +struct _xmlNode { + void *_private; /* application data */ + xmlElementType type; /* type number, must be second ! */ + const xmlChar *name; /* the name of the node, or the entity */ + struct _xmlNode *children; /* parent->childs link */ + struct _xmlNode *last; /* last child link */ + struct _xmlNode *parent; /* child->parent link */ + struct _xmlNode *next; /* next sibling link */ + struct _xmlNode *prev; /* previous sibling link */ + struct _xmlDoc *doc; /* the containing document */ + + /* End of common part */ + xmlNs *ns; /* pointer to the associated namespace */ + xmlChar *content; /* the content */ + struct _xmlAttr *properties;/* properties list */ + xmlNs *nsDef; /* namespace definitions on this node */ + void *psvi; /* for type/PSVI information */ + unsigned short line; /* line number */ + unsigned short extra; /* extra data for XPath/XSLT */ +}; + +/** + * XML_GET_CONTENT: + * + * Macro to extract the content pointer of a node. + */ +#define XML_GET_CONTENT(n) \ + ((n)->type == XML_ELEMENT_NODE ? NULL : (n)->content) + +/** + * XML_GET_LINE: + * + * Macro to extract the line number of an element node. + */ +#define XML_GET_LINE(n) \ + (xmlGetLineNo(n)) + +/** + * xmlDocProperty + * + * Set of properties of the document as found by the parser + * Some of them are linked to similarly named xmlParserOption + */ +typedef enum { + XML_DOC_WELLFORMED = 1<<0, /* document is XML well formed */ + XML_DOC_NSVALID = 1<<1, /* document is Namespace valid */ + XML_DOC_OLD10 = 1<<2, /* parsed with old XML-1.0 parser */ + XML_DOC_DTDVALID = 1<<3, /* DTD validation was successful */ + XML_DOC_XINCLUDE = 1<<4, /* XInclude substitution was done */ + XML_DOC_USERBUILT = 1<<5, /* Document was built using the API + and not by parsing an instance */ + XML_DOC_INTERNAL = 1<<6, /* built for internal processing */ + XML_DOC_HTML = 1<<7 /* parsed or built HTML document */ +} xmlDocProperties; + +/** + * xmlDoc: + * + * An XML document. + */ +typedef struct _xmlDoc xmlDoc; +typedef xmlDoc *xmlDocPtr; +struct _xmlDoc { + void *_private; /* application data */ + xmlElementType type; /* XML_DOCUMENT_NODE, must be second ! */ + char *name; /* name/filename/URI of the document */ + struct _xmlNode *children; /* the document tree */ + struct _xmlNode *last; /* last child link */ + struct _xmlNode *parent; /* child->parent link */ + struct _xmlNode *next; /* next sibling link */ + struct _xmlNode *prev; /* previous sibling link */ + struct _xmlDoc *doc; /* autoreference to itself */ + + /* End of common part */ + int compression;/* level of zlib compression */ + int standalone; /* standalone document (no external refs) + 1 if standalone="yes" + 0 if standalone="no" + -1 if there is no XML declaration + -2 if there is an XML declaration, but no + standalone attribute was specified */ + struct _xmlDtd *intSubset; /* the document internal subset */ + struct _xmlDtd *extSubset; /* the document external subset */ + struct _xmlNs *oldNs; /* Global namespace, the old way */ + const xmlChar *version; /* the XML version string */ + const xmlChar *encoding; /* actual encoding, if any */ + void *ids; /* Hash table for ID attributes if any */ + void *refs; /* Hash table for IDREFs attributes if any */ + const xmlChar *URL; /* The URI for that document */ + int charset; /* unused */ + struct _xmlDict *dict; /* dict used to allocate names or NULL */ + void *psvi; /* for type/PSVI information */ + int parseFlags; /* set of xmlParserOption used to parse the + document */ + int properties; /* set of xmlDocProperties for this document + set at the end of parsing */ +}; + + +typedef struct _xmlDOMWrapCtxt xmlDOMWrapCtxt; +typedef xmlDOMWrapCtxt *xmlDOMWrapCtxtPtr; + +/** + * xmlDOMWrapAcquireNsFunction: + * @ctxt: a DOM wrapper context + * @node: the context node (element or attribute) + * @nsName: the requested namespace name + * @nsPrefix: the requested namespace prefix + * + * A function called to acquire namespaces (xmlNs) from the wrapper. + * + * Returns an xmlNsPtr or NULL in case of an error. + */ +typedef xmlNsPtr (*xmlDOMWrapAcquireNsFunction) (xmlDOMWrapCtxtPtr ctxt, + xmlNodePtr node, + const xmlChar *nsName, + const xmlChar *nsPrefix); + +/** + * xmlDOMWrapCtxt: + * + * Context for DOM wrapper-operations. + */ +struct _xmlDOMWrapCtxt { + void * _private; + /* + * The type of this context, just in case we need specialized + * contexts in the future. + */ + int type; + /* + * Internal namespace map used for various operations. + */ + void * namespaceMap; + /* + * Use this one to acquire an xmlNsPtr intended for node->ns. + * (Note that this is not intended for elem->nsDef). + */ + xmlDOMWrapAcquireNsFunction getNsForNodeFunc; +}; + +/** + * xmlRegisterNodeFunc: + * @node: the current node + * + * Signature for the registration callback of a created node + */ +typedef void (*xmlRegisterNodeFunc) (xmlNodePtr node); + +/** + * xmlDeregisterNodeFunc: + * @node: the current node + * + * Signature for the deregistration callback of a discarded node + */ +typedef void (*xmlDeregisterNodeFunc) (xmlNodePtr node); + +/** + * xmlChildrenNode: + * + * Macro for compatibility naming layer with libxml1. Maps + * to "children." + */ +#ifndef xmlChildrenNode +#define xmlChildrenNode children +#endif + +/** + * xmlRootNode: + * + * Macro for compatibility naming layer with libxml1. Maps + * to "children". + */ +#ifndef xmlRootNode +#define xmlRootNode children +#endif + +/* + * Variables. + */ + +/** DOC_DISABLE */ +#define XML_GLOBALS_TREE \ + XML_OP(xmlBufferAllocScheme, xmlBufferAllocationScheme, XML_DEPRECATED) \ + XML_OP(xmlDefaultBufferSize, int, XML_DEPRECATED) \ + XML_OP(xmlRegisterNodeDefaultValue, xmlRegisterNodeFunc, XML_DEPRECATED) \ + XML_OP(xmlDeregisterNodeDefaultValue, xmlDeregisterNodeFunc, \ + XML_DEPRECATED) + +#define XML_OP XML_DECLARE_GLOBAL +XML_GLOBALS_TREE +#undef XML_OP + +#if defined(LIBXML_THREAD_ENABLED) && !defined(XML_GLOBALS_NO_REDEFINITION) + #define xmlBufferAllocScheme XML_GLOBAL_MACRO(xmlBufferAllocScheme) + #define xmlDefaultBufferSize XML_GLOBAL_MACRO(xmlDefaultBufferSize) + #define xmlRegisterNodeDefaultValue \ + XML_GLOBAL_MACRO(xmlRegisterNodeDefaultValue) + #define xmlDeregisterNodeDefaultValue \ + XML_GLOBAL_MACRO(xmlDeregisterNodeDefaultValue) +#endif +/** DOC_ENABLE */ + +/* + * Some helper functions + */ +XMLPUBFUN int + xmlValidateNCName (const xmlChar *value, + int space); + +#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) +XMLPUBFUN int + xmlValidateQName (const xmlChar *value, + int space); +XMLPUBFUN int + xmlValidateName (const xmlChar *value, + int space); +XMLPUBFUN int + xmlValidateNMToken (const xmlChar *value, + int space); +#endif + +XMLPUBFUN xmlChar * + xmlBuildQName (const xmlChar *ncname, + const xmlChar *prefix, + xmlChar *memory, + int len); +XMLPUBFUN xmlChar * + xmlSplitQName2 (const xmlChar *name, + xmlChar **prefix); +XMLPUBFUN const xmlChar * + xmlSplitQName3 (const xmlChar *name, + int *len); + +/* + * Handling Buffers, the old ones see @xmlBuf for the new ones. + */ + +XMLPUBFUN void + xmlSetBufferAllocationScheme(xmlBufferAllocationScheme scheme); +XMLPUBFUN xmlBufferAllocationScheme + xmlGetBufferAllocationScheme(void); + +XMLPUBFUN xmlBufferPtr + xmlBufferCreate (void); +XMLPUBFUN xmlBufferPtr + xmlBufferCreateSize (size_t size); +XMLPUBFUN xmlBufferPtr + xmlBufferCreateStatic (void *mem, + size_t size); +XMLPUBFUN int + xmlBufferResize (xmlBufferPtr buf, + unsigned int size); +XMLPUBFUN void + xmlBufferFree (xmlBufferPtr buf); +XMLPUBFUN int + xmlBufferDump (FILE *file, + xmlBufferPtr buf); +XMLPUBFUN int + xmlBufferAdd (xmlBufferPtr buf, + const xmlChar *str, + int len); +XMLPUBFUN int + xmlBufferAddHead (xmlBufferPtr buf, + const xmlChar *str, + int len); +XMLPUBFUN int + xmlBufferCat (xmlBufferPtr buf, + const xmlChar *str); +XMLPUBFUN int + xmlBufferCCat (xmlBufferPtr buf, + const char *str); +XMLPUBFUN int + xmlBufferShrink (xmlBufferPtr buf, + unsigned int len); +XMLPUBFUN int + xmlBufferGrow (xmlBufferPtr buf, + unsigned int len); +XMLPUBFUN void + xmlBufferEmpty (xmlBufferPtr buf); +XMLPUBFUN const xmlChar* + xmlBufferContent (const xmlBuffer *buf); +XMLPUBFUN xmlChar* + xmlBufferDetach (xmlBufferPtr buf); +XMLPUBFUN void + xmlBufferSetAllocationScheme(xmlBufferPtr buf, + xmlBufferAllocationScheme scheme); +XMLPUBFUN int + xmlBufferLength (const xmlBuffer *buf); + +/* + * Creating/freeing new structures. + */ +XMLPUBFUN xmlDtdPtr + xmlCreateIntSubset (xmlDocPtr doc, + const xmlChar *name, + const xmlChar *ExternalID, + const xmlChar *SystemID); +XMLPUBFUN xmlDtdPtr + xmlNewDtd (xmlDocPtr doc, + const xmlChar *name, + const xmlChar *ExternalID, + const xmlChar *SystemID); +XMLPUBFUN xmlDtdPtr + xmlGetIntSubset (const xmlDoc *doc); +XMLPUBFUN void + xmlFreeDtd (xmlDtdPtr cur); +#ifdef LIBXML_LEGACY_ENABLED +XML_DEPRECATED +XMLPUBFUN xmlNsPtr + xmlNewGlobalNs (xmlDocPtr doc, + const xmlChar *href, + const xmlChar *prefix); +#endif /* LIBXML_LEGACY_ENABLED */ +XMLPUBFUN xmlNsPtr + xmlNewNs (xmlNodePtr node, + const xmlChar *href, + const xmlChar *prefix); +XMLPUBFUN void + xmlFreeNs (xmlNsPtr cur); +XMLPUBFUN void + xmlFreeNsList (xmlNsPtr cur); +XMLPUBFUN xmlDocPtr + xmlNewDoc (const xmlChar *version); +XMLPUBFUN void + xmlFreeDoc (xmlDocPtr cur); +XMLPUBFUN xmlAttrPtr + xmlNewDocProp (xmlDocPtr doc, + const xmlChar *name, + const xmlChar *value); +#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED) || \ + defined(LIBXML_SCHEMAS_ENABLED) +XMLPUBFUN xmlAttrPtr + xmlNewProp (xmlNodePtr node, + const xmlChar *name, + const xmlChar *value); +#endif +XMLPUBFUN xmlAttrPtr + xmlNewNsProp (xmlNodePtr node, + xmlNsPtr ns, + const xmlChar *name, + const xmlChar *value); +XMLPUBFUN xmlAttrPtr + xmlNewNsPropEatName (xmlNodePtr node, + xmlNsPtr ns, + xmlChar *name, + const xmlChar *value); +XMLPUBFUN void + xmlFreePropList (xmlAttrPtr cur); +XMLPUBFUN void + xmlFreeProp (xmlAttrPtr cur); +XMLPUBFUN xmlAttrPtr + xmlCopyProp (xmlNodePtr target, + xmlAttrPtr cur); +XMLPUBFUN xmlAttrPtr + xmlCopyPropList (xmlNodePtr target, + xmlAttrPtr cur); +#ifdef LIBXML_TREE_ENABLED +XMLPUBFUN xmlDtdPtr + xmlCopyDtd (xmlDtdPtr dtd); +#endif /* LIBXML_TREE_ENABLED */ +#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) +XMLPUBFUN xmlDocPtr + xmlCopyDoc (xmlDocPtr doc, + int recursive); +#endif /* defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) */ +/* + * Creating new nodes. + */ +XMLPUBFUN xmlNodePtr + xmlNewDocNode (xmlDocPtr doc, + xmlNsPtr ns, + const xmlChar *name, + const xmlChar *content); +XMLPUBFUN xmlNodePtr + xmlNewDocNodeEatName (xmlDocPtr doc, + xmlNsPtr ns, + xmlChar *name, + const xmlChar *content); +XMLPUBFUN xmlNodePtr + xmlNewNode (xmlNsPtr ns, + const xmlChar *name); +XMLPUBFUN xmlNodePtr + xmlNewNodeEatName (xmlNsPtr ns, + xmlChar *name); +#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) +XMLPUBFUN xmlNodePtr + xmlNewChild (xmlNodePtr parent, + xmlNsPtr ns, + const xmlChar *name, + const xmlChar *content); +#endif +XMLPUBFUN xmlNodePtr + xmlNewDocText (const xmlDoc *doc, + const xmlChar *content); +XMLPUBFUN xmlNodePtr + xmlNewText (const xmlChar *content); +XMLPUBFUN xmlNodePtr + xmlNewDocPI (xmlDocPtr doc, + const xmlChar *name, + const xmlChar *content); +XMLPUBFUN xmlNodePtr + xmlNewPI (const xmlChar *name, + const xmlChar *content); +XMLPUBFUN xmlNodePtr + xmlNewDocTextLen (xmlDocPtr doc, + const xmlChar *content, + int len); +XMLPUBFUN xmlNodePtr + xmlNewTextLen (const xmlChar *content, + int len); +XMLPUBFUN xmlNodePtr + xmlNewDocComment (xmlDocPtr doc, + const xmlChar *content); +XMLPUBFUN xmlNodePtr + xmlNewComment (const xmlChar *content); +XMLPUBFUN xmlNodePtr + xmlNewCDataBlock (xmlDocPtr doc, + const xmlChar *content, + int len); +XMLPUBFUN xmlNodePtr + xmlNewCharRef (xmlDocPtr doc, + const xmlChar *name); +XMLPUBFUN xmlNodePtr + xmlNewReference (const xmlDoc *doc, + const xmlChar *name); +XMLPUBFUN xmlNodePtr + xmlCopyNode (xmlNodePtr node, + int recursive); +XMLPUBFUN xmlNodePtr + xmlDocCopyNode (xmlNodePtr node, + xmlDocPtr doc, + int recursive); +XMLPUBFUN xmlNodePtr + xmlDocCopyNodeList (xmlDocPtr doc, + xmlNodePtr node); +XMLPUBFUN xmlNodePtr + xmlCopyNodeList (xmlNodePtr node); +#ifdef LIBXML_TREE_ENABLED +XMLPUBFUN xmlNodePtr + xmlNewTextChild (xmlNodePtr parent, + xmlNsPtr ns, + const xmlChar *name, + const xmlChar *content); +XMLPUBFUN xmlNodePtr + xmlNewDocRawNode (xmlDocPtr doc, + xmlNsPtr ns, + const xmlChar *name, + const xmlChar *content); +XMLPUBFUN xmlNodePtr + xmlNewDocFragment (xmlDocPtr doc); +#endif /* LIBXML_TREE_ENABLED */ + +/* + * Navigating. + */ +XMLPUBFUN long + xmlGetLineNo (const xmlNode *node); +#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED) +XMLPUBFUN xmlChar * + xmlGetNodePath (const xmlNode *node); +#endif /* defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED) */ +XMLPUBFUN xmlNodePtr + xmlDocGetRootElement (const xmlDoc *doc); +XMLPUBFUN xmlNodePtr + xmlGetLastChild (const xmlNode *parent); +XMLPUBFUN int + xmlNodeIsText (const xmlNode *node); +XMLPUBFUN int + xmlIsBlankNode (const xmlNode *node); + +/* + * Changing the structure. + */ +#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_WRITER_ENABLED) +XMLPUBFUN xmlNodePtr + xmlDocSetRootElement (xmlDocPtr doc, + xmlNodePtr root); +#endif /* defined(LIBXML_TREE_ENABLED) || defined(LIBXML_WRITER_ENABLED) */ +#ifdef LIBXML_TREE_ENABLED +XMLPUBFUN void + xmlNodeSetName (xmlNodePtr cur, + const xmlChar *name); +#endif /* LIBXML_TREE_ENABLED */ +XMLPUBFUN xmlNodePtr + xmlAddChild (xmlNodePtr parent, + xmlNodePtr cur); +XMLPUBFUN xmlNodePtr + xmlAddChildList (xmlNodePtr parent, + xmlNodePtr cur); +#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_WRITER_ENABLED) +XMLPUBFUN xmlNodePtr + xmlReplaceNode (xmlNodePtr old, + xmlNodePtr cur); +#endif /* defined(LIBXML_TREE_ENABLED) || defined(LIBXML_WRITER_ENABLED) */ +#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED) || \ + defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED) +XMLPUBFUN xmlNodePtr + xmlAddPrevSibling (xmlNodePtr cur, + xmlNodePtr elem); +#endif /* LIBXML_TREE_ENABLED || LIBXML_HTML_ENABLED || LIBXML_SCHEMAS_ENABLED */ +XMLPUBFUN xmlNodePtr + xmlAddSibling (xmlNodePtr cur, + xmlNodePtr elem); +XMLPUBFUN xmlNodePtr + xmlAddNextSibling (xmlNodePtr cur, + xmlNodePtr elem); +XMLPUBFUN void + xmlUnlinkNode (xmlNodePtr cur); +XMLPUBFUN xmlNodePtr + xmlTextMerge (xmlNodePtr first, + xmlNodePtr second); +XMLPUBFUN int + xmlTextConcat (xmlNodePtr node, + const xmlChar *content, + int len); +XMLPUBFUN void + xmlFreeNodeList (xmlNodePtr cur); +XMLPUBFUN void + xmlFreeNode (xmlNodePtr cur); +XMLPUBFUN int + xmlSetTreeDoc (xmlNodePtr tree, + xmlDocPtr doc); +XMLPUBFUN int + xmlSetListDoc (xmlNodePtr list, + xmlDocPtr doc); +/* + * Namespaces. + */ +XMLPUBFUN xmlNsPtr + xmlSearchNs (xmlDocPtr doc, + xmlNodePtr node, + const xmlChar *nameSpace); +XMLPUBFUN xmlNsPtr + xmlSearchNsByHref (xmlDocPtr doc, + xmlNodePtr node, + const xmlChar *href); +#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || \ + defined(LIBXML_SCHEMAS_ENABLED) +XMLPUBFUN int + xmlGetNsListSafe (const xmlDoc *doc, + const xmlNode *node, + xmlNsPtr **out); +XMLPUBFUN xmlNsPtr * + xmlGetNsList (const xmlDoc *doc, + const xmlNode *node); +#endif /* defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) */ + +XMLPUBFUN void + xmlSetNs (xmlNodePtr node, + xmlNsPtr ns); +XMLPUBFUN xmlNsPtr + xmlCopyNamespace (xmlNsPtr cur); +XMLPUBFUN xmlNsPtr + xmlCopyNamespaceList (xmlNsPtr cur); + +/* + * Changing the content. + */ +#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED) || \ + defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_HTML_ENABLED) +XMLPUBFUN xmlAttrPtr + xmlSetProp (xmlNodePtr node, + const xmlChar *name, + const xmlChar *value); +XMLPUBFUN xmlAttrPtr + xmlSetNsProp (xmlNodePtr node, + xmlNsPtr ns, + const xmlChar *name, + const xmlChar *value); +#endif /* defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED) || \ + defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_HTML_ENABLED) */ +XMLPUBFUN int + xmlNodeGetAttrValue (const xmlNode *node, + const xmlChar *name, + const xmlChar *nsUri, + xmlChar **out); +XMLPUBFUN xmlChar * + xmlGetNoNsProp (const xmlNode *node, + const xmlChar *name); +XMLPUBFUN xmlChar * + xmlGetProp (const xmlNode *node, + const xmlChar *name); +XMLPUBFUN xmlAttrPtr + xmlHasProp (const xmlNode *node, + const xmlChar *name); +XMLPUBFUN xmlAttrPtr + xmlHasNsProp (const xmlNode *node, + const xmlChar *name, + const xmlChar *nameSpace); +XMLPUBFUN xmlChar * + xmlGetNsProp (const xmlNode *node, + const xmlChar *name, + const xmlChar *nameSpace); +XMLPUBFUN xmlNodePtr + xmlStringGetNodeList (const xmlDoc *doc, + const xmlChar *value); +XMLPUBFUN xmlNodePtr + xmlStringLenGetNodeList (const xmlDoc *doc, + const xmlChar *value, + int len); +XMLPUBFUN xmlChar * + xmlNodeListGetString (xmlDocPtr doc, + const xmlNode *list, + int inLine); +#ifdef LIBXML_TREE_ENABLED +XMLPUBFUN xmlChar * + xmlNodeListGetRawString (const xmlDoc *doc, + const xmlNode *list, + int inLine); +#endif /* LIBXML_TREE_ENABLED */ +XMLPUBFUN int + xmlNodeSetContent (xmlNodePtr cur, + const xmlChar *content); +#ifdef LIBXML_TREE_ENABLED +XMLPUBFUN int + xmlNodeSetContentLen (xmlNodePtr cur, + const xmlChar *content, + int len); +#endif /* LIBXML_TREE_ENABLED */ +XMLPUBFUN int + xmlNodeAddContent (xmlNodePtr cur, + const xmlChar *content); +XMLPUBFUN int + xmlNodeAddContentLen (xmlNodePtr cur, + const xmlChar *content, + int len); +XMLPUBFUN xmlChar * + xmlNodeGetContent (const xmlNode *cur); + +XMLPUBFUN int + xmlNodeBufGetContent (xmlBufferPtr buffer, + const xmlNode *cur); +XMLPUBFUN int + xmlBufGetNodeContent (xmlBufPtr buf, + const xmlNode *cur); + +XMLPUBFUN xmlChar * + xmlNodeGetLang (const xmlNode *cur); +XMLPUBFUN int + xmlNodeGetSpacePreserve (const xmlNode *cur); +#ifdef LIBXML_TREE_ENABLED +XMLPUBFUN int + xmlNodeSetLang (xmlNodePtr cur, + const xmlChar *lang); +XMLPUBFUN int + xmlNodeSetSpacePreserve (xmlNodePtr cur, + int val); +#endif /* LIBXML_TREE_ENABLED */ +XMLPUBFUN int + xmlNodeGetBaseSafe (const xmlDoc *doc, + const xmlNode *cur, + xmlChar **baseOut); +XMLPUBFUN xmlChar * + xmlNodeGetBase (const xmlDoc *doc, + const xmlNode *cur); +#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED) +XMLPUBFUN int + xmlNodeSetBase (xmlNodePtr cur, + const xmlChar *uri); +#endif + +/* + * Removing content. + */ +XMLPUBFUN int + xmlRemoveProp (xmlAttrPtr cur); +#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) +XMLPUBFUN int + xmlUnsetNsProp (xmlNodePtr node, + xmlNsPtr ns, + const xmlChar *name); +XMLPUBFUN int + xmlUnsetProp (xmlNodePtr node, + const xmlChar *name); +#endif /* defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) */ + +/* + * Internal, don't use. + */ +XMLPUBFUN void + xmlBufferWriteCHAR (xmlBufferPtr buf, + const xmlChar *string); +XMLPUBFUN void + xmlBufferWriteChar (xmlBufferPtr buf, + const char *string); +XMLPUBFUN void + xmlBufferWriteQuotedString(xmlBufferPtr buf, + const xmlChar *string); + +#ifdef LIBXML_OUTPUT_ENABLED +XMLPUBFUN void xmlAttrSerializeTxtContent(xmlBufferPtr buf, + xmlDocPtr doc, + xmlAttrPtr attr, + const xmlChar *string); +#endif /* LIBXML_OUTPUT_ENABLED */ + +#ifdef LIBXML_TREE_ENABLED +/* + * Namespace handling. + */ +XMLPUBFUN int + xmlReconciliateNs (xmlDocPtr doc, + xmlNodePtr tree); +#endif + +#ifdef LIBXML_OUTPUT_ENABLED +/* + * Saving. + */ +XMLPUBFUN void + xmlDocDumpFormatMemory (xmlDocPtr cur, + xmlChar **mem, + int *size, + int format); +XMLPUBFUN void + xmlDocDumpMemory (xmlDocPtr cur, + xmlChar **mem, + int *size); +XMLPUBFUN void + xmlDocDumpMemoryEnc (xmlDocPtr out_doc, + xmlChar **doc_txt_ptr, + int * doc_txt_len, + const char *txt_encoding); +XMLPUBFUN void + xmlDocDumpFormatMemoryEnc(xmlDocPtr out_doc, + xmlChar **doc_txt_ptr, + int * doc_txt_len, + const char *txt_encoding, + int format); +XMLPUBFUN int + xmlDocFormatDump (FILE *f, + xmlDocPtr cur, + int format); +XMLPUBFUN int + xmlDocDump (FILE *f, + xmlDocPtr cur); +XMLPUBFUN void + xmlElemDump (FILE *f, + xmlDocPtr doc, + xmlNodePtr cur); +XMLPUBFUN int + xmlSaveFile (const char *filename, + xmlDocPtr cur); +XMLPUBFUN int + xmlSaveFormatFile (const char *filename, + xmlDocPtr cur, + int format); +XMLPUBFUN size_t + xmlBufNodeDump (xmlBufPtr buf, + xmlDocPtr doc, + xmlNodePtr cur, + int level, + int format); +XMLPUBFUN int + xmlNodeDump (xmlBufferPtr buf, + xmlDocPtr doc, + xmlNodePtr cur, + int level, + int format); + +XMLPUBFUN int + xmlSaveFileTo (xmlOutputBufferPtr buf, + xmlDocPtr cur, + const char *encoding); +XMLPUBFUN int + xmlSaveFormatFileTo (xmlOutputBufferPtr buf, + xmlDocPtr cur, + const char *encoding, + int format); +XMLPUBFUN void + xmlNodeDumpOutput (xmlOutputBufferPtr buf, + xmlDocPtr doc, + xmlNodePtr cur, + int level, + int format, + const char *encoding); + +XMLPUBFUN int + xmlSaveFormatFileEnc (const char *filename, + xmlDocPtr cur, + const char *encoding, + int format); + +XMLPUBFUN int + xmlSaveFileEnc (const char *filename, + xmlDocPtr cur, + const char *encoding); + +#endif /* LIBXML_OUTPUT_ENABLED */ +/* + * XHTML + */ +XMLPUBFUN int + xmlIsXHTML (const xmlChar *systemID, + const xmlChar *publicID); + +/* + * Compression. + */ +XMLPUBFUN int + xmlGetDocCompressMode (const xmlDoc *doc); +XMLPUBFUN void + xmlSetDocCompressMode (xmlDocPtr doc, + int mode); +XML_DEPRECATED +XMLPUBFUN int + xmlGetCompressMode (void); +XML_DEPRECATED +XMLPUBFUN void + xmlSetCompressMode (int mode); + +/* +* DOM-wrapper helper functions. +*/ +XMLPUBFUN xmlDOMWrapCtxtPtr + xmlDOMWrapNewCtxt (void); +XMLPUBFUN void + xmlDOMWrapFreeCtxt (xmlDOMWrapCtxtPtr ctxt); +XMLPUBFUN int + xmlDOMWrapReconcileNamespaces(xmlDOMWrapCtxtPtr ctxt, + xmlNodePtr elem, + int options); +XMLPUBFUN int + xmlDOMWrapAdoptNode (xmlDOMWrapCtxtPtr ctxt, + xmlDocPtr sourceDoc, + xmlNodePtr node, + xmlDocPtr destDoc, + xmlNodePtr destParent, + int options); +XMLPUBFUN int + xmlDOMWrapRemoveNode (xmlDOMWrapCtxtPtr ctxt, + xmlDocPtr doc, + xmlNodePtr node, + int options); +XMLPUBFUN int + xmlDOMWrapCloneNode (xmlDOMWrapCtxtPtr ctxt, + xmlDocPtr sourceDoc, + xmlNodePtr node, + xmlNodePtr *clonedNode, + xmlDocPtr destDoc, + xmlNodePtr destParent, + int deep, + int options); + +#ifdef LIBXML_TREE_ENABLED +/* + * 5 interfaces from DOM ElementTraversal, but different in entities + * traversal. + */ +XMLPUBFUN unsigned long + xmlChildElementCount (xmlNodePtr parent); +XMLPUBFUN xmlNodePtr + xmlNextElementSibling (xmlNodePtr node); +XMLPUBFUN xmlNodePtr + xmlFirstElementChild (xmlNodePtr parent); +XMLPUBFUN xmlNodePtr + xmlLastElementChild (xmlNodePtr parent); +XMLPUBFUN xmlNodePtr + xmlPreviousElementSibling (xmlNodePtr node); +#endif + +XML_DEPRECATED +XMLPUBFUN xmlRegisterNodeFunc + xmlRegisterNodeDefault (xmlRegisterNodeFunc func); +XML_DEPRECATED +XMLPUBFUN xmlDeregisterNodeFunc + xmlDeregisterNodeDefault (xmlDeregisterNodeFunc func); +XML_DEPRECATED +XMLPUBFUN xmlRegisterNodeFunc + xmlThrDefRegisterNodeDefault(xmlRegisterNodeFunc func); +XML_DEPRECATED +XMLPUBFUN xmlDeregisterNodeFunc + xmlThrDefDeregisterNodeDefault(xmlDeregisterNodeFunc func); + +XML_DEPRECATED XMLPUBFUN xmlBufferAllocationScheme + xmlThrDefBufferAllocScheme (xmlBufferAllocationScheme v); +XML_DEPRECATED XMLPUBFUN int + xmlThrDefDefaultBufferSize (int v); + +#ifdef __cplusplus +} +#endif + +#endif /* __XML_TREE_H__ */ + +#endif /* XML_TREE_INTERNALS */ + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/uri.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/uri.h new file mode 100644 index 0000000..19980b7 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/uri.h @@ -0,0 +1,106 @@ +/** + * Summary: library of generic URI related routines + * Description: library of generic URI related routines + * Implements RFC 2396 + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_URI_H__ +#define __XML_URI_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * xmlURI: + * + * A parsed URI reference. This is a struct containing the various fields + * as described in RFC 2396 but separated for further processing. + * + * Note: query is a deprecated field which is incorrectly unescaped. + * query_raw takes precedence over query if the former is set. + * See: http://mail.gnome.org/archives/xml/2007-April/thread.html#00127 + */ +typedef struct _xmlURI xmlURI; +typedef xmlURI *xmlURIPtr; +struct _xmlURI { + char *scheme; /* the URI scheme */ + char *opaque; /* opaque part */ + char *authority; /* the authority part */ + char *server; /* the server part */ + char *user; /* the user part */ + int port; /* the port number */ + char *path; /* the path string */ + char *query; /* the query string (deprecated - use with caution) */ + char *fragment; /* the fragment identifier */ + int cleanup; /* parsing potentially unclean URI */ + char *query_raw; /* the query string (as it appears in the URI) */ +}; + +/* + * This function is in tree.h: + * xmlChar * xmlNodeGetBase (xmlDocPtr doc, + * xmlNodePtr cur); + */ +XMLPUBFUN xmlURIPtr + xmlCreateURI (void); +XMLPUBFUN int + xmlBuildURISafe (const xmlChar *URI, + const xmlChar *base, + xmlChar **out); +XMLPUBFUN xmlChar * + xmlBuildURI (const xmlChar *URI, + const xmlChar *base); +XMLPUBFUN int + xmlBuildRelativeURISafe (const xmlChar *URI, + const xmlChar *base, + xmlChar **out); +XMLPUBFUN xmlChar * + xmlBuildRelativeURI (const xmlChar *URI, + const xmlChar *base); +XMLPUBFUN xmlURIPtr + xmlParseURI (const char *str); +XMLPUBFUN int + xmlParseURISafe (const char *str, + xmlURIPtr *uri); +XMLPUBFUN xmlURIPtr + xmlParseURIRaw (const char *str, + int raw); +XMLPUBFUN int + xmlParseURIReference (xmlURIPtr uri, + const char *str); +XMLPUBFUN xmlChar * + xmlSaveUri (xmlURIPtr uri); +XMLPUBFUN void + xmlPrintURI (FILE *stream, + xmlURIPtr uri); +XMLPUBFUN xmlChar * + xmlURIEscapeStr (const xmlChar *str, + const xmlChar *list); +XMLPUBFUN char * + xmlURIUnescapeString (const char *str, + int len, + char *target); +XMLPUBFUN int + xmlNormalizeURIPath (char *path); +XMLPUBFUN xmlChar * + xmlURIEscape (const xmlChar *str); +XMLPUBFUN void + xmlFreeURI (xmlURIPtr uri); +XMLPUBFUN xmlChar* + xmlCanonicPath (const xmlChar *path); +XMLPUBFUN xmlChar* + xmlPathToURI (const xmlChar *path); + +#ifdef __cplusplus +} +#endif +#endif /* __XML_URI_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/valid.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/valid.h new file mode 100644 index 0000000..e1698d7 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/valid.h @@ -0,0 +1,477 @@ +/* + * Summary: The DTD validation + * Description: API for the DTD handling and the validity checking + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + + +#ifndef __XML_VALID_H__ +#define __XML_VALID_H__ + +/** DOC_DISABLE */ +#include +#include +#define XML_TREE_INTERNALS +#include +#undef XML_TREE_INTERNALS +#include +#include +#include +/** DOC_ENABLE */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Validation state added for non-determinist content model. + */ +typedef struct _xmlValidState xmlValidState; +typedef xmlValidState *xmlValidStatePtr; + +/** + * xmlValidityErrorFunc: + * @ctx: usually an xmlValidCtxtPtr to a validity error context, + * but comes from ctxt->userData (which normally contains such + * a pointer); ctxt->userData can be changed by the user. + * @msg: the string to format *printf like vararg + * @...: remaining arguments to the format + * + * Callback called when a validity error is found. This is a message + * oriented function similar to an *printf function. + */ +typedef void (*xmlValidityErrorFunc) (void *ctx, + const char *msg, + ...) LIBXML_ATTR_FORMAT(2,3); + +/** + * xmlValidityWarningFunc: + * @ctx: usually an xmlValidCtxtPtr to a validity error context, + * but comes from ctxt->userData (which normally contains such + * a pointer); ctxt->userData can be changed by the user. + * @msg: the string to format *printf like vararg + * @...: remaining arguments to the format + * + * Callback called when a validity warning is found. This is a message + * oriented function similar to an *printf function. + */ +typedef void (*xmlValidityWarningFunc) (void *ctx, + const char *msg, + ...) LIBXML_ATTR_FORMAT(2,3); + +/* + * xmlValidCtxt: + * An xmlValidCtxt is used for error reporting when validating. + */ +typedef struct _xmlValidCtxt xmlValidCtxt; +typedef xmlValidCtxt *xmlValidCtxtPtr; +struct _xmlValidCtxt { + void *userData; /* user specific data block */ + xmlValidityErrorFunc error; /* the callback in case of errors */ + xmlValidityWarningFunc warning; /* the callback in case of warning */ + + /* Node analysis stack used when validating within entities */ + xmlNodePtr node; /* Current parsed Node */ + int nodeNr; /* Depth of the parsing stack */ + int nodeMax; /* Max depth of the parsing stack */ + xmlNodePtr *nodeTab; /* array of nodes */ + + unsigned int flags; /* internal flags */ + xmlDocPtr doc; /* the document */ + int valid; /* temporary validity check result */ + + /* state state used for non-determinist content validation */ + xmlValidState *vstate; /* current state */ + int vstateNr; /* Depth of the validation stack */ + int vstateMax; /* Max depth of the validation stack */ + xmlValidState *vstateTab; /* array of validation states */ + +#ifdef LIBXML_REGEXP_ENABLED + xmlAutomataPtr am; /* the automata */ + xmlAutomataStatePtr state; /* used to build the automata */ +#else + void *am; + void *state; +#endif +}; + +/* + * ALL notation declarations are stored in a table. + * There is one table per DTD. + */ + +typedef struct _xmlHashTable xmlNotationTable; +typedef xmlNotationTable *xmlNotationTablePtr; + +/* + * ALL element declarations are stored in a table. + * There is one table per DTD. + */ + +typedef struct _xmlHashTable xmlElementTable; +typedef xmlElementTable *xmlElementTablePtr; + +/* + * ALL attribute declarations are stored in a table. + * There is one table per DTD. + */ + +typedef struct _xmlHashTable xmlAttributeTable; +typedef xmlAttributeTable *xmlAttributeTablePtr; + +/* + * ALL IDs attributes are stored in a table. + * There is one table per document. + */ + +typedef struct _xmlHashTable xmlIDTable; +typedef xmlIDTable *xmlIDTablePtr; + +/* + * ALL Refs attributes are stored in a table. + * There is one table per document. + */ + +typedef struct _xmlHashTable xmlRefTable; +typedef xmlRefTable *xmlRefTablePtr; + +/* Notation */ +XMLPUBFUN xmlNotationPtr + xmlAddNotationDecl (xmlValidCtxtPtr ctxt, + xmlDtdPtr dtd, + const xmlChar *name, + const xmlChar *PublicID, + const xmlChar *SystemID); +#ifdef LIBXML_TREE_ENABLED +XMLPUBFUN xmlNotationTablePtr + xmlCopyNotationTable (xmlNotationTablePtr table); +#endif /* LIBXML_TREE_ENABLED */ +XMLPUBFUN void + xmlFreeNotationTable (xmlNotationTablePtr table); +#ifdef LIBXML_OUTPUT_ENABLED +XML_DEPRECATED +XMLPUBFUN void + xmlDumpNotationDecl (xmlBufferPtr buf, + xmlNotationPtr nota); +/* XML_DEPRECATED, still used in lxml */ +XMLPUBFUN void + xmlDumpNotationTable (xmlBufferPtr buf, + xmlNotationTablePtr table); +#endif /* LIBXML_OUTPUT_ENABLED */ + +/* Element Content */ +/* the non Doc version are being deprecated */ +XMLPUBFUN xmlElementContentPtr + xmlNewElementContent (const xmlChar *name, + xmlElementContentType type); +XMLPUBFUN xmlElementContentPtr + xmlCopyElementContent (xmlElementContentPtr content); +XMLPUBFUN void + xmlFreeElementContent (xmlElementContentPtr cur); +/* the new versions with doc argument */ +XMLPUBFUN xmlElementContentPtr + xmlNewDocElementContent (xmlDocPtr doc, + const xmlChar *name, + xmlElementContentType type); +XMLPUBFUN xmlElementContentPtr + xmlCopyDocElementContent(xmlDocPtr doc, + xmlElementContentPtr content); +XMLPUBFUN void + xmlFreeDocElementContent(xmlDocPtr doc, + xmlElementContentPtr cur); +XMLPUBFUN void + xmlSnprintfElementContent(char *buf, + int size, + xmlElementContentPtr content, + int englob); +#ifdef LIBXML_OUTPUT_ENABLED +XML_DEPRECATED +XMLPUBFUN void + xmlSprintfElementContent(char *buf, + xmlElementContentPtr content, + int englob); +#endif /* LIBXML_OUTPUT_ENABLED */ + +/* Element */ +XMLPUBFUN xmlElementPtr + xmlAddElementDecl (xmlValidCtxtPtr ctxt, + xmlDtdPtr dtd, + const xmlChar *name, + xmlElementTypeVal type, + xmlElementContentPtr content); +#ifdef LIBXML_TREE_ENABLED +XMLPUBFUN xmlElementTablePtr + xmlCopyElementTable (xmlElementTablePtr table); +#endif /* LIBXML_TREE_ENABLED */ +XMLPUBFUN void + xmlFreeElementTable (xmlElementTablePtr table); +#ifdef LIBXML_OUTPUT_ENABLED +XML_DEPRECATED +XMLPUBFUN void + xmlDumpElementTable (xmlBufferPtr buf, + xmlElementTablePtr table); +XML_DEPRECATED +XMLPUBFUN void + xmlDumpElementDecl (xmlBufferPtr buf, + xmlElementPtr elem); +#endif /* LIBXML_OUTPUT_ENABLED */ + +/* Enumeration */ +XMLPUBFUN xmlEnumerationPtr + xmlCreateEnumeration (const xmlChar *name); +XMLPUBFUN void + xmlFreeEnumeration (xmlEnumerationPtr cur); +#ifdef LIBXML_TREE_ENABLED +XMLPUBFUN xmlEnumerationPtr + xmlCopyEnumeration (xmlEnumerationPtr cur); +#endif /* LIBXML_TREE_ENABLED */ + +/* Attribute */ +XMLPUBFUN xmlAttributePtr + xmlAddAttributeDecl (xmlValidCtxtPtr ctxt, + xmlDtdPtr dtd, + const xmlChar *elem, + const xmlChar *name, + const xmlChar *ns, + xmlAttributeType type, + xmlAttributeDefault def, + const xmlChar *defaultValue, + xmlEnumerationPtr tree); +#ifdef LIBXML_TREE_ENABLED +XMLPUBFUN xmlAttributeTablePtr + xmlCopyAttributeTable (xmlAttributeTablePtr table); +#endif /* LIBXML_TREE_ENABLED */ +XMLPUBFUN void + xmlFreeAttributeTable (xmlAttributeTablePtr table); +#ifdef LIBXML_OUTPUT_ENABLED +XML_DEPRECATED +XMLPUBFUN void + xmlDumpAttributeTable (xmlBufferPtr buf, + xmlAttributeTablePtr table); +XML_DEPRECATED +XMLPUBFUN void + xmlDumpAttributeDecl (xmlBufferPtr buf, + xmlAttributePtr attr); +#endif /* LIBXML_OUTPUT_ENABLED */ + +/* IDs */ +XMLPUBFUN int + xmlAddIDSafe (xmlAttrPtr attr, + const xmlChar *value); +XMLPUBFUN xmlIDPtr + xmlAddID (xmlValidCtxtPtr ctxt, + xmlDocPtr doc, + const xmlChar *value, + xmlAttrPtr attr); +XMLPUBFUN void + xmlFreeIDTable (xmlIDTablePtr table); +XMLPUBFUN xmlAttrPtr + xmlGetID (xmlDocPtr doc, + const xmlChar *ID); +XMLPUBFUN int + xmlIsID (xmlDocPtr doc, + xmlNodePtr elem, + xmlAttrPtr attr); +XMLPUBFUN int + xmlRemoveID (xmlDocPtr doc, + xmlAttrPtr attr); + +/* IDREFs */ +XML_DEPRECATED +XMLPUBFUN xmlRefPtr + xmlAddRef (xmlValidCtxtPtr ctxt, + xmlDocPtr doc, + const xmlChar *value, + xmlAttrPtr attr); +XML_DEPRECATED +XMLPUBFUN void + xmlFreeRefTable (xmlRefTablePtr table); +XML_DEPRECATED +XMLPUBFUN int + xmlIsRef (xmlDocPtr doc, + xmlNodePtr elem, + xmlAttrPtr attr); +XML_DEPRECATED +XMLPUBFUN int + xmlRemoveRef (xmlDocPtr doc, + xmlAttrPtr attr); +XML_DEPRECATED +XMLPUBFUN xmlListPtr + xmlGetRefs (xmlDocPtr doc, + const xmlChar *ID); + +/** + * The public function calls related to validity checking. + */ +#ifdef LIBXML_VALID_ENABLED +/* Allocate/Release Validation Contexts */ +XMLPUBFUN xmlValidCtxtPtr + xmlNewValidCtxt(void); +XMLPUBFUN void + xmlFreeValidCtxt(xmlValidCtxtPtr); + +XML_DEPRECATED +XMLPUBFUN int + xmlValidateRoot (xmlValidCtxtPtr ctxt, + xmlDocPtr doc); +XML_DEPRECATED +XMLPUBFUN int + xmlValidateElementDecl (xmlValidCtxtPtr ctxt, + xmlDocPtr doc, + xmlElementPtr elem); +XML_DEPRECATED +XMLPUBFUN xmlChar * + xmlValidNormalizeAttributeValue(xmlDocPtr doc, + xmlNodePtr elem, + const xmlChar *name, + const xmlChar *value); +XML_DEPRECATED +XMLPUBFUN xmlChar * + xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, + xmlDocPtr doc, + xmlNodePtr elem, + const xmlChar *name, + const xmlChar *value); +XML_DEPRECATED +XMLPUBFUN int + xmlValidateAttributeDecl(xmlValidCtxtPtr ctxt, + xmlDocPtr doc, + xmlAttributePtr attr); +XML_DEPRECATED +XMLPUBFUN int + xmlValidateAttributeValue(xmlAttributeType type, + const xmlChar *value); +XML_DEPRECATED +XMLPUBFUN int + xmlValidateNotationDecl (xmlValidCtxtPtr ctxt, + xmlDocPtr doc, + xmlNotationPtr nota); +XMLPUBFUN int + xmlValidateDtd (xmlValidCtxtPtr ctxt, + xmlDocPtr doc, + xmlDtdPtr dtd); +XML_DEPRECATED +XMLPUBFUN int + xmlValidateDtdFinal (xmlValidCtxtPtr ctxt, + xmlDocPtr doc); +XMLPUBFUN int + xmlValidateDocument (xmlValidCtxtPtr ctxt, + xmlDocPtr doc); +XMLPUBFUN int + xmlValidateElement (xmlValidCtxtPtr ctxt, + xmlDocPtr doc, + xmlNodePtr elem); +XML_DEPRECATED +XMLPUBFUN int + xmlValidateOneElement (xmlValidCtxtPtr ctxt, + xmlDocPtr doc, + xmlNodePtr elem); +XML_DEPRECATED +XMLPUBFUN int + xmlValidateOneAttribute (xmlValidCtxtPtr ctxt, + xmlDocPtr doc, + xmlNodePtr elem, + xmlAttrPtr attr, + const xmlChar *value); +XML_DEPRECATED +XMLPUBFUN int + xmlValidateOneNamespace (xmlValidCtxtPtr ctxt, + xmlDocPtr doc, + xmlNodePtr elem, + const xmlChar *prefix, + xmlNsPtr ns, + const xmlChar *value); +XML_DEPRECATED +XMLPUBFUN int + xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt, + xmlDocPtr doc); +#endif /* LIBXML_VALID_ENABLED */ + +#if defined(LIBXML_VALID_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) +XML_DEPRECATED +XMLPUBFUN int + xmlValidateNotationUse (xmlValidCtxtPtr ctxt, + xmlDocPtr doc, + const xmlChar *notationName); +#endif /* LIBXML_VALID_ENABLED or LIBXML_SCHEMAS_ENABLED */ + +XMLPUBFUN int + xmlIsMixedElement (xmlDocPtr doc, + const xmlChar *name); +XMLPUBFUN xmlAttributePtr + xmlGetDtdAttrDesc (xmlDtdPtr dtd, + const xmlChar *elem, + const xmlChar *name); +XMLPUBFUN xmlAttributePtr + xmlGetDtdQAttrDesc (xmlDtdPtr dtd, + const xmlChar *elem, + const xmlChar *name, + const xmlChar *prefix); +XMLPUBFUN xmlNotationPtr + xmlGetDtdNotationDesc (xmlDtdPtr dtd, + const xmlChar *name); +XMLPUBFUN xmlElementPtr + xmlGetDtdQElementDesc (xmlDtdPtr dtd, + const xmlChar *name, + const xmlChar *prefix); +XMLPUBFUN xmlElementPtr + xmlGetDtdElementDesc (xmlDtdPtr dtd, + const xmlChar *name); + +#ifdef LIBXML_VALID_ENABLED + +XMLPUBFUN int + xmlValidGetPotentialChildren(xmlElementContent *ctree, + const xmlChar **names, + int *len, + int max); + +XMLPUBFUN int + xmlValidGetValidElements(xmlNode *prev, + xmlNode *next, + const xmlChar **names, + int max); +XMLPUBFUN int + xmlValidateNameValue (const xmlChar *value); +XMLPUBFUN int + xmlValidateNamesValue (const xmlChar *value); +XMLPUBFUN int + xmlValidateNmtokenValue (const xmlChar *value); +XMLPUBFUN int + xmlValidateNmtokensValue(const xmlChar *value); + +#ifdef LIBXML_REGEXP_ENABLED +/* + * Validation based on the regexp support + */ +XML_DEPRECATED +XMLPUBFUN int + xmlValidBuildContentModel(xmlValidCtxtPtr ctxt, + xmlElementPtr elem); + +XML_DEPRECATED +XMLPUBFUN int + xmlValidatePushElement (xmlValidCtxtPtr ctxt, + xmlDocPtr doc, + xmlNodePtr elem, + const xmlChar *qname); +XML_DEPRECATED +XMLPUBFUN int + xmlValidatePushCData (xmlValidCtxtPtr ctxt, + const xmlChar *data, + int len); +XML_DEPRECATED +XMLPUBFUN int + xmlValidatePopElement (xmlValidCtxtPtr ctxt, + xmlDocPtr doc, + xmlNodePtr elem, + const xmlChar *qname); +#endif /* LIBXML_REGEXP_ENABLED */ +#endif /* LIBXML_VALID_ENABLED */ +#ifdef __cplusplus +} +#endif +#endif /* __XML_VALID_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xinclude.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xinclude.h new file mode 100644 index 0000000..71fa4c2 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xinclude.h @@ -0,0 +1,136 @@ +/* + * Summary: implementation of XInclude + * Description: API to handle XInclude processing, + * implements the + * World Wide Web Consortium Last Call Working Draft 10 November 2003 + * http://www.w3.org/TR/2003/WD-xinclude-20031110 + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_XINCLUDE_H__ +#define __XML_XINCLUDE_H__ + +#include +#include +#include + +#ifdef LIBXML_XINCLUDE_ENABLED + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * XINCLUDE_NS: + * + * Macro defining the Xinclude namespace: http://www.w3.org/2003/XInclude + */ +#define XINCLUDE_NS (const xmlChar *) "http://www.w3.org/2003/XInclude" +/** + * XINCLUDE_OLD_NS: + * + * Macro defining the draft Xinclude namespace: http://www.w3.org/2001/XInclude + */ +#define XINCLUDE_OLD_NS (const xmlChar *) "http://www.w3.org/2001/XInclude" +/** + * XINCLUDE_NODE: + * + * Macro defining "include" + */ +#define XINCLUDE_NODE (const xmlChar *) "include" +/** + * XINCLUDE_FALLBACK: + * + * Macro defining "fallback" + */ +#define XINCLUDE_FALLBACK (const xmlChar *) "fallback" +/** + * XINCLUDE_HREF: + * + * Macro defining "href" + */ +#define XINCLUDE_HREF (const xmlChar *) "href" +/** + * XINCLUDE_PARSE: + * + * Macro defining "parse" + */ +#define XINCLUDE_PARSE (const xmlChar *) "parse" +/** + * XINCLUDE_PARSE_XML: + * + * Macro defining "xml" + */ +#define XINCLUDE_PARSE_XML (const xmlChar *) "xml" +/** + * XINCLUDE_PARSE_TEXT: + * + * Macro defining "text" + */ +#define XINCLUDE_PARSE_TEXT (const xmlChar *) "text" +/** + * XINCLUDE_PARSE_ENCODING: + * + * Macro defining "encoding" + */ +#define XINCLUDE_PARSE_ENCODING (const xmlChar *) "encoding" +/** + * XINCLUDE_PARSE_XPOINTER: + * + * Macro defining "xpointer" + */ +#define XINCLUDE_PARSE_XPOINTER (const xmlChar *) "xpointer" + +typedef struct _xmlXIncludeCtxt xmlXIncludeCtxt; +typedef xmlXIncludeCtxt *xmlXIncludeCtxtPtr; + +/* + * standalone processing + */ +XMLPUBFUN int + xmlXIncludeProcess (xmlDocPtr doc); +XMLPUBFUN int + xmlXIncludeProcessFlags (xmlDocPtr doc, + int flags); +XMLPUBFUN int + xmlXIncludeProcessFlagsData(xmlDocPtr doc, + int flags, + void *data); +XMLPUBFUN int + xmlXIncludeProcessTreeFlagsData(xmlNodePtr tree, + int flags, + void *data); +XMLPUBFUN int + xmlXIncludeProcessTree (xmlNodePtr tree); +XMLPUBFUN int + xmlXIncludeProcessTreeFlags(xmlNodePtr tree, + int flags); +/* + * contextual processing + */ +XMLPUBFUN xmlXIncludeCtxtPtr + xmlXIncludeNewContext (xmlDocPtr doc); +XMLPUBFUN int + xmlXIncludeSetFlags (xmlXIncludeCtxtPtr ctxt, + int flags); +XMLPUBFUN void + xmlXIncludeSetErrorHandler(xmlXIncludeCtxtPtr ctxt, + xmlStructuredErrorFunc handler, + void *data); +XMLPUBFUN int + xmlXIncludeGetLastError (xmlXIncludeCtxtPtr ctxt); +XMLPUBFUN void + xmlXIncludeFreeContext (xmlXIncludeCtxtPtr ctxt); +XMLPUBFUN int + xmlXIncludeProcessNode (xmlXIncludeCtxtPtr ctxt, + xmlNodePtr tree); +#ifdef __cplusplus +} +#endif + +#endif /* LIBXML_XINCLUDE_ENABLED */ + +#endif /* __XML_XINCLUDE_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xlink.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xlink.h new file mode 100644 index 0000000..1065736 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xlink.h @@ -0,0 +1,189 @@ +/* + * Summary: unfinished XLink detection module + * Description: unfinished XLink detection module + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_XLINK_H__ +#define __XML_XLINK_H__ + +#include +#include + +#ifdef LIBXML_XPTR_ENABLED + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Various defines for the various Link properties. + * + * NOTE: the link detection layer will try to resolve QName expansion + * of namespaces. If "foo" is the prefix for "http://foo.com/" + * then the link detection layer will expand role="foo:myrole" + * to "http://foo.com/:myrole". + * NOTE: the link detection layer will expand URI-References found on + * href attributes by using the base mechanism if found. + */ +typedef xmlChar *xlinkHRef; +typedef xmlChar *xlinkRole; +typedef xmlChar *xlinkTitle; + +typedef enum { + XLINK_TYPE_NONE = 0, + XLINK_TYPE_SIMPLE, + XLINK_TYPE_EXTENDED, + XLINK_TYPE_EXTENDED_SET +} xlinkType; + +typedef enum { + XLINK_SHOW_NONE = 0, + XLINK_SHOW_NEW, + XLINK_SHOW_EMBED, + XLINK_SHOW_REPLACE +} xlinkShow; + +typedef enum { + XLINK_ACTUATE_NONE = 0, + XLINK_ACTUATE_AUTO, + XLINK_ACTUATE_ONREQUEST +} xlinkActuate; + +/** + * xlinkNodeDetectFunc: + * @ctx: user data pointer + * @node: the node to check + * + * This is the prototype for the link detection routine. + * It calls the default link detection callbacks upon link detection. + */ +typedef void (*xlinkNodeDetectFunc) (void *ctx, xmlNodePtr node); + +/* + * The link detection module interact with the upper layers using + * a set of callback registered at parsing time. + */ + +/** + * xlinkSimpleLinkFunk: + * @ctx: user data pointer + * @node: the node carrying the link + * @href: the target of the link + * @role: the role string + * @title: the link title + * + * This is the prototype for a simple link detection callback. + */ +typedef void +(*xlinkSimpleLinkFunk) (void *ctx, + xmlNodePtr node, + const xlinkHRef href, + const xlinkRole role, + const xlinkTitle title); + +/** + * xlinkExtendedLinkFunk: + * @ctx: user data pointer + * @node: the node carrying the link + * @nbLocators: the number of locators detected on the link + * @hrefs: pointer to the array of locator hrefs + * @roles: pointer to the array of locator roles + * @nbArcs: the number of arcs detected on the link + * @from: pointer to the array of source roles found on the arcs + * @to: pointer to the array of target roles found on the arcs + * @show: array of values for the show attributes found on the arcs + * @actuate: array of values for the actuate attributes found on the arcs + * @nbTitles: the number of titles detected on the link + * @title: array of titles detected on the link + * @langs: array of xml:lang values for the titles + * + * This is the prototype for a extended link detection callback. + */ +typedef void +(*xlinkExtendedLinkFunk)(void *ctx, + xmlNodePtr node, + int nbLocators, + const xlinkHRef *hrefs, + const xlinkRole *roles, + int nbArcs, + const xlinkRole *from, + const xlinkRole *to, + xlinkShow *show, + xlinkActuate *actuate, + int nbTitles, + const xlinkTitle *titles, + const xmlChar **langs); + +/** + * xlinkExtendedLinkSetFunk: + * @ctx: user data pointer + * @node: the node carrying the link + * @nbLocators: the number of locators detected on the link + * @hrefs: pointer to the array of locator hrefs + * @roles: pointer to the array of locator roles + * @nbTitles: the number of titles detected on the link + * @title: array of titles detected on the link + * @langs: array of xml:lang values for the titles + * + * This is the prototype for a extended link set detection callback. + */ +typedef void +(*xlinkExtendedLinkSetFunk) (void *ctx, + xmlNodePtr node, + int nbLocators, + const xlinkHRef *hrefs, + const xlinkRole *roles, + int nbTitles, + const xlinkTitle *titles, + const xmlChar **langs); + +/** + * This is the structure containing a set of Links detection callbacks. + * + * There is no default xlink callbacks, if one want to get link + * recognition activated, those call backs must be provided before parsing. + */ +typedef struct _xlinkHandler xlinkHandler; +typedef xlinkHandler *xlinkHandlerPtr; +struct _xlinkHandler { + xlinkSimpleLinkFunk simple; + xlinkExtendedLinkFunk extended; + xlinkExtendedLinkSetFunk set; +}; + +/* + * The default detection routine, can be overridden, they call the default + * detection callbacks. + */ + +XMLPUBFUN xlinkNodeDetectFunc + xlinkGetDefaultDetect (void); +XMLPUBFUN void + xlinkSetDefaultDetect (xlinkNodeDetectFunc func); + +/* + * Routines to set/get the default handlers. + */ +XMLPUBFUN xlinkHandlerPtr + xlinkGetDefaultHandler (void); +XMLPUBFUN void + xlinkSetDefaultHandler (xlinkHandlerPtr handler); + +/* + * Link detection module itself. + */ +XMLPUBFUN xlinkType + xlinkIsLink (xmlDocPtr doc, + xmlNodePtr node); + +#ifdef __cplusplus +} +#endif + +#endif /* LIBXML_XPTR_ENABLED */ + +#endif /* __XML_XLINK_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlIO.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlIO.h new file mode 100644 index 0000000..e950773 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlIO.h @@ -0,0 +1,438 @@ +/* + * Summary: interface for the I/O interfaces used by the parser + * Description: interface for the I/O interfaces used by the parser + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_IO_H__ +#define __XML_IO_H__ + +/** DOC_DISABLE */ +#include +#include +#include +#define XML_TREE_INTERNALS +#include +#undef XML_TREE_INTERNALS +/** DOC_ENABLE */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Those are the functions and datatypes for the parser input + * I/O structures. + */ + +/** + * xmlInputMatchCallback: + * @filename: the filename or URI + * + * Callback used in the I/O Input API to detect if the current handler + * can provide input functionality for this resource. + * + * Returns 1 if yes and 0 if another Input module should be used + */ +typedef int (*xmlInputMatchCallback) (char const *filename); +/** + * xmlInputOpenCallback: + * @filename: the filename or URI + * + * Callback used in the I/O Input API to open the resource + * + * Returns an Input context or NULL in case or error + */ +typedef void * (*xmlInputOpenCallback) (char const *filename); +/** + * xmlInputReadCallback: + * @context: an Input context + * @buffer: the buffer to store data read + * @len: the length of the buffer in bytes + * + * Callback used in the I/O Input API to read the resource + * + * Returns the number of bytes read or -1 in case of error + */ +typedef int (*xmlInputReadCallback) (void * context, char * buffer, int len); +/** + * xmlInputCloseCallback: + * @context: an Input context + * + * Callback used in the I/O Input API to close the resource + * + * Returns 0 or -1 in case of error + */ +typedef int (*xmlInputCloseCallback) (void * context); + +#ifdef LIBXML_OUTPUT_ENABLED +/* + * Those are the functions and datatypes for the library output + * I/O structures. + */ + +/** + * xmlOutputMatchCallback: + * @filename: the filename or URI + * + * Callback used in the I/O Output API to detect if the current handler + * can provide output functionality for this resource. + * + * Returns 1 if yes and 0 if another Output module should be used + */ +typedef int (*xmlOutputMatchCallback) (char const *filename); +/** + * xmlOutputOpenCallback: + * @filename: the filename or URI + * + * Callback used in the I/O Output API to open the resource + * + * Returns an Output context or NULL in case or error + */ +typedef void * (*xmlOutputOpenCallback) (char const *filename); +/** + * xmlOutputWriteCallback: + * @context: an Output context + * @buffer: the buffer of data to write + * @len: the length of the buffer in bytes + * + * Callback used in the I/O Output API to write to the resource + * + * Returns the number of bytes written or -1 in case of error + */ +typedef int (*xmlOutputWriteCallback) (void * context, const char * buffer, + int len); +/** + * xmlOutputCloseCallback: + * @context: an Output context + * + * Callback used in the I/O Output API to close the resource + * + * Returns 0 or -1 in case of error + */ +typedef int (*xmlOutputCloseCallback) (void * context); +#endif /* LIBXML_OUTPUT_ENABLED */ + +/** + * xmlParserInputBufferCreateFilenameFunc: + * @URI: the URI to read from + * @enc: the requested source encoding + * + * Signature for the function doing the lookup for a suitable input method + * corresponding to an URI. + * + * Returns the new xmlParserInputBufferPtr in case of success or NULL if no + * method was found. + */ +typedef xmlParserInputBufferPtr +(*xmlParserInputBufferCreateFilenameFunc)(const char *URI, xmlCharEncoding enc); + +/** + * xmlOutputBufferCreateFilenameFunc: + * @URI: the URI to write to + * @enc: the requested target encoding + * + * Signature for the function doing the lookup for a suitable output method + * corresponding to an URI. + * + * Returns the new xmlOutputBufferPtr in case of success or NULL if no + * method was found. + */ +typedef xmlOutputBufferPtr +(*xmlOutputBufferCreateFilenameFunc)(const char *URI, + xmlCharEncodingHandlerPtr encoder, int compression); + +struct _xmlParserInputBuffer { + void* context; + xmlInputReadCallback readcallback; + xmlInputCloseCallback closecallback; + + xmlCharEncodingHandlerPtr encoder; /* I18N conversions to UTF-8 */ + + xmlBufPtr buffer; /* Local buffer encoded in UTF-8 */ + xmlBufPtr raw; /* if encoder != NULL buffer for raw input */ + int compressed; /* -1=unknown, 0=not compressed, 1=compressed */ + int error; + unsigned long rawconsumed;/* amount consumed from raw */ +}; + + +#ifdef LIBXML_OUTPUT_ENABLED +struct _xmlOutputBuffer { + void* context; + xmlOutputWriteCallback writecallback; + xmlOutputCloseCallback closecallback; + + xmlCharEncodingHandlerPtr encoder; /* I18N conversions to UTF-8 */ + + xmlBufPtr buffer; /* Local buffer encoded in UTF-8 or ISOLatin */ + xmlBufPtr conv; /* if encoder != NULL buffer for output */ + int written; /* total number of byte written */ + int error; +}; +#endif /* LIBXML_OUTPUT_ENABLED */ + +/** DOC_DISABLE */ +#define XML_GLOBALS_IO \ + XML_OP(xmlParserInputBufferCreateFilenameValue, \ + xmlParserInputBufferCreateFilenameFunc, XML_DEPRECATED) \ + XML_OP(xmlOutputBufferCreateFilenameValue, \ + xmlOutputBufferCreateFilenameFunc, XML_DEPRECATED) + +#define XML_OP XML_DECLARE_GLOBAL +XML_GLOBALS_IO +#undef XML_OP + +#if defined(LIBXML_THREAD_ENABLED) && !defined(XML_GLOBALS_NO_REDEFINITION) + #define xmlParserInputBufferCreateFilenameValue \ + XML_GLOBAL_MACRO(xmlParserInputBufferCreateFilenameValue) + #define xmlOutputBufferCreateFilenameValue \ + XML_GLOBAL_MACRO(xmlOutputBufferCreateFilenameValue) +#endif +/** DOC_ENABLE */ + +/* + * Interfaces for input + */ +XMLPUBFUN void + xmlCleanupInputCallbacks (void); + +XMLPUBFUN int + xmlPopInputCallbacks (void); + +XMLPUBFUN void + xmlRegisterDefaultInputCallbacks (void); +XMLPUBFUN xmlParserInputBufferPtr + xmlAllocParserInputBuffer (xmlCharEncoding enc); + +XMLPUBFUN xmlParserInputBufferPtr + xmlParserInputBufferCreateFilename (const char *URI, + xmlCharEncoding enc); +XMLPUBFUN xmlParserInputBufferPtr + xmlParserInputBufferCreateFile (FILE *file, + xmlCharEncoding enc); +XMLPUBFUN xmlParserInputBufferPtr + xmlParserInputBufferCreateFd (int fd, + xmlCharEncoding enc); +XMLPUBFUN xmlParserInputBufferPtr + xmlParserInputBufferCreateMem (const char *mem, int size, + xmlCharEncoding enc); +XMLPUBFUN xmlParserInputBufferPtr + xmlParserInputBufferCreateStatic (const char *mem, int size, + xmlCharEncoding enc); +XMLPUBFUN xmlParserInputBufferPtr + xmlParserInputBufferCreateIO (xmlInputReadCallback ioread, + xmlInputCloseCallback ioclose, + void *ioctx, + xmlCharEncoding enc); +XMLPUBFUN int + xmlParserInputBufferRead (xmlParserInputBufferPtr in, + int len); +XMLPUBFUN int + xmlParserInputBufferGrow (xmlParserInputBufferPtr in, + int len); +XMLPUBFUN int + xmlParserInputBufferPush (xmlParserInputBufferPtr in, + int len, + const char *buf); +XMLPUBFUN void + xmlFreeParserInputBuffer (xmlParserInputBufferPtr in); +XMLPUBFUN char * + xmlParserGetDirectory (const char *filename); + +XMLPUBFUN int + xmlRegisterInputCallbacks (xmlInputMatchCallback matchFunc, + xmlInputOpenCallback openFunc, + xmlInputReadCallback readFunc, + xmlInputCloseCallback closeFunc); + +XMLPUBFUN xmlParserInputBufferPtr + __xmlParserInputBufferCreateFilename(const char *URI, + xmlCharEncoding enc); + +#ifdef LIBXML_OUTPUT_ENABLED +/* + * Interfaces for output + */ +XMLPUBFUN void + xmlCleanupOutputCallbacks (void); +XMLPUBFUN int + xmlPopOutputCallbacks (void); +XMLPUBFUN void + xmlRegisterDefaultOutputCallbacks(void); +XMLPUBFUN xmlOutputBufferPtr + xmlAllocOutputBuffer (xmlCharEncodingHandlerPtr encoder); + +XMLPUBFUN xmlOutputBufferPtr + xmlOutputBufferCreateFilename (const char *URI, + xmlCharEncodingHandlerPtr encoder, + int compression); + +XMLPUBFUN xmlOutputBufferPtr + xmlOutputBufferCreateFile (FILE *file, + xmlCharEncodingHandlerPtr encoder); + +XMLPUBFUN xmlOutputBufferPtr + xmlOutputBufferCreateBuffer (xmlBufferPtr buffer, + xmlCharEncodingHandlerPtr encoder); + +XMLPUBFUN xmlOutputBufferPtr + xmlOutputBufferCreateFd (int fd, + xmlCharEncodingHandlerPtr encoder); + +XMLPUBFUN xmlOutputBufferPtr + xmlOutputBufferCreateIO (xmlOutputWriteCallback iowrite, + xmlOutputCloseCallback ioclose, + void *ioctx, + xmlCharEncodingHandlerPtr encoder); + +/* Couple of APIs to get the output without digging into the buffers */ +XMLPUBFUN const xmlChar * + xmlOutputBufferGetContent (xmlOutputBufferPtr out); +XMLPUBFUN size_t + xmlOutputBufferGetSize (xmlOutputBufferPtr out); + +XMLPUBFUN int + xmlOutputBufferWrite (xmlOutputBufferPtr out, + int len, + const char *buf); +XMLPUBFUN int + xmlOutputBufferWriteString (xmlOutputBufferPtr out, + const char *str); +XMLPUBFUN int + xmlOutputBufferWriteEscape (xmlOutputBufferPtr out, + const xmlChar *str, + xmlCharEncodingOutputFunc escaping); + +XMLPUBFUN int + xmlOutputBufferFlush (xmlOutputBufferPtr out); +XMLPUBFUN int + xmlOutputBufferClose (xmlOutputBufferPtr out); + +XMLPUBFUN int + xmlRegisterOutputCallbacks (xmlOutputMatchCallback matchFunc, + xmlOutputOpenCallback openFunc, + xmlOutputWriteCallback writeFunc, + xmlOutputCloseCallback closeFunc); + +XMLPUBFUN xmlOutputBufferPtr + __xmlOutputBufferCreateFilename(const char *URI, + xmlCharEncodingHandlerPtr encoder, + int compression); + +#ifdef LIBXML_HTTP_ENABLED +/* This function only exists if HTTP support built into the library */ +XML_DEPRECATED +XMLPUBFUN void + xmlRegisterHTTPPostCallbacks (void ); +#endif /* LIBXML_HTTP_ENABLED */ + +#endif /* LIBXML_OUTPUT_ENABLED */ + +XML_DEPRECATED +XMLPUBFUN xmlParserInputPtr + xmlCheckHTTPInput (xmlParserCtxtPtr ctxt, + xmlParserInputPtr ret); + +/* + * A predefined entity loader disabling network accesses + */ +XMLPUBFUN xmlParserInputPtr + xmlNoNetExternalEntityLoader (const char *URL, + const char *ID, + xmlParserCtxtPtr ctxt); + +XML_DEPRECATED +XMLPUBFUN xmlChar * + xmlNormalizeWindowsPath (const xmlChar *path); + +XML_DEPRECATED +XMLPUBFUN int + xmlCheckFilename (const char *path); +/** + * Default 'file://' protocol callbacks + */ +XML_DEPRECATED +XMLPUBFUN int + xmlFileMatch (const char *filename); +XML_DEPRECATED +XMLPUBFUN void * + xmlFileOpen (const char *filename); +XML_DEPRECATED +XMLPUBFUN int + xmlFileRead (void * context, + char * buffer, + int len); +XML_DEPRECATED +XMLPUBFUN int + xmlFileClose (void * context); + +/** + * Default 'http://' protocol callbacks + */ +#ifdef LIBXML_HTTP_ENABLED +XML_DEPRECATED +XMLPUBFUN int + xmlIOHTTPMatch (const char *filename); +XML_DEPRECATED +XMLPUBFUN void * + xmlIOHTTPOpen (const char *filename); +#ifdef LIBXML_OUTPUT_ENABLED +XML_DEPRECATED +XMLPUBFUN void * + xmlIOHTTPOpenW (const char * post_uri, + int compression ); +#endif /* LIBXML_OUTPUT_ENABLED */ +XML_DEPRECATED +XMLPUBFUN int + xmlIOHTTPRead (void * context, + char * buffer, + int len); +XML_DEPRECATED +XMLPUBFUN int + xmlIOHTTPClose (void * context); +#endif /* LIBXML_HTTP_ENABLED */ + +/** + * Default 'ftp://' protocol callbacks + */ +#if defined(LIBXML_FTP_ENABLED) +XML_DEPRECATED +XMLPUBFUN int + xmlIOFTPMatch (const char *filename); +XML_DEPRECATED +XMLPUBFUN void * + xmlIOFTPOpen (const char *filename); +XML_DEPRECATED +XMLPUBFUN int + xmlIOFTPRead (void * context, + char * buffer, + int len); +XML_DEPRECATED +XMLPUBFUN int + xmlIOFTPClose (void * context); +#endif /* defined(LIBXML_FTP_ENABLED) */ + +XMLPUBFUN xmlParserInputBufferCreateFilenameFunc + xmlParserInputBufferCreateFilenameDefault( + xmlParserInputBufferCreateFilenameFunc func); +XMLPUBFUN xmlOutputBufferCreateFilenameFunc + xmlOutputBufferCreateFilenameDefault( + xmlOutputBufferCreateFilenameFunc func); +XML_DEPRECATED +XMLPUBFUN xmlOutputBufferCreateFilenameFunc + xmlThrDefOutputBufferCreateFilenameDefault( + xmlOutputBufferCreateFilenameFunc func); +XML_DEPRECATED +XMLPUBFUN xmlParserInputBufferCreateFilenameFunc + xmlThrDefParserInputBufferCreateFilenameDefault( + xmlParserInputBufferCreateFilenameFunc func); + +#ifdef __cplusplus +} +#endif + +#endif /* __XML_IO_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlautomata.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlautomata.h new file mode 100644 index 0000000..ea38eb3 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlautomata.h @@ -0,0 +1,146 @@ +/* + * Summary: API to build regexp automata + * Description: the API to build regexp automata + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_AUTOMATA_H__ +#define __XML_AUTOMATA_H__ + +#include + +#ifdef LIBXML_REGEXP_ENABLED +#ifdef LIBXML_AUTOMATA_ENABLED + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * xmlAutomataPtr: + * + * A libxml automata description, It can be compiled into a regexp + */ +typedef struct _xmlAutomata xmlAutomata; +typedef xmlAutomata *xmlAutomataPtr; + +/** + * xmlAutomataStatePtr: + * + * A state int the automata description, + */ +typedef struct _xmlAutomataState xmlAutomataState; +typedef xmlAutomataState *xmlAutomataStatePtr; + +/* + * Building API + */ +XMLPUBFUN xmlAutomataPtr + xmlNewAutomata (void); +XMLPUBFUN void + xmlFreeAutomata (xmlAutomataPtr am); + +XMLPUBFUN xmlAutomataStatePtr + xmlAutomataGetInitState (xmlAutomataPtr am); +XMLPUBFUN int + xmlAutomataSetFinalState (xmlAutomataPtr am, + xmlAutomataStatePtr state); +XMLPUBFUN xmlAutomataStatePtr + xmlAutomataNewState (xmlAutomataPtr am); +XMLPUBFUN xmlAutomataStatePtr + xmlAutomataNewTransition (xmlAutomataPtr am, + xmlAutomataStatePtr from, + xmlAutomataStatePtr to, + const xmlChar *token, + void *data); +XMLPUBFUN xmlAutomataStatePtr + xmlAutomataNewTransition2 (xmlAutomataPtr am, + xmlAutomataStatePtr from, + xmlAutomataStatePtr to, + const xmlChar *token, + const xmlChar *token2, + void *data); +XMLPUBFUN xmlAutomataStatePtr + xmlAutomataNewNegTrans (xmlAutomataPtr am, + xmlAutomataStatePtr from, + xmlAutomataStatePtr to, + const xmlChar *token, + const xmlChar *token2, + void *data); + +XMLPUBFUN xmlAutomataStatePtr + xmlAutomataNewCountTrans (xmlAutomataPtr am, + xmlAutomataStatePtr from, + xmlAutomataStatePtr to, + const xmlChar *token, + int min, + int max, + void *data); +XMLPUBFUN xmlAutomataStatePtr + xmlAutomataNewCountTrans2 (xmlAutomataPtr am, + xmlAutomataStatePtr from, + xmlAutomataStatePtr to, + const xmlChar *token, + const xmlChar *token2, + int min, + int max, + void *data); +XMLPUBFUN xmlAutomataStatePtr + xmlAutomataNewOnceTrans (xmlAutomataPtr am, + xmlAutomataStatePtr from, + xmlAutomataStatePtr to, + const xmlChar *token, + int min, + int max, + void *data); +XMLPUBFUN xmlAutomataStatePtr + xmlAutomataNewOnceTrans2 (xmlAutomataPtr am, + xmlAutomataStatePtr from, + xmlAutomataStatePtr to, + const xmlChar *token, + const xmlChar *token2, + int min, + int max, + void *data); +XMLPUBFUN xmlAutomataStatePtr + xmlAutomataNewAllTrans (xmlAutomataPtr am, + xmlAutomataStatePtr from, + xmlAutomataStatePtr to, + int lax); +XMLPUBFUN xmlAutomataStatePtr + xmlAutomataNewEpsilon (xmlAutomataPtr am, + xmlAutomataStatePtr from, + xmlAutomataStatePtr to); +XMLPUBFUN xmlAutomataStatePtr + xmlAutomataNewCountedTrans (xmlAutomataPtr am, + xmlAutomataStatePtr from, + xmlAutomataStatePtr to, + int counter); +XMLPUBFUN xmlAutomataStatePtr + xmlAutomataNewCounterTrans (xmlAutomataPtr am, + xmlAutomataStatePtr from, + xmlAutomataStatePtr to, + int counter); +XMLPUBFUN int + xmlAutomataNewCounter (xmlAutomataPtr am, + int min, + int max); + +XMLPUBFUN struct _xmlRegexp * + xmlAutomataCompile (xmlAutomataPtr am); +XMLPUBFUN int + xmlAutomataIsDeterminist (xmlAutomataPtr am); + +#ifdef __cplusplus +} +#endif + +#endif /* LIBXML_AUTOMATA_ENABLED */ +#endif /* LIBXML_REGEXP_ENABLED */ + +#endif /* __XML_AUTOMATA_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlerror.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlerror.h new file mode 100644 index 0000000..36381be --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlerror.h @@ -0,0 +1,962 @@ +/* + * Summary: error handling + * Description: the API used to report errors + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_ERROR_H__ +#define __XML_ERROR_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * xmlErrorLevel: + * + * Indicates the level of an error + */ +typedef enum { + XML_ERR_NONE = 0, + XML_ERR_WARNING = 1, /* A simple warning */ + XML_ERR_ERROR = 2, /* A recoverable error */ + XML_ERR_FATAL = 3 /* A fatal error */ +} xmlErrorLevel; + +/** + * xmlErrorDomain: + * + * Indicates where an error may have come from + */ +typedef enum { + XML_FROM_NONE = 0, + XML_FROM_PARSER, /* The XML parser */ + XML_FROM_TREE, /* The tree module */ + XML_FROM_NAMESPACE, /* The XML Namespace module */ + XML_FROM_DTD, /* The XML DTD validation with parser context*/ + XML_FROM_HTML, /* The HTML parser */ + XML_FROM_MEMORY, /* The memory allocator */ + XML_FROM_OUTPUT, /* The serialization code */ + XML_FROM_IO, /* The Input/Output stack */ + XML_FROM_FTP, /* The FTP module */ + XML_FROM_HTTP, /* The HTTP module */ + XML_FROM_XINCLUDE, /* The XInclude processing */ + XML_FROM_XPATH, /* The XPath module */ + XML_FROM_XPOINTER, /* The XPointer module */ + XML_FROM_REGEXP, /* The regular expressions module */ + XML_FROM_DATATYPE, /* The W3C XML Schemas Datatype module */ + XML_FROM_SCHEMASP, /* The W3C XML Schemas parser module */ + XML_FROM_SCHEMASV, /* The W3C XML Schemas validation module */ + XML_FROM_RELAXNGP, /* The Relax-NG parser module */ + XML_FROM_RELAXNGV, /* The Relax-NG validator module */ + XML_FROM_CATALOG, /* The Catalog module */ + XML_FROM_C14N, /* The Canonicalization module */ + XML_FROM_XSLT, /* The XSLT engine from libxslt */ + XML_FROM_VALID, /* The XML DTD validation with valid context */ + XML_FROM_CHECK, /* The error checking module */ + XML_FROM_WRITER, /* The xmlwriter module */ + XML_FROM_MODULE, /* The dynamically loaded module module*/ + XML_FROM_I18N, /* The module handling character conversion */ + XML_FROM_SCHEMATRONV,/* The Schematron validator module */ + XML_FROM_BUFFER, /* The buffers module */ + XML_FROM_URI /* The URI module */ +} xmlErrorDomain; + +/** + * xmlError: + * + * An XML Error instance. + */ + +typedef struct _xmlError xmlError; +typedef xmlError *xmlErrorPtr; +struct _xmlError { + int domain; /* What part of the library raised this error */ + int code; /* The error code, e.g. an xmlParserError */ + char *message;/* human-readable informative error message */ + xmlErrorLevel level;/* how consequent is the error */ + char *file; /* the filename */ + int line; /* the line number if available */ + char *str1; /* extra string information */ + char *str2; /* extra string information */ + char *str3; /* extra string information */ + int int1; /* extra number information */ + int int2; /* error column # or 0 if N/A (todo: rename field when we would brk ABI) */ + void *ctxt; /* the parser context if available */ + void *node; /* the node in the tree */ +}; + +/** + * xmlParserError: + * + * This is an error that the XML (or HTML) parser can generate + */ +typedef enum { + XML_ERR_OK = 0, + XML_ERR_INTERNAL_ERROR, /* 1 */ + XML_ERR_NO_MEMORY, /* 2 */ + XML_ERR_DOCUMENT_START, /* 3 */ + XML_ERR_DOCUMENT_EMPTY, /* 4 */ + XML_ERR_DOCUMENT_END, /* 5 */ + XML_ERR_INVALID_HEX_CHARREF, /* 6 */ + XML_ERR_INVALID_DEC_CHARREF, /* 7 */ + XML_ERR_INVALID_CHARREF, /* 8 */ + XML_ERR_INVALID_CHAR, /* 9 */ + XML_ERR_CHARREF_AT_EOF, /* 10 */ + XML_ERR_CHARREF_IN_PROLOG, /* 11 */ + XML_ERR_CHARREF_IN_EPILOG, /* 12 */ + XML_ERR_CHARREF_IN_DTD, /* 13 */ + XML_ERR_ENTITYREF_AT_EOF, /* 14 */ + XML_ERR_ENTITYREF_IN_PROLOG, /* 15 */ + XML_ERR_ENTITYREF_IN_EPILOG, /* 16 */ + XML_ERR_ENTITYREF_IN_DTD, /* 17 */ + XML_ERR_PEREF_AT_EOF, /* 18 */ + XML_ERR_PEREF_IN_PROLOG, /* 19 */ + XML_ERR_PEREF_IN_EPILOG, /* 20 */ + XML_ERR_PEREF_IN_INT_SUBSET, /* 21 */ + XML_ERR_ENTITYREF_NO_NAME, /* 22 */ + XML_ERR_ENTITYREF_SEMICOL_MISSING, /* 23 */ + XML_ERR_PEREF_NO_NAME, /* 24 */ + XML_ERR_PEREF_SEMICOL_MISSING, /* 25 */ + XML_ERR_UNDECLARED_ENTITY, /* 26 */ + XML_WAR_UNDECLARED_ENTITY, /* 27 */ + XML_ERR_UNPARSED_ENTITY, /* 28 */ + XML_ERR_ENTITY_IS_EXTERNAL, /* 29 */ + XML_ERR_ENTITY_IS_PARAMETER, /* 30 */ + XML_ERR_UNKNOWN_ENCODING, /* 31 */ + XML_ERR_UNSUPPORTED_ENCODING, /* 32 */ + XML_ERR_STRING_NOT_STARTED, /* 33 */ + XML_ERR_STRING_NOT_CLOSED, /* 34 */ + XML_ERR_NS_DECL_ERROR, /* 35 */ + XML_ERR_ENTITY_NOT_STARTED, /* 36 */ + XML_ERR_ENTITY_NOT_FINISHED, /* 37 */ + XML_ERR_LT_IN_ATTRIBUTE, /* 38 */ + XML_ERR_ATTRIBUTE_NOT_STARTED, /* 39 */ + XML_ERR_ATTRIBUTE_NOT_FINISHED, /* 40 */ + XML_ERR_ATTRIBUTE_WITHOUT_VALUE, /* 41 */ + XML_ERR_ATTRIBUTE_REDEFINED, /* 42 */ + XML_ERR_LITERAL_NOT_STARTED, /* 43 */ + XML_ERR_LITERAL_NOT_FINISHED, /* 44 */ + XML_ERR_COMMENT_NOT_FINISHED, /* 45 */ + XML_ERR_PI_NOT_STARTED, /* 46 */ + XML_ERR_PI_NOT_FINISHED, /* 47 */ + XML_ERR_NOTATION_NOT_STARTED, /* 48 */ + XML_ERR_NOTATION_NOT_FINISHED, /* 49 */ + XML_ERR_ATTLIST_NOT_STARTED, /* 50 */ + XML_ERR_ATTLIST_NOT_FINISHED, /* 51 */ + XML_ERR_MIXED_NOT_STARTED, /* 52 */ + XML_ERR_MIXED_NOT_FINISHED, /* 53 */ + XML_ERR_ELEMCONTENT_NOT_STARTED, /* 54 */ + XML_ERR_ELEMCONTENT_NOT_FINISHED, /* 55 */ + XML_ERR_XMLDECL_NOT_STARTED, /* 56 */ + XML_ERR_XMLDECL_NOT_FINISHED, /* 57 */ + XML_ERR_CONDSEC_NOT_STARTED, /* 58 */ + XML_ERR_CONDSEC_NOT_FINISHED, /* 59 */ + XML_ERR_EXT_SUBSET_NOT_FINISHED, /* 60 */ + XML_ERR_DOCTYPE_NOT_FINISHED, /* 61 */ + XML_ERR_MISPLACED_CDATA_END, /* 62 */ + XML_ERR_CDATA_NOT_FINISHED, /* 63 */ + XML_ERR_RESERVED_XML_NAME, /* 64 */ + XML_ERR_SPACE_REQUIRED, /* 65 */ + XML_ERR_SEPARATOR_REQUIRED, /* 66 */ + XML_ERR_NMTOKEN_REQUIRED, /* 67 */ + XML_ERR_NAME_REQUIRED, /* 68 */ + XML_ERR_PCDATA_REQUIRED, /* 69 */ + XML_ERR_URI_REQUIRED, /* 70 */ + XML_ERR_PUBID_REQUIRED, /* 71 */ + XML_ERR_LT_REQUIRED, /* 72 */ + XML_ERR_GT_REQUIRED, /* 73 */ + XML_ERR_LTSLASH_REQUIRED, /* 74 */ + XML_ERR_EQUAL_REQUIRED, /* 75 */ + XML_ERR_TAG_NAME_MISMATCH, /* 76 */ + XML_ERR_TAG_NOT_FINISHED, /* 77 */ + XML_ERR_STANDALONE_VALUE, /* 78 */ + XML_ERR_ENCODING_NAME, /* 79 */ + XML_ERR_HYPHEN_IN_COMMENT, /* 80 */ + XML_ERR_INVALID_ENCODING, /* 81 */ + XML_ERR_EXT_ENTITY_STANDALONE, /* 82 */ + XML_ERR_CONDSEC_INVALID, /* 83 */ + XML_ERR_VALUE_REQUIRED, /* 84 */ + XML_ERR_NOT_WELL_BALANCED, /* 85 */ + XML_ERR_EXTRA_CONTENT, /* 86 */ + XML_ERR_ENTITY_CHAR_ERROR, /* 87 */ + XML_ERR_ENTITY_PE_INTERNAL, /* 88 */ + XML_ERR_ENTITY_LOOP, /* 89 */ + XML_ERR_ENTITY_BOUNDARY, /* 90 */ + XML_ERR_INVALID_URI, /* 91 */ + XML_ERR_URI_FRAGMENT, /* 92 */ + XML_WAR_CATALOG_PI, /* 93 */ + XML_ERR_NO_DTD, /* 94 */ + XML_ERR_CONDSEC_INVALID_KEYWORD, /* 95 */ + XML_ERR_VERSION_MISSING, /* 96 */ + XML_WAR_UNKNOWN_VERSION, /* 97 */ + XML_WAR_LANG_VALUE, /* 98 */ + XML_WAR_NS_URI, /* 99 */ + XML_WAR_NS_URI_RELATIVE, /* 100 */ + XML_ERR_MISSING_ENCODING, /* 101 */ + XML_WAR_SPACE_VALUE, /* 102 */ + XML_ERR_NOT_STANDALONE, /* 103 */ + XML_ERR_ENTITY_PROCESSING, /* 104 */ + XML_ERR_NOTATION_PROCESSING, /* 105 */ + XML_WAR_NS_COLUMN, /* 106 */ + XML_WAR_ENTITY_REDEFINED, /* 107 */ + XML_ERR_UNKNOWN_VERSION, /* 108 */ + XML_ERR_VERSION_MISMATCH, /* 109 */ + XML_ERR_NAME_TOO_LONG, /* 110 */ + XML_ERR_USER_STOP, /* 111 */ + XML_ERR_COMMENT_ABRUPTLY_ENDED, /* 112 */ + XML_WAR_ENCODING_MISMATCH, /* 113 */ + XML_ERR_RESOURCE_LIMIT, /* 114 */ + XML_ERR_ARGUMENT, /* 115 */ + XML_ERR_SYSTEM, /* 116 */ + XML_ERR_REDECL_PREDEF_ENTITY, /* 117 */ + XML_ERR_INT_SUBSET_NOT_FINISHED, /* 118 */ + XML_NS_ERR_XML_NAMESPACE = 200, + XML_NS_ERR_UNDEFINED_NAMESPACE, /* 201 */ + XML_NS_ERR_QNAME, /* 202 */ + XML_NS_ERR_ATTRIBUTE_REDEFINED, /* 203 */ + XML_NS_ERR_EMPTY, /* 204 */ + XML_NS_ERR_COLON, /* 205 */ + XML_DTD_ATTRIBUTE_DEFAULT = 500, + XML_DTD_ATTRIBUTE_REDEFINED, /* 501 */ + XML_DTD_ATTRIBUTE_VALUE, /* 502 */ + XML_DTD_CONTENT_ERROR, /* 503 */ + XML_DTD_CONTENT_MODEL, /* 504 */ + XML_DTD_CONTENT_NOT_DETERMINIST, /* 505 */ + XML_DTD_DIFFERENT_PREFIX, /* 506 */ + XML_DTD_ELEM_DEFAULT_NAMESPACE, /* 507 */ + XML_DTD_ELEM_NAMESPACE, /* 508 */ + XML_DTD_ELEM_REDEFINED, /* 509 */ + XML_DTD_EMPTY_NOTATION, /* 510 */ + XML_DTD_ENTITY_TYPE, /* 511 */ + XML_DTD_ID_FIXED, /* 512 */ + XML_DTD_ID_REDEFINED, /* 513 */ + XML_DTD_ID_SUBSET, /* 514 */ + XML_DTD_INVALID_CHILD, /* 515 */ + XML_DTD_INVALID_DEFAULT, /* 516 */ + XML_DTD_LOAD_ERROR, /* 517 */ + XML_DTD_MISSING_ATTRIBUTE, /* 518 */ + XML_DTD_MIXED_CORRUPT, /* 519 */ + XML_DTD_MULTIPLE_ID, /* 520 */ + XML_DTD_NO_DOC, /* 521 */ + XML_DTD_NO_DTD, /* 522 */ + XML_DTD_NO_ELEM_NAME, /* 523 */ + XML_DTD_NO_PREFIX, /* 524 */ + XML_DTD_NO_ROOT, /* 525 */ + XML_DTD_NOTATION_REDEFINED, /* 526 */ + XML_DTD_NOTATION_VALUE, /* 527 */ + XML_DTD_NOT_EMPTY, /* 528 */ + XML_DTD_NOT_PCDATA, /* 529 */ + XML_DTD_NOT_STANDALONE, /* 530 */ + XML_DTD_ROOT_NAME, /* 531 */ + XML_DTD_STANDALONE_WHITE_SPACE, /* 532 */ + XML_DTD_UNKNOWN_ATTRIBUTE, /* 533 */ + XML_DTD_UNKNOWN_ELEM, /* 534 */ + XML_DTD_UNKNOWN_ENTITY, /* 535 */ + XML_DTD_UNKNOWN_ID, /* 536 */ + XML_DTD_UNKNOWN_NOTATION, /* 537 */ + XML_DTD_STANDALONE_DEFAULTED, /* 538 */ + XML_DTD_XMLID_VALUE, /* 539 */ + XML_DTD_XMLID_TYPE, /* 540 */ + XML_DTD_DUP_TOKEN, /* 541 */ + XML_HTML_STRUCURE_ERROR = 800, + XML_HTML_UNKNOWN_TAG, /* 801 */ + XML_HTML_INCORRECTLY_OPENED_COMMENT, /* 802 */ + XML_RNGP_ANYNAME_ATTR_ANCESTOR = 1000, + XML_RNGP_ATTR_CONFLICT, /* 1001 */ + XML_RNGP_ATTRIBUTE_CHILDREN, /* 1002 */ + XML_RNGP_ATTRIBUTE_CONTENT, /* 1003 */ + XML_RNGP_ATTRIBUTE_EMPTY, /* 1004 */ + XML_RNGP_ATTRIBUTE_NOOP, /* 1005 */ + XML_RNGP_CHOICE_CONTENT, /* 1006 */ + XML_RNGP_CHOICE_EMPTY, /* 1007 */ + XML_RNGP_CREATE_FAILURE, /* 1008 */ + XML_RNGP_DATA_CONTENT, /* 1009 */ + XML_RNGP_DEF_CHOICE_AND_INTERLEAVE, /* 1010 */ + XML_RNGP_DEFINE_CREATE_FAILED, /* 1011 */ + XML_RNGP_DEFINE_EMPTY, /* 1012 */ + XML_RNGP_DEFINE_MISSING, /* 1013 */ + XML_RNGP_DEFINE_NAME_MISSING, /* 1014 */ + XML_RNGP_ELEM_CONTENT_EMPTY, /* 1015 */ + XML_RNGP_ELEM_CONTENT_ERROR, /* 1016 */ + XML_RNGP_ELEMENT_EMPTY, /* 1017 */ + XML_RNGP_ELEMENT_CONTENT, /* 1018 */ + XML_RNGP_ELEMENT_NAME, /* 1019 */ + XML_RNGP_ELEMENT_NO_CONTENT, /* 1020 */ + XML_RNGP_ELEM_TEXT_CONFLICT, /* 1021 */ + XML_RNGP_EMPTY, /* 1022 */ + XML_RNGP_EMPTY_CONSTRUCT, /* 1023 */ + XML_RNGP_EMPTY_CONTENT, /* 1024 */ + XML_RNGP_EMPTY_NOT_EMPTY, /* 1025 */ + XML_RNGP_ERROR_TYPE_LIB, /* 1026 */ + XML_RNGP_EXCEPT_EMPTY, /* 1027 */ + XML_RNGP_EXCEPT_MISSING, /* 1028 */ + XML_RNGP_EXCEPT_MULTIPLE, /* 1029 */ + XML_RNGP_EXCEPT_NO_CONTENT, /* 1030 */ + XML_RNGP_EXTERNALREF_EMTPY, /* 1031 */ + XML_RNGP_EXTERNAL_REF_FAILURE, /* 1032 */ + XML_RNGP_EXTERNALREF_RECURSE, /* 1033 */ + XML_RNGP_FORBIDDEN_ATTRIBUTE, /* 1034 */ + XML_RNGP_FOREIGN_ELEMENT, /* 1035 */ + XML_RNGP_GRAMMAR_CONTENT, /* 1036 */ + XML_RNGP_GRAMMAR_EMPTY, /* 1037 */ + XML_RNGP_GRAMMAR_MISSING, /* 1038 */ + XML_RNGP_GRAMMAR_NO_START, /* 1039 */ + XML_RNGP_GROUP_ATTR_CONFLICT, /* 1040 */ + XML_RNGP_HREF_ERROR, /* 1041 */ + XML_RNGP_INCLUDE_EMPTY, /* 1042 */ + XML_RNGP_INCLUDE_FAILURE, /* 1043 */ + XML_RNGP_INCLUDE_RECURSE, /* 1044 */ + XML_RNGP_INTERLEAVE_ADD, /* 1045 */ + XML_RNGP_INTERLEAVE_CREATE_FAILED, /* 1046 */ + XML_RNGP_INTERLEAVE_EMPTY, /* 1047 */ + XML_RNGP_INTERLEAVE_NO_CONTENT, /* 1048 */ + XML_RNGP_INVALID_DEFINE_NAME, /* 1049 */ + XML_RNGP_INVALID_URI, /* 1050 */ + XML_RNGP_INVALID_VALUE, /* 1051 */ + XML_RNGP_MISSING_HREF, /* 1052 */ + XML_RNGP_NAME_MISSING, /* 1053 */ + XML_RNGP_NEED_COMBINE, /* 1054 */ + XML_RNGP_NOTALLOWED_NOT_EMPTY, /* 1055 */ + XML_RNGP_NSNAME_ATTR_ANCESTOR, /* 1056 */ + XML_RNGP_NSNAME_NO_NS, /* 1057 */ + XML_RNGP_PARAM_FORBIDDEN, /* 1058 */ + XML_RNGP_PARAM_NAME_MISSING, /* 1059 */ + XML_RNGP_PARENTREF_CREATE_FAILED, /* 1060 */ + XML_RNGP_PARENTREF_NAME_INVALID, /* 1061 */ + XML_RNGP_PARENTREF_NO_NAME, /* 1062 */ + XML_RNGP_PARENTREF_NO_PARENT, /* 1063 */ + XML_RNGP_PARENTREF_NOT_EMPTY, /* 1064 */ + XML_RNGP_PARSE_ERROR, /* 1065 */ + XML_RNGP_PAT_ANYNAME_EXCEPT_ANYNAME, /* 1066 */ + XML_RNGP_PAT_ATTR_ATTR, /* 1067 */ + XML_RNGP_PAT_ATTR_ELEM, /* 1068 */ + XML_RNGP_PAT_DATA_EXCEPT_ATTR, /* 1069 */ + XML_RNGP_PAT_DATA_EXCEPT_ELEM, /* 1070 */ + XML_RNGP_PAT_DATA_EXCEPT_EMPTY, /* 1071 */ + XML_RNGP_PAT_DATA_EXCEPT_GROUP, /* 1072 */ + XML_RNGP_PAT_DATA_EXCEPT_INTERLEAVE, /* 1073 */ + XML_RNGP_PAT_DATA_EXCEPT_LIST, /* 1074 */ + XML_RNGP_PAT_DATA_EXCEPT_ONEMORE, /* 1075 */ + XML_RNGP_PAT_DATA_EXCEPT_REF, /* 1076 */ + XML_RNGP_PAT_DATA_EXCEPT_TEXT, /* 1077 */ + XML_RNGP_PAT_LIST_ATTR, /* 1078 */ + XML_RNGP_PAT_LIST_ELEM, /* 1079 */ + XML_RNGP_PAT_LIST_INTERLEAVE, /* 1080 */ + XML_RNGP_PAT_LIST_LIST, /* 1081 */ + XML_RNGP_PAT_LIST_REF, /* 1082 */ + XML_RNGP_PAT_LIST_TEXT, /* 1083 */ + XML_RNGP_PAT_NSNAME_EXCEPT_ANYNAME, /* 1084 */ + XML_RNGP_PAT_NSNAME_EXCEPT_NSNAME, /* 1085 */ + XML_RNGP_PAT_ONEMORE_GROUP_ATTR, /* 1086 */ + XML_RNGP_PAT_ONEMORE_INTERLEAVE_ATTR, /* 1087 */ + XML_RNGP_PAT_START_ATTR, /* 1088 */ + XML_RNGP_PAT_START_DATA, /* 1089 */ + XML_RNGP_PAT_START_EMPTY, /* 1090 */ + XML_RNGP_PAT_START_GROUP, /* 1091 */ + XML_RNGP_PAT_START_INTERLEAVE, /* 1092 */ + XML_RNGP_PAT_START_LIST, /* 1093 */ + XML_RNGP_PAT_START_ONEMORE, /* 1094 */ + XML_RNGP_PAT_START_TEXT, /* 1095 */ + XML_RNGP_PAT_START_VALUE, /* 1096 */ + XML_RNGP_PREFIX_UNDEFINED, /* 1097 */ + XML_RNGP_REF_CREATE_FAILED, /* 1098 */ + XML_RNGP_REF_CYCLE, /* 1099 */ + XML_RNGP_REF_NAME_INVALID, /* 1100 */ + XML_RNGP_REF_NO_DEF, /* 1101 */ + XML_RNGP_REF_NO_NAME, /* 1102 */ + XML_RNGP_REF_NOT_EMPTY, /* 1103 */ + XML_RNGP_START_CHOICE_AND_INTERLEAVE, /* 1104 */ + XML_RNGP_START_CONTENT, /* 1105 */ + XML_RNGP_START_EMPTY, /* 1106 */ + XML_RNGP_START_MISSING, /* 1107 */ + XML_RNGP_TEXT_EXPECTED, /* 1108 */ + XML_RNGP_TEXT_HAS_CHILD, /* 1109 */ + XML_RNGP_TYPE_MISSING, /* 1110 */ + XML_RNGP_TYPE_NOT_FOUND, /* 1111 */ + XML_RNGP_TYPE_VALUE, /* 1112 */ + XML_RNGP_UNKNOWN_ATTRIBUTE, /* 1113 */ + XML_RNGP_UNKNOWN_COMBINE, /* 1114 */ + XML_RNGP_UNKNOWN_CONSTRUCT, /* 1115 */ + XML_RNGP_UNKNOWN_TYPE_LIB, /* 1116 */ + XML_RNGP_URI_FRAGMENT, /* 1117 */ + XML_RNGP_URI_NOT_ABSOLUTE, /* 1118 */ + XML_RNGP_VALUE_EMPTY, /* 1119 */ + XML_RNGP_VALUE_NO_CONTENT, /* 1120 */ + XML_RNGP_XMLNS_NAME, /* 1121 */ + XML_RNGP_XML_NS, /* 1122 */ + XML_XPATH_EXPRESSION_OK = 1200, + XML_XPATH_NUMBER_ERROR, /* 1201 */ + XML_XPATH_UNFINISHED_LITERAL_ERROR, /* 1202 */ + XML_XPATH_START_LITERAL_ERROR, /* 1203 */ + XML_XPATH_VARIABLE_REF_ERROR, /* 1204 */ + XML_XPATH_UNDEF_VARIABLE_ERROR, /* 1205 */ + XML_XPATH_INVALID_PREDICATE_ERROR, /* 1206 */ + XML_XPATH_EXPR_ERROR, /* 1207 */ + XML_XPATH_UNCLOSED_ERROR, /* 1208 */ + XML_XPATH_UNKNOWN_FUNC_ERROR, /* 1209 */ + XML_XPATH_INVALID_OPERAND, /* 1210 */ + XML_XPATH_INVALID_TYPE, /* 1211 */ + XML_XPATH_INVALID_ARITY, /* 1212 */ + XML_XPATH_INVALID_CTXT_SIZE, /* 1213 */ + XML_XPATH_INVALID_CTXT_POSITION, /* 1214 */ + XML_XPATH_MEMORY_ERROR, /* 1215 */ + XML_XPTR_SYNTAX_ERROR, /* 1216 */ + XML_XPTR_RESOURCE_ERROR, /* 1217 */ + XML_XPTR_SUB_RESOURCE_ERROR, /* 1218 */ + XML_XPATH_UNDEF_PREFIX_ERROR, /* 1219 */ + XML_XPATH_ENCODING_ERROR, /* 1220 */ + XML_XPATH_INVALID_CHAR_ERROR, /* 1221 */ + XML_TREE_INVALID_HEX = 1300, + XML_TREE_INVALID_DEC, /* 1301 */ + XML_TREE_UNTERMINATED_ENTITY, /* 1302 */ + XML_TREE_NOT_UTF8, /* 1303 */ + XML_SAVE_NOT_UTF8 = 1400, + XML_SAVE_CHAR_INVALID, /* 1401 */ + XML_SAVE_NO_DOCTYPE, /* 1402 */ + XML_SAVE_UNKNOWN_ENCODING, /* 1403 */ + XML_REGEXP_COMPILE_ERROR = 1450, + XML_IO_UNKNOWN = 1500, + XML_IO_EACCES, /* 1501 */ + XML_IO_EAGAIN, /* 1502 */ + XML_IO_EBADF, /* 1503 */ + XML_IO_EBADMSG, /* 1504 */ + XML_IO_EBUSY, /* 1505 */ + XML_IO_ECANCELED, /* 1506 */ + XML_IO_ECHILD, /* 1507 */ + XML_IO_EDEADLK, /* 1508 */ + XML_IO_EDOM, /* 1509 */ + XML_IO_EEXIST, /* 1510 */ + XML_IO_EFAULT, /* 1511 */ + XML_IO_EFBIG, /* 1512 */ + XML_IO_EINPROGRESS, /* 1513 */ + XML_IO_EINTR, /* 1514 */ + XML_IO_EINVAL, /* 1515 */ + XML_IO_EIO, /* 1516 */ + XML_IO_EISDIR, /* 1517 */ + XML_IO_EMFILE, /* 1518 */ + XML_IO_EMLINK, /* 1519 */ + XML_IO_EMSGSIZE, /* 1520 */ + XML_IO_ENAMETOOLONG, /* 1521 */ + XML_IO_ENFILE, /* 1522 */ + XML_IO_ENODEV, /* 1523 */ + XML_IO_ENOENT, /* 1524 */ + XML_IO_ENOEXEC, /* 1525 */ + XML_IO_ENOLCK, /* 1526 */ + XML_IO_ENOMEM, /* 1527 */ + XML_IO_ENOSPC, /* 1528 */ + XML_IO_ENOSYS, /* 1529 */ + XML_IO_ENOTDIR, /* 1530 */ + XML_IO_ENOTEMPTY, /* 1531 */ + XML_IO_ENOTSUP, /* 1532 */ + XML_IO_ENOTTY, /* 1533 */ + XML_IO_ENXIO, /* 1534 */ + XML_IO_EPERM, /* 1535 */ + XML_IO_EPIPE, /* 1536 */ + XML_IO_ERANGE, /* 1537 */ + XML_IO_EROFS, /* 1538 */ + XML_IO_ESPIPE, /* 1539 */ + XML_IO_ESRCH, /* 1540 */ + XML_IO_ETIMEDOUT, /* 1541 */ + XML_IO_EXDEV, /* 1542 */ + XML_IO_NETWORK_ATTEMPT, /* 1543 */ + XML_IO_ENCODER, /* 1544 */ + XML_IO_FLUSH, /* 1545 */ + XML_IO_WRITE, /* 1546 */ + XML_IO_NO_INPUT, /* 1547 */ + XML_IO_BUFFER_FULL, /* 1548 */ + XML_IO_LOAD_ERROR, /* 1549 */ + XML_IO_ENOTSOCK, /* 1550 */ + XML_IO_EISCONN, /* 1551 */ + XML_IO_ECONNREFUSED, /* 1552 */ + XML_IO_ENETUNREACH, /* 1553 */ + XML_IO_EADDRINUSE, /* 1554 */ + XML_IO_EALREADY, /* 1555 */ + XML_IO_EAFNOSUPPORT, /* 1556 */ + XML_IO_UNSUPPORTED_PROTOCOL, /* 1557 */ + XML_XINCLUDE_RECURSION=1600, + XML_XINCLUDE_PARSE_VALUE, /* 1601 */ + XML_XINCLUDE_ENTITY_DEF_MISMATCH, /* 1602 */ + XML_XINCLUDE_NO_HREF, /* 1603 */ + XML_XINCLUDE_NO_FALLBACK, /* 1604 */ + XML_XINCLUDE_HREF_URI, /* 1605 */ + XML_XINCLUDE_TEXT_FRAGMENT, /* 1606 */ + XML_XINCLUDE_TEXT_DOCUMENT, /* 1607 */ + XML_XINCLUDE_INVALID_CHAR, /* 1608 */ + XML_XINCLUDE_BUILD_FAILED, /* 1609 */ + XML_XINCLUDE_UNKNOWN_ENCODING, /* 1610 */ + XML_XINCLUDE_MULTIPLE_ROOT, /* 1611 */ + XML_XINCLUDE_XPTR_FAILED, /* 1612 */ + XML_XINCLUDE_XPTR_RESULT, /* 1613 */ + XML_XINCLUDE_INCLUDE_IN_INCLUDE, /* 1614 */ + XML_XINCLUDE_FALLBACKS_IN_INCLUDE, /* 1615 */ + XML_XINCLUDE_FALLBACK_NOT_IN_INCLUDE, /* 1616 */ + XML_XINCLUDE_DEPRECATED_NS, /* 1617 */ + XML_XINCLUDE_FRAGMENT_ID, /* 1618 */ + XML_CATALOG_MISSING_ATTR = 1650, + XML_CATALOG_ENTRY_BROKEN, /* 1651 */ + XML_CATALOG_PREFER_VALUE, /* 1652 */ + XML_CATALOG_NOT_CATALOG, /* 1653 */ + XML_CATALOG_RECURSION, /* 1654 */ + XML_SCHEMAP_PREFIX_UNDEFINED = 1700, + XML_SCHEMAP_ATTRFORMDEFAULT_VALUE, /* 1701 */ + XML_SCHEMAP_ATTRGRP_NONAME_NOREF, /* 1702 */ + XML_SCHEMAP_ATTR_NONAME_NOREF, /* 1703 */ + XML_SCHEMAP_COMPLEXTYPE_NONAME_NOREF, /* 1704 */ + XML_SCHEMAP_ELEMFORMDEFAULT_VALUE, /* 1705 */ + XML_SCHEMAP_ELEM_NONAME_NOREF, /* 1706 */ + XML_SCHEMAP_EXTENSION_NO_BASE, /* 1707 */ + XML_SCHEMAP_FACET_NO_VALUE, /* 1708 */ + XML_SCHEMAP_FAILED_BUILD_IMPORT, /* 1709 */ + XML_SCHEMAP_GROUP_NONAME_NOREF, /* 1710 */ + XML_SCHEMAP_IMPORT_NAMESPACE_NOT_URI, /* 1711 */ + XML_SCHEMAP_IMPORT_REDEFINE_NSNAME, /* 1712 */ + XML_SCHEMAP_IMPORT_SCHEMA_NOT_URI, /* 1713 */ + XML_SCHEMAP_INVALID_BOOLEAN, /* 1714 */ + XML_SCHEMAP_INVALID_ENUM, /* 1715 */ + XML_SCHEMAP_INVALID_FACET, /* 1716 */ + XML_SCHEMAP_INVALID_FACET_VALUE, /* 1717 */ + XML_SCHEMAP_INVALID_MAXOCCURS, /* 1718 */ + XML_SCHEMAP_INVALID_MINOCCURS, /* 1719 */ + XML_SCHEMAP_INVALID_REF_AND_SUBTYPE, /* 1720 */ + XML_SCHEMAP_INVALID_WHITE_SPACE, /* 1721 */ + XML_SCHEMAP_NOATTR_NOREF, /* 1722 */ + XML_SCHEMAP_NOTATION_NO_NAME, /* 1723 */ + XML_SCHEMAP_NOTYPE_NOREF, /* 1724 */ + XML_SCHEMAP_REF_AND_SUBTYPE, /* 1725 */ + XML_SCHEMAP_RESTRICTION_NONAME_NOREF, /* 1726 */ + XML_SCHEMAP_SIMPLETYPE_NONAME, /* 1727 */ + XML_SCHEMAP_TYPE_AND_SUBTYPE, /* 1728 */ + XML_SCHEMAP_UNKNOWN_ALL_CHILD, /* 1729 */ + XML_SCHEMAP_UNKNOWN_ANYATTRIBUTE_CHILD, /* 1730 */ + XML_SCHEMAP_UNKNOWN_ATTR_CHILD, /* 1731 */ + XML_SCHEMAP_UNKNOWN_ATTRGRP_CHILD, /* 1732 */ + XML_SCHEMAP_UNKNOWN_ATTRIBUTE_GROUP, /* 1733 */ + XML_SCHEMAP_UNKNOWN_BASE_TYPE, /* 1734 */ + XML_SCHEMAP_UNKNOWN_CHOICE_CHILD, /* 1735 */ + XML_SCHEMAP_UNKNOWN_COMPLEXCONTENT_CHILD, /* 1736 */ + XML_SCHEMAP_UNKNOWN_COMPLEXTYPE_CHILD, /* 1737 */ + XML_SCHEMAP_UNKNOWN_ELEM_CHILD, /* 1738 */ + XML_SCHEMAP_UNKNOWN_EXTENSION_CHILD, /* 1739 */ + XML_SCHEMAP_UNKNOWN_FACET_CHILD, /* 1740 */ + XML_SCHEMAP_UNKNOWN_FACET_TYPE, /* 1741 */ + XML_SCHEMAP_UNKNOWN_GROUP_CHILD, /* 1742 */ + XML_SCHEMAP_UNKNOWN_IMPORT_CHILD, /* 1743 */ + XML_SCHEMAP_UNKNOWN_LIST_CHILD, /* 1744 */ + XML_SCHEMAP_UNKNOWN_NOTATION_CHILD, /* 1745 */ + XML_SCHEMAP_UNKNOWN_PROCESSCONTENT_CHILD, /* 1746 */ + XML_SCHEMAP_UNKNOWN_REF, /* 1747 */ + XML_SCHEMAP_UNKNOWN_RESTRICTION_CHILD, /* 1748 */ + XML_SCHEMAP_UNKNOWN_SCHEMAS_CHILD, /* 1749 */ + XML_SCHEMAP_UNKNOWN_SEQUENCE_CHILD, /* 1750 */ + XML_SCHEMAP_UNKNOWN_SIMPLECONTENT_CHILD, /* 1751 */ + XML_SCHEMAP_UNKNOWN_SIMPLETYPE_CHILD, /* 1752 */ + XML_SCHEMAP_UNKNOWN_TYPE, /* 1753 */ + XML_SCHEMAP_UNKNOWN_UNION_CHILD, /* 1754 */ + XML_SCHEMAP_ELEM_DEFAULT_FIXED, /* 1755 */ + XML_SCHEMAP_REGEXP_INVALID, /* 1756 */ + XML_SCHEMAP_FAILED_LOAD, /* 1757 */ + XML_SCHEMAP_NOTHING_TO_PARSE, /* 1758 */ + XML_SCHEMAP_NOROOT, /* 1759 */ + XML_SCHEMAP_REDEFINED_GROUP, /* 1760 */ + XML_SCHEMAP_REDEFINED_TYPE, /* 1761 */ + XML_SCHEMAP_REDEFINED_ELEMENT, /* 1762 */ + XML_SCHEMAP_REDEFINED_ATTRGROUP, /* 1763 */ + XML_SCHEMAP_REDEFINED_ATTR, /* 1764 */ + XML_SCHEMAP_REDEFINED_NOTATION, /* 1765 */ + XML_SCHEMAP_FAILED_PARSE, /* 1766 */ + XML_SCHEMAP_UNKNOWN_PREFIX, /* 1767 */ + XML_SCHEMAP_DEF_AND_PREFIX, /* 1768 */ + XML_SCHEMAP_UNKNOWN_INCLUDE_CHILD, /* 1769 */ + XML_SCHEMAP_INCLUDE_SCHEMA_NOT_URI, /* 1770 */ + XML_SCHEMAP_INCLUDE_SCHEMA_NO_URI, /* 1771 */ + XML_SCHEMAP_NOT_SCHEMA, /* 1772 */ + XML_SCHEMAP_UNKNOWN_MEMBER_TYPE, /* 1773 */ + XML_SCHEMAP_INVALID_ATTR_USE, /* 1774 */ + XML_SCHEMAP_RECURSIVE, /* 1775 */ + XML_SCHEMAP_SUPERNUMEROUS_LIST_ITEM_TYPE, /* 1776 */ + XML_SCHEMAP_INVALID_ATTR_COMBINATION, /* 1777 */ + XML_SCHEMAP_INVALID_ATTR_INLINE_COMBINATION, /* 1778 */ + XML_SCHEMAP_MISSING_SIMPLETYPE_CHILD, /* 1779 */ + XML_SCHEMAP_INVALID_ATTR_NAME, /* 1780 */ + XML_SCHEMAP_REF_AND_CONTENT, /* 1781 */ + XML_SCHEMAP_CT_PROPS_CORRECT_1, /* 1782 */ + XML_SCHEMAP_CT_PROPS_CORRECT_2, /* 1783 */ + XML_SCHEMAP_CT_PROPS_CORRECT_3, /* 1784 */ + XML_SCHEMAP_CT_PROPS_CORRECT_4, /* 1785 */ + XML_SCHEMAP_CT_PROPS_CORRECT_5, /* 1786 */ + XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, /* 1787 */ + XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1, /* 1788 */ + XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2, /* 1789 */ + XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2, /* 1790 */ + XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3, /* 1791 */ + XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER, /* 1792 */ + XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE, /* 1793 */ + XML_SCHEMAP_UNION_NOT_EXPRESSIBLE, /* 1794 */ + XML_SCHEMAP_SRC_IMPORT_3_1, /* 1795 */ + XML_SCHEMAP_SRC_IMPORT_3_2, /* 1796 */ + XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1, /* 1797 */ + XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2, /* 1798 */ + XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3, /* 1799 */ + XML_SCHEMAP_COS_CT_EXTENDS_1_3, /* 1800 */ + XML_SCHEMAV_NOROOT = 1801, + XML_SCHEMAV_UNDECLAREDELEM, /* 1802 */ + XML_SCHEMAV_NOTTOPLEVEL, /* 1803 */ + XML_SCHEMAV_MISSING, /* 1804 */ + XML_SCHEMAV_WRONGELEM, /* 1805 */ + XML_SCHEMAV_NOTYPE, /* 1806 */ + XML_SCHEMAV_NOROLLBACK, /* 1807 */ + XML_SCHEMAV_ISABSTRACT, /* 1808 */ + XML_SCHEMAV_NOTEMPTY, /* 1809 */ + XML_SCHEMAV_ELEMCONT, /* 1810 */ + XML_SCHEMAV_HAVEDEFAULT, /* 1811 */ + XML_SCHEMAV_NOTNILLABLE, /* 1812 */ + XML_SCHEMAV_EXTRACONTENT, /* 1813 */ + XML_SCHEMAV_INVALIDATTR, /* 1814 */ + XML_SCHEMAV_INVALIDELEM, /* 1815 */ + XML_SCHEMAV_NOTDETERMINIST, /* 1816 */ + XML_SCHEMAV_CONSTRUCT, /* 1817 */ + XML_SCHEMAV_INTERNAL, /* 1818 */ + XML_SCHEMAV_NOTSIMPLE, /* 1819 */ + XML_SCHEMAV_ATTRUNKNOWN, /* 1820 */ + XML_SCHEMAV_ATTRINVALID, /* 1821 */ + XML_SCHEMAV_VALUE, /* 1822 */ + XML_SCHEMAV_FACET, /* 1823 */ + XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, /* 1824 */ + XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2, /* 1825 */ + XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3, /* 1826 */ + XML_SCHEMAV_CVC_TYPE_3_1_1, /* 1827 */ + XML_SCHEMAV_CVC_TYPE_3_1_2, /* 1828 */ + XML_SCHEMAV_CVC_FACET_VALID, /* 1829 */ + XML_SCHEMAV_CVC_LENGTH_VALID, /* 1830 */ + XML_SCHEMAV_CVC_MINLENGTH_VALID, /* 1831 */ + XML_SCHEMAV_CVC_MAXLENGTH_VALID, /* 1832 */ + XML_SCHEMAV_CVC_MININCLUSIVE_VALID, /* 1833 */ + XML_SCHEMAV_CVC_MAXINCLUSIVE_VALID, /* 1834 */ + XML_SCHEMAV_CVC_MINEXCLUSIVE_VALID, /* 1835 */ + XML_SCHEMAV_CVC_MAXEXCLUSIVE_VALID, /* 1836 */ + XML_SCHEMAV_CVC_TOTALDIGITS_VALID, /* 1837 */ + XML_SCHEMAV_CVC_FRACTIONDIGITS_VALID, /* 1838 */ + XML_SCHEMAV_CVC_PATTERN_VALID, /* 1839 */ + XML_SCHEMAV_CVC_ENUMERATION_VALID, /* 1840 */ + XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, /* 1841 */ + XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2, /* 1842 */ + XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, /* 1843 */ + XML_SCHEMAV_CVC_COMPLEX_TYPE_2_4, /* 1844 */ + XML_SCHEMAV_CVC_ELT_1, /* 1845 */ + XML_SCHEMAV_CVC_ELT_2, /* 1846 */ + XML_SCHEMAV_CVC_ELT_3_1, /* 1847 */ + XML_SCHEMAV_CVC_ELT_3_2_1, /* 1848 */ + XML_SCHEMAV_CVC_ELT_3_2_2, /* 1849 */ + XML_SCHEMAV_CVC_ELT_4_1, /* 1850 */ + XML_SCHEMAV_CVC_ELT_4_2, /* 1851 */ + XML_SCHEMAV_CVC_ELT_4_3, /* 1852 */ + XML_SCHEMAV_CVC_ELT_5_1_1, /* 1853 */ + XML_SCHEMAV_CVC_ELT_5_1_2, /* 1854 */ + XML_SCHEMAV_CVC_ELT_5_2_1, /* 1855 */ + XML_SCHEMAV_CVC_ELT_5_2_2_1, /* 1856 */ + XML_SCHEMAV_CVC_ELT_5_2_2_2_1, /* 1857 */ + XML_SCHEMAV_CVC_ELT_5_2_2_2_2, /* 1858 */ + XML_SCHEMAV_CVC_ELT_6, /* 1859 */ + XML_SCHEMAV_CVC_ELT_7, /* 1860 */ + XML_SCHEMAV_CVC_ATTRIBUTE_1, /* 1861 */ + XML_SCHEMAV_CVC_ATTRIBUTE_2, /* 1862 */ + XML_SCHEMAV_CVC_ATTRIBUTE_3, /* 1863 */ + XML_SCHEMAV_CVC_ATTRIBUTE_4, /* 1864 */ + XML_SCHEMAV_CVC_COMPLEX_TYPE_3_1, /* 1865 */ + XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, /* 1866 */ + XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, /* 1867 */ + XML_SCHEMAV_CVC_COMPLEX_TYPE_4, /* 1868 */ + XML_SCHEMAV_CVC_COMPLEX_TYPE_5_1, /* 1869 */ + XML_SCHEMAV_CVC_COMPLEX_TYPE_5_2, /* 1870 */ + XML_SCHEMAV_ELEMENT_CONTENT, /* 1871 */ + XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING, /* 1872 */ + XML_SCHEMAV_CVC_COMPLEX_TYPE_1, /* 1873 */ + XML_SCHEMAV_CVC_AU, /* 1874 */ + XML_SCHEMAV_CVC_TYPE_1, /* 1875 */ + XML_SCHEMAV_CVC_TYPE_2, /* 1876 */ + XML_SCHEMAV_CVC_IDC, /* 1877 */ + XML_SCHEMAV_CVC_WILDCARD, /* 1878 */ + XML_SCHEMAV_MISC, /* 1879 */ + XML_XPTR_UNKNOWN_SCHEME = 1900, + XML_XPTR_CHILDSEQ_START, /* 1901 */ + XML_XPTR_EVAL_FAILED, /* 1902 */ + XML_XPTR_EXTRA_OBJECTS, /* 1903 */ + XML_C14N_CREATE_CTXT = 1950, + XML_C14N_REQUIRES_UTF8, /* 1951 */ + XML_C14N_CREATE_STACK, /* 1952 */ + XML_C14N_INVALID_NODE, /* 1953 */ + XML_C14N_UNKNOW_NODE, /* 1954 */ + XML_C14N_RELATIVE_NAMESPACE, /* 1955 */ + XML_FTP_PASV_ANSWER = 2000, + XML_FTP_EPSV_ANSWER, /* 2001 */ + XML_FTP_ACCNT, /* 2002 */ + XML_FTP_URL_SYNTAX, /* 2003 */ + XML_HTTP_URL_SYNTAX = 2020, + XML_HTTP_USE_IP, /* 2021 */ + XML_HTTP_UNKNOWN_HOST, /* 2022 */ + XML_SCHEMAP_SRC_SIMPLE_TYPE_1 = 3000, + XML_SCHEMAP_SRC_SIMPLE_TYPE_2, /* 3001 */ + XML_SCHEMAP_SRC_SIMPLE_TYPE_3, /* 3002 */ + XML_SCHEMAP_SRC_SIMPLE_TYPE_4, /* 3003 */ + XML_SCHEMAP_SRC_RESOLVE, /* 3004 */ + XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE, /* 3005 */ + XML_SCHEMAP_SRC_LIST_ITEMTYPE_OR_SIMPLETYPE, /* 3006 */ + XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES, /* 3007 */ + XML_SCHEMAP_ST_PROPS_CORRECT_1, /* 3008 */ + XML_SCHEMAP_ST_PROPS_CORRECT_2, /* 3009 */ + XML_SCHEMAP_ST_PROPS_CORRECT_3, /* 3010 */ + XML_SCHEMAP_COS_ST_RESTRICTS_1_1, /* 3011 */ + XML_SCHEMAP_COS_ST_RESTRICTS_1_2, /* 3012 */ + XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1, /* 3013 */ + XML_SCHEMAP_COS_ST_RESTRICTS_1_3_2, /* 3014 */ + XML_SCHEMAP_COS_ST_RESTRICTS_2_1, /* 3015 */ + XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1, /* 3016 */ + XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2, /* 3017 */ + XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1, /* 3018 */ + XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2, /* 3019 */ + XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3, /* 3020 */ + XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4, /* 3021 */ + XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_5, /* 3022 */ + XML_SCHEMAP_COS_ST_RESTRICTS_3_1, /* 3023 */ + XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1, /* 3024 */ + XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2, /* 3025 */ + XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2, /* 3026 */ + XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1, /* 3027 */ + XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3, /* 3028 */ + XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4, /* 3029 */ + XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_5, /* 3030 */ + XML_SCHEMAP_COS_ST_DERIVED_OK_2_1, /* 3031 */ + XML_SCHEMAP_COS_ST_DERIVED_OK_2_2, /* 3032 */ + XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, /* 3033 */ + XML_SCHEMAP_S4S_ELEM_MISSING, /* 3034 */ + XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, /* 3035 */ + XML_SCHEMAP_S4S_ATTR_MISSING, /* 3036 */ + XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, /* 3037 */ + XML_SCHEMAP_SRC_ELEMENT_1, /* 3038 */ + XML_SCHEMAP_SRC_ELEMENT_2_1, /* 3039 */ + XML_SCHEMAP_SRC_ELEMENT_2_2, /* 3040 */ + XML_SCHEMAP_SRC_ELEMENT_3, /* 3041 */ + XML_SCHEMAP_P_PROPS_CORRECT_1, /* 3042 */ + XML_SCHEMAP_P_PROPS_CORRECT_2_1, /* 3043 */ + XML_SCHEMAP_P_PROPS_CORRECT_2_2, /* 3044 */ + XML_SCHEMAP_E_PROPS_CORRECT_2, /* 3045 */ + XML_SCHEMAP_E_PROPS_CORRECT_3, /* 3046 */ + XML_SCHEMAP_E_PROPS_CORRECT_4, /* 3047 */ + XML_SCHEMAP_E_PROPS_CORRECT_5, /* 3048 */ + XML_SCHEMAP_E_PROPS_CORRECT_6, /* 3049 */ + XML_SCHEMAP_SRC_INCLUDE, /* 3050 */ + XML_SCHEMAP_SRC_ATTRIBUTE_1, /* 3051 */ + XML_SCHEMAP_SRC_ATTRIBUTE_2, /* 3052 */ + XML_SCHEMAP_SRC_ATTRIBUTE_3_1, /* 3053 */ + XML_SCHEMAP_SRC_ATTRIBUTE_3_2, /* 3054 */ + XML_SCHEMAP_SRC_ATTRIBUTE_4, /* 3055 */ + XML_SCHEMAP_NO_XMLNS, /* 3056 */ + XML_SCHEMAP_NO_XSI, /* 3057 */ + XML_SCHEMAP_COS_VALID_DEFAULT_1, /* 3058 */ + XML_SCHEMAP_COS_VALID_DEFAULT_2_1, /* 3059 */ + XML_SCHEMAP_COS_VALID_DEFAULT_2_2_1, /* 3060 */ + XML_SCHEMAP_COS_VALID_DEFAULT_2_2_2, /* 3061 */ + XML_SCHEMAP_CVC_SIMPLE_TYPE, /* 3062 */ + XML_SCHEMAP_COS_CT_EXTENDS_1_1, /* 3063 */ + XML_SCHEMAP_SRC_IMPORT_1_1, /* 3064 */ + XML_SCHEMAP_SRC_IMPORT_1_2, /* 3065 */ + XML_SCHEMAP_SRC_IMPORT_2, /* 3066 */ + XML_SCHEMAP_SRC_IMPORT_2_1, /* 3067 */ + XML_SCHEMAP_SRC_IMPORT_2_2, /* 3068 */ + XML_SCHEMAP_INTERNAL, /* 3069 non-W3C */ + XML_SCHEMAP_NOT_DETERMINISTIC, /* 3070 non-W3C */ + XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_1, /* 3071 */ + XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_2, /* 3072 */ + XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3, /* 3073 */ + XML_SCHEMAP_MG_PROPS_CORRECT_1, /* 3074 */ + XML_SCHEMAP_MG_PROPS_CORRECT_2, /* 3075 */ + XML_SCHEMAP_SRC_CT_1, /* 3076 */ + XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3, /* 3077 */ + XML_SCHEMAP_AU_PROPS_CORRECT_2, /* 3078 */ + XML_SCHEMAP_A_PROPS_CORRECT_2, /* 3079 */ + XML_SCHEMAP_C_PROPS_CORRECT, /* 3080 */ + XML_SCHEMAP_SRC_REDEFINE, /* 3081 */ + XML_SCHEMAP_SRC_IMPORT, /* 3082 */ + XML_SCHEMAP_WARN_SKIP_SCHEMA, /* 3083 */ + XML_SCHEMAP_WARN_UNLOCATED_SCHEMA, /* 3084 */ + XML_SCHEMAP_WARN_ATTR_REDECL_PROH, /* 3085 */ + XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, /* 3085 */ + XML_SCHEMAP_AG_PROPS_CORRECT, /* 3086 */ + XML_SCHEMAP_COS_CT_EXTENDS_1_2, /* 3087 */ + XML_SCHEMAP_AU_PROPS_CORRECT, /* 3088 */ + XML_SCHEMAP_A_PROPS_CORRECT_3, /* 3089 */ + XML_SCHEMAP_COS_ALL_LIMITED, /* 3090 */ + XML_SCHEMATRONV_ASSERT = 4000, /* 4000 */ + XML_SCHEMATRONV_REPORT, + XML_MODULE_OPEN = 4900, /* 4900 */ + XML_MODULE_CLOSE, /* 4901 */ + XML_CHECK_FOUND_ELEMENT = 5000, + XML_CHECK_FOUND_ATTRIBUTE, /* 5001 */ + XML_CHECK_FOUND_TEXT, /* 5002 */ + XML_CHECK_FOUND_CDATA, /* 5003 */ + XML_CHECK_FOUND_ENTITYREF, /* 5004 */ + XML_CHECK_FOUND_ENTITY, /* 5005 */ + XML_CHECK_FOUND_PI, /* 5006 */ + XML_CHECK_FOUND_COMMENT, /* 5007 */ + XML_CHECK_FOUND_DOCTYPE, /* 5008 */ + XML_CHECK_FOUND_FRAGMENT, /* 5009 */ + XML_CHECK_FOUND_NOTATION, /* 5010 */ + XML_CHECK_UNKNOWN_NODE, /* 5011 */ + XML_CHECK_ENTITY_TYPE, /* 5012 */ + XML_CHECK_NO_PARENT, /* 5013 */ + XML_CHECK_NO_DOC, /* 5014 */ + XML_CHECK_NO_NAME, /* 5015 */ + XML_CHECK_NO_ELEM, /* 5016 */ + XML_CHECK_WRONG_DOC, /* 5017 */ + XML_CHECK_NO_PREV, /* 5018 */ + XML_CHECK_WRONG_PREV, /* 5019 */ + XML_CHECK_NO_NEXT, /* 5020 */ + XML_CHECK_WRONG_NEXT, /* 5021 */ + XML_CHECK_NOT_DTD, /* 5022 */ + XML_CHECK_NOT_ATTR, /* 5023 */ + XML_CHECK_NOT_ATTR_DECL, /* 5024 */ + XML_CHECK_NOT_ELEM_DECL, /* 5025 */ + XML_CHECK_NOT_ENTITY_DECL, /* 5026 */ + XML_CHECK_NOT_NS_DECL, /* 5027 */ + XML_CHECK_NO_HREF, /* 5028 */ + XML_CHECK_WRONG_PARENT,/* 5029 */ + XML_CHECK_NS_SCOPE, /* 5030 */ + XML_CHECK_NS_ANCESTOR, /* 5031 */ + XML_CHECK_NOT_UTF8, /* 5032 */ + XML_CHECK_NO_DICT, /* 5033 */ + XML_CHECK_NOT_NCNAME, /* 5034 */ + XML_CHECK_OUTSIDE_DICT, /* 5035 */ + XML_CHECK_WRONG_NAME, /* 5036 */ + XML_CHECK_NAME_NOT_NULL, /* 5037 */ + XML_I18N_NO_NAME = 6000, + XML_I18N_NO_HANDLER, /* 6001 */ + XML_I18N_EXCESS_HANDLER, /* 6002 */ + XML_I18N_CONV_FAILED, /* 6003 */ + XML_I18N_NO_OUTPUT, /* 6004 */ + XML_BUF_OVERFLOW = 7000 +} xmlParserErrors; + +/** + * xmlGenericErrorFunc: + * @ctx: a parsing context + * @msg: the message + * @...: the extra arguments of the varargs to format the message + * + * Signature of the function to use when there is an error and + * no parsing or validity context available . + */ +typedef void (*xmlGenericErrorFunc) (void *ctx, + const char *msg, + ...) LIBXML_ATTR_FORMAT(2,3); +/** + * xmlStructuredErrorFunc: + * @userData: user provided data for the error callback + * @error: the error being raised. + * + * Signature of the function to use when there is an error and + * the module handles the new error reporting mechanism. + */ +typedef void (*xmlStructuredErrorFunc) (void *userData, const xmlError *error); + +/** DOC_DISABLE */ +#define XML_GLOBALS_ERROR \ + XML_OP(xmlLastError, xmlError, XML_DEPRECATED) \ + XML_OP(xmlGenericError, xmlGenericErrorFunc, XML_NO_ATTR) \ + XML_OP(xmlGenericErrorContext, void *, XML_NO_ATTR) \ + XML_OP(xmlStructuredError, xmlStructuredErrorFunc, XML_NO_ATTR) \ + XML_OP(xmlStructuredErrorContext, void *, XML_NO_ATTR) + +#define XML_OP XML_DECLARE_GLOBAL +XML_GLOBALS_ERROR +#undef XML_OP + +#if defined(LIBXML_THREAD_ENABLED) && !defined(XML_GLOBALS_NO_REDEFINITION) + #define xmlLastError XML_GLOBAL_MACRO(xmlLastError) + #define xmlGenericError XML_GLOBAL_MACRO(xmlGenericError) + #define xmlGenericErrorContext XML_GLOBAL_MACRO(xmlGenericErrorContext) + #define xmlStructuredError XML_GLOBAL_MACRO(xmlStructuredError) + #define xmlStructuredErrorContext XML_GLOBAL_MACRO(xmlStructuredErrorContext) +#endif +/** DOC_ENABLE */ + +/* + * Use the following function to reset the two global variables + * xmlGenericError and xmlGenericErrorContext. + */ +XMLPUBFUN void + xmlSetGenericErrorFunc (void *ctx, + xmlGenericErrorFunc handler); +XML_DEPRECATED +XMLPUBFUN void + xmlThrDefSetGenericErrorFunc(void *ctx, + xmlGenericErrorFunc handler); +XML_DEPRECATED +XMLPUBFUN void + initGenericErrorDefaultFunc (xmlGenericErrorFunc *handler); + +XMLPUBFUN void + xmlSetStructuredErrorFunc (void *ctx, + xmlStructuredErrorFunc handler); +XML_DEPRECATED +XMLPUBFUN void + xmlThrDefSetStructuredErrorFunc(void *ctx, + xmlStructuredErrorFunc handler); +/* + * Default message routines used by SAX and Valid context for error + * and warning reporting. + */ +XMLPUBFUN void + xmlParserError (void *ctx, + const char *msg, + ...) LIBXML_ATTR_FORMAT(2,3); +XMLPUBFUN void + xmlParserWarning (void *ctx, + const char *msg, + ...) LIBXML_ATTR_FORMAT(2,3); +XMLPUBFUN void + xmlParserValidityError (void *ctx, + const char *msg, + ...) LIBXML_ATTR_FORMAT(2,3); +XMLPUBFUN void + xmlParserValidityWarning (void *ctx, + const char *msg, + ...) LIBXML_ATTR_FORMAT(2,3); +/** DOC_DISABLE */ +struct _xmlParserInput; +/** DOC_ENABLE */ +XMLPUBFUN void + xmlParserPrintFileInfo (struct _xmlParserInput *input); +XMLPUBFUN void + xmlParserPrintFileContext (struct _xmlParserInput *input); +XMLPUBFUN void +xmlFormatError (const xmlError *err, + xmlGenericErrorFunc channel, + void *data); + +/* + * Extended error information routines + */ +XMLPUBFUN const xmlError * + xmlGetLastError (void); +XMLPUBFUN void + xmlResetLastError (void); +XMLPUBFUN const xmlError * + xmlCtxtGetLastError (void *ctx); +XMLPUBFUN void + xmlCtxtResetLastError (void *ctx); +XMLPUBFUN void + xmlResetError (xmlErrorPtr err); +XMLPUBFUN int + xmlCopyError (const xmlError *from, + xmlErrorPtr to); + +#ifdef __cplusplus +} +#endif +#endif /* __XML_ERROR_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlexports.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlexports.h new file mode 100644 index 0000000..3c1d83f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlexports.h @@ -0,0 +1,146 @@ +/* + * Summary: macros for marking symbols as exportable/importable. + * Description: macros for marking symbols as exportable/importable. + * + * Copy: See Copyright for the status of this software. + */ + +#ifndef __XML_EXPORTS_H__ +#define __XML_EXPORTS_H__ + +/** DOC_DISABLE */ + +/* + * Symbol visibility + */ + +#if defined(_WIN32) || defined(__CYGWIN__) + #ifdef LIBXML_STATIC + #define XMLPUBLIC + #elif defined(IN_LIBXML) + #define XMLPUBLIC __declspec(dllexport) + #else + #define XMLPUBLIC __declspec(dllimport) + #endif +#else /* not Windows */ + #define XMLPUBLIC +#endif /* platform switch */ + +#define XMLPUBFUN XMLPUBLIC + +#define XMLPUBVAR XMLPUBLIC extern + +/* Compatibility */ +#define XMLCALL +#define XMLCDECL +#ifndef LIBXML_DLL_IMPORT + #define LIBXML_DLL_IMPORT XMLPUBVAR +#endif + +/* + * Attributes + */ + +#ifndef ATTRIBUTE_UNUSED + #if __GNUC__ * 100 + __GNUC_MINOR__ >= 207 || defined(__clang__) + #define ATTRIBUTE_UNUSED __attribute__((unused)) + #else + #define ATTRIBUTE_UNUSED + #endif +#endif + +#if !defined(__clang__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403) + #define LIBXML_ATTR_ALLOC_SIZE(x) __attribute__((alloc_size(x))) +#else + #define LIBXML_ATTR_ALLOC_SIZE(x) +#endif + +#if __GNUC__ * 100 + __GNUC_MINOR__ >= 303 + #define LIBXML_ATTR_FORMAT(fmt,args) \ + __attribute__((__format__(__printf__,fmt,args))) +#else + #define LIBXML_ATTR_FORMAT(fmt,args) +#endif + +#ifndef XML_DEPRECATED + #if defined(IN_LIBXML) + #define XML_DEPRECATED + #elif __GNUC__ * 100 + __GNUC_MINOR__ >= 301 + #define XML_DEPRECATED __attribute__((deprecated)) + #elif defined(_MSC_VER) && _MSC_VER >= 1400 + /* Available since Visual Studio 2005 */ + #define XML_DEPRECATED __declspec(deprecated) + #else + #define XML_DEPRECATED + #endif +#endif + +/* + * Warnings pragmas, should be moved from public headers + */ + +#if defined(__LCC__) + + #define XML_IGNORE_FPTR_CAST_WARNINGS + #define XML_POP_WARNINGS \ + _Pragma("diag_default 1215") + +#elif defined(__clang__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 406) + + #if defined(__clang__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 800) + #define XML_IGNORE_FPTR_CAST_WARNINGS \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wpedantic\"") \ + _Pragma("GCC diagnostic ignored \"-Wcast-function-type\"") + #else + #define XML_IGNORE_FPTR_CAST_WARNINGS \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wpedantic\"") + #endif + #define XML_POP_WARNINGS \ + _Pragma("GCC diagnostic pop") + +#elif defined(_MSC_VER) && _MSC_VER >= 1400 + + #define XML_IGNORE_FPTR_CAST_WARNINGS __pragma(warning(push)) + #define XML_POP_WARNINGS __pragma(warning(pop)) + +#else + + #define XML_IGNORE_FPTR_CAST_WARNINGS + #define XML_POP_WARNINGS + +#endif + +/* + * Accessors for globals + */ + +#define XML_NO_ATTR + +#ifdef LIBXML_THREAD_ENABLED + #define XML_DECLARE_GLOBAL(name, type, attrs) \ + attrs XMLPUBFUN type *__##name(void); + #define XML_GLOBAL_MACRO(name) (*__##name()) +#else + #define XML_DECLARE_GLOBAL(name, type, attrs) \ + attrs XMLPUBVAR type name; +#endif + +/* + * Originally declared in xmlversion.h which is generated + */ + +#ifdef __cplusplus +extern "C" { +#endif + +XMLPUBFUN void xmlCheckVersion(int version); + +#ifdef __cplusplus +} +#endif + +#endif /* __XML_EXPORTS_H__ */ + + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlmemory.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlmemory.h new file mode 100644 index 0000000..1de3e9f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlmemory.h @@ -0,0 +1,188 @@ +/* + * Summary: interface for the memory allocator + * Description: provides interfaces for the memory allocator, + * including debugging capabilities. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + + +#ifndef __DEBUG_MEMORY_ALLOC__ +#define __DEBUG_MEMORY_ALLOC__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The XML memory wrapper support 4 basic overloadable functions. + */ +/** + * xmlFreeFunc: + * @mem: an already allocated block of memory + * + * Signature for a free() implementation. + */ +typedef void (*xmlFreeFunc)(void *mem); +/** + * xmlMallocFunc: + * @size: the size requested in bytes + * + * Signature for a malloc() implementation. + * + * Returns a pointer to the newly allocated block or NULL in case of error. + */ +typedef void *(LIBXML_ATTR_ALLOC_SIZE(1) *xmlMallocFunc)(size_t size); + +/** + * xmlReallocFunc: + * @mem: an already allocated block of memory + * @size: the new size requested in bytes + * + * Signature for a realloc() implementation. + * + * Returns a pointer to the newly reallocated block or NULL in case of error. + */ +typedef void *(*xmlReallocFunc)(void *mem, size_t size); + +/** + * xmlStrdupFunc: + * @str: a zero terminated string + * + * Signature for an strdup() implementation. + * + * Returns the copy of the string or NULL in case of error. + */ +typedef char *(*xmlStrdupFunc)(const char *str); + +/* + * In general the memory allocation entry points are not kept + * thread specific but this can be overridden by LIBXML_THREAD_ALLOC_ENABLED + * - xmlMalloc + * - xmlMallocAtomic + * - xmlRealloc + * - xmlMemStrdup + * - xmlFree + */ +/** DOC_DISABLE */ +#ifdef LIBXML_THREAD_ALLOC_ENABLED + #define XML_GLOBALS_ALLOC \ + XML_OP(xmlMalloc, xmlMallocFunc, XML_NO_ATTR) \ + XML_OP(xmlMallocAtomic, xmlMallocFunc, XML_NO_ATTR) \ + XML_OP(xmlRealloc, xmlReallocFunc, XML_NO_ATTR) \ + XML_OP(xmlFree, xmlFreeFunc, XML_NO_ATTR) \ + XML_OP(xmlMemStrdup, xmlStrdupFunc, XML_NO_ATTR) + #define XML_OP XML_DECLARE_GLOBAL + XML_GLOBALS_ALLOC + #undef XML_OP + #if defined(LIBXML_THREAD_ENABLED) && !defined(XML_GLOBALS_NO_REDEFINITION) + #define xmlMalloc XML_GLOBAL_MACRO(xmlMalloc) + #define xmlMallocAtomic XML_GLOBAL_MACRO(xmlMallocAtomic) + #define xmlRealloc XML_GLOBAL_MACRO(xmlRealloc) + #define xmlFree XML_GLOBAL_MACRO(xmlFree) + #define xmlMemStrdup XML_GLOBAL_MACRO(xmlMemStrdup) + #endif +#else + #define XML_GLOBALS_ALLOC +/** DOC_ENABLE */ + XMLPUBVAR xmlMallocFunc xmlMalloc; + XMLPUBVAR xmlMallocFunc xmlMallocAtomic; + XMLPUBVAR xmlReallocFunc xmlRealloc; + XMLPUBVAR xmlFreeFunc xmlFree; + XMLPUBVAR xmlStrdupFunc xmlMemStrdup; +#endif + +/* + * The way to overload the existing functions. + * The xmlGc function have an extra entry for atomic block + * allocations useful for garbage collected memory allocators + */ +XMLPUBFUN int + xmlMemSetup (xmlFreeFunc freeFunc, + xmlMallocFunc mallocFunc, + xmlReallocFunc reallocFunc, + xmlStrdupFunc strdupFunc); +XMLPUBFUN int + xmlMemGet (xmlFreeFunc *freeFunc, + xmlMallocFunc *mallocFunc, + xmlReallocFunc *reallocFunc, + xmlStrdupFunc *strdupFunc); +XMLPUBFUN int + xmlGcMemSetup (xmlFreeFunc freeFunc, + xmlMallocFunc mallocFunc, + xmlMallocFunc mallocAtomicFunc, + xmlReallocFunc reallocFunc, + xmlStrdupFunc strdupFunc); +XMLPUBFUN int + xmlGcMemGet (xmlFreeFunc *freeFunc, + xmlMallocFunc *mallocFunc, + xmlMallocFunc *mallocAtomicFunc, + xmlReallocFunc *reallocFunc, + xmlStrdupFunc *strdupFunc); + +/* + * Initialization of the memory layer. + */ +XML_DEPRECATED +XMLPUBFUN int + xmlInitMemory (void); + +/* + * Cleanup of the memory layer. + */ +XML_DEPRECATED +XMLPUBFUN void + xmlCleanupMemory (void); +/* + * These are specific to the XML debug memory wrapper. + */ +XMLPUBFUN size_t + xmlMemSize (void *ptr); +XMLPUBFUN int + xmlMemUsed (void); +XMLPUBFUN int + xmlMemBlocks (void); +XML_DEPRECATED +XMLPUBFUN void + xmlMemDisplay (FILE *fp); +XML_DEPRECATED +XMLPUBFUN void + xmlMemDisplayLast(FILE *fp, long nbBytes); +XML_DEPRECATED +XMLPUBFUN void + xmlMemShow (FILE *fp, int nr); +XML_DEPRECATED +XMLPUBFUN void + xmlMemoryDump (void); +XMLPUBFUN void * + xmlMemMalloc (size_t size) LIBXML_ATTR_ALLOC_SIZE(1); +XMLPUBFUN void * + xmlMemRealloc (void *ptr,size_t size); +XMLPUBFUN void + xmlMemFree (void *ptr); +XMLPUBFUN char * + xmlMemoryStrdup (const char *str); +XML_DEPRECATED +XMLPUBFUN void * + xmlMallocLoc (size_t size, const char *file, int line) LIBXML_ATTR_ALLOC_SIZE(1); +XML_DEPRECATED +XMLPUBFUN void * + xmlReallocLoc (void *ptr, size_t size, const char *file, int line); +XML_DEPRECATED +XMLPUBFUN void * + xmlMallocAtomicLoc (size_t size, const char *file, int line) LIBXML_ATTR_ALLOC_SIZE(1); +XML_DEPRECATED +XMLPUBFUN char * + xmlMemStrdupLoc (const char *str, const char *file, int line); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __DEBUG_MEMORY_ALLOC__ */ + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlmodule.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlmodule.h new file mode 100644 index 0000000..279986c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlmodule.h @@ -0,0 +1,57 @@ +/* + * Summary: dynamic module loading + * Description: basic API for dynamic module loading, used by + * libexslt added in 2.6.17 + * + * Copy: See Copyright for the status of this software. + * + * Author: Joel W. Reed + */ + +#ifndef __XML_MODULE_H__ +#define __XML_MODULE_H__ + +#include + +#ifdef LIBXML_MODULES_ENABLED + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * xmlModulePtr: + * + * A handle to a dynamically loaded module + */ +typedef struct _xmlModule xmlModule; +typedef xmlModule *xmlModulePtr; + +/** + * xmlModuleOption: + * + * enumeration of options that can be passed down to xmlModuleOpen() + */ +typedef enum { + XML_MODULE_LAZY = 1, /* lazy binding */ + XML_MODULE_LOCAL= 2 /* local binding */ +} xmlModuleOption; + +XMLPUBFUN xmlModulePtr xmlModuleOpen (const char *filename, + int options); + +XMLPUBFUN int xmlModuleSymbol (xmlModulePtr module, + const char* name, + void **result); + +XMLPUBFUN int xmlModuleClose (xmlModulePtr module); + +XMLPUBFUN int xmlModuleFree (xmlModulePtr module); + +#ifdef __cplusplus +} +#endif + +#endif /* LIBXML_MODULES_ENABLED */ + +#endif /*__XML_MODULE_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlreader.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlreader.h new file mode 100644 index 0000000..5d4fc5d --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlreader.h @@ -0,0 +1,436 @@ +/* + * Summary: the XMLReader implementation + * Description: API of the XML streaming API based on C# interfaces. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_XMLREADER_H__ +#define __XML_XMLREADER_H__ + +#include +#include +#include +#include +#ifdef LIBXML_SCHEMAS_ENABLED +#include +#include +#endif +/* for compatibility */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * xmlParserSeverities: + * + * How severe an error callback is when the per-reader error callback API + * is used. + */ +typedef enum { + XML_PARSER_SEVERITY_VALIDITY_WARNING = 1, + XML_PARSER_SEVERITY_VALIDITY_ERROR = 2, + XML_PARSER_SEVERITY_WARNING = 3, + XML_PARSER_SEVERITY_ERROR = 4 +} xmlParserSeverities; + +#ifdef LIBXML_READER_ENABLED + +/** + * xmlTextReaderMode: + * + * Internal state values for the reader. + */ +typedef enum { + XML_TEXTREADER_MODE_INITIAL = 0, + XML_TEXTREADER_MODE_INTERACTIVE = 1, + XML_TEXTREADER_MODE_ERROR = 2, + XML_TEXTREADER_MODE_EOF =3, + XML_TEXTREADER_MODE_CLOSED = 4, + XML_TEXTREADER_MODE_READING = 5 +} xmlTextReaderMode; + +/** + * xmlParserProperties: + * + * Some common options to use with xmlTextReaderSetParserProp, but it + * is better to use xmlParserOption and the xmlReaderNewxxx and + * xmlReaderForxxx APIs now. + */ +typedef enum { + XML_PARSER_LOADDTD = 1, + XML_PARSER_DEFAULTATTRS = 2, + XML_PARSER_VALIDATE = 3, + XML_PARSER_SUBST_ENTITIES = 4 +} xmlParserProperties; + +/** + * xmlReaderTypes: + * + * Predefined constants for the different types of nodes. + */ +typedef enum { + XML_READER_TYPE_NONE = 0, + XML_READER_TYPE_ELEMENT = 1, + XML_READER_TYPE_ATTRIBUTE = 2, + XML_READER_TYPE_TEXT = 3, + XML_READER_TYPE_CDATA = 4, + XML_READER_TYPE_ENTITY_REFERENCE = 5, + XML_READER_TYPE_ENTITY = 6, + XML_READER_TYPE_PROCESSING_INSTRUCTION = 7, + XML_READER_TYPE_COMMENT = 8, + XML_READER_TYPE_DOCUMENT = 9, + XML_READER_TYPE_DOCUMENT_TYPE = 10, + XML_READER_TYPE_DOCUMENT_FRAGMENT = 11, + XML_READER_TYPE_NOTATION = 12, + XML_READER_TYPE_WHITESPACE = 13, + XML_READER_TYPE_SIGNIFICANT_WHITESPACE = 14, + XML_READER_TYPE_END_ELEMENT = 15, + XML_READER_TYPE_END_ENTITY = 16, + XML_READER_TYPE_XML_DECLARATION = 17 +} xmlReaderTypes; + +/** + * xmlTextReader: + * + * Structure for an xmlReader context. + */ +typedef struct _xmlTextReader xmlTextReader; + +/** + * xmlTextReaderPtr: + * + * Pointer to an xmlReader context. + */ +typedef xmlTextReader *xmlTextReaderPtr; + +/* + * Constructors & Destructor + */ +XMLPUBFUN xmlTextReaderPtr + xmlNewTextReader (xmlParserInputBufferPtr input, + const char *URI); +XMLPUBFUN xmlTextReaderPtr + xmlNewTextReaderFilename(const char *URI); + +XMLPUBFUN void + xmlFreeTextReader (xmlTextReaderPtr reader); + +XMLPUBFUN int + xmlTextReaderSetup(xmlTextReaderPtr reader, + xmlParserInputBufferPtr input, const char *URL, + const char *encoding, int options); +XMLPUBFUN void + xmlTextReaderSetMaxAmplification(xmlTextReaderPtr reader, + unsigned maxAmpl); +XMLPUBFUN const xmlError * + xmlTextReaderGetLastError(xmlTextReaderPtr reader); + +/* + * Iterators + */ +XMLPUBFUN int + xmlTextReaderRead (xmlTextReaderPtr reader); + +#ifdef LIBXML_WRITER_ENABLED +XMLPUBFUN xmlChar * + xmlTextReaderReadInnerXml(xmlTextReaderPtr reader); + +XMLPUBFUN xmlChar * + xmlTextReaderReadOuterXml(xmlTextReaderPtr reader); +#endif + +XMLPUBFUN xmlChar * + xmlTextReaderReadString (xmlTextReaderPtr reader); +XMLPUBFUN int + xmlTextReaderReadAttributeValue(xmlTextReaderPtr reader); + +/* + * Attributes of the node + */ +XMLPUBFUN int + xmlTextReaderAttributeCount(xmlTextReaderPtr reader); +XMLPUBFUN int + xmlTextReaderDepth (xmlTextReaderPtr reader); +XMLPUBFUN int + xmlTextReaderHasAttributes(xmlTextReaderPtr reader); +XMLPUBFUN int + xmlTextReaderHasValue(xmlTextReaderPtr reader); +XMLPUBFUN int + xmlTextReaderIsDefault (xmlTextReaderPtr reader); +XMLPUBFUN int + xmlTextReaderIsEmptyElement(xmlTextReaderPtr reader); +XMLPUBFUN int + xmlTextReaderNodeType (xmlTextReaderPtr reader); +XMLPUBFUN int + xmlTextReaderQuoteChar (xmlTextReaderPtr reader); +XMLPUBFUN int + xmlTextReaderReadState (xmlTextReaderPtr reader); +XMLPUBFUN int + xmlTextReaderIsNamespaceDecl(xmlTextReaderPtr reader); + +XMLPUBFUN const xmlChar * + xmlTextReaderConstBaseUri (xmlTextReaderPtr reader); +XMLPUBFUN const xmlChar * + xmlTextReaderConstLocalName (xmlTextReaderPtr reader); +XMLPUBFUN const xmlChar * + xmlTextReaderConstName (xmlTextReaderPtr reader); +XMLPUBFUN const xmlChar * + xmlTextReaderConstNamespaceUri(xmlTextReaderPtr reader); +XMLPUBFUN const xmlChar * + xmlTextReaderConstPrefix (xmlTextReaderPtr reader); +XMLPUBFUN const xmlChar * + xmlTextReaderConstXmlLang (xmlTextReaderPtr reader); +XMLPUBFUN const xmlChar * + xmlTextReaderConstString (xmlTextReaderPtr reader, + const xmlChar *str); +XMLPUBFUN const xmlChar * + xmlTextReaderConstValue (xmlTextReaderPtr reader); + +/* + * use the Const version of the routine for + * better performance and simpler code + */ +XMLPUBFUN xmlChar * + xmlTextReaderBaseUri (xmlTextReaderPtr reader); +XMLPUBFUN xmlChar * + xmlTextReaderLocalName (xmlTextReaderPtr reader); +XMLPUBFUN xmlChar * + xmlTextReaderName (xmlTextReaderPtr reader); +XMLPUBFUN xmlChar * + xmlTextReaderNamespaceUri(xmlTextReaderPtr reader); +XMLPUBFUN xmlChar * + xmlTextReaderPrefix (xmlTextReaderPtr reader); +XMLPUBFUN xmlChar * + xmlTextReaderXmlLang (xmlTextReaderPtr reader); +XMLPUBFUN xmlChar * + xmlTextReaderValue (xmlTextReaderPtr reader); + +/* + * Methods of the XmlTextReader + */ +XMLPUBFUN int + xmlTextReaderClose (xmlTextReaderPtr reader); +XMLPUBFUN xmlChar * + xmlTextReaderGetAttributeNo (xmlTextReaderPtr reader, + int no); +XMLPUBFUN xmlChar * + xmlTextReaderGetAttribute (xmlTextReaderPtr reader, + const xmlChar *name); +XMLPUBFUN xmlChar * + xmlTextReaderGetAttributeNs (xmlTextReaderPtr reader, + const xmlChar *localName, + const xmlChar *namespaceURI); +XMLPUBFUN xmlParserInputBufferPtr + xmlTextReaderGetRemainder (xmlTextReaderPtr reader); +XMLPUBFUN xmlChar * + xmlTextReaderLookupNamespace(xmlTextReaderPtr reader, + const xmlChar *prefix); +XMLPUBFUN int + xmlTextReaderMoveToAttributeNo(xmlTextReaderPtr reader, + int no); +XMLPUBFUN int + xmlTextReaderMoveToAttribute(xmlTextReaderPtr reader, + const xmlChar *name); +XMLPUBFUN int + xmlTextReaderMoveToAttributeNs(xmlTextReaderPtr reader, + const xmlChar *localName, + const xmlChar *namespaceURI); +XMLPUBFUN int + xmlTextReaderMoveToFirstAttribute(xmlTextReaderPtr reader); +XMLPUBFUN int + xmlTextReaderMoveToNextAttribute(xmlTextReaderPtr reader); +XMLPUBFUN int + xmlTextReaderMoveToElement (xmlTextReaderPtr reader); +XMLPUBFUN int + xmlTextReaderNormalization (xmlTextReaderPtr reader); +XMLPUBFUN const xmlChar * + xmlTextReaderConstEncoding (xmlTextReaderPtr reader); + +/* + * Extensions + */ +XMLPUBFUN int + xmlTextReaderSetParserProp (xmlTextReaderPtr reader, + int prop, + int value); +XMLPUBFUN int + xmlTextReaderGetParserProp (xmlTextReaderPtr reader, + int prop); +XMLPUBFUN xmlNodePtr + xmlTextReaderCurrentNode (xmlTextReaderPtr reader); + +XMLPUBFUN int + xmlTextReaderGetParserLineNumber(xmlTextReaderPtr reader); + +XMLPUBFUN int + xmlTextReaderGetParserColumnNumber(xmlTextReaderPtr reader); + +XMLPUBFUN xmlNodePtr + xmlTextReaderPreserve (xmlTextReaderPtr reader); +#ifdef LIBXML_PATTERN_ENABLED +XMLPUBFUN int + xmlTextReaderPreservePattern(xmlTextReaderPtr reader, + const xmlChar *pattern, + const xmlChar **namespaces); +#endif /* LIBXML_PATTERN_ENABLED */ +XMLPUBFUN xmlDocPtr + xmlTextReaderCurrentDoc (xmlTextReaderPtr reader); +XMLPUBFUN xmlNodePtr + xmlTextReaderExpand (xmlTextReaderPtr reader); +XMLPUBFUN int + xmlTextReaderNext (xmlTextReaderPtr reader); +XMLPUBFUN int + xmlTextReaderNextSibling (xmlTextReaderPtr reader); +XMLPUBFUN int + xmlTextReaderIsValid (xmlTextReaderPtr reader); +#ifdef LIBXML_SCHEMAS_ENABLED +XMLPUBFUN int + xmlTextReaderRelaxNGValidate(xmlTextReaderPtr reader, + const char *rng); +XMLPUBFUN int + xmlTextReaderRelaxNGValidateCtxt(xmlTextReaderPtr reader, + xmlRelaxNGValidCtxtPtr ctxt, + int options); + +XMLPUBFUN int + xmlTextReaderRelaxNGSetSchema(xmlTextReaderPtr reader, + xmlRelaxNGPtr schema); +XMLPUBFUN int + xmlTextReaderSchemaValidate (xmlTextReaderPtr reader, + const char *xsd); +XMLPUBFUN int + xmlTextReaderSchemaValidateCtxt(xmlTextReaderPtr reader, + xmlSchemaValidCtxtPtr ctxt, + int options); +XMLPUBFUN int + xmlTextReaderSetSchema (xmlTextReaderPtr reader, + xmlSchemaPtr schema); +#endif +XMLPUBFUN const xmlChar * + xmlTextReaderConstXmlVersion(xmlTextReaderPtr reader); +XMLPUBFUN int + xmlTextReaderStandalone (xmlTextReaderPtr reader); + + +/* + * Index lookup + */ +XMLPUBFUN long + xmlTextReaderByteConsumed (xmlTextReaderPtr reader); + +/* + * New more complete APIs for simpler creation and reuse of readers + */ +XMLPUBFUN xmlTextReaderPtr + xmlReaderWalker (xmlDocPtr doc); +XMLPUBFUN xmlTextReaderPtr + xmlReaderForDoc (const xmlChar * cur, + const char *URL, + const char *encoding, + int options); +XMLPUBFUN xmlTextReaderPtr + xmlReaderForFile (const char *filename, + const char *encoding, + int options); +XMLPUBFUN xmlTextReaderPtr + xmlReaderForMemory (const char *buffer, + int size, + const char *URL, + const char *encoding, + int options); +XMLPUBFUN xmlTextReaderPtr + xmlReaderForFd (int fd, + const char *URL, + const char *encoding, + int options); +XMLPUBFUN xmlTextReaderPtr + xmlReaderForIO (xmlInputReadCallback ioread, + xmlInputCloseCallback ioclose, + void *ioctx, + const char *URL, + const char *encoding, + int options); + +XMLPUBFUN int + xmlReaderNewWalker (xmlTextReaderPtr reader, + xmlDocPtr doc); +XMLPUBFUN int + xmlReaderNewDoc (xmlTextReaderPtr reader, + const xmlChar * cur, + const char *URL, + const char *encoding, + int options); +XMLPUBFUN int + xmlReaderNewFile (xmlTextReaderPtr reader, + const char *filename, + const char *encoding, + int options); +XMLPUBFUN int + xmlReaderNewMemory (xmlTextReaderPtr reader, + const char *buffer, + int size, + const char *URL, + const char *encoding, + int options); +XMLPUBFUN int + xmlReaderNewFd (xmlTextReaderPtr reader, + int fd, + const char *URL, + const char *encoding, + int options); +XMLPUBFUN int + xmlReaderNewIO (xmlTextReaderPtr reader, + xmlInputReadCallback ioread, + xmlInputCloseCallback ioclose, + void *ioctx, + const char *URL, + const char *encoding, + int options); +/* + * Error handling extensions + */ +typedef void * xmlTextReaderLocatorPtr; + +/** + * xmlTextReaderErrorFunc: + * @arg: the user argument + * @msg: the message + * @severity: the severity of the error + * @locator: a locator indicating where the error occurred + * + * Signature of an error callback from a reader parser + */ +typedef void (*xmlTextReaderErrorFunc)(void *arg, + const char *msg, + xmlParserSeverities severity, + xmlTextReaderLocatorPtr locator); +XMLPUBFUN int + xmlTextReaderLocatorLineNumber(xmlTextReaderLocatorPtr locator); +XMLPUBFUN xmlChar * + xmlTextReaderLocatorBaseURI (xmlTextReaderLocatorPtr locator); +XMLPUBFUN void + xmlTextReaderSetErrorHandler(xmlTextReaderPtr reader, + xmlTextReaderErrorFunc f, + void *arg); +XMLPUBFUN void + xmlTextReaderSetStructuredErrorHandler(xmlTextReaderPtr reader, + xmlStructuredErrorFunc f, + void *arg); +XMLPUBFUN void + xmlTextReaderGetErrorHandler(xmlTextReaderPtr reader, + xmlTextReaderErrorFunc *f, + void **arg); + +#endif /* LIBXML_READER_ENABLED */ + +#ifdef __cplusplus +} +#endif + +#endif /* __XML_XMLREADER_H__ */ + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlregexp.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlregexp.h new file mode 100644 index 0000000..2d66437 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlregexp.h @@ -0,0 +1,215 @@ +/* + * Summary: regular expressions handling + * Description: basic API for libxml regular expressions handling used + * for XML Schemas and validation. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_REGEXP_H__ +#define __XML_REGEXP_H__ + +#include +#include +#include + +#ifdef LIBXML_REGEXP_ENABLED + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * xmlRegexpPtr: + * + * A libxml regular expression, they can actually be far more complex + * thank the POSIX regex expressions. + */ +typedef struct _xmlRegexp xmlRegexp; +typedef xmlRegexp *xmlRegexpPtr; + +/** + * xmlRegExecCtxtPtr: + * + * A libxml progressive regular expression evaluation context + */ +typedef struct _xmlRegExecCtxt xmlRegExecCtxt; +typedef xmlRegExecCtxt *xmlRegExecCtxtPtr; + +/* + * The POSIX like API + */ +XMLPUBFUN xmlRegexpPtr + xmlRegexpCompile (const xmlChar *regexp); +XMLPUBFUN void xmlRegFreeRegexp(xmlRegexpPtr regexp); +XMLPUBFUN int + xmlRegexpExec (xmlRegexpPtr comp, + const xmlChar *value); +XMLPUBFUN void + xmlRegexpPrint (FILE *output, + xmlRegexpPtr regexp); +XMLPUBFUN int + xmlRegexpIsDeterminist(xmlRegexpPtr comp); + +/** + * xmlRegExecCallbacks: + * @exec: the regular expression context + * @token: the current token string + * @transdata: transition data + * @inputdata: input data + * + * Callback function when doing a transition in the automata + */ +typedef void (*xmlRegExecCallbacks) (xmlRegExecCtxtPtr exec, + const xmlChar *token, + void *transdata, + void *inputdata); + +/* + * The progressive API + */ +XMLPUBFUN xmlRegExecCtxtPtr + xmlRegNewExecCtxt (xmlRegexpPtr comp, + xmlRegExecCallbacks callback, + void *data); +XMLPUBFUN void + xmlRegFreeExecCtxt (xmlRegExecCtxtPtr exec); +XMLPUBFUN int + xmlRegExecPushString(xmlRegExecCtxtPtr exec, + const xmlChar *value, + void *data); +XMLPUBFUN int + xmlRegExecPushString2(xmlRegExecCtxtPtr exec, + const xmlChar *value, + const xmlChar *value2, + void *data); + +XMLPUBFUN int + xmlRegExecNextValues(xmlRegExecCtxtPtr exec, + int *nbval, + int *nbneg, + xmlChar **values, + int *terminal); +XMLPUBFUN int + xmlRegExecErrInfo (xmlRegExecCtxtPtr exec, + const xmlChar **string, + int *nbval, + int *nbneg, + xmlChar **values, + int *terminal); +#ifdef LIBXML_EXPR_ENABLED +/* + * Formal regular expression handling + * Its goal is to do some formal work on content models + */ + +/* expressions are used within a context */ +typedef struct _xmlExpCtxt xmlExpCtxt; +typedef xmlExpCtxt *xmlExpCtxtPtr; + +XMLPUBFUN void + xmlExpFreeCtxt (xmlExpCtxtPtr ctxt); +XMLPUBFUN xmlExpCtxtPtr + xmlExpNewCtxt (int maxNodes, + xmlDictPtr dict); + +XMLPUBFUN int + xmlExpCtxtNbNodes(xmlExpCtxtPtr ctxt); +XMLPUBFUN int + xmlExpCtxtNbCons(xmlExpCtxtPtr ctxt); + +/* Expressions are trees but the tree is opaque */ +typedef struct _xmlExpNode xmlExpNode; +typedef xmlExpNode *xmlExpNodePtr; + +typedef enum { + XML_EXP_EMPTY = 0, + XML_EXP_FORBID = 1, + XML_EXP_ATOM = 2, + XML_EXP_SEQ = 3, + XML_EXP_OR = 4, + XML_EXP_COUNT = 5 +} xmlExpNodeType; + +/* + * 2 core expressions shared by all for the empty language set + * and for the set with just the empty token + */ +XMLPUBVAR xmlExpNodePtr forbiddenExp; +XMLPUBVAR xmlExpNodePtr emptyExp; + +/* + * Expressions are reference counted internally + */ +XMLPUBFUN void + xmlExpFree (xmlExpCtxtPtr ctxt, + xmlExpNodePtr expr); +XMLPUBFUN void + xmlExpRef (xmlExpNodePtr expr); + +/* + * constructors can be either manual or from a string + */ +XMLPUBFUN xmlExpNodePtr + xmlExpParse (xmlExpCtxtPtr ctxt, + const char *expr); +XMLPUBFUN xmlExpNodePtr + xmlExpNewAtom (xmlExpCtxtPtr ctxt, + const xmlChar *name, + int len); +XMLPUBFUN xmlExpNodePtr + xmlExpNewOr (xmlExpCtxtPtr ctxt, + xmlExpNodePtr left, + xmlExpNodePtr right); +XMLPUBFUN xmlExpNodePtr + xmlExpNewSeq (xmlExpCtxtPtr ctxt, + xmlExpNodePtr left, + xmlExpNodePtr right); +XMLPUBFUN xmlExpNodePtr + xmlExpNewRange (xmlExpCtxtPtr ctxt, + xmlExpNodePtr subset, + int min, + int max); +/* + * The really interesting APIs + */ +XMLPUBFUN int + xmlExpIsNillable(xmlExpNodePtr expr); +XMLPUBFUN int + xmlExpMaxToken (xmlExpNodePtr expr); +XMLPUBFUN int + xmlExpGetLanguage(xmlExpCtxtPtr ctxt, + xmlExpNodePtr expr, + const xmlChar**langList, + int len); +XMLPUBFUN int + xmlExpGetStart (xmlExpCtxtPtr ctxt, + xmlExpNodePtr expr, + const xmlChar**tokList, + int len); +XMLPUBFUN xmlExpNodePtr + xmlExpStringDerive(xmlExpCtxtPtr ctxt, + xmlExpNodePtr expr, + const xmlChar *str, + int len); +XMLPUBFUN xmlExpNodePtr + xmlExpExpDerive (xmlExpCtxtPtr ctxt, + xmlExpNodePtr expr, + xmlExpNodePtr sub); +XMLPUBFUN int + xmlExpSubsume (xmlExpCtxtPtr ctxt, + xmlExpNodePtr expr, + xmlExpNodePtr sub); +XMLPUBFUN void + xmlExpDump (xmlBufferPtr buf, + xmlExpNodePtr expr); +#endif /* LIBXML_EXPR_ENABLED */ +#ifdef __cplusplus +} +#endif + +#endif /* LIBXML_REGEXP_ENABLED */ + +#endif /*__XML_REGEXP_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlsave.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlsave.h new file mode 100644 index 0000000..e266e46 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlsave.h @@ -0,0 +1,102 @@ +/* + * Summary: the XML document serializer + * Description: API to save document or subtree of document + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_XMLSAVE_H__ +#define __XML_XMLSAVE_H__ + +#include +#include +#include +#include + +#ifdef LIBXML_OUTPUT_ENABLED +#ifdef __cplusplus +extern "C" { +#endif + +/** + * xmlSaveOption: + * + * This is the set of XML save options that can be passed down + * to the xmlSaveToFd() and similar calls. + */ +typedef enum { + XML_SAVE_FORMAT = 1<<0, /* format save output */ + XML_SAVE_NO_DECL = 1<<1, /* drop the xml declaration */ + XML_SAVE_NO_EMPTY = 1<<2, /* no empty tags */ + XML_SAVE_NO_XHTML = 1<<3, /* disable XHTML1 specific rules */ + XML_SAVE_XHTML = 1<<4, /* force XHTML1 specific rules */ + XML_SAVE_AS_XML = 1<<5, /* force XML serialization on HTML doc */ + XML_SAVE_AS_HTML = 1<<6, /* force HTML serialization on XML doc */ + XML_SAVE_WSNONSIG = 1<<7 /* format with non-significant whitespace */ +} xmlSaveOption; + + +typedef struct _xmlSaveCtxt xmlSaveCtxt; +typedef xmlSaveCtxt *xmlSaveCtxtPtr; + +XMLPUBFUN xmlSaveCtxtPtr + xmlSaveToFd (int fd, + const char *encoding, + int options); +XMLPUBFUN xmlSaveCtxtPtr + xmlSaveToFilename (const char *filename, + const char *encoding, + int options); + +XMLPUBFUN xmlSaveCtxtPtr + xmlSaveToBuffer (xmlBufferPtr buffer, + const char *encoding, + int options); + +XMLPUBFUN xmlSaveCtxtPtr + xmlSaveToIO (xmlOutputWriteCallback iowrite, + xmlOutputCloseCallback ioclose, + void *ioctx, + const char *encoding, + int options); + +XMLPUBFUN long + xmlSaveDoc (xmlSaveCtxtPtr ctxt, + xmlDocPtr doc); +XMLPUBFUN long + xmlSaveTree (xmlSaveCtxtPtr ctxt, + xmlNodePtr node); + +XMLPUBFUN int + xmlSaveFlush (xmlSaveCtxtPtr ctxt); +XMLPUBFUN int + xmlSaveClose (xmlSaveCtxtPtr ctxt); +XMLPUBFUN int + xmlSaveFinish (xmlSaveCtxtPtr ctxt); +XMLPUBFUN int + xmlSaveSetEscape (xmlSaveCtxtPtr ctxt, + xmlCharEncodingOutputFunc escape); +XMLPUBFUN int + xmlSaveSetAttrEscape (xmlSaveCtxtPtr ctxt, + xmlCharEncodingOutputFunc escape); + +XML_DEPRECATED +XMLPUBFUN int + xmlThrDefIndentTreeOutput(int v); +XML_DEPRECATED +XMLPUBFUN const char * + xmlThrDefTreeIndentString(const char * v); +XML_DEPRECATED +XMLPUBFUN int + xmlThrDefSaveNoEmptyTags(int v); + +#ifdef __cplusplus +} +#endif + +#endif /* LIBXML_OUTPUT_ENABLED */ +#endif /* __XML_XMLSAVE_H__ */ + + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlschemas.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlschemas.h new file mode 100644 index 0000000..c2af3d7 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlschemas.h @@ -0,0 +1,249 @@ +/* + * Summary: incomplete XML Schemas structure implementation + * Description: interface to the XML Schemas handling and schema validity + * checking, it is incomplete right now. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + + +#ifndef __XML_SCHEMA_H__ +#define __XML_SCHEMA_H__ + +#include + +#ifdef LIBXML_SCHEMAS_ENABLED + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * This error codes are obsolete; not used any more. + */ +typedef enum { + XML_SCHEMAS_ERR_OK = 0, + XML_SCHEMAS_ERR_NOROOT = 1, + XML_SCHEMAS_ERR_UNDECLAREDELEM, + XML_SCHEMAS_ERR_NOTTOPLEVEL, + XML_SCHEMAS_ERR_MISSING, + XML_SCHEMAS_ERR_WRONGELEM, + XML_SCHEMAS_ERR_NOTYPE, + XML_SCHEMAS_ERR_NOROLLBACK, + XML_SCHEMAS_ERR_ISABSTRACT, + XML_SCHEMAS_ERR_NOTEMPTY, + XML_SCHEMAS_ERR_ELEMCONT, + XML_SCHEMAS_ERR_HAVEDEFAULT, + XML_SCHEMAS_ERR_NOTNILLABLE, + XML_SCHEMAS_ERR_EXTRACONTENT, + XML_SCHEMAS_ERR_INVALIDATTR, + XML_SCHEMAS_ERR_INVALIDELEM, + XML_SCHEMAS_ERR_NOTDETERMINIST, + XML_SCHEMAS_ERR_CONSTRUCT, + XML_SCHEMAS_ERR_INTERNAL, + XML_SCHEMAS_ERR_NOTSIMPLE, + XML_SCHEMAS_ERR_ATTRUNKNOWN, + XML_SCHEMAS_ERR_ATTRINVALID, + XML_SCHEMAS_ERR_VALUE, + XML_SCHEMAS_ERR_FACET, + XML_SCHEMAS_ERR_, + XML_SCHEMAS_ERR_XXX +} xmlSchemaValidError; + +/* +* ATTENTION: Change xmlSchemaSetValidOptions's check +* for invalid values, if adding to the validation +* options below. +*/ +/** + * xmlSchemaValidOption: + * + * This is the set of XML Schema validation options. + */ +typedef enum { + XML_SCHEMA_VAL_VC_I_CREATE = 1<<0 + /* Default/fixed: create an attribute node + * or an element's text node on the instance. + */ +} xmlSchemaValidOption; + +/* + XML_SCHEMA_VAL_XSI_ASSEMBLE = 1<<1, + * assemble schemata using + * xsi:schemaLocation and + * xsi:noNamespaceSchemaLocation +*/ + +/** + * The schemas related types are kept internal + */ +typedef struct _xmlSchema xmlSchema; +typedef xmlSchema *xmlSchemaPtr; + +/** + * xmlSchemaValidityErrorFunc: + * @ctx: the validation context + * @msg: the message + * @...: extra arguments + * + * Signature of an error callback from an XSD validation + */ +typedef void (*xmlSchemaValidityErrorFunc) + (void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3); + +/** + * xmlSchemaValidityWarningFunc: + * @ctx: the validation context + * @msg: the message + * @...: extra arguments + * + * Signature of a warning callback from an XSD validation + */ +typedef void (*xmlSchemaValidityWarningFunc) + (void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3); + +/** + * A schemas validation context + */ +typedef struct _xmlSchemaParserCtxt xmlSchemaParserCtxt; +typedef xmlSchemaParserCtxt *xmlSchemaParserCtxtPtr; + +typedef struct _xmlSchemaValidCtxt xmlSchemaValidCtxt; +typedef xmlSchemaValidCtxt *xmlSchemaValidCtxtPtr; + +/** + * xmlSchemaValidityLocatorFunc: + * @ctx: user provided context + * @file: returned file information + * @line: returned line information + * + * A schemas validation locator, a callback called by the validator. + * This is used when file or node information are not available + * to find out what file and line number are affected + * + * Returns: 0 in case of success and -1 in case of error + */ + +typedef int (*xmlSchemaValidityLocatorFunc) (void *ctx, + const char **file, unsigned long *line); + +/* + * Interfaces for parsing. + */ +XMLPUBFUN xmlSchemaParserCtxtPtr + xmlSchemaNewParserCtxt (const char *URL); +XMLPUBFUN xmlSchemaParserCtxtPtr + xmlSchemaNewMemParserCtxt (const char *buffer, + int size); +XMLPUBFUN xmlSchemaParserCtxtPtr + xmlSchemaNewDocParserCtxt (xmlDocPtr doc); +XMLPUBFUN void + xmlSchemaFreeParserCtxt (xmlSchemaParserCtxtPtr ctxt); +XMLPUBFUN void + xmlSchemaSetParserErrors (xmlSchemaParserCtxtPtr ctxt, + xmlSchemaValidityErrorFunc err, + xmlSchemaValidityWarningFunc warn, + void *ctx); +XMLPUBFUN void + xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt, + xmlStructuredErrorFunc serror, + void *ctx); +XMLPUBFUN int + xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt, + xmlSchemaValidityErrorFunc * err, + xmlSchemaValidityWarningFunc * warn, + void **ctx); +XMLPUBFUN int + xmlSchemaIsValid (xmlSchemaValidCtxtPtr ctxt); + +XMLPUBFUN xmlSchemaPtr + xmlSchemaParse (xmlSchemaParserCtxtPtr ctxt); +XMLPUBFUN void + xmlSchemaFree (xmlSchemaPtr schema); +#ifdef LIBXML_OUTPUT_ENABLED +XMLPUBFUN void + xmlSchemaDump (FILE *output, + xmlSchemaPtr schema); +#endif /* LIBXML_OUTPUT_ENABLED */ +/* + * Interfaces for validating + */ +XMLPUBFUN void + xmlSchemaSetValidErrors (xmlSchemaValidCtxtPtr ctxt, + xmlSchemaValidityErrorFunc err, + xmlSchemaValidityWarningFunc warn, + void *ctx); +XMLPUBFUN void + xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt, + xmlStructuredErrorFunc serror, + void *ctx); +XMLPUBFUN int + xmlSchemaGetValidErrors (xmlSchemaValidCtxtPtr ctxt, + xmlSchemaValidityErrorFunc *err, + xmlSchemaValidityWarningFunc *warn, + void **ctx); +XMLPUBFUN int + xmlSchemaSetValidOptions (xmlSchemaValidCtxtPtr ctxt, + int options); +XMLPUBFUN void + xmlSchemaValidateSetFilename(xmlSchemaValidCtxtPtr vctxt, + const char *filename); +XMLPUBFUN int + xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt); + +XMLPUBFUN xmlSchemaValidCtxtPtr + xmlSchemaNewValidCtxt (xmlSchemaPtr schema); +XMLPUBFUN void + xmlSchemaFreeValidCtxt (xmlSchemaValidCtxtPtr ctxt); +XMLPUBFUN int + xmlSchemaValidateDoc (xmlSchemaValidCtxtPtr ctxt, + xmlDocPtr instance); +XMLPUBFUN int + xmlSchemaValidateOneElement (xmlSchemaValidCtxtPtr ctxt, + xmlNodePtr elem); +XMLPUBFUN int + xmlSchemaValidateStream (xmlSchemaValidCtxtPtr ctxt, + xmlParserInputBufferPtr input, + xmlCharEncoding enc, + xmlSAXHandlerPtr sax, + void *user_data); +XMLPUBFUN int + xmlSchemaValidateFile (xmlSchemaValidCtxtPtr ctxt, + const char * filename, + int options); + +XMLPUBFUN xmlParserCtxtPtr + xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt); + +/* + * Interface to insert Schemas SAX validation in a SAX stream + */ +typedef struct _xmlSchemaSAXPlug xmlSchemaSAXPlugStruct; +typedef xmlSchemaSAXPlugStruct *xmlSchemaSAXPlugPtr; + +XMLPUBFUN xmlSchemaSAXPlugPtr + xmlSchemaSAXPlug (xmlSchemaValidCtxtPtr ctxt, + xmlSAXHandlerPtr *sax, + void **user_data); +XMLPUBFUN int + xmlSchemaSAXUnplug (xmlSchemaSAXPlugPtr plug); + + +XMLPUBFUN void + xmlSchemaValidateSetLocator (xmlSchemaValidCtxtPtr vctxt, + xmlSchemaValidityLocatorFunc f, + void *ctxt); + +#ifdef __cplusplus +} +#endif + +#endif /* LIBXML_SCHEMAS_ENABLED */ +#endif /* __XML_SCHEMA_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlschemastypes.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlschemastypes.h new file mode 100644 index 0000000..e2cde35 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlschemastypes.h @@ -0,0 +1,152 @@ +/* + * Summary: implementation of XML Schema Datatypes + * Description: module providing the XML Schema Datatypes implementation + * both definition and validity checking + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + + +#ifndef __XML_SCHEMA_TYPES_H__ +#define __XML_SCHEMA_TYPES_H__ + +#include + +#ifdef LIBXML_SCHEMAS_ENABLED + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + XML_SCHEMA_WHITESPACE_UNKNOWN = 0, + XML_SCHEMA_WHITESPACE_PRESERVE = 1, + XML_SCHEMA_WHITESPACE_REPLACE = 2, + XML_SCHEMA_WHITESPACE_COLLAPSE = 3 +} xmlSchemaWhitespaceValueType; + +XMLPUBFUN int + xmlSchemaInitTypes (void); +XML_DEPRECATED +XMLPUBFUN void + xmlSchemaCleanupTypes (void); +XMLPUBFUN xmlSchemaTypePtr + xmlSchemaGetPredefinedType (const xmlChar *name, + const xmlChar *ns); +XMLPUBFUN int + xmlSchemaValidatePredefinedType (xmlSchemaTypePtr type, + const xmlChar *value, + xmlSchemaValPtr *val); +XMLPUBFUN int + xmlSchemaValPredefTypeNode (xmlSchemaTypePtr type, + const xmlChar *value, + xmlSchemaValPtr *val, + xmlNodePtr node); +XMLPUBFUN int + xmlSchemaValidateFacet (xmlSchemaTypePtr base, + xmlSchemaFacetPtr facet, + const xmlChar *value, + xmlSchemaValPtr val); +XMLPUBFUN int + xmlSchemaValidateFacetWhtsp (xmlSchemaFacetPtr facet, + xmlSchemaWhitespaceValueType fws, + xmlSchemaValType valType, + const xmlChar *value, + xmlSchemaValPtr val, + xmlSchemaWhitespaceValueType ws); +XMLPUBFUN void + xmlSchemaFreeValue (xmlSchemaValPtr val); +XMLPUBFUN xmlSchemaFacetPtr + xmlSchemaNewFacet (void); +XMLPUBFUN int + xmlSchemaCheckFacet (xmlSchemaFacetPtr facet, + xmlSchemaTypePtr typeDecl, + xmlSchemaParserCtxtPtr ctxt, + const xmlChar *name); +XMLPUBFUN void + xmlSchemaFreeFacet (xmlSchemaFacetPtr facet); +XMLPUBFUN int + xmlSchemaCompareValues (xmlSchemaValPtr x, + xmlSchemaValPtr y); +XMLPUBFUN xmlSchemaTypePtr + xmlSchemaGetBuiltInListSimpleTypeItemType (xmlSchemaTypePtr type); +XMLPUBFUN int + xmlSchemaValidateListSimpleTypeFacet (xmlSchemaFacetPtr facet, + const xmlChar *value, + unsigned long actualLen, + unsigned long *expectedLen); +XMLPUBFUN xmlSchemaTypePtr + xmlSchemaGetBuiltInType (xmlSchemaValType type); +XMLPUBFUN int + xmlSchemaIsBuiltInTypeFacet (xmlSchemaTypePtr type, + int facetType); +XMLPUBFUN xmlChar * + xmlSchemaCollapseString (const xmlChar *value); +XMLPUBFUN xmlChar * + xmlSchemaWhiteSpaceReplace (const xmlChar *value); +XMLPUBFUN unsigned long + xmlSchemaGetFacetValueAsULong (xmlSchemaFacetPtr facet); +XMLPUBFUN int + xmlSchemaValidateLengthFacet (xmlSchemaTypePtr type, + xmlSchemaFacetPtr facet, + const xmlChar *value, + xmlSchemaValPtr val, + unsigned long *length); +XMLPUBFUN int + xmlSchemaValidateLengthFacetWhtsp(xmlSchemaFacetPtr facet, + xmlSchemaValType valType, + const xmlChar *value, + xmlSchemaValPtr val, + unsigned long *length, + xmlSchemaWhitespaceValueType ws); +XMLPUBFUN int + xmlSchemaValPredefTypeNodeNoNorm(xmlSchemaTypePtr type, + const xmlChar *value, + xmlSchemaValPtr *val, + xmlNodePtr node); +XMLPUBFUN int + xmlSchemaGetCanonValue (xmlSchemaValPtr val, + const xmlChar **retValue); +XMLPUBFUN int + xmlSchemaGetCanonValueWhtsp (xmlSchemaValPtr val, + const xmlChar **retValue, + xmlSchemaWhitespaceValueType ws); +XMLPUBFUN int + xmlSchemaValueAppend (xmlSchemaValPtr prev, + xmlSchemaValPtr cur); +XMLPUBFUN xmlSchemaValPtr + xmlSchemaValueGetNext (xmlSchemaValPtr cur); +XMLPUBFUN const xmlChar * + xmlSchemaValueGetAsString (xmlSchemaValPtr val); +XMLPUBFUN int + xmlSchemaValueGetAsBoolean (xmlSchemaValPtr val); +XMLPUBFUN xmlSchemaValPtr + xmlSchemaNewStringValue (xmlSchemaValType type, + const xmlChar *value); +XMLPUBFUN xmlSchemaValPtr + xmlSchemaNewNOTATIONValue (const xmlChar *name, + const xmlChar *ns); +XMLPUBFUN xmlSchemaValPtr + xmlSchemaNewQNameValue (const xmlChar *namespaceName, + const xmlChar *localName); +XMLPUBFUN int + xmlSchemaCompareValuesWhtsp (xmlSchemaValPtr x, + xmlSchemaWhitespaceValueType xws, + xmlSchemaValPtr y, + xmlSchemaWhitespaceValueType yws); +XMLPUBFUN xmlSchemaValPtr + xmlSchemaCopyValue (xmlSchemaValPtr val); +XMLPUBFUN xmlSchemaValType + xmlSchemaGetValType (xmlSchemaValPtr val); + +#ifdef __cplusplus +} +#endif + +#endif /* LIBXML_SCHEMAS_ENABLED */ +#endif /* __XML_SCHEMA_TYPES_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlstring.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlstring.h new file mode 100644 index 0000000..db11a0b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlstring.h @@ -0,0 +1,140 @@ +/* + * Summary: set of routines to process strings + * Description: type and interfaces needed for the internal string handling + * of the library, especially UTF8 processing. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_STRING_H__ +#define __XML_STRING_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * xmlChar: + * + * This is a basic byte in an UTF-8 encoded string. + * It's unsigned allowing to pinpoint case where char * are assigned + * to xmlChar * (possibly making serialization back impossible). + */ +typedef unsigned char xmlChar; + +/** + * BAD_CAST: + * + * Macro to cast a string to an xmlChar * when one know its safe. + */ +#define BAD_CAST (xmlChar *) + +/* + * xmlChar handling + */ +XMLPUBFUN xmlChar * + xmlStrdup (const xmlChar *cur); +XMLPUBFUN xmlChar * + xmlStrndup (const xmlChar *cur, + int len); +XMLPUBFUN xmlChar * + xmlCharStrndup (const char *cur, + int len); +XMLPUBFUN xmlChar * + xmlCharStrdup (const char *cur); +XMLPUBFUN xmlChar * + xmlStrsub (const xmlChar *str, + int start, + int len); +XMLPUBFUN const xmlChar * + xmlStrchr (const xmlChar *str, + xmlChar val); +XMLPUBFUN const xmlChar * + xmlStrstr (const xmlChar *str, + const xmlChar *val); +XMLPUBFUN const xmlChar * + xmlStrcasestr (const xmlChar *str, + const xmlChar *val); +XMLPUBFUN int + xmlStrcmp (const xmlChar *str1, + const xmlChar *str2); +XMLPUBFUN int + xmlStrncmp (const xmlChar *str1, + const xmlChar *str2, + int len); +XMLPUBFUN int + xmlStrcasecmp (const xmlChar *str1, + const xmlChar *str2); +XMLPUBFUN int + xmlStrncasecmp (const xmlChar *str1, + const xmlChar *str2, + int len); +XMLPUBFUN int + xmlStrEqual (const xmlChar *str1, + const xmlChar *str2); +XMLPUBFUN int + xmlStrQEqual (const xmlChar *pref, + const xmlChar *name, + const xmlChar *str); +XMLPUBFUN int + xmlStrlen (const xmlChar *str); +XMLPUBFUN xmlChar * + xmlStrcat (xmlChar *cur, + const xmlChar *add); +XMLPUBFUN xmlChar * + xmlStrncat (xmlChar *cur, + const xmlChar *add, + int len); +XMLPUBFUN xmlChar * + xmlStrncatNew (const xmlChar *str1, + const xmlChar *str2, + int len); +XMLPUBFUN int + xmlStrPrintf (xmlChar *buf, + int len, + const char *msg, + ...) LIBXML_ATTR_FORMAT(3,4); +XMLPUBFUN int + xmlStrVPrintf (xmlChar *buf, + int len, + const char *msg, + va_list ap) LIBXML_ATTR_FORMAT(3,0); + +XMLPUBFUN int + xmlGetUTF8Char (const unsigned char *utf, + int *len); +XMLPUBFUN int + xmlCheckUTF8 (const unsigned char *utf); +XMLPUBFUN int + xmlUTF8Strsize (const xmlChar *utf, + int len); +XMLPUBFUN xmlChar * + xmlUTF8Strndup (const xmlChar *utf, + int len); +XMLPUBFUN const xmlChar * + xmlUTF8Strpos (const xmlChar *utf, + int pos); +XMLPUBFUN int + xmlUTF8Strloc (const xmlChar *utf, + const xmlChar *utfchar); +XMLPUBFUN xmlChar * + xmlUTF8Strsub (const xmlChar *utf, + int start, + int len); +XMLPUBFUN int + xmlUTF8Strlen (const xmlChar *utf); +XMLPUBFUN int + xmlUTF8Size (const xmlChar *utf); +XMLPUBFUN int + xmlUTF8Charcmp (const xmlChar *utf1, + const xmlChar *utf2); + +#ifdef __cplusplus +} +#endif +#endif /* __XML_STRING_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlunicode.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlunicode.h new file mode 100644 index 0000000..b6d795b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlunicode.h @@ -0,0 +1,366 @@ +/* + * Summary: Unicode character APIs + * Description: API for the Unicode character APIs + * + * This file is automatically generated from the + * UCS description files of the Unicode Character Database + * http://www.unicode.org/Public/4.0-Update1/UCD-4.0.1.html + * using the genUnicode.py Python script. + * + * Generation date: Tue Apr 30 17:30:38 2024 + * Sources: Blocks-4.0.1.txt UnicodeData-4.0.1.txt + * Author: Daniel Veillard + */ + +#ifndef __XML_UNICODE_H__ +#define __XML_UNICODE_H__ + +#include + +#ifdef LIBXML_UNICODE_ENABLED + +#ifdef __cplusplus +extern "C" { +#endif + +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsAegeanNumbers (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsAlphabeticPresentationForms (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsArabic (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsArabicPresentationFormsA (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsArabicPresentationFormsB (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsArmenian (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsArrows (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsBasicLatin (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsBengali (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsBlockElements (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsBopomofo (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsBopomofoExtended (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsBoxDrawing (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsBraillePatterns (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsBuhid (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsByzantineMusicalSymbols (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCJKCompatibility (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCJKCompatibilityForms (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCJKCompatibilityIdeographs (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCJKCompatibilityIdeographsSupplement (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCJKRadicalsSupplement (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCJKSymbolsandPunctuation (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCJKUnifiedIdeographs (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCJKUnifiedIdeographsExtensionA (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCJKUnifiedIdeographsExtensionB (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCherokee (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCombiningDiacriticalMarks (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCombiningDiacriticalMarksforSymbols (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCombiningHalfMarks (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCombiningMarksforSymbols (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsControlPictures (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCurrencySymbols (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCypriotSyllabary (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCyrillic (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCyrillicSupplement (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsDeseret (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsDevanagari (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsDingbats (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsEnclosedAlphanumerics (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsEnclosedCJKLettersandMonths (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsEthiopic (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsGeneralPunctuation (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsGeometricShapes (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsGeorgian (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsGothic (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsGreek (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsGreekExtended (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsGreekandCoptic (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsGujarati (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsGurmukhi (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsHalfwidthandFullwidthForms (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsHangulCompatibilityJamo (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsHangulJamo (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsHangulSyllables (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsHanunoo (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsHebrew (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsHighPrivateUseSurrogates (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsHighSurrogates (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsHiragana (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsIPAExtensions (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsIdeographicDescriptionCharacters (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsKanbun (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsKangxiRadicals (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsKannada (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsKatakana (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsKatakanaPhoneticExtensions (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsKhmer (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsKhmerSymbols (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsLao (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsLatin1Supplement (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsLatinExtendedA (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsLatinExtendedB (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsLatinExtendedAdditional (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsLetterlikeSymbols (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsLimbu (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsLinearBIdeograms (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsLinearBSyllabary (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsLowSurrogates (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsMalayalam (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsMathematicalAlphanumericSymbols (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsMathematicalOperators (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsMiscellaneousMathematicalSymbolsA (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsMiscellaneousMathematicalSymbolsB (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsMiscellaneousSymbols (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsMiscellaneousSymbolsandArrows (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsMiscellaneousTechnical (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsMongolian (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsMusicalSymbols (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsMyanmar (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsNumberForms (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsOgham (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsOldItalic (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsOpticalCharacterRecognition (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsOriya (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsOsmanya (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsPhoneticExtensions (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsPrivateUse (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsPrivateUseArea (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsRunic (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsShavian (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsSinhala (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsSmallFormVariants (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsSpacingModifierLetters (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsSpecials (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsSuperscriptsandSubscripts (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsSupplementalArrowsA (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsSupplementalArrowsB (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsSupplementalMathematicalOperators (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsSupplementaryPrivateUseAreaA (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsSupplementaryPrivateUseAreaB (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsSyriac (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsTagalog (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsTagbanwa (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsTags (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsTaiLe (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsTaiXuanJingSymbols (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsTamil (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsTelugu (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsThaana (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsThai (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsTibetan (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsUgaritic (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsUnifiedCanadianAboriginalSyllabics (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsVariationSelectors (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsVariationSelectorsSupplement (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsYiRadicals (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsYiSyllables (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsYijingHexagramSymbols (int code); + +XMLPUBFUN int xmlUCSIsBlock (int code, const char *block); + +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatC (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatCc (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatCf (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatCo (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatCs (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatL (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatLl (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatLm (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatLo (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatLt (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatLu (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatM (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatMc (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatMe (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatMn (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatN (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatNd (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatNl (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatNo (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatP (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatPc (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatPd (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatPe (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatPf (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatPi (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatPo (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatPs (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatS (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatSc (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatSk (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatSm (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatSo (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatZ (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatZl (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatZp (int code); +XML_DEPRECATED +XMLPUBFUN int xmlUCSIsCatZs (int code); + +XMLPUBFUN int xmlUCSIsCat (int code, const char *cat); + +#ifdef __cplusplus +} +#endif + +#endif /* LIBXML_UNICODE_ENABLED */ + +#endif /* __XML_UNICODE_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlversion.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlversion.h new file mode 100644 index 0000000..59c08cf --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlversion.h @@ -0,0 +1,347 @@ +/* + * Summary: compile-time version information + * Description: compile-time version information for the XML library + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_VERSION_H__ +#define __XML_VERSION_H__ + +/** + * LIBXML_DOTTED_VERSION: + * + * the version string like "1.2.3" + */ +#define LIBXML_DOTTED_VERSION "2.13.9" + +/** + * LIBXML_VERSION: + * + * the version number: 1.2.3 value is 10203 + */ +#define LIBXML_VERSION 21309 + +/** + * LIBXML_VERSION_STRING: + * + * the version number string, 1.2.3 value is "10203" + */ +#define LIBXML_VERSION_STRING "21309" + +/** + * LIBXML_VERSION_EXTRA: + * + * extra version information, used to show a git commit description + */ +#define LIBXML_VERSION_EXTRA "" + +/** + * LIBXML_TEST_VERSION: + * + * Macro to check that the libxml version in use is compatible with + * the version the software has been compiled against + */ +#define LIBXML_TEST_VERSION xmlCheckVersion(21309); + +/** + * LIBXML_THREAD_ENABLED: + * + * Whether the thread support is configured in + */ +#if 1 +#define LIBXML_THREAD_ENABLED +#endif + +/** + * LIBXML_THREAD_ALLOC_ENABLED: + * + * Whether the allocation hooks are per-thread + */ +#if 0 +#define LIBXML_THREAD_ALLOC_ENABLED +#endif + +/** + * LIBXML_TREE_ENABLED: + * + * Whether the DOM like tree manipulation API support is configured in + */ +#if 1 +#define LIBXML_TREE_ENABLED +#endif + +/** + * LIBXML_OUTPUT_ENABLED: + * + * Whether the serialization/saving support is configured in + */ +#if 1 +#define LIBXML_OUTPUT_ENABLED +#endif + +/** + * LIBXML_PUSH_ENABLED: + * + * Whether the push parsing interfaces are configured in + */ +#if 1 +#define LIBXML_PUSH_ENABLED +#endif + +/** + * LIBXML_READER_ENABLED: + * + * Whether the xmlReader parsing interface is configured in + */ +#if 1 +#define LIBXML_READER_ENABLED +#endif + +/** + * LIBXML_PATTERN_ENABLED: + * + * Whether the xmlPattern node selection interface is configured in + */ +#if 1 +#define LIBXML_PATTERN_ENABLED +#endif + +/** + * LIBXML_WRITER_ENABLED: + * + * Whether the xmlWriter saving interface is configured in + */ +#if 1 +#define LIBXML_WRITER_ENABLED +#endif + +/** + * LIBXML_SAX1_ENABLED: + * + * Whether the older SAX1 interface is configured in + */ +#if 1 +#define LIBXML_SAX1_ENABLED +#endif + +/** + * LIBXML_FTP_ENABLED: + * + * Whether the FTP support is configured in + */ +#if 0 +#define LIBXML_FTP_ENABLED +#endif + +/** + * LIBXML_HTTP_ENABLED: + * + * Whether the HTTP support is configured in + */ +#if 1 +#define LIBXML_HTTP_ENABLED +#endif + +/** + * LIBXML_VALID_ENABLED: + * + * Whether the DTD validation support is configured in + */ +#if 1 +#define LIBXML_VALID_ENABLED +#endif + +/** + * LIBXML_HTML_ENABLED: + * + * Whether the HTML support is configured in + */ +#if 1 +#define LIBXML_HTML_ENABLED +#endif + +/** + * LIBXML_LEGACY_ENABLED: + * + * Whether the deprecated APIs are compiled in for compatibility + */ +#if 1 +#define LIBXML_LEGACY_ENABLED +#endif + +/** + * LIBXML_C14N_ENABLED: + * + * Whether the Canonicalization support is configured in + */ +#if 1 +#define LIBXML_C14N_ENABLED +#endif + +/** + * LIBXML_CATALOG_ENABLED: + * + * Whether the Catalog support is configured in + */ +#if 1 +#define LIBXML_CATALOG_ENABLED +#endif + +/** + * LIBXML_XPATH_ENABLED: + * + * Whether XPath is configured in + */ +#if 1 +#define LIBXML_XPATH_ENABLED +#endif + +/** + * LIBXML_XPTR_ENABLED: + * + * Whether XPointer is configured in + */ +#if 1 +#define LIBXML_XPTR_ENABLED +#endif + +/** + * LIBXML_XPTR_LOCS_ENABLED: + * + * Whether support for XPointer locations is configured in + */ +#if 0 +#define LIBXML_XPTR_LOCS_ENABLED +#endif + +/** + * LIBXML_XINCLUDE_ENABLED: + * + * Whether XInclude is configured in + */ +#if 1 +#define LIBXML_XINCLUDE_ENABLED +#endif + +/** + * LIBXML_ICONV_ENABLED: + * + * Whether iconv support is available + */ +#if 1 +#define LIBXML_ICONV_ENABLED +#endif + +/** + * LIBXML_ICU_ENABLED: + * + * Whether icu support is available + */ +#if 0 +#define LIBXML_ICU_ENABLED +#endif + +/** + * LIBXML_ISO8859X_ENABLED: + * + * Whether ISO-8859-* support is made available in case iconv is not + */ +#if 1 +#define LIBXML_ISO8859X_ENABLED +#endif + +/** + * LIBXML_DEBUG_ENABLED: + * + * Whether Debugging module is configured in + */ +#if 1 +#define LIBXML_DEBUG_ENABLED +#endif + +/** + * LIBXML_UNICODE_ENABLED: + * + * Whether the Unicode related interfaces are compiled in + */ +#if 1 +#define LIBXML_UNICODE_ENABLED +#endif + +/** + * LIBXML_REGEXP_ENABLED: + * + * Whether the regular expressions interfaces are compiled in + */ +#if 1 +#define LIBXML_REGEXP_ENABLED +#endif + +/** + * LIBXML_AUTOMATA_ENABLED: + * + * Whether the automata interfaces are compiled in + */ +#if 1 +#define LIBXML_AUTOMATA_ENABLED +#endif + +/** + * LIBXML_SCHEMAS_ENABLED: + * + * Whether the Schemas validation interfaces are compiled in + */ +#if 1 +#define LIBXML_SCHEMAS_ENABLED +#endif + +/** + * LIBXML_SCHEMATRON_ENABLED: + * + * Whether the Schematron validation interfaces are compiled in + */ +#if 1 +#define LIBXML_SCHEMATRON_ENABLED +#endif + +/** + * LIBXML_MODULES_ENABLED: + * + * Whether the module interfaces are compiled in + */ +#if 1 +#define LIBXML_MODULES_ENABLED +/** + * LIBXML_MODULE_EXTENSION: + * + * the string suffix used by dynamic modules (usually shared libraries) + */ +#define LIBXML_MODULE_EXTENSION ".so" +#endif + +/** + * LIBXML_ZLIB_ENABLED: + * + * Whether the Zlib support is compiled in + */ +#if 1 +#define LIBXML_ZLIB_ENABLED +#endif + +/** + * LIBXML_LZMA_ENABLED: + * + * Whether the Lzma support is compiled in + */ +#if 0 +#define LIBXML_LZMA_ENABLED +#endif + +#include + +#endif + + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlwriter.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlwriter.h new file mode 100644 index 0000000..55f88bc --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xmlwriter.h @@ -0,0 +1,489 @@ +/* + * Summary: text writing API for XML + * Description: text writing API for XML + * + * Copy: See Copyright for the status of this software. + * + * Author: Alfred Mickautsch + */ + +#ifndef __XML_XMLWRITER_H__ +#define __XML_XMLWRITER_H__ + +#include + +#ifdef LIBXML_WRITER_ENABLED + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + typedef struct _xmlTextWriter xmlTextWriter; + typedef xmlTextWriter *xmlTextWriterPtr; + +/* + * Constructors & Destructor + */ + XMLPUBFUN xmlTextWriterPtr + xmlNewTextWriter(xmlOutputBufferPtr out); + XMLPUBFUN xmlTextWriterPtr + xmlNewTextWriterFilename(const char *uri, int compression); + XMLPUBFUN xmlTextWriterPtr + xmlNewTextWriterMemory(xmlBufferPtr buf, int compression); + XMLPUBFUN xmlTextWriterPtr + xmlNewTextWriterPushParser(xmlParserCtxtPtr ctxt, int compression); + XMLPUBFUN xmlTextWriterPtr + xmlNewTextWriterDoc(xmlDocPtr * doc, int compression); + XMLPUBFUN xmlTextWriterPtr + xmlNewTextWriterTree(xmlDocPtr doc, xmlNodePtr node, + int compression); + XMLPUBFUN void xmlFreeTextWriter(xmlTextWriterPtr writer); + +/* + * Functions + */ + + +/* + * Document + */ + XMLPUBFUN int + xmlTextWriterStartDocument(xmlTextWriterPtr writer, + const char *version, + const char *encoding, + const char *standalone); + XMLPUBFUN int xmlTextWriterEndDocument(xmlTextWriterPtr + writer); + +/* + * Comments + */ + XMLPUBFUN int xmlTextWriterStartComment(xmlTextWriterPtr + writer); + XMLPUBFUN int xmlTextWriterEndComment(xmlTextWriterPtr writer); + XMLPUBFUN int + xmlTextWriterWriteFormatComment(xmlTextWriterPtr writer, + const char *format, ...) + LIBXML_ATTR_FORMAT(2,3); + XMLPUBFUN int + xmlTextWriterWriteVFormatComment(xmlTextWriterPtr writer, + const char *format, + va_list argptr) + LIBXML_ATTR_FORMAT(2,0); + XMLPUBFUN int xmlTextWriterWriteComment(xmlTextWriterPtr + writer, + const xmlChar * + content); + +/* + * Elements + */ + XMLPUBFUN int + xmlTextWriterStartElement(xmlTextWriterPtr writer, + const xmlChar * name); + XMLPUBFUN int xmlTextWriterStartElementNS(xmlTextWriterPtr + writer, + const xmlChar * + prefix, + const xmlChar * name, + const xmlChar * + namespaceURI); + XMLPUBFUN int xmlTextWriterEndElement(xmlTextWriterPtr writer); + XMLPUBFUN int xmlTextWriterFullEndElement(xmlTextWriterPtr + writer); + +/* + * Elements conveniency functions + */ + XMLPUBFUN int + xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer, + const xmlChar * name, + const char *format, ...) + LIBXML_ATTR_FORMAT(3,4); + XMLPUBFUN int + xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer, + const xmlChar * name, + const char *format, + va_list argptr) + LIBXML_ATTR_FORMAT(3,0); + XMLPUBFUN int xmlTextWriterWriteElement(xmlTextWriterPtr + writer, + const xmlChar * name, + const xmlChar * + content); + XMLPUBFUN int + xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer, + const xmlChar * prefix, + const xmlChar * name, + const xmlChar * namespaceURI, + const char *format, ...) + LIBXML_ATTR_FORMAT(5,6); + XMLPUBFUN int + xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer, + const xmlChar * prefix, + const xmlChar * name, + const xmlChar * namespaceURI, + const char *format, + va_list argptr) + LIBXML_ATTR_FORMAT(5,0); + XMLPUBFUN int xmlTextWriterWriteElementNS(xmlTextWriterPtr + writer, + const xmlChar * + prefix, + const xmlChar * name, + const xmlChar * + namespaceURI, + const xmlChar * + content); + +/* + * Text + */ + XMLPUBFUN int + xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer, + const char *format, ...) + LIBXML_ATTR_FORMAT(2,3); + XMLPUBFUN int + xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer, + const char *format, va_list argptr) + LIBXML_ATTR_FORMAT(2,0); + XMLPUBFUN int + xmlTextWriterWriteRawLen(xmlTextWriterPtr writer, + const xmlChar * content, int len); + XMLPUBFUN int + xmlTextWriterWriteRaw(xmlTextWriterPtr writer, + const xmlChar * content); + XMLPUBFUN int xmlTextWriterWriteFormatString(xmlTextWriterPtr + writer, + const char + *format, ...) + LIBXML_ATTR_FORMAT(2,3); + XMLPUBFUN int xmlTextWriterWriteVFormatString(xmlTextWriterPtr + writer, + const char + *format, + va_list argptr) + LIBXML_ATTR_FORMAT(2,0); + XMLPUBFUN int xmlTextWriterWriteString(xmlTextWriterPtr writer, + const xmlChar * + content); + XMLPUBFUN int xmlTextWriterWriteBase64(xmlTextWriterPtr writer, + const char *data, + int start, int len); + XMLPUBFUN int xmlTextWriterWriteBinHex(xmlTextWriterPtr writer, + const char *data, + int start, int len); + +/* + * Attributes + */ + XMLPUBFUN int + xmlTextWriterStartAttribute(xmlTextWriterPtr writer, + const xmlChar * name); + XMLPUBFUN int xmlTextWriterStartAttributeNS(xmlTextWriterPtr + writer, + const xmlChar * + prefix, + const xmlChar * + name, + const xmlChar * + namespaceURI); + XMLPUBFUN int xmlTextWriterEndAttribute(xmlTextWriterPtr + writer); + +/* + * Attributes conveniency functions + */ + XMLPUBFUN int + xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer, + const xmlChar * name, + const char *format, ...) + LIBXML_ATTR_FORMAT(3,4); + XMLPUBFUN int + xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer, + const xmlChar * name, + const char *format, + va_list argptr) + LIBXML_ATTR_FORMAT(3,0); + XMLPUBFUN int xmlTextWriterWriteAttribute(xmlTextWriterPtr + writer, + const xmlChar * name, + const xmlChar * + content); + XMLPUBFUN int + xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer, + const xmlChar * prefix, + const xmlChar * name, + const xmlChar * namespaceURI, + const char *format, ...) + LIBXML_ATTR_FORMAT(5,6); + XMLPUBFUN int + xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer, + const xmlChar * prefix, + const xmlChar * name, + const xmlChar * namespaceURI, + const char *format, + va_list argptr) + LIBXML_ATTR_FORMAT(5,0); + XMLPUBFUN int xmlTextWriterWriteAttributeNS(xmlTextWriterPtr + writer, + const xmlChar * + prefix, + const xmlChar * + name, + const xmlChar * + namespaceURI, + const xmlChar * + content); + +/* + * PI's + */ + XMLPUBFUN int + xmlTextWriterStartPI(xmlTextWriterPtr writer, + const xmlChar * target); + XMLPUBFUN int xmlTextWriterEndPI(xmlTextWriterPtr writer); + +/* + * PI conveniency functions + */ + XMLPUBFUN int + xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer, + const xmlChar * target, + const char *format, ...) + LIBXML_ATTR_FORMAT(3,4); + XMLPUBFUN int + xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer, + const xmlChar * target, + const char *format, va_list argptr) + LIBXML_ATTR_FORMAT(3,0); + XMLPUBFUN int + xmlTextWriterWritePI(xmlTextWriterPtr writer, + const xmlChar * target, + const xmlChar * content); + +/** + * xmlTextWriterWriteProcessingInstruction: + * + * This macro maps to xmlTextWriterWritePI + */ +#define xmlTextWriterWriteProcessingInstruction xmlTextWriterWritePI + +/* + * CDATA + */ + XMLPUBFUN int xmlTextWriterStartCDATA(xmlTextWriterPtr writer); + XMLPUBFUN int xmlTextWriterEndCDATA(xmlTextWriterPtr writer); + +/* + * CDATA conveniency functions + */ + XMLPUBFUN int + xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer, + const char *format, ...) + LIBXML_ATTR_FORMAT(2,3); + XMLPUBFUN int + xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer, + const char *format, va_list argptr) + LIBXML_ATTR_FORMAT(2,0); + XMLPUBFUN int + xmlTextWriterWriteCDATA(xmlTextWriterPtr writer, + const xmlChar * content); + +/* + * DTD + */ + XMLPUBFUN int + xmlTextWriterStartDTD(xmlTextWriterPtr writer, + const xmlChar * name, + const xmlChar * pubid, + const xmlChar * sysid); + XMLPUBFUN int xmlTextWriterEndDTD(xmlTextWriterPtr writer); + +/* + * DTD conveniency functions + */ + XMLPUBFUN int + xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer, + const xmlChar * name, + const xmlChar * pubid, + const xmlChar * sysid, + const char *format, ...) + LIBXML_ATTR_FORMAT(5,6); + XMLPUBFUN int + xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer, + const xmlChar * name, + const xmlChar * pubid, + const xmlChar * sysid, + const char *format, va_list argptr) + LIBXML_ATTR_FORMAT(5,0); + XMLPUBFUN int + xmlTextWriterWriteDTD(xmlTextWriterPtr writer, + const xmlChar * name, + const xmlChar * pubid, + const xmlChar * sysid, + const xmlChar * subset); + +/** + * xmlTextWriterWriteDocType: + * + * this macro maps to xmlTextWriterWriteDTD + */ +#define xmlTextWriterWriteDocType xmlTextWriterWriteDTD + +/* + * DTD element definition + */ + XMLPUBFUN int + xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, + const xmlChar * name); + XMLPUBFUN int xmlTextWriterEndDTDElement(xmlTextWriterPtr + writer); + +/* + * DTD element definition conveniency functions + */ + XMLPUBFUN int + xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer, + const xmlChar * name, + const char *format, ...) + LIBXML_ATTR_FORMAT(3,4); + XMLPUBFUN int + xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer, + const xmlChar * name, + const char *format, + va_list argptr) + LIBXML_ATTR_FORMAT(3,0); + XMLPUBFUN int xmlTextWriterWriteDTDElement(xmlTextWriterPtr + writer, + const xmlChar * + name, + const xmlChar * + content); + +/* + * DTD attribute list definition + */ + XMLPUBFUN int + xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, + const xmlChar * name); + XMLPUBFUN int xmlTextWriterEndDTDAttlist(xmlTextWriterPtr + writer); + +/* + * DTD attribute list definition conveniency functions + */ + XMLPUBFUN int + xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer, + const xmlChar * name, + const char *format, ...) + LIBXML_ATTR_FORMAT(3,4); + XMLPUBFUN int + xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer, + const xmlChar * name, + const char *format, + va_list argptr) + LIBXML_ATTR_FORMAT(3,0); + XMLPUBFUN int xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr + writer, + const xmlChar * + name, + const xmlChar * + content); + +/* + * DTD entity definition + */ + XMLPUBFUN int + xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer, + int pe, const xmlChar * name); + XMLPUBFUN int xmlTextWriterEndDTDEntity(xmlTextWriterPtr + writer); + +/* + * DTD entity definition conveniency functions + */ + XMLPUBFUN int + xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer, + int pe, + const xmlChar * name, + const char *format, ...) + LIBXML_ATTR_FORMAT(4,5); + XMLPUBFUN int + xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer, + int pe, + const xmlChar * name, + const char *format, + va_list argptr) + LIBXML_ATTR_FORMAT(4,0); + XMLPUBFUN int + xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer, + int pe, + const xmlChar * name, + const xmlChar * content); + XMLPUBFUN int + xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer, + int pe, + const xmlChar * name, + const xmlChar * pubid, + const xmlChar * sysid, + const xmlChar * ndataid); + XMLPUBFUN int + xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriterPtr + writer, + const xmlChar * pubid, + const xmlChar * sysid, + const xmlChar * + ndataid); + XMLPUBFUN int xmlTextWriterWriteDTDEntity(xmlTextWriterPtr + writer, int pe, + const xmlChar * name, + const xmlChar * + pubid, + const xmlChar * + sysid, + const xmlChar * + ndataid, + const xmlChar * + content); + +/* + * DTD notation definition + */ + XMLPUBFUN int + xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer, + const xmlChar * name, + const xmlChar * pubid, + const xmlChar * sysid); + +/* + * Indentation + */ + XMLPUBFUN int + xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent); + XMLPUBFUN int + xmlTextWriterSetIndentString(xmlTextWriterPtr writer, + const xmlChar * str); + + XMLPUBFUN int + xmlTextWriterSetQuoteChar(xmlTextWriterPtr writer, xmlChar quotechar); + + +/* + * misc + */ + XMLPUBFUN int xmlTextWriterFlush(xmlTextWriterPtr writer); + XMLPUBFUN int xmlTextWriterClose(xmlTextWriterPtr writer); + +#ifdef __cplusplus +} +#endif + +#endif /* LIBXML_WRITER_ENABLED */ + +#endif /* __XML_XMLWRITER_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xpath.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xpath.h new file mode 100644 index 0000000..b89e105 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xpath.h @@ -0,0 +1,579 @@ +/* + * Summary: XML Path Language implementation + * Description: API for the XML Path Language implementation + * + * XML Path Language implementation + * XPath is a language for addressing parts of an XML document, + * designed to be used by both XSLT and XPointer + * http://www.w3.org/TR/xpath + * + * Implements + * W3C Recommendation 16 November 1999 + * http://www.w3.org/TR/1999/REC-xpath-19991116 + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_XPATH_H__ +#define __XML_XPATH_H__ + +#include + +#ifdef LIBXML_XPATH_ENABLED + +#include +#include +#include +#endif /* LIBXML_XPATH_ENABLED */ + +#if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) +#ifdef __cplusplus +extern "C" { +#endif +#endif /* LIBXML_XPATH_ENABLED or LIBXML_SCHEMAS_ENABLED */ + +#ifdef LIBXML_XPATH_ENABLED + +typedef struct _xmlXPathContext xmlXPathContext; +typedef xmlXPathContext *xmlXPathContextPtr; +typedef struct _xmlXPathParserContext xmlXPathParserContext; +typedef xmlXPathParserContext *xmlXPathParserContextPtr; + +/** + * The set of XPath error codes. + */ + +typedef enum { + XPATH_EXPRESSION_OK = 0, + XPATH_NUMBER_ERROR, + XPATH_UNFINISHED_LITERAL_ERROR, + XPATH_START_LITERAL_ERROR, + XPATH_VARIABLE_REF_ERROR, + XPATH_UNDEF_VARIABLE_ERROR, + XPATH_INVALID_PREDICATE_ERROR, + XPATH_EXPR_ERROR, + XPATH_UNCLOSED_ERROR, + XPATH_UNKNOWN_FUNC_ERROR, + XPATH_INVALID_OPERAND, + XPATH_INVALID_TYPE, + XPATH_INVALID_ARITY, + XPATH_INVALID_CTXT_SIZE, + XPATH_INVALID_CTXT_POSITION, + XPATH_MEMORY_ERROR, + XPTR_SYNTAX_ERROR, + XPTR_RESOURCE_ERROR, + XPTR_SUB_RESOURCE_ERROR, + XPATH_UNDEF_PREFIX_ERROR, + XPATH_ENCODING_ERROR, + XPATH_INVALID_CHAR_ERROR, + XPATH_INVALID_CTXT, + XPATH_STACK_ERROR, + XPATH_FORBID_VARIABLE_ERROR, + XPATH_OP_LIMIT_EXCEEDED, + XPATH_RECURSION_LIMIT_EXCEEDED +} xmlXPathError; + +/* + * A node-set (an unordered collection of nodes without duplicates). + */ +typedef struct _xmlNodeSet xmlNodeSet; +typedef xmlNodeSet *xmlNodeSetPtr; +struct _xmlNodeSet { + int nodeNr; /* number of nodes in the set */ + int nodeMax; /* size of the array as allocated */ + xmlNodePtr *nodeTab; /* array of nodes in no particular order */ + /* @@ with_ns to check whether namespace nodes should be looked at @@ */ +}; + +/* + * An expression is evaluated to yield an object, which + * has one of the following four basic types: + * - node-set + * - boolean + * - number + * - string + * + * @@ XPointer will add more types ! + */ + +typedef enum { + XPATH_UNDEFINED = 0, + XPATH_NODESET = 1, + XPATH_BOOLEAN = 2, + XPATH_NUMBER = 3, + XPATH_STRING = 4, +#ifdef LIBXML_XPTR_LOCS_ENABLED + XPATH_POINT = 5, + XPATH_RANGE = 6, + XPATH_LOCATIONSET = 7, +#endif + XPATH_USERS = 8, + XPATH_XSLT_TREE = 9 /* An XSLT value tree, non modifiable */ +} xmlXPathObjectType; + +#ifndef LIBXML_XPTR_LOCS_ENABLED +/** DOC_DISABLE */ +#define XPATH_POINT 5 +#define XPATH_RANGE 6 +#define XPATH_LOCATIONSET 7 +/** DOC_ENABLE */ +#endif + +typedef struct _xmlXPathObject xmlXPathObject; +typedef xmlXPathObject *xmlXPathObjectPtr; +struct _xmlXPathObject { + xmlXPathObjectType type; + xmlNodeSetPtr nodesetval; + int boolval; + double floatval; + xmlChar *stringval; + void *user; + int index; + void *user2; + int index2; +}; + +/** + * xmlXPathConvertFunc: + * @obj: an XPath object + * @type: the number of the target type + * + * A conversion function is associated to a type and used to cast + * the new type to primitive values. + * + * Returns -1 in case of error, 0 otherwise + */ +typedef int (*xmlXPathConvertFunc) (xmlXPathObjectPtr obj, int type); + +/* + * Extra type: a name and a conversion function. + */ + +typedef struct _xmlXPathType xmlXPathType; +typedef xmlXPathType *xmlXPathTypePtr; +struct _xmlXPathType { + const xmlChar *name; /* the type name */ + xmlXPathConvertFunc func; /* the conversion function */ +}; + +/* + * Extra variable: a name and a value. + */ + +typedef struct _xmlXPathVariable xmlXPathVariable; +typedef xmlXPathVariable *xmlXPathVariablePtr; +struct _xmlXPathVariable { + const xmlChar *name; /* the variable name */ + xmlXPathObjectPtr value; /* the value */ +}; + +/** + * xmlXPathEvalFunc: + * @ctxt: an XPath parser context + * @nargs: the number of arguments passed to the function + * + * An XPath evaluation function, the parameters are on the XPath context stack. + */ + +typedef void (*xmlXPathEvalFunc)(xmlXPathParserContextPtr ctxt, + int nargs); + +/* + * Extra function: a name and a evaluation function. + */ + +typedef struct _xmlXPathFunct xmlXPathFunct; +typedef xmlXPathFunct *xmlXPathFuncPtr; +struct _xmlXPathFunct { + const xmlChar *name; /* the function name */ + xmlXPathEvalFunc func; /* the evaluation function */ +}; + +/** + * xmlXPathAxisFunc: + * @ctxt: the XPath interpreter context + * @cur: the previous node being explored on that axis + * + * An axis traversal function. To traverse an axis, the engine calls + * the first time with cur == NULL and repeat until the function returns + * NULL indicating the end of the axis traversal. + * + * Returns the next node in that axis or NULL if at the end of the axis. + */ + +typedef xmlXPathObjectPtr (*xmlXPathAxisFunc) (xmlXPathParserContextPtr ctxt, + xmlXPathObjectPtr cur); + +/* + * Extra axis: a name and an axis function. + */ + +typedef struct _xmlXPathAxis xmlXPathAxis; +typedef xmlXPathAxis *xmlXPathAxisPtr; +struct _xmlXPathAxis { + const xmlChar *name; /* the axis name */ + xmlXPathAxisFunc func; /* the search function */ +}; + +/** + * xmlXPathFunction: + * @ctxt: the XPath interprestation context + * @nargs: the number of arguments + * + * An XPath function. + * The arguments (if any) are popped out from the context stack + * and the result is pushed on the stack. + */ + +typedef void (*xmlXPathFunction) (xmlXPathParserContextPtr ctxt, int nargs); + +/* + * Function and Variable Lookup. + */ + +/** + * xmlXPathVariableLookupFunc: + * @ctxt: an XPath context + * @name: name of the variable + * @ns_uri: the namespace name hosting this variable + * + * Prototype for callbacks used to plug variable lookup in the XPath + * engine. + * + * Returns the XPath object value or NULL if not found. + */ +typedef xmlXPathObjectPtr (*xmlXPathVariableLookupFunc) (void *ctxt, + const xmlChar *name, + const xmlChar *ns_uri); + +/** + * xmlXPathFuncLookupFunc: + * @ctxt: an XPath context + * @name: name of the function + * @ns_uri: the namespace name hosting this function + * + * Prototype for callbacks used to plug function lookup in the XPath + * engine. + * + * Returns the XPath function or NULL if not found. + */ +typedef xmlXPathFunction (*xmlXPathFuncLookupFunc) (void *ctxt, + const xmlChar *name, + const xmlChar *ns_uri); + +/** + * xmlXPathFlags: + * Flags for XPath engine compilation and runtime + */ +/** + * XML_XPATH_CHECKNS: + * + * check namespaces at compilation + */ +#define XML_XPATH_CHECKNS (1<<0) +/** + * XML_XPATH_NOVAR: + * + * forbid variables in expression + */ +#define XML_XPATH_NOVAR (1<<1) + +/** + * xmlXPathContext: + * + * Expression evaluation occurs with respect to a context. + * he context consists of: + * - a node (the context node) + * - a node list (the context node list) + * - a set of variable bindings + * - a function library + * - the set of namespace declarations in scope for the expression + * Following the switch to hash tables, this need to be trimmed up at + * the next binary incompatible release. + * The node may be modified when the context is passed to libxml2 + * for an XPath evaluation so you may need to initialize it again + * before the next call. + */ + +struct _xmlXPathContext { + xmlDocPtr doc; /* The current document */ + xmlNodePtr node; /* The current node */ + + int nb_variables_unused; /* unused (hash table) */ + int max_variables_unused; /* unused (hash table) */ + xmlHashTablePtr varHash; /* Hash table of defined variables */ + + int nb_types; /* number of defined types */ + int max_types; /* max number of types */ + xmlXPathTypePtr types; /* Array of defined types */ + + int nb_funcs_unused; /* unused (hash table) */ + int max_funcs_unused; /* unused (hash table) */ + xmlHashTablePtr funcHash; /* Hash table of defined funcs */ + + int nb_axis; /* number of defined axis */ + int max_axis; /* max number of axis */ + xmlXPathAxisPtr axis; /* Array of defined axis */ + + /* the namespace nodes of the context node */ + xmlNsPtr *namespaces; /* Array of namespaces */ + int nsNr; /* number of namespace in scope */ + void *user; /* function to free */ + + /* extra variables */ + int contextSize; /* the context size */ + int proximityPosition; /* the proximity position */ + + /* extra stuff for XPointer */ + int xptr; /* is this an XPointer context? */ + xmlNodePtr here; /* for here() */ + xmlNodePtr origin; /* for origin() */ + + /* the set of namespace declarations in scope for the expression */ + xmlHashTablePtr nsHash; /* The namespaces hash table */ + xmlXPathVariableLookupFunc varLookupFunc;/* variable lookup func */ + void *varLookupData; /* variable lookup data */ + + /* Possibility to link in an extra item */ + void *extra; /* needed for XSLT */ + + /* The function name and URI when calling a function */ + const xmlChar *function; + const xmlChar *functionURI; + + /* function lookup function and data */ + xmlXPathFuncLookupFunc funcLookupFunc;/* function lookup func */ + void *funcLookupData; /* function lookup data */ + + /* temporary namespace lists kept for walking the namespace axis */ + xmlNsPtr *tmpNsList; /* Array of namespaces */ + int tmpNsNr; /* number of namespaces in scope */ + + /* error reporting mechanism */ + void *userData; /* user specific data block */ + xmlStructuredErrorFunc error; /* the callback in case of errors */ + xmlError lastError; /* the last error */ + xmlNodePtr debugNode; /* the source node XSLT */ + + /* dictionary */ + xmlDictPtr dict; /* dictionary if any */ + + int flags; /* flags to control compilation */ + + /* Cache for reusal of XPath objects */ + void *cache; + + /* Resource limits */ + unsigned long opLimit; + unsigned long opCount; + int depth; +}; + +/* + * The structure of a compiled expression form is not public. + */ + +typedef struct _xmlXPathCompExpr xmlXPathCompExpr; +typedef xmlXPathCompExpr *xmlXPathCompExprPtr; + +/** + * xmlXPathParserContext: + * + * An XPath parser context. It contains pure parsing information, + * an xmlXPathContext, and the stack of objects. + */ +struct _xmlXPathParserContext { + const xmlChar *cur; /* the current char being parsed */ + const xmlChar *base; /* the full expression */ + + int error; /* error code */ + + xmlXPathContextPtr context; /* the evaluation context */ + xmlXPathObjectPtr value; /* the current value */ + int valueNr; /* number of values stacked */ + int valueMax; /* max number of values stacked */ + xmlXPathObjectPtr *valueTab; /* stack of values */ + + xmlXPathCompExprPtr comp; /* the precompiled expression */ + int xptr; /* it this an XPointer expression */ + xmlNodePtr ancestor; /* used for walking preceding axis */ + + int valueFrame; /* always zero for compatibility */ +}; + +/************************************************************************ + * * + * Public API * + * * + ************************************************************************/ + +/** + * Objects and Nodesets handling + */ + +XMLPUBVAR double xmlXPathNAN; +XMLPUBVAR double xmlXPathPINF; +XMLPUBVAR double xmlXPathNINF; + +/* These macros may later turn into functions */ +/** + * xmlXPathNodeSetGetLength: + * @ns: a node-set + * + * Implement a functionality similar to the DOM NodeList.length. + * + * Returns the number of nodes in the node-set. + */ +#define xmlXPathNodeSetGetLength(ns) ((ns) ? (ns)->nodeNr : 0) +/** + * xmlXPathNodeSetItem: + * @ns: a node-set + * @index: index of a node in the set + * + * Implements a functionality similar to the DOM NodeList.item(). + * + * Returns the xmlNodePtr at the given @index in @ns or NULL if + * @index is out of range (0 to length-1) + */ +#define xmlXPathNodeSetItem(ns, index) \ + ((((ns) != NULL) && \ + ((index) >= 0) && ((index) < (ns)->nodeNr)) ? \ + (ns)->nodeTab[(index)] \ + : NULL) +/** + * xmlXPathNodeSetIsEmpty: + * @ns: a node-set + * + * Checks whether @ns is empty or not. + * + * Returns %TRUE if @ns is an empty node-set. + */ +#define xmlXPathNodeSetIsEmpty(ns) \ + (((ns) == NULL) || ((ns)->nodeNr == 0) || ((ns)->nodeTab == NULL)) + + +XMLPUBFUN void + xmlXPathFreeObject (xmlXPathObjectPtr obj); +XMLPUBFUN xmlNodeSetPtr + xmlXPathNodeSetCreate (xmlNodePtr val); +XMLPUBFUN void + xmlXPathFreeNodeSetList (xmlXPathObjectPtr obj); +XMLPUBFUN void + xmlXPathFreeNodeSet (xmlNodeSetPtr obj); +XMLPUBFUN xmlXPathObjectPtr + xmlXPathObjectCopy (xmlXPathObjectPtr val); +XMLPUBFUN int + xmlXPathCmpNodes (xmlNodePtr node1, + xmlNodePtr node2); +/** + * Conversion functions to basic types. + */ +XMLPUBFUN int + xmlXPathCastNumberToBoolean (double val); +XMLPUBFUN int + xmlXPathCastStringToBoolean (const xmlChar * val); +XMLPUBFUN int + xmlXPathCastNodeSetToBoolean(xmlNodeSetPtr ns); +XMLPUBFUN int + xmlXPathCastToBoolean (xmlXPathObjectPtr val); + +XMLPUBFUN double + xmlXPathCastBooleanToNumber (int val); +XMLPUBFUN double + xmlXPathCastStringToNumber (const xmlChar * val); +XMLPUBFUN double + xmlXPathCastNodeToNumber (xmlNodePtr node); +XMLPUBFUN double + xmlXPathCastNodeSetToNumber (xmlNodeSetPtr ns); +XMLPUBFUN double + xmlXPathCastToNumber (xmlXPathObjectPtr val); + +XMLPUBFUN xmlChar * + xmlXPathCastBooleanToString (int val); +XMLPUBFUN xmlChar * + xmlXPathCastNumberToString (double val); +XMLPUBFUN xmlChar * + xmlXPathCastNodeToString (xmlNodePtr node); +XMLPUBFUN xmlChar * + xmlXPathCastNodeSetToString (xmlNodeSetPtr ns); +XMLPUBFUN xmlChar * + xmlXPathCastToString (xmlXPathObjectPtr val); + +XMLPUBFUN xmlXPathObjectPtr + xmlXPathConvertBoolean (xmlXPathObjectPtr val); +XMLPUBFUN xmlXPathObjectPtr + xmlXPathConvertNumber (xmlXPathObjectPtr val); +XMLPUBFUN xmlXPathObjectPtr + xmlXPathConvertString (xmlXPathObjectPtr val); + +/** + * Context handling. + */ +XMLPUBFUN xmlXPathContextPtr + xmlXPathNewContext (xmlDocPtr doc); +XMLPUBFUN void + xmlXPathFreeContext (xmlXPathContextPtr ctxt); +XMLPUBFUN void + xmlXPathSetErrorHandler(xmlXPathContextPtr ctxt, + xmlStructuredErrorFunc handler, + void *context); +XMLPUBFUN int + xmlXPathContextSetCache(xmlXPathContextPtr ctxt, + int active, + int value, + int options); +/** + * Evaluation functions. + */ +XMLPUBFUN long + xmlXPathOrderDocElems (xmlDocPtr doc); +XMLPUBFUN int + xmlXPathSetContextNode (xmlNodePtr node, + xmlXPathContextPtr ctx); +XMLPUBFUN xmlXPathObjectPtr + xmlXPathNodeEval (xmlNodePtr node, + const xmlChar *str, + xmlXPathContextPtr ctx); +XMLPUBFUN xmlXPathObjectPtr + xmlXPathEval (const xmlChar *str, + xmlXPathContextPtr ctx); +XMLPUBFUN xmlXPathObjectPtr + xmlXPathEvalExpression (const xmlChar *str, + xmlXPathContextPtr ctxt); +XMLPUBFUN int + xmlXPathEvalPredicate (xmlXPathContextPtr ctxt, + xmlXPathObjectPtr res); +/** + * Separate compilation/evaluation entry points. + */ +XMLPUBFUN xmlXPathCompExprPtr + xmlXPathCompile (const xmlChar *str); +XMLPUBFUN xmlXPathCompExprPtr + xmlXPathCtxtCompile (xmlXPathContextPtr ctxt, + const xmlChar *str); +XMLPUBFUN xmlXPathObjectPtr + xmlXPathCompiledEval (xmlXPathCompExprPtr comp, + xmlXPathContextPtr ctx); +XMLPUBFUN int + xmlXPathCompiledEvalToBoolean(xmlXPathCompExprPtr comp, + xmlXPathContextPtr ctxt); +XMLPUBFUN void + xmlXPathFreeCompExpr (xmlXPathCompExprPtr comp); +#endif /* LIBXML_XPATH_ENABLED */ +#if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) +XML_DEPRECATED +XMLPUBFUN void + xmlXPathInit (void); +XMLPUBFUN int + xmlXPathIsNaN (double val); +XMLPUBFUN int + xmlXPathIsInf (double val); + +#ifdef __cplusplus +} +#endif + +#endif /* LIBXML_XPATH_ENABLED or LIBXML_SCHEMAS_ENABLED*/ +#endif /* ! __XML_XPATH_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xpathInternals.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xpathInternals.h new file mode 100644 index 0000000..d1c90df --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xpathInternals.h @@ -0,0 +1,633 @@ +/* + * Summary: internal interfaces for XML Path Language implementation + * Description: internal interfaces for XML Path Language implementation + * used to build new modules on top of XPath like XPointer and + * XSLT + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_XPATH_INTERNALS_H__ +#define __XML_XPATH_INTERNALS_H__ + +#include +#include +#include + +#ifdef LIBXML_XPATH_ENABLED + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************ + * * + * Helpers * + * * + ************************************************************************/ + +/* + * Many of these macros may later turn into functions. They + * shouldn't be used in #ifdef's preprocessor instructions. + */ +/** + * xmlXPathSetError: + * @ctxt: an XPath parser context + * @err: an xmlXPathError code + * + * Raises an error. + */ +#define xmlXPathSetError(ctxt, err) \ + { xmlXPatherror((ctxt), __FILE__, __LINE__, (err)); \ + if ((ctxt) != NULL) (ctxt)->error = (err); } + +/** + * xmlXPathSetArityError: + * @ctxt: an XPath parser context + * + * Raises an XPATH_INVALID_ARITY error. + */ +#define xmlXPathSetArityError(ctxt) \ + xmlXPathSetError((ctxt), XPATH_INVALID_ARITY) + +/** + * xmlXPathSetTypeError: + * @ctxt: an XPath parser context + * + * Raises an XPATH_INVALID_TYPE error. + */ +#define xmlXPathSetTypeError(ctxt) \ + xmlXPathSetError((ctxt), XPATH_INVALID_TYPE) + +/** + * xmlXPathGetError: + * @ctxt: an XPath parser context + * + * Get the error code of an XPath context. + * + * Returns the context error. + */ +#define xmlXPathGetError(ctxt) ((ctxt)->error) + +/** + * xmlXPathCheckError: + * @ctxt: an XPath parser context + * + * Check if an XPath error was raised. + * + * Returns true if an error has been raised, false otherwise. + */ +#define xmlXPathCheckError(ctxt) ((ctxt)->error != XPATH_EXPRESSION_OK) + +/** + * xmlXPathGetDocument: + * @ctxt: an XPath parser context + * + * Get the document of an XPath context. + * + * Returns the context document. + */ +#define xmlXPathGetDocument(ctxt) ((ctxt)->context->doc) + +/** + * xmlXPathGetContextNode: + * @ctxt: an XPath parser context + * + * Get the context node of an XPath context. + * + * Returns the context node. + */ +#define xmlXPathGetContextNode(ctxt) ((ctxt)->context->node) + +XMLPUBFUN int + xmlXPathPopBoolean (xmlXPathParserContextPtr ctxt); +XMLPUBFUN double + xmlXPathPopNumber (xmlXPathParserContextPtr ctxt); +XMLPUBFUN xmlChar * + xmlXPathPopString (xmlXPathParserContextPtr ctxt); +XMLPUBFUN xmlNodeSetPtr + xmlXPathPopNodeSet (xmlXPathParserContextPtr ctxt); +XMLPUBFUN void * + xmlXPathPopExternal (xmlXPathParserContextPtr ctxt); + +/** + * xmlXPathReturnBoolean: + * @ctxt: an XPath parser context + * @val: a boolean + * + * Pushes the boolean @val on the context stack. + */ +#define xmlXPathReturnBoolean(ctxt, val) \ + valuePush((ctxt), xmlXPathNewBoolean(val)) + +/** + * xmlXPathReturnTrue: + * @ctxt: an XPath parser context + * + * Pushes true on the context stack. + */ +#define xmlXPathReturnTrue(ctxt) xmlXPathReturnBoolean((ctxt), 1) + +/** + * xmlXPathReturnFalse: + * @ctxt: an XPath parser context + * + * Pushes false on the context stack. + */ +#define xmlXPathReturnFalse(ctxt) xmlXPathReturnBoolean((ctxt), 0) + +/** + * xmlXPathReturnNumber: + * @ctxt: an XPath parser context + * @val: a double + * + * Pushes the double @val on the context stack. + */ +#define xmlXPathReturnNumber(ctxt, val) \ + valuePush((ctxt), xmlXPathNewFloat(val)) + +/** + * xmlXPathReturnString: + * @ctxt: an XPath parser context + * @str: a string + * + * Pushes the string @str on the context stack. + */ +#define xmlXPathReturnString(ctxt, str) \ + valuePush((ctxt), xmlXPathWrapString(str)) + +/** + * xmlXPathReturnEmptyString: + * @ctxt: an XPath parser context + * + * Pushes an empty string on the stack. + */ +#define xmlXPathReturnEmptyString(ctxt) \ + valuePush((ctxt), xmlXPathNewCString("")) + +/** + * xmlXPathReturnNodeSet: + * @ctxt: an XPath parser context + * @ns: a node-set + * + * Pushes the node-set @ns on the context stack. + */ +#define xmlXPathReturnNodeSet(ctxt, ns) \ + valuePush((ctxt), xmlXPathWrapNodeSet(ns)) + +/** + * xmlXPathReturnEmptyNodeSet: + * @ctxt: an XPath parser context + * + * Pushes an empty node-set on the context stack. + */ +#define xmlXPathReturnEmptyNodeSet(ctxt) \ + valuePush((ctxt), xmlXPathNewNodeSet(NULL)) + +/** + * xmlXPathReturnExternal: + * @ctxt: an XPath parser context + * @val: user data + * + * Pushes user data on the context stack. + */ +#define xmlXPathReturnExternal(ctxt, val) \ + valuePush((ctxt), xmlXPathWrapExternal(val)) + +/** + * xmlXPathStackIsNodeSet: + * @ctxt: an XPath parser context + * + * Check if the current value on the XPath stack is a node set or + * an XSLT value tree. + * + * Returns true if the current object on the stack is a node-set. + */ +#define xmlXPathStackIsNodeSet(ctxt) \ + (((ctxt)->value != NULL) \ + && (((ctxt)->value->type == XPATH_NODESET) \ + || ((ctxt)->value->type == XPATH_XSLT_TREE))) + +/** + * xmlXPathStackIsExternal: + * @ctxt: an XPath parser context + * + * Checks if the current value on the XPath stack is an external + * object. + * + * Returns true if the current object on the stack is an external + * object. + */ +#define xmlXPathStackIsExternal(ctxt) \ + ((ctxt->value != NULL) && (ctxt->value->type == XPATH_USERS)) + +/** + * xmlXPathEmptyNodeSet: + * @ns: a node-set + * + * Empties a node-set. + */ +#define xmlXPathEmptyNodeSet(ns) \ + { while ((ns)->nodeNr > 0) (ns)->nodeTab[--(ns)->nodeNr] = NULL; } + +/** + * CHECK_ERROR: + * + * Macro to return from the function if an XPath error was detected. + */ +#define CHECK_ERROR \ + if (ctxt->error != XPATH_EXPRESSION_OK) return + +/** + * CHECK_ERROR0: + * + * Macro to return 0 from the function if an XPath error was detected. + */ +#define CHECK_ERROR0 \ + if (ctxt->error != XPATH_EXPRESSION_OK) return(0) + +/** + * XP_ERROR: + * @X: the error code + * + * Macro to raise an XPath error and return. + */ +#define XP_ERROR(X) \ + { xmlXPathErr(ctxt, X); return; } + +/** + * XP_ERROR0: + * @X: the error code + * + * Macro to raise an XPath error and return 0. + */ +#define XP_ERROR0(X) \ + { xmlXPathErr(ctxt, X); return(0); } + +/** + * CHECK_TYPE: + * @typeval: the XPath type + * + * Macro to check that the value on top of the XPath stack is of a given + * type. + */ +#define CHECK_TYPE(typeval) \ + if ((ctxt->value == NULL) || (ctxt->value->type != typeval)) \ + XP_ERROR(XPATH_INVALID_TYPE) + +/** + * CHECK_TYPE0: + * @typeval: the XPath type + * + * Macro to check that the value on top of the XPath stack is of a given + * type. Return(0) in case of failure + */ +#define CHECK_TYPE0(typeval) \ + if ((ctxt->value == NULL) || (ctxt->value->type != typeval)) \ + XP_ERROR0(XPATH_INVALID_TYPE) + +/** + * CHECK_ARITY: + * @x: the number of expected args + * + * Macro to check that the number of args passed to an XPath function matches. + */ +#define CHECK_ARITY(x) \ + if (ctxt == NULL) return; \ + if (nargs != (x)) \ + XP_ERROR(XPATH_INVALID_ARITY); \ + if (ctxt->valueNr < (x)) \ + XP_ERROR(XPATH_STACK_ERROR); + +/** + * CAST_TO_STRING: + * + * Macro to try to cast the value on the top of the XPath stack to a string. + */ +#define CAST_TO_STRING \ + if ((ctxt->value != NULL) && (ctxt->value->type != XPATH_STRING)) \ + xmlXPathStringFunction(ctxt, 1); + +/** + * CAST_TO_NUMBER: + * + * Macro to try to cast the value on the top of the XPath stack to a number. + */ +#define CAST_TO_NUMBER \ + if ((ctxt->value != NULL) && (ctxt->value->type != XPATH_NUMBER)) \ + xmlXPathNumberFunction(ctxt, 1); + +/** + * CAST_TO_BOOLEAN: + * + * Macro to try to cast the value on the top of the XPath stack to a boolean. + */ +#define CAST_TO_BOOLEAN \ + if ((ctxt->value != NULL) && (ctxt->value->type != XPATH_BOOLEAN)) \ + xmlXPathBooleanFunction(ctxt, 1); + +/* + * Variable Lookup forwarding. + */ + +XMLPUBFUN void + xmlXPathRegisterVariableLookup (xmlXPathContextPtr ctxt, + xmlXPathVariableLookupFunc f, + void *data); + +/* + * Function Lookup forwarding. + */ + +XMLPUBFUN void + xmlXPathRegisterFuncLookup (xmlXPathContextPtr ctxt, + xmlXPathFuncLookupFunc f, + void *funcCtxt); + +/* + * Error reporting. + */ +XMLPUBFUN void + xmlXPatherror (xmlXPathParserContextPtr ctxt, + const char *file, + int line, + int no); + +XMLPUBFUN void + xmlXPathErr (xmlXPathParserContextPtr ctxt, + int error); + +#ifdef LIBXML_DEBUG_ENABLED +XMLPUBFUN void + xmlXPathDebugDumpObject (FILE *output, + xmlXPathObjectPtr cur, + int depth); +XMLPUBFUN void + xmlXPathDebugDumpCompExpr(FILE *output, + xmlXPathCompExprPtr comp, + int depth); +#endif +/** + * NodeSet handling. + */ +XMLPUBFUN int + xmlXPathNodeSetContains (xmlNodeSetPtr cur, + xmlNodePtr val); +XMLPUBFUN xmlNodeSetPtr + xmlXPathDifference (xmlNodeSetPtr nodes1, + xmlNodeSetPtr nodes2); +XMLPUBFUN xmlNodeSetPtr + xmlXPathIntersection (xmlNodeSetPtr nodes1, + xmlNodeSetPtr nodes2); + +XMLPUBFUN xmlNodeSetPtr + xmlXPathDistinctSorted (xmlNodeSetPtr nodes); +XMLPUBFUN xmlNodeSetPtr + xmlXPathDistinct (xmlNodeSetPtr nodes); + +XMLPUBFUN int + xmlXPathHasSameNodes (xmlNodeSetPtr nodes1, + xmlNodeSetPtr nodes2); + +XMLPUBFUN xmlNodeSetPtr + xmlXPathNodeLeadingSorted (xmlNodeSetPtr nodes, + xmlNodePtr node); +XMLPUBFUN xmlNodeSetPtr + xmlXPathLeadingSorted (xmlNodeSetPtr nodes1, + xmlNodeSetPtr nodes2); +XMLPUBFUN xmlNodeSetPtr + xmlXPathNodeLeading (xmlNodeSetPtr nodes, + xmlNodePtr node); +XMLPUBFUN xmlNodeSetPtr + xmlXPathLeading (xmlNodeSetPtr nodes1, + xmlNodeSetPtr nodes2); + +XMLPUBFUN xmlNodeSetPtr + xmlXPathNodeTrailingSorted (xmlNodeSetPtr nodes, + xmlNodePtr node); +XMLPUBFUN xmlNodeSetPtr + xmlXPathTrailingSorted (xmlNodeSetPtr nodes1, + xmlNodeSetPtr nodes2); +XMLPUBFUN xmlNodeSetPtr + xmlXPathNodeTrailing (xmlNodeSetPtr nodes, + xmlNodePtr node); +XMLPUBFUN xmlNodeSetPtr + xmlXPathTrailing (xmlNodeSetPtr nodes1, + xmlNodeSetPtr nodes2); + + +/** + * Extending a context. + */ + +XMLPUBFUN int + xmlXPathRegisterNs (xmlXPathContextPtr ctxt, + const xmlChar *prefix, + const xmlChar *ns_uri); +XMLPUBFUN const xmlChar * + xmlXPathNsLookup (xmlXPathContextPtr ctxt, + const xmlChar *prefix); +XMLPUBFUN void + xmlXPathRegisteredNsCleanup (xmlXPathContextPtr ctxt); + +XMLPUBFUN int + xmlXPathRegisterFunc (xmlXPathContextPtr ctxt, + const xmlChar *name, + xmlXPathFunction f); +XMLPUBFUN int + xmlXPathRegisterFuncNS (xmlXPathContextPtr ctxt, + const xmlChar *name, + const xmlChar *ns_uri, + xmlXPathFunction f); +XMLPUBFUN int + xmlXPathRegisterVariable (xmlXPathContextPtr ctxt, + const xmlChar *name, + xmlXPathObjectPtr value); +XMLPUBFUN int + xmlXPathRegisterVariableNS (xmlXPathContextPtr ctxt, + const xmlChar *name, + const xmlChar *ns_uri, + xmlXPathObjectPtr value); +XMLPUBFUN xmlXPathFunction + xmlXPathFunctionLookup (xmlXPathContextPtr ctxt, + const xmlChar *name); +XMLPUBFUN xmlXPathFunction + xmlXPathFunctionLookupNS (xmlXPathContextPtr ctxt, + const xmlChar *name, + const xmlChar *ns_uri); +XMLPUBFUN void + xmlXPathRegisteredFuncsCleanup (xmlXPathContextPtr ctxt); +XMLPUBFUN xmlXPathObjectPtr + xmlXPathVariableLookup (xmlXPathContextPtr ctxt, + const xmlChar *name); +XMLPUBFUN xmlXPathObjectPtr + xmlXPathVariableLookupNS (xmlXPathContextPtr ctxt, + const xmlChar *name, + const xmlChar *ns_uri); +XMLPUBFUN void + xmlXPathRegisteredVariablesCleanup(xmlXPathContextPtr ctxt); + +/** + * Utilities to extend XPath. + */ +XMLPUBFUN xmlXPathParserContextPtr + xmlXPathNewParserContext (const xmlChar *str, + xmlXPathContextPtr ctxt); +XMLPUBFUN void + xmlXPathFreeParserContext (xmlXPathParserContextPtr ctxt); + +/* TODO: remap to xmlXPathValuePop and Push. */ +XMLPUBFUN xmlXPathObjectPtr + valuePop (xmlXPathParserContextPtr ctxt); +XMLPUBFUN int + valuePush (xmlXPathParserContextPtr ctxt, + xmlXPathObjectPtr value); + +XMLPUBFUN xmlXPathObjectPtr + xmlXPathNewString (const xmlChar *val); +XMLPUBFUN xmlXPathObjectPtr + xmlXPathNewCString (const char *val); +XMLPUBFUN xmlXPathObjectPtr + xmlXPathWrapString (xmlChar *val); +XMLPUBFUN xmlXPathObjectPtr + xmlXPathWrapCString (char * val); +XMLPUBFUN xmlXPathObjectPtr + xmlXPathNewFloat (double val); +XMLPUBFUN xmlXPathObjectPtr + xmlXPathNewBoolean (int val); +XMLPUBFUN xmlXPathObjectPtr + xmlXPathNewNodeSet (xmlNodePtr val); +XMLPUBFUN xmlXPathObjectPtr + xmlXPathNewValueTree (xmlNodePtr val); +XMLPUBFUN int + xmlXPathNodeSetAdd (xmlNodeSetPtr cur, + xmlNodePtr val); +XMLPUBFUN int + xmlXPathNodeSetAddUnique (xmlNodeSetPtr cur, + xmlNodePtr val); +XMLPUBFUN int + xmlXPathNodeSetAddNs (xmlNodeSetPtr cur, + xmlNodePtr node, + xmlNsPtr ns); +XMLPUBFUN void + xmlXPathNodeSetSort (xmlNodeSetPtr set); + +XMLPUBFUN void + xmlXPathRoot (xmlXPathParserContextPtr ctxt); +XMLPUBFUN void + xmlXPathEvalExpr (xmlXPathParserContextPtr ctxt); +XMLPUBFUN xmlChar * + xmlXPathParseName (xmlXPathParserContextPtr ctxt); +XMLPUBFUN xmlChar * + xmlXPathParseNCName (xmlXPathParserContextPtr ctxt); + +/* + * Existing functions. + */ +XMLPUBFUN double + xmlXPathStringEvalNumber (const xmlChar *str); +XMLPUBFUN int + xmlXPathEvaluatePredicateResult (xmlXPathParserContextPtr ctxt, + xmlXPathObjectPtr res); +XMLPUBFUN void + xmlXPathRegisterAllFunctions (xmlXPathContextPtr ctxt); +XMLPUBFUN xmlNodeSetPtr + xmlXPathNodeSetMerge (xmlNodeSetPtr val1, + xmlNodeSetPtr val2); +XMLPUBFUN void + xmlXPathNodeSetDel (xmlNodeSetPtr cur, + xmlNodePtr val); +XMLPUBFUN void + xmlXPathNodeSetRemove (xmlNodeSetPtr cur, + int val); +XMLPUBFUN xmlXPathObjectPtr + xmlXPathNewNodeSetList (xmlNodeSetPtr val); +XMLPUBFUN xmlXPathObjectPtr + xmlXPathWrapNodeSet (xmlNodeSetPtr val); +XMLPUBFUN xmlXPathObjectPtr + xmlXPathWrapExternal (void *val); + +XMLPUBFUN int xmlXPathEqualValues(xmlXPathParserContextPtr ctxt); +XMLPUBFUN int xmlXPathNotEqualValues(xmlXPathParserContextPtr ctxt); +XMLPUBFUN int xmlXPathCompareValues(xmlXPathParserContextPtr ctxt, int inf, int strict); +XMLPUBFUN void xmlXPathValueFlipSign(xmlXPathParserContextPtr ctxt); +XMLPUBFUN void xmlXPathAddValues(xmlXPathParserContextPtr ctxt); +XMLPUBFUN void xmlXPathSubValues(xmlXPathParserContextPtr ctxt); +XMLPUBFUN void xmlXPathMultValues(xmlXPathParserContextPtr ctxt); +XMLPUBFUN void xmlXPathDivValues(xmlXPathParserContextPtr ctxt); +XMLPUBFUN void xmlXPathModValues(xmlXPathParserContextPtr ctxt); + +XMLPUBFUN int xmlXPathIsNodeType(const xmlChar *name); + +/* + * Some of the axis navigation routines. + */ +XMLPUBFUN xmlNodePtr xmlXPathNextSelf(xmlXPathParserContextPtr ctxt, + xmlNodePtr cur); +XMLPUBFUN xmlNodePtr xmlXPathNextChild(xmlXPathParserContextPtr ctxt, + xmlNodePtr cur); +XMLPUBFUN xmlNodePtr xmlXPathNextDescendant(xmlXPathParserContextPtr ctxt, + xmlNodePtr cur); +XMLPUBFUN xmlNodePtr xmlXPathNextDescendantOrSelf(xmlXPathParserContextPtr ctxt, + xmlNodePtr cur); +XMLPUBFUN xmlNodePtr xmlXPathNextParent(xmlXPathParserContextPtr ctxt, + xmlNodePtr cur); +XMLPUBFUN xmlNodePtr xmlXPathNextAncestorOrSelf(xmlXPathParserContextPtr ctxt, + xmlNodePtr cur); +XMLPUBFUN xmlNodePtr xmlXPathNextFollowingSibling(xmlXPathParserContextPtr ctxt, + xmlNodePtr cur); +XMLPUBFUN xmlNodePtr xmlXPathNextFollowing(xmlXPathParserContextPtr ctxt, + xmlNodePtr cur); +XMLPUBFUN xmlNodePtr xmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, + xmlNodePtr cur); +XMLPUBFUN xmlNodePtr xmlXPathNextAttribute(xmlXPathParserContextPtr ctxt, + xmlNodePtr cur); +XMLPUBFUN xmlNodePtr xmlXPathNextPreceding(xmlXPathParserContextPtr ctxt, + xmlNodePtr cur); +XMLPUBFUN xmlNodePtr xmlXPathNextAncestor(xmlXPathParserContextPtr ctxt, + xmlNodePtr cur); +XMLPUBFUN xmlNodePtr xmlXPathNextPrecedingSibling(xmlXPathParserContextPtr ctxt, + xmlNodePtr cur); +/* + * The official core of XPath functions. + */ +XMLPUBFUN void xmlXPathLastFunction(xmlXPathParserContextPtr ctxt, int nargs); +XMLPUBFUN void xmlXPathPositionFunction(xmlXPathParserContextPtr ctxt, int nargs); +XMLPUBFUN void xmlXPathCountFunction(xmlXPathParserContextPtr ctxt, int nargs); +XMLPUBFUN void xmlXPathIdFunction(xmlXPathParserContextPtr ctxt, int nargs); +XMLPUBFUN void xmlXPathLocalNameFunction(xmlXPathParserContextPtr ctxt, int nargs); +XMLPUBFUN void xmlXPathNamespaceURIFunction(xmlXPathParserContextPtr ctxt, int nargs); +XMLPUBFUN void xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs); +XMLPUBFUN void xmlXPathStringLengthFunction(xmlXPathParserContextPtr ctxt, int nargs); +XMLPUBFUN void xmlXPathConcatFunction(xmlXPathParserContextPtr ctxt, int nargs); +XMLPUBFUN void xmlXPathContainsFunction(xmlXPathParserContextPtr ctxt, int nargs); +XMLPUBFUN void xmlXPathStartsWithFunction(xmlXPathParserContextPtr ctxt, int nargs); +XMLPUBFUN void xmlXPathSubstringFunction(xmlXPathParserContextPtr ctxt, int nargs); +XMLPUBFUN void xmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs); +XMLPUBFUN void xmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs); +XMLPUBFUN void xmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs); +XMLPUBFUN void xmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs); +XMLPUBFUN void xmlXPathNotFunction(xmlXPathParserContextPtr ctxt, int nargs); +XMLPUBFUN void xmlXPathTrueFunction(xmlXPathParserContextPtr ctxt, int nargs); +XMLPUBFUN void xmlXPathFalseFunction(xmlXPathParserContextPtr ctxt, int nargs); +XMLPUBFUN void xmlXPathLangFunction(xmlXPathParserContextPtr ctxt, int nargs); +XMLPUBFUN void xmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs); +XMLPUBFUN void xmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs); +XMLPUBFUN void xmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs); +XMLPUBFUN void xmlXPathCeilingFunction(xmlXPathParserContextPtr ctxt, int nargs); +XMLPUBFUN void xmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs); +XMLPUBFUN void xmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs); + +/** + * Really internal functions + */ +XMLPUBFUN void xmlXPathNodeSetFreeNs(xmlNsPtr ns); + +#ifdef __cplusplus +} +#endif + +#endif /* LIBXML_XPATH_ENABLED */ +#endif /* ! __XML_XPATH_INTERNALS_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xpointer.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xpointer.h new file mode 100644 index 0000000..a526000 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxml2/libxml/xpointer.h @@ -0,0 +1,138 @@ +/* + * Summary: API to handle XML Pointers + * Description: API to handle XML Pointers + * Base implementation was made accordingly to + * W3C Candidate Recommendation 7 June 2000 + * http://www.w3.org/TR/2000/CR-xptr-20000607 + * + * Added support for the element() scheme described in: + * W3C Proposed Recommendation 13 November 2002 + * http://www.w3.org/TR/2002/PR-xptr-element-20021113/ + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_XPTR_H__ +#define __XML_XPTR_H__ + +#include + +#ifdef LIBXML_XPTR_ENABLED + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(LIBXML_XPTR_LOCS_ENABLED) +/* + * A Location Set + */ +typedef struct _xmlLocationSet xmlLocationSet; +typedef xmlLocationSet *xmlLocationSetPtr; +struct _xmlLocationSet { + int locNr; /* number of locations in the set */ + int locMax; /* size of the array as allocated */ + xmlXPathObjectPtr *locTab;/* array of locations */ +}; + +/* + * Handling of location sets. + */ + +XML_DEPRECATED +XMLPUBFUN xmlLocationSetPtr + xmlXPtrLocationSetCreate (xmlXPathObjectPtr val); +XML_DEPRECATED +XMLPUBFUN void + xmlXPtrFreeLocationSet (xmlLocationSetPtr obj); +XML_DEPRECATED +XMLPUBFUN xmlLocationSetPtr + xmlXPtrLocationSetMerge (xmlLocationSetPtr val1, + xmlLocationSetPtr val2); +XML_DEPRECATED +XMLPUBFUN xmlXPathObjectPtr + xmlXPtrNewRange (xmlNodePtr start, + int startindex, + xmlNodePtr end, + int endindex); +XML_DEPRECATED +XMLPUBFUN xmlXPathObjectPtr + xmlXPtrNewRangePoints (xmlXPathObjectPtr start, + xmlXPathObjectPtr end); +XML_DEPRECATED +XMLPUBFUN xmlXPathObjectPtr + xmlXPtrNewRangeNodePoint (xmlNodePtr start, + xmlXPathObjectPtr end); +XML_DEPRECATED +XMLPUBFUN xmlXPathObjectPtr + xmlXPtrNewRangePointNode (xmlXPathObjectPtr start, + xmlNodePtr end); +XML_DEPRECATED +XMLPUBFUN xmlXPathObjectPtr + xmlXPtrNewRangeNodes (xmlNodePtr start, + xmlNodePtr end); +XML_DEPRECATED +XMLPUBFUN xmlXPathObjectPtr + xmlXPtrNewLocationSetNodes (xmlNodePtr start, + xmlNodePtr end); +XML_DEPRECATED +XMLPUBFUN xmlXPathObjectPtr + xmlXPtrNewLocationSetNodeSet(xmlNodeSetPtr set); +XML_DEPRECATED +XMLPUBFUN xmlXPathObjectPtr + xmlXPtrNewRangeNodeObject (xmlNodePtr start, + xmlXPathObjectPtr end); +XML_DEPRECATED +XMLPUBFUN xmlXPathObjectPtr + xmlXPtrNewCollapsedRange (xmlNodePtr start); +XML_DEPRECATED +XMLPUBFUN void + xmlXPtrLocationSetAdd (xmlLocationSetPtr cur, + xmlXPathObjectPtr val); +XML_DEPRECATED +XMLPUBFUN xmlXPathObjectPtr + xmlXPtrWrapLocationSet (xmlLocationSetPtr val); +XML_DEPRECATED +XMLPUBFUN void + xmlXPtrLocationSetDel (xmlLocationSetPtr cur, + xmlXPathObjectPtr val); +XML_DEPRECATED +XMLPUBFUN void + xmlXPtrLocationSetRemove (xmlLocationSetPtr cur, + int val); +#endif /* defined(LIBXML_XPTR_LOCS_ENABLED) */ + +/* + * Functions. + */ +XMLPUBFUN xmlXPathContextPtr + xmlXPtrNewContext (xmlDocPtr doc, + xmlNodePtr here, + xmlNodePtr origin); +XMLPUBFUN xmlXPathObjectPtr + xmlXPtrEval (const xmlChar *str, + xmlXPathContextPtr ctx); + +#if defined(LIBXML_XPTR_LOCS_ENABLED) +XML_DEPRECATED +XMLPUBFUN void + xmlXPtrRangeToFunction (xmlXPathParserContextPtr ctxt, + int nargs); +XML_DEPRECATED +XMLPUBFUN xmlNodePtr + xmlXPtrBuildNodeList (xmlXPathObjectPtr obj); +XML_DEPRECATED +XMLPUBFUN void + xmlXPtrEvalRangePredicate (xmlXPathParserContextPtr ctxt); +#endif /* defined(LIBXML_XPTR_LOCS_ENABLED) */ +#ifdef __cplusplus +} +#endif + +#endif /* LIBXML_XPTR_ENABLED */ +#endif /* __XML_XPTR_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/attributes.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/attributes.h new file mode 100644 index 0000000..d9b99a7 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/attributes.h @@ -0,0 +1,39 @@ +/* + * Summary: interface for the XSLT attribute handling + * Description: this module handles the specificities of attribute + * and attribute groups processing. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_XSLT_ATTRIBUTES_H__ +#define __XML_XSLT_ATTRIBUTES_H__ + +#include +#include "xsltexports.h" +#include "xsltInternals.h" + +#ifdef __cplusplus +extern "C" { +#endif + +XSLTPUBFUN void XSLTCALL + xsltParseStylesheetAttributeSet (xsltStylesheetPtr style, + xmlNodePtr cur); +XSLTPUBFUN void XSLTCALL + xsltFreeAttributeSetsHashes (xsltStylesheetPtr style); +XSLTPUBFUN void XSLTCALL + xsltApplyAttributeSet (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst, + const xmlChar *attributes); +XSLTPUBFUN void XSLTCALL + xsltResolveStylesheetAttributeSet(xsltStylesheetPtr style); +#ifdef __cplusplus +} +#endif + +#endif /* __XML_XSLT_ATTRIBUTES_H__ */ + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/documents.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/documents.h new file mode 100644 index 0000000..ae7c0ca --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/documents.h @@ -0,0 +1,93 @@ +/* + * Summary: interface for the document handling + * Description: implements document loading and cache (multiple + * document() reference for the same resources must + * be equal. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_XSLT_DOCUMENTS_H__ +#define __XML_XSLT_DOCUMENTS_H__ + +#include +#include "xsltexports.h" +#include "xsltInternals.h" + +#ifdef __cplusplus +extern "C" { +#endif + +XSLTPUBFUN xsltDocumentPtr XSLTCALL + xsltNewDocument (xsltTransformContextPtr ctxt, + xmlDocPtr doc); +XSLTPUBFUN xsltDocumentPtr XSLTCALL + xsltLoadDocument (xsltTransformContextPtr ctxt, + const xmlChar *URI); +XSLTPUBFUN xsltDocumentPtr XSLTCALL + xsltFindDocument (xsltTransformContextPtr ctxt, + xmlDocPtr doc); +XSLTPUBFUN void XSLTCALL + xsltFreeDocuments (xsltTransformContextPtr ctxt); + +XSLTPUBFUN xsltDocumentPtr XSLTCALL + xsltLoadStyleDocument (xsltStylesheetPtr style, + const xmlChar *URI); +XSLTPUBFUN xsltDocumentPtr XSLTCALL + xsltNewStyleDocument (xsltStylesheetPtr style, + xmlDocPtr doc); +XSLTPUBFUN void XSLTCALL + xsltFreeStyleDocuments (xsltStylesheetPtr style); + +/* + * Hooks for document loading + */ + +/** + * xsltLoadType: + * + * Enum defining the kind of loader requirement. + */ +typedef enum { + XSLT_LOAD_START = 0, /* loading for a top stylesheet */ + XSLT_LOAD_STYLESHEET = 1, /* loading for a stylesheet include/import */ + XSLT_LOAD_DOCUMENT = 2 /* loading document at transformation time */ +} xsltLoadType; + +/** + * xsltDocLoaderFunc: + * @URI: the URI of the document to load + * @dict: the dictionary to use when parsing that document + * @options: parsing options, a set of xmlParserOption + * @ctxt: the context, either a stylesheet or a transformation context + * @type: the xsltLoadType indicating the kind of loading required + * + * An xsltDocLoaderFunc is a signature for a function which can be + * registered to load document not provided by the compilation or + * transformation API themselve, for example when an xsl:import, + * xsl:include is found at compilation time or when a document() + * call is made at runtime. + * + * Returns the pointer to the document (which will be modified and + * freed by the engine later), or NULL in case of error. + */ +typedef xmlDocPtr (*xsltDocLoaderFunc) (const xmlChar *URI, + xmlDictPtr dict, + int options, + void *ctxt, + xsltLoadType type); + +XSLTPUBFUN void XSLTCALL + xsltSetLoaderFunc (xsltDocLoaderFunc f); + +/* the loader may be needed by extension libraries so it is exported */ +XSLTPUBVAR xsltDocLoaderFunc xsltDocDefaultLoader; + +#ifdef __cplusplus +} +#endif + +#endif /* __XML_XSLT_DOCUMENTS_H__ */ + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/extensions.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/extensions.h new file mode 100644 index 0000000..84d6aa4 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/extensions.h @@ -0,0 +1,262 @@ +/* + * Summary: interface for the extension support + * Description: This provide the API needed for simple and module + * extension support. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_XSLT_EXTENSION_H__ +#define __XML_XSLT_EXTENSION_H__ + +#include +#include "xsltexports.h" +#include "xsltInternals.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Extension Modules API. + */ + +/** + * xsltInitGlobals: + * + * Initialize the global variables for extensions + * + */ + +XSLTPUBFUN void XSLTCALL + xsltInitGlobals (void); + +/** + * xsltStyleExtInitFunction: + * @ctxt: an XSLT stylesheet + * @URI: the namespace URI for the extension + * + * A function called at initialization time of an XSLT extension module. + * + * Returns a pointer to the module specific data for this transformation. + */ +typedef void * (*xsltStyleExtInitFunction) (xsltStylesheetPtr style, + const xmlChar *URI); + +/** + * xsltStyleExtShutdownFunction: + * @ctxt: an XSLT stylesheet + * @URI: the namespace URI for the extension + * @data: the data associated to this module + * + * A function called at shutdown time of an XSLT extension module. + */ +typedef void (*xsltStyleExtShutdownFunction) (xsltStylesheetPtr style, + const xmlChar *URI, + void *data); + +/** + * xsltExtInitFunction: + * @ctxt: an XSLT transformation context + * @URI: the namespace URI for the extension + * + * A function called at initialization time of an XSLT extension module. + * + * Returns a pointer to the module specific data for this transformation. + */ +typedef void * (*xsltExtInitFunction) (xsltTransformContextPtr ctxt, + const xmlChar *URI); + +/** + * xsltExtShutdownFunction: + * @ctxt: an XSLT transformation context + * @URI: the namespace URI for the extension + * @data: the data associated to this module + * + * A function called at shutdown time of an XSLT extension module. + */ +typedef void (*xsltExtShutdownFunction) (xsltTransformContextPtr ctxt, + const xmlChar *URI, + void *data); + +XSLTPUBFUN int XSLTCALL + xsltRegisterExtModule (const xmlChar *URI, + xsltExtInitFunction initFunc, + xsltExtShutdownFunction shutdownFunc); +XSLTPUBFUN int XSLTCALL + xsltRegisterExtModuleFull + (const xmlChar * URI, + xsltExtInitFunction initFunc, + xsltExtShutdownFunction shutdownFunc, + xsltStyleExtInitFunction styleInitFunc, + xsltStyleExtShutdownFunction styleShutdownFunc); + +XSLTPUBFUN int XSLTCALL + xsltUnregisterExtModule (const xmlChar * URI); + +XSLTPUBFUN void * XSLTCALL + xsltGetExtData (xsltTransformContextPtr ctxt, + const xmlChar *URI); + +XSLTPUBFUN void * XSLTCALL + xsltStyleGetExtData (xsltStylesheetPtr style, + const xmlChar *URI); +#ifdef XSLT_REFACTORED +XSLTPUBFUN void * XSLTCALL + xsltStyleStylesheetLevelGetExtData( + xsltStylesheetPtr style, + const xmlChar * URI); +#endif +XSLTPUBFUN void XSLTCALL + xsltShutdownCtxtExts (xsltTransformContextPtr ctxt); + +XSLTPUBFUN void XSLTCALL + xsltShutdownExts (xsltStylesheetPtr style); + +XSLTPUBFUN xsltTransformContextPtr XSLTCALL + xsltXPathGetTransformContext + (xmlXPathParserContextPtr ctxt); + +/* + * extension functions +*/ +XSLTPUBFUN int XSLTCALL + xsltRegisterExtModuleFunction + (const xmlChar *name, + const xmlChar *URI, + xmlXPathFunction function); +XSLTPUBFUN xmlXPathFunction XSLTCALL + xsltExtModuleFunctionLookup (const xmlChar *name, + const xmlChar *URI); +XSLTPUBFUN int XSLTCALL + xsltUnregisterExtModuleFunction + (const xmlChar *name, + const xmlChar *URI); + +/* + * extension elements + */ +typedef xsltElemPreCompPtr (*xsltPreComputeFunction) + (xsltStylesheetPtr style, + xmlNodePtr inst, + xsltTransformFunction function); + +XSLTPUBFUN xsltElemPreCompPtr XSLTCALL + xsltNewElemPreComp (xsltStylesheetPtr style, + xmlNodePtr inst, + xsltTransformFunction function); +XSLTPUBFUN void XSLTCALL + xsltInitElemPreComp (xsltElemPreCompPtr comp, + xsltStylesheetPtr style, + xmlNodePtr inst, + xsltTransformFunction function, + xsltElemPreCompDeallocator freeFunc); + +XSLTPUBFUN int XSLTCALL + xsltRegisterExtModuleElement + (const xmlChar *name, + const xmlChar *URI, + xsltPreComputeFunction precomp, + xsltTransformFunction transform); +XSLTPUBFUN xsltTransformFunction XSLTCALL + xsltExtElementLookup (xsltTransformContextPtr ctxt, + const xmlChar *name, + const xmlChar *URI); +XSLTPUBFUN xsltTransformFunction XSLTCALL + xsltExtModuleElementLookup + (const xmlChar *name, + const xmlChar *URI); +XSLTPUBFUN xsltPreComputeFunction XSLTCALL + xsltExtModuleElementPreComputeLookup + (const xmlChar *name, + const xmlChar *URI); +XSLTPUBFUN int XSLTCALL + xsltUnregisterExtModuleElement + (const xmlChar *name, + const xmlChar *URI); + +/* + * top-level elements + */ +typedef void (*xsltTopLevelFunction) (xsltStylesheetPtr style, + xmlNodePtr inst); + +XSLTPUBFUN int XSLTCALL + xsltRegisterExtModuleTopLevel + (const xmlChar *name, + const xmlChar *URI, + xsltTopLevelFunction function); +XSLTPUBFUN xsltTopLevelFunction XSLTCALL + xsltExtModuleTopLevelLookup + (const xmlChar *name, + const xmlChar *URI); +XSLTPUBFUN int XSLTCALL + xsltUnregisterExtModuleTopLevel + (const xmlChar *name, + const xmlChar *URI); + + +/* These 2 functions are deprecated for use within modules. */ +XSLTPUBFUN int XSLTCALL + xsltRegisterExtFunction (xsltTransformContextPtr ctxt, + const xmlChar *name, + const xmlChar *URI, + xmlXPathFunction function); +XSLTPUBFUN int XSLTCALL + xsltRegisterExtElement (xsltTransformContextPtr ctxt, + const xmlChar *name, + const xmlChar *URI, + xsltTransformFunction function); + +/* + * Extension Prefix handling API. + * Those are used by the XSLT (pre)processor. + */ + +XSLTPUBFUN int XSLTCALL + xsltRegisterExtPrefix (xsltStylesheetPtr style, + const xmlChar *prefix, + const xmlChar *URI); +XSLTPUBFUN int XSLTCALL + xsltCheckExtPrefix (xsltStylesheetPtr style, + const xmlChar *URI); +XSLTPUBFUN int XSLTCALL + xsltCheckExtURI (xsltStylesheetPtr style, + const xmlChar *URI); +XSLTPUBFUN int XSLTCALL + xsltInitCtxtExts (xsltTransformContextPtr ctxt); +XSLTPUBFUN void XSLTCALL + xsltFreeCtxtExts (xsltTransformContextPtr ctxt); +XSLTPUBFUN void XSLTCALL + xsltFreeExts (xsltStylesheetPtr style); + +XSLTPUBFUN xsltElemPreCompPtr XSLTCALL + xsltPreComputeExtModuleElement + (xsltStylesheetPtr style, + xmlNodePtr inst); +/* + * Extension Infos access. + * Used by exslt initialisation + */ + +XSLTPUBFUN xmlHashTablePtr XSLTCALL + xsltGetExtInfo (xsltStylesheetPtr style, + const xmlChar *URI); + +/** + * Test of the extension module API + */ +XSLTPUBFUN void XSLTCALL + xsltRegisterTestModule (void); +XSLTPUBFUN void XSLTCALL + xsltDebugDumpExtensions (FILE * output); + + +#ifdef __cplusplus +} +#endif + +#endif /* __XML_XSLT_EXTENSION_H__ */ + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/extra.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/extra.h new file mode 100644 index 0000000..e512fd0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/extra.h @@ -0,0 +1,72 @@ +/* + * Summary: interface for the non-standard features + * Description: implement some extension outside the XSLT namespace + * but not EXSLT with is in a different library. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_XSLT_EXTRA_H__ +#define __XML_XSLT_EXTRA_H__ + +#include +#include "xsltexports.h" +#include "xsltInternals.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * XSLT_LIBXSLT_NAMESPACE: + * + * This is the libxslt namespace for specific extensions. + */ +#define XSLT_LIBXSLT_NAMESPACE ((xmlChar *) "http://xmlsoft.org/XSLT/namespace") + +/** + * XSLT_SAXON_NAMESPACE: + * + * This is Michael Kay's Saxon processor namespace for extensions. + */ +#define XSLT_SAXON_NAMESPACE ((xmlChar *) "http://icl.com/saxon") + +/** + * XSLT_XT_NAMESPACE: + * + * This is James Clark's XT processor namespace for extensions. + */ +#define XSLT_XT_NAMESPACE ((xmlChar *) "http://www.jclark.com/xt") + +/** + * XSLT_XALAN_NAMESPACE: + * + * This is the Apache project XALAN processor namespace for extensions. + */ +#define XSLT_XALAN_NAMESPACE ((xmlChar *) \ + "org.apache.xalan.xslt.extensions.Redirect") + + +XSLTPUBFUN void XSLTCALL + xsltFunctionNodeSet (xmlXPathParserContextPtr ctxt, + int nargs); +XSLTPUBFUN void XSLTCALL + xsltDebug (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst, + xsltElemPreCompPtr comp); + + +XSLTPUBFUN void XSLTCALL + xsltRegisterExtras (xsltTransformContextPtr ctxt); +XSLTPUBFUN void XSLTCALL + xsltRegisterAllExtras (void); + +#ifdef __cplusplus +} +#endif + +#endif /* __XML_XSLT_EXTRA_H__ */ + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/functions.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/functions.h new file mode 100644 index 0000000..5455b7f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/functions.h @@ -0,0 +1,78 @@ +/* + * Summary: interface for the XSLT functions not from XPath + * Description: a set of extra functions coming from XSLT but not in XPath + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard and Bjorn Reese + */ + +#ifndef __XML_XSLT_FUNCTIONS_H__ +#define __XML_XSLT_FUNCTIONS_H__ + +#include +#include +#include "xsltexports.h" +#include "xsltInternals.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * XSLT_REGISTER_FUNCTION_LOOKUP: + * + * Registering macro, not general purpose at all but used in different modules. + */ +#define XSLT_REGISTER_FUNCTION_LOOKUP(ctxt) \ + xmlXPathRegisterFuncLookup((ctxt)->xpathCtxt, \ + xsltXPathFunctionLookup, \ + (void *)(ctxt->xpathCtxt)); + +XSLTPUBFUN xmlXPathFunction XSLTCALL + xsltXPathFunctionLookup (void *vctxt, + const xmlChar *name, + const xmlChar *ns_uri); + +/* + * Interfaces for the functions implementations. + */ + +XSLTPUBFUN void XSLTCALL + xsltDocumentFunction (xmlXPathParserContextPtr ctxt, + int nargs); +XSLTPUBFUN void XSLTCALL + xsltKeyFunction (xmlXPathParserContextPtr ctxt, + int nargs); +XSLTPUBFUN void XSLTCALL + xsltUnparsedEntityURIFunction (xmlXPathParserContextPtr ctxt, + int nargs); +XSLTPUBFUN void XSLTCALL + xsltFormatNumberFunction (xmlXPathParserContextPtr ctxt, + int nargs); +XSLTPUBFUN void XSLTCALL + xsltGenerateIdFunction (xmlXPathParserContextPtr ctxt, + int nargs); +XSLTPUBFUN void XSLTCALL + xsltSystemPropertyFunction (xmlXPathParserContextPtr ctxt, + int nargs); +XSLTPUBFUN void XSLTCALL + xsltElementAvailableFunction (xmlXPathParserContextPtr ctxt, + int nargs); +XSLTPUBFUN void XSLTCALL + xsltFunctionAvailableFunction (xmlXPathParserContextPtr ctxt, + int nargs); + +/* + * And the registration + */ + +XSLTPUBFUN void XSLTCALL + xsltRegisterAllFunctions (xmlXPathContextPtr ctxt); + +#ifdef __cplusplus +} +#endif + +#endif /* __XML_XSLT_FUNCTIONS_H__ */ + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/imports.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/imports.h new file mode 100644 index 0000000..95e44e5 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/imports.h @@ -0,0 +1,75 @@ +/* + * Summary: interface for the XSLT import support + * Description: macros and fuctions needed to implement and + * access the import tree + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_XSLT_IMPORTS_H__ +#define __XML_XSLT_IMPORTS_H__ + +#include +#include "xsltexports.h" +#include "xsltInternals.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * XSLT_GET_IMPORT_PTR: + * + * A macro to import pointers from the stylesheet cascading order. + */ +#define XSLT_GET_IMPORT_PTR(res, style, name) { \ + xsltStylesheetPtr st = style; \ + res = NULL; \ + while (st != NULL) { \ + if (st->name != NULL) { res = st->name; break; } \ + st = xsltNextImport(st); \ + }} + +/** + * XSLT_GET_IMPORT_INT: + * + * A macro to import intergers from the stylesheet cascading order. + */ +#define XSLT_GET_IMPORT_INT(res, style, name) { \ + xsltStylesheetPtr st = style; \ + res = -1; \ + while (st != NULL) { \ + if (st->name != -1) { res = st->name; break; } \ + st = xsltNextImport(st); \ + }} + +/* + * Module interfaces + */ +XSLTPUBFUN int XSLTCALL + xsltParseStylesheetImport(xsltStylesheetPtr style, + xmlNodePtr cur); +XSLTPUBFUN int XSLTCALL + xsltParseStylesheetInclude + (xsltStylesheetPtr style, + xmlNodePtr cur); +XSLTPUBFUN xsltStylesheetPtr XSLTCALL + xsltNextImport (xsltStylesheetPtr style); +XSLTPUBFUN int XSLTCALL + xsltNeedElemSpaceHandling(xsltTransformContextPtr ctxt); +XSLTPUBFUN int XSLTCALL + xsltFindElemSpaceHandling(xsltTransformContextPtr ctxt, + xmlNodePtr node); +XSLTPUBFUN xsltTemplatePtr XSLTCALL + xsltFindTemplate (xsltTransformContextPtr ctxt, + const xmlChar *name, + const xmlChar *nameURI); + +#ifdef __cplusplus +} +#endif + +#endif /* __XML_XSLT_IMPORTS_H__ */ + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/keys.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/keys.h new file mode 100644 index 0000000..757d122 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/keys.h @@ -0,0 +1,53 @@ +/* + * Summary: interface for the key matching used in key() and template matches. + * Description: implementation of the key mechanims. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_XSLT_KEY_H__ +#define __XML_XSLT_KEY_H__ + +#include +#include "xsltexports.h" +#include "xsltInternals.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * NODE_IS_KEYED: + * + * check for bit 15 set + */ +#define NODE_IS_KEYED (1 >> 15) + +XSLTPUBFUN int XSLTCALL + xsltAddKey (xsltStylesheetPtr style, + const xmlChar *name, + const xmlChar *nameURI, + const xmlChar *match, + const xmlChar *use, + xmlNodePtr inst); +XSLTPUBFUN xmlNodeSetPtr XSLTCALL + xsltGetKey (xsltTransformContextPtr ctxt, + const xmlChar *name, + const xmlChar *nameURI, + const xmlChar *value); +XSLTPUBFUN void XSLTCALL + xsltInitCtxtKeys (xsltTransformContextPtr ctxt, + xsltDocumentPtr doc); +XSLTPUBFUN void XSLTCALL + xsltFreeKeys (xsltStylesheetPtr style); +XSLTPUBFUN void XSLTCALL + xsltFreeDocumentKeys (xsltDocumentPtr doc); + +#ifdef __cplusplus +} +#endif + +#endif /* __XML_XSLT_H__ */ + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/namespaces.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/namespaces.h new file mode 100644 index 0000000..fa2d3b4 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/namespaces.h @@ -0,0 +1,68 @@ +/* + * Summary: interface for the XSLT namespace handling + * Description: set of function easing the processing and generation + * of namespace nodes in XSLT. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_XSLT_NAMESPACES_H__ +#define __XML_XSLT_NAMESPACES_H__ + +#include +#include "xsltexports.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Used within nsAliases hashtable when the default namespace is required + * but it's not been explicitly defined + */ +/** + * UNDEFINED_DEFAULT_NS: + * + * Special value for undefined namespace, internal + */ +#define UNDEFINED_DEFAULT_NS (const xmlChar *) -1L + +XSLTPUBFUN void XSLTCALL + xsltNamespaceAlias (xsltStylesheetPtr style, + xmlNodePtr node); +XSLTPUBFUN xmlNsPtr XSLTCALL + xsltGetNamespace (xsltTransformContextPtr ctxt, + xmlNodePtr cur, + xmlNsPtr ns, + xmlNodePtr out); +XSLTPUBFUN xmlNsPtr XSLTCALL + xsltGetPlainNamespace (xsltTransformContextPtr ctxt, + xmlNodePtr cur, + xmlNsPtr ns, + xmlNodePtr out); +XSLTPUBFUN xmlNsPtr XSLTCALL + xsltGetSpecialNamespace (xsltTransformContextPtr ctxt, + xmlNodePtr cur, + const xmlChar *URI, + const xmlChar *prefix, + xmlNodePtr out); +XSLTPUBFUN xmlNsPtr XSLTCALL + xsltCopyNamespace (xsltTransformContextPtr ctxt, + xmlNodePtr elem, + xmlNsPtr ns); +XSLTPUBFUN xmlNsPtr XSLTCALL + xsltCopyNamespaceList (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNsPtr cur); +XSLTPUBFUN void XSLTCALL + xsltFreeNamespaceAliasHashes + (xsltStylesheetPtr style); + +#ifdef __cplusplus +} +#endif + +#endif /* __XML_XSLT_NAMESPACES_H__ */ + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/numbersInternals.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/numbersInternals.h new file mode 100644 index 0000000..8524592 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/numbersInternals.h @@ -0,0 +1,73 @@ +/* + * Summary: Implementation of the XSLT number functions + * Description: Implementation of the XSLT number functions + * + * Copy: See Copyright for the status of this software. + * + * Author: Bjorn Reese and Daniel Veillard + */ + +#ifndef __XML_XSLT_NUMBERSINTERNALS_H__ +#define __XML_XSLT_NUMBERSINTERNALS_H__ + +#include +#include "xsltexports.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct _xsltCompMatch; + +/** + * xsltNumberData: + * + * This data structure is just a wrapper to pass xsl:number data in. + */ +typedef struct _xsltNumberData xsltNumberData; +typedef xsltNumberData *xsltNumberDataPtr; + +struct _xsltNumberData { + const xmlChar *level; + const xmlChar *count; + const xmlChar *from; + const xmlChar *value; + const xmlChar *format; + int has_format; + int digitsPerGroup; + int groupingCharacter; + int groupingCharacterLen; + xmlDocPtr doc; + xmlNodePtr node; + struct _xsltCompMatch *countPat; + struct _xsltCompMatch *fromPat; + + /* + * accelerators + */ +}; + +/** + * xsltFormatNumberInfo,: + * + * This data structure lists the various parameters needed to format numbers. + */ +typedef struct _xsltFormatNumberInfo xsltFormatNumberInfo; +typedef xsltFormatNumberInfo *xsltFormatNumberInfoPtr; + +struct _xsltFormatNumberInfo { + int integer_hash; /* Number of '#' in integer part */ + int integer_digits; /* Number of '0' in integer part */ + int frac_digits; /* Number of '0' in fractional part */ + int frac_hash; /* Number of '#' in fractional part */ + int group; /* Number of chars per display 'group' */ + int multiplier; /* Scaling for percent or permille */ + char add_decimal; /* Flag for whether decimal point appears in pattern */ + char is_multiplier_set; /* Flag to catch multiple occurences of percent/permille */ + char is_negative_pattern;/* Flag for processing -ve prefix/suffix */ +}; + +#ifdef __cplusplus +} +#endif +#endif /* __XML_XSLT_NUMBERSINTERNALS_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/pattern.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/pattern.h new file mode 100644 index 0000000..a0991c0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/pattern.h @@ -0,0 +1,84 @@ +/* + * Summary: interface for the pattern matching used in template matches. + * Description: the implementation of the lookup of the right template + * for a given node must be really fast in order to keep + * decent performances. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_XSLT_PATTERN_H__ +#define __XML_XSLT_PATTERN_H__ + +#include "xsltInternals.h" +#include "xsltexports.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * xsltCompMatch: + * + * Data structure used for the implementation of patterns. + * It is kept private (in pattern.c). + */ +typedef struct _xsltCompMatch xsltCompMatch; +typedef xsltCompMatch *xsltCompMatchPtr; + +/* + * Pattern related interfaces. + */ + +XSLTPUBFUN xsltCompMatchPtr XSLTCALL + xsltCompilePattern (const xmlChar *pattern, + xmlDocPtr doc, + xmlNodePtr node, + xsltStylesheetPtr style, + xsltTransformContextPtr runtime); +XSLTPUBFUN void XSLTCALL + xsltFreeCompMatchList (xsltCompMatchPtr comp); +XSLTPUBFUN int XSLTCALL + xsltTestCompMatchList (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xsltCompMatchPtr comp); +XSLTPUBFUN void XSLTCALL + xsltCompMatchClearCache (xsltTransformContextPtr ctxt, + xsltCompMatchPtr comp); +XSLTPUBFUN void XSLTCALL + xsltNormalizeCompSteps (void *payload, + void *data, + const xmlChar *name); + +/* + * Template related interfaces. + */ +XSLTPUBFUN int XSLTCALL + xsltAddTemplate (xsltStylesheetPtr style, + xsltTemplatePtr cur, + const xmlChar *mode, + const xmlChar *modeURI); +XSLTPUBFUN xsltTemplatePtr XSLTCALL + xsltGetTemplate (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xsltStylesheetPtr style); +XSLTPUBFUN void XSLTCALL + xsltFreeTemplateHashes (xsltStylesheetPtr style); +XSLTPUBFUN void XSLTCALL + xsltCleanupTemplates (xsltStylesheetPtr style); + +#if 0 +int xsltMatchPattern (xsltTransformContextPtr ctxt, + xmlNodePtr node, + const xmlChar *pattern, + xmlDocPtr ctxtdoc, + xmlNodePtr ctxtnode); +#endif +#ifdef __cplusplus +} +#endif + +#endif /* __XML_XSLT_PATTERN_H__ */ + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/preproc.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/preproc.h new file mode 100644 index 0000000..2a2fc7e --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/preproc.h @@ -0,0 +1,43 @@ +/* + * Summary: precomputing stylesheets + * Description: this is the compilation phase, where most of the + * stylesheet is "compiled" into faster to use data. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_XSLT_PRECOMP_H__ +#define __XML_XSLT_PRECOMP_H__ + +#include +#include "xsltexports.h" +#include "xsltInternals.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Interfaces + */ +XSLTPUBVAR const xmlChar *xsltExtMarker; + +XSLTPUBFUN xsltElemPreCompPtr XSLTCALL + xsltDocumentComp (xsltStylesheetPtr style, + xmlNodePtr inst, + xsltTransformFunction function); + +XSLTPUBFUN void XSLTCALL + xsltStylePreCompute (xsltStylesheetPtr style, + xmlNodePtr inst); +XSLTPUBFUN void XSLTCALL + xsltFreeStylePreComps (xsltStylesheetPtr style); + +#ifdef __cplusplus +} +#endif + +#endif /* __XML_XSLT_PRECOMP_H__ */ + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/security.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/security.h new file mode 100644 index 0000000..bab5c8c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/security.h @@ -0,0 +1,104 @@ +/* + * Summary: interface for the libxslt security framework + * Description: the libxslt security framework allow to restrict + * the access to new resources (file or URL) from + * the stylesheet at runtime. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_XSLT_SECURITY_H__ +#define __XML_XSLT_SECURITY_H__ + +#include +#include "xsltexports.h" +#include "xsltInternals.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * xsltSecurityPref: + * + * structure to indicate the preferences for security in the XSLT + * transformation. + */ +typedef struct _xsltSecurityPrefs xsltSecurityPrefs; +typedef xsltSecurityPrefs *xsltSecurityPrefsPtr; + +/** + * xsltSecurityOption: + * + * the set of option that can be configured + */ +typedef enum { + XSLT_SECPREF_READ_FILE = 1, + XSLT_SECPREF_WRITE_FILE, + XSLT_SECPREF_CREATE_DIRECTORY, + XSLT_SECPREF_READ_NETWORK, + XSLT_SECPREF_WRITE_NETWORK +} xsltSecurityOption; + +/** + * xsltSecurityCheck: + * + * User provided function to check the value of a string like a file + * path or an URL ... + */ +typedef int (*xsltSecurityCheck) (xsltSecurityPrefsPtr sec, + xsltTransformContextPtr ctxt, + const char *value); + +/* + * Module interfaces + */ +XSLTPUBFUN xsltSecurityPrefsPtr XSLTCALL + xsltNewSecurityPrefs (void); +XSLTPUBFUN void XSLTCALL + xsltFreeSecurityPrefs (xsltSecurityPrefsPtr sec); +XSLTPUBFUN int XSLTCALL + xsltSetSecurityPrefs (xsltSecurityPrefsPtr sec, + xsltSecurityOption option, + xsltSecurityCheck func); +XSLTPUBFUN xsltSecurityCheck XSLTCALL + xsltGetSecurityPrefs (xsltSecurityPrefsPtr sec, + xsltSecurityOption option); + +XSLTPUBFUN void XSLTCALL + xsltSetDefaultSecurityPrefs (xsltSecurityPrefsPtr sec); +XSLTPUBFUN xsltSecurityPrefsPtr XSLTCALL + xsltGetDefaultSecurityPrefs (void); + +XSLTPUBFUN int XSLTCALL + xsltSetCtxtSecurityPrefs (xsltSecurityPrefsPtr sec, + xsltTransformContextPtr ctxt); + +XSLTPUBFUN int XSLTCALL + xsltSecurityAllow (xsltSecurityPrefsPtr sec, + xsltTransformContextPtr ctxt, + const char *value); +XSLTPUBFUN int XSLTCALL + xsltSecurityForbid (xsltSecurityPrefsPtr sec, + xsltTransformContextPtr ctxt, + const char *value); +/* + * internal interfaces + */ +XSLTPUBFUN int XSLTCALL + xsltCheckWrite (xsltSecurityPrefsPtr sec, + xsltTransformContextPtr ctxt, + const xmlChar *URL); +XSLTPUBFUN int XSLTCALL + xsltCheckRead (xsltSecurityPrefsPtr sec, + xsltTransformContextPtr ctxt, + const xmlChar *URL); + +#ifdef __cplusplus +} +#endif + +#endif /* __XML_XSLT_SECURITY_H__ */ + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/templates.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/templates.h new file mode 100644 index 0000000..84a9de4 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/templates.h @@ -0,0 +1,77 @@ +/* + * Summary: interface for the template processing + * Description: This set of routine encapsulates XPath calls + * and Attribute Value Templates evaluation. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_XSLT_TEMPLATES_H__ +#define __XML_XSLT_TEMPLATES_H__ + +#include +#include +#include "xsltexports.h" +#include "xsltInternals.h" + +#ifdef __cplusplus +extern "C" { +#endif + +XSLTPUBFUN int XSLTCALL + xsltEvalXPathPredicate (xsltTransformContextPtr ctxt, + xmlXPathCompExprPtr comp, + xmlNsPtr *nsList, + int nsNr); +XSLTPUBFUN xmlChar * XSLTCALL + xsltEvalTemplateString (xsltTransformContextPtr ctxt, + xmlNodePtr contextNode, + xmlNodePtr inst); +XSLTPUBFUN xmlChar * XSLTCALL + xsltEvalAttrValueTemplate (xsltTransformContextPtr ctxt, + xmlNodePtr node, + const xmlChar *name, + const xmlChar *ns); +XSLTPUBFUN const xmlChar * XSLTCALL + xsltEvalStaticAttrValueTemplate (xsltStylesheetPtr style, + xmlNodePtr node, + const xmlChar *name, + const xmlChar *ns, + int *found); + +/* TODO: this is obviously broken ... the namespaces should be passed too ! */ +XSLTPUBFUN xmlChar * XSLTCALL + xsltEvalXPathString (xsltTransformContextPtr ctxt, + xmlXPathCompExprPtr comp); +XSLTPUBFUN xmlChar * XSLTCALL + xsltEvalXPathStringNs (xsltTransformContextPtr ctxt, + xmlXPathCompExprPtr comp, + int nsNr, + xmlNsPtr *nsList); + +XSLTPUBFUN xmlNodePtr * XSLTCALL + xsltTemplateProcess (xsltTransformContextPtr ctxt, + xmlNodePtr node); +XSLTPUBFUN xmlAttrPtr XSLTCALL + xsltAttrListTemplateProcess (xsltTransformContextPtr ctxt, + xmlNodePtr target, + xmlAttrPtr cur); +XSLTPUBFUN xmlAttrPtr XSLTCALL + xsltAttrTemplateProcess (xsltTransformContextPtr ctxt, + xmlNodePtr target, + xmlAttrPtr attr); +XSLTPUBFUN xmlChar * XSLTCALL + xsltAttrTemplateValueProcess (xsltTransformContextPtr ctxt, + const xmlChar* attr); +XSLTPUBFUN xmlChar * XSLTCALL + xsltAttrTemplateValueProcessNode(xsltTransformContextPtr ctxt, + const xmlChar* str, + xmlNodePtr node); +#ifdef __cplusplus +} +#endif + +#endif /* __XML_XSLT_TEMPLATES_H__ */ + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/transform.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/transform.h new file mode 100644 index 0000000..5a6f795 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/transform.h @@ -0,0 +1,207 @@ +/* + * Summary: the XSLT engine transformation part. + * Description: This module implements the bulk of the actual + * transformation processing. Most of the xsl: element + * constructs are implemented in this module. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_XSLT_TRANSFORM_H__ +#define __XML_XSLT_TRANSFORM_H__ + +#include +#include +#include "xsltexports.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * XInclude default processing. + */ +XSLTPUBFUN void XSLTCALL + xsltSetXIncludeDefault (int xinclude); +XSLTPUBFUN int XSLTCALL + xsltGetXIncludeDefault (void); + +/** + * Export context to users. + */ +XSLTPUBFUN xsltTransformContextPtr XSLTCALL + xsltNewTransformContext (xsltStylesheetPtr style, + xmlDocPtr doc); + +XSLTPUBFUN void XSLTCALL + xsltFreeTransformContext(xsltTransformContextPtr ctxt); + +XSLTPUBFUN xmlDocPtr XSLTCALL + xsltApplyStylesheetUser (xsltStylesheetPtr style, + xmlDocPtr doc, + const char **params, + const char *output, + FILE * profile, + xsltTransformContextPtr userCtxt); +XSLTPUBFUN void XSLTCALL + xsltProcessOneNode (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xsltStackElemPtr params); +/** + * Private Interfaces. + */ +XSLTPUBFUN void XSLTCALL + xsltApplyStripSpaces (xsltTransformContextPtr ctxt, + xmlNodePtr node); +XSLTPUBFUN xmlDocPtr XSLTCALL + xsltApplyStylesheet (xsltStylesheetPtr style, + xmlDocPtr doc, + const char **params); +XSLTPUBFUN xmlDocPtr XSLTCALL + xsltProfileStylesheet (xsltStylesheetPtr style, + xmlDocPtr doc, + const char **params, + FILE * output); +XSLTPUBFUN int XSLTCALL + xsltRunStylesheet (xsltStylesheetPtr style, + xmlDocPtr doc, + const char **params, + const char *output, + xmlSAXHandlerPtr SAX, + xmlOutputBufferPtr IObuf); +XSLTPUBFUN int XSLTCALL + xsltRunStylesheetUser (xsltStylesheetPtr style, + xmlDocPtr doc, + const char **params, + const char *output, + xmlSAXHandlerPtr SAX, + xmlOutputBufferPtr IObuf, + FILE * profile, + xsltTransformContextPtr userCtxt); +XSLTPUBFUN void XSLTCALL + xsltApplyOneTemplate (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr list, + xsltTemplatePtr templ, + xsltStackElemPtr params); +XSLTPUBFUN void XSLTCALL + xsltDocumentElem (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst, + xsltElemPreCompPtr comp); +XSLTPUBFUN void XSLTCALL + xsltSort (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst, + xsltElemPreCompPtr comp); +XSLTPUBFUN void XSLTCALL + xsltCopy (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst, + xsltElemPreCompPtr comp); +XSLTPUBFUN void XSLTCALL + xsltText (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst, + xsltElemPreCompPtr comp); +XSLTPUBFUN void XSLTCALL + xsltElement (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst, + xsltElemPreCompPtr comp); +XSLTPUBFUN void XSLTCALL + xsltComment (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst, + xsltElemPreCompPtr comp); +XSLTPUBFUN void XSLTCALL + xsltAttribute (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst, + xsltElemPreCompPtr comp); +XSLTPUBFUN void XSLTCALL + xsltProcessingInstruction(xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst, + xsltElemPreCompPtr comp); +XSLTPUBFUN void XSLTCALL + xsltCopyOf (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst, + xsltElemPreCompPtr comp); +XSLTPUBFUN void XSLTCALL + xsltValueOf (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst, + xsltElemPreCompPtr comp); +XSLTPUBFUN void XSLTCALL + xsltNumber (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst, + xsltElemPreCompPtr comp); +XSLTPUBFUN void XSLTCALL + xsltApplyImports (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst, + xsltElemPreCompPtr comp); +XSLTPUBFUN void XSLTCALL + xsltCallTemplate (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst, + xsltElemPreCompPtr comp); +XSLTPUBFUN void XSLTCALL + xsltApplyTemplates (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst, + xsltElemPreCompPtr comp); +XSLTPUBFUN void XSLTCALL + xsltChoose (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst, + xsltElemPreCompPtr comp); +XSLTPUBFUN void XSLTCALL + xsltIf (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst, + xsltElemPreCompPtr comp); +XSLTPUBFUN void XSLTCALL + xsltForEach (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst, + xsltElemPreCompPtr comp); +XSLTPUBFUN void XSLTCALL + xsltRegisterAllElement (xsltTransformContextPtr ctxt); + +XSLTPUBFUN xmlNodePtr XSLTCALL + xsltCopyTextString (xsltTransformContextPtr ctxt, + xmlNodePtr target, + const xmlChar *string, + int noescape); + +/* Following 2 functions needed for libexslt/functions.c */ +XSLTPUBFUN void XSLTCALL + xsltLocalVariablePop (xsltTransformContextPtr ctxt, + int limitNr, + int level); +XSLTPUBFUN int XSLTCALL + xsltLocalVariablePush (xsltTransformContextPtr ctxt, + xsltStackElemPtr variable, + int level); +/* + * Hook for the debugger if activated. + */ +XSLTPUBFUN void XSLTCALL + xslHandleDebugger (xmlNodePtr cur, + xmlNodePtr node, + xsltTemplatePtr templ, + xsltTransformContextPtr ctxt); + +#ifdef __cplusplus +} +#endif + +#endif /* __XML_XSLT_TRANSFORM_H__ */ + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/variables.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/variables.h new file mode 100644 index 0000000..e2adee0 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/variables.h @@ -0,0 +1,118 @@ +/* + * Summary: interface for the variable matching and lookup. + * Description: interface for the variable matching and lookup. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_XSLT_VARIABLES_H__ +#define __XML_XSLT_VARIABLES_H__ + +#include +#include +#include "xsltexports.h" +#include "xsltInternals.h" +#include "functions.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * XSLT_REGISTER_VARIABLE_LOOKUP: + * + * Registering macro, not general purpose at all but used in different modules. + */ + +#define XSLT_REGISTER_VARIABLE_LOOKUP(ctxt) \ + xmlXPathRegisterVariableLookup((ctxt)->xpathCtxt, \ + xsltXPathVariableLookup, (void *)(ctxt)); \ + xsltRegisterAllFunctions((ctxt)->xpathCtxt); \ + xsltRegisterAllElement(ctxt); \ + (ctxt)->xpathCtxt->extra = ctxt + +/* + * Flags for memory management of RVTs + */ + +/** + * XSLT_RVT_LOCAL: + * + * RVT is destroyed after the current instructions ends. + */ +#define XSLT_RVT_LOCAL 1 + +/** + * XSLT_RVT_FUNC_RESULT: + * + * RVT is part of results returned with func:result. The RVT won't be + * destroyed after exiting a template and will be reset to XSLT_RVT_LOCAL or + * XSLT_RVT_VARIABLE in the template that receives the return value. + */ +#define XSLT_RVT_FUNC_RESULT 2 + +/** + * XSLT_RVT_GLOBAL: + * + * RVT is part of a global variable. + */ +#define XSLT_RVT_GLOBAL 3 + +/* + * Interfaces for the variable module. + */ + +XSLTPUBFUN int XSLTCALL + xsltEvalGlobalVariables (xsltTransformContextPtr ctxt); +XSLTPUBFUN int XSLTCALL + xsltEvalUserParams (xsltTransformContextPtr ctxt, + const char **params); +XSLTPUBFUN int XSLTCALL + xsltQuoteUserParams (xsltTransformContextPtr ctxt, + const char **params); +XSLTPUBFUN int XSLTCALL + xsltEvalOneUserParam (xsltTransformContextPtr ctxt, + const xmlChar * name, + const xmlChar * value); +XSLTPUBFUN int XSLTCALL + xsltQuoteOneUserParam (xsltTransformContextPtr ctxt, + const xmlChar * name, + const xmlChar * value); + +XSLTPUBFUN void XSLTCALL + xsltParseGlobalVariable (xsltStylesheetPtr style, + xmlNodePtr cur); +XSLTPUBFUN void XSLTCALL + xsltParseGlobalParam (xsltStylesheetPtr style, + xmlNodePtr cur); +XSLTPUBFUN void XSLTCALL + xsltParseStylesheetVariable (xsltTransformContextPtr ctxt, + xmlNodePtr cur); +XSLTPUBFUN void XSLTCALL + xsltParseStylesheetParam (xsltTransformContextPtr ctxt, + xmlNodePtr cur); +XSLTPUBFUN xsltStackElemPtr XSLTCALL + xsltParseStylesheetCallerParam (xsltTransformContextPtr ctxt, + xmlNodePtr cur); +XSLTPUBFUN int XSLTCALL + xsltAddStackElemList (xsltTransformContextPtr ctxt, + xsltStackElemPtr elems); +XSLTPUBFUN void XSLTCALL + xsltFreeGlobalVariables (xsltTransformContextPtr ctxt); +XSLTPUBFUN xmlXPathObjectPtr XSLTCALL + xsltVariableLookup (xsltTransformContextPtr ctxt, + const xmlChar *name, + const xmlChar *ns_uri); +XSLTPUBFUN xmlXPathObjectPtr XSLTCALL + xsltXPathVariableLookup (void *ctxt, + const xmlChar *name, + const xmlChar *ns_uri); +#ifdef __cplusplus +} +#endif + +#endif /* __XML_XSLT_VARIABLES_H__ */ + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/xslt.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/xslt.h new file mode 100644 index 0000000..02f491a --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/xslt.h @@ -0,0 +1,110 @@ +/* + * Summary: Interfaces, constants and types related to the XSLT engine + * Description: Interfaces, constants and types related to the XSLT engine + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_XSLT_H__ +#define __XML_XSLT_H__ + +#include +#include "xsltexports.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * XSLT_DEFAULT_VERSION: + * + * The default version of XSLT supported. + */ +#define XSLT_DEFAULT_VERSION "1.0" + +/** + * XSLT_DEFAULT_VENDOR: + * + * The XSLT "vendor" string for this processor. + */ +#define XSLT_DEFAULT_VENDOR "libxslt" + +/** + * XSLT_DEFAULT_URL: + * + * The XSLT "vendor" URL for this processor. + */ +#define XSLT_DEFAULT_URL "http://xmlsoft.org/XSLT/" + +/** + * XSLT_NAMESPACE: + * + * The XSLT specification namespace. + */ +#define XSLT_NAMESPACE ((const xmlChar *)"http://www.w3.org/1999/XSL/Transform") + +/** + * XSLT_PARSE_OPTIONS: + * + * The set of options to pass to an xmlReadxxx when loading files for + * XSLT consumption. + */ +#define XSLT_PARSE_OPTIONS \ + XML_PARSE_NOENT | XML_PARSE_DTDLOAD | XML_PARSE_DTDATTR | XML_PARSE_NOCDATA + +/** + * xsltMaxDepth: + * + * This value is used to detect templates loops. + */ +XSLTPUBVAR int xsltMaxDepth; + +/** + * * xsltMaxVars: + * * + * * This value is used to detect templates loops. + * */ +XSLTPUBVAR int xsltMaxVars; + +/** + * xsltEngineVersion: + * + * The version string for libxslt. + */ +XSLTPUBVAR const char *xsltEngineVersion; + +/** + * xsltLibxsltVersion: + * + * The version of libxslt compiled. + */ +XSLTPUBVAR const int xsltLibxsltVersion; + +/** + * xsltLibxmlVersion: + * + * The version of libxml libxslt was compiled against. + */ +XSLTPUBVAR const int xsltLibxmlVersion; + +/* + * Global initialization function. + */ + +XSLTPUBFUN void XSLTCALL + xsltInit (void); + +/* + * Global cleanup function. + */ +XSLTPUBFUN void XSLTCALL + xsltCleanupGlobals (void); + +#ifdef __cplusplus +} +#endif + +#endif /* __XML_XSLT_H__ */ + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/xsltInternals.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/xsltInternals.h new file mode 100644 index 0000000..6faa07d --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/xsltInternals.h @@ -0,0 +1,1995 @@ +/* + * Summary: internal data structures, constants and functions + * Description: Internal data structures, constants and functions used + * by the XSLT engine. + * They are not part of the API or ABI, i.e. they can change + * without prior notice, use carefully. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_XSLT_INTERNALS_H__ +#define __XML_XSLT_INTERNALS_H__ + +#include +#include +#include +#include +#include +#include +#include +#include "xsltexports.h" +#include "numbersInternals.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* #define XSLT_DEBUG_PROFILE_CACHE */ + +/** + * XSLT_IS_TEXT_NODE: + * + * check if the argument is a text node + */ +#define XSLT_IS_TEXT_NODE(n) ((n != NULL) && \ + (((n)->type == XML_TEXT_NODE) || \ + ((n)->type == XML_CDATA_SECTION_NODE))) + + +/** + * XSLT_MARK_RES_TREE_FRAG: + * + * internal macro to set up tree fragments + */ +#define XSLT_MARK_RES_TREE_FRAG(n) \ + (n)->name = (char *) xmlStrdup(BAD_CAST " fake node libxslt"); + +/** + * XSLT_IS_RES_TREE_FRAG: + * + * internal macro to test tree fragments + */ +#define XSLT_IS_RES_TREE_FRAG(n) \ + ((n != NULL) && ((n)->type == XML_DOCUMENT_NODE) && \ + ((n)->name != NULL) && ((n)->name[0] == ' ')) + +/** + * XSLT_REFACTORED_KEYCOMP: + * + * Internal define to enable on-demand xsl:key computation. + * That's the only mode now but the define is kept for compatibility + */ +#define XSLT_REFACTORED_KEYCOMP + +/** + * XSLT_FAST_IF: + * + * Internal define to enable usage of xmlXPathCompiledEvalToBoolean() + * for XSLT "tests"; e.g. in + */ +#define XSLT_FAST_IF + +/** + * XSLT_REFACTORED: + * + * Internal define to enable the refactored parts of Libxslt. + */ +/* #define XSLT_REFACTORED */ +/* ==================================================================== */ + +/** + * XSLT_REFACTORED_VARS: + * + * Internal define to enable the refactored variable part of libxslt + */ +#define XSLT_REFACTORED_VARS + +#ifdef XSLT_REFACTORED + +extern const xmlChar *xsltXSLTAttrMarker; + + +/* TODO: REMOVE: #define XSLT_REFACTORED_EXCLRESNS */ + +/* TODO: REMOVE: #define XSLT_REFACTORED_NSALIAS */ + +/** + * XSLT_REFACTORED_XSLT_NSCOMP + * + * Internal define to enable the pointer-comparison of + * namespaces of XSLT elements. + */ +/* #define XSLT_REFACTORED_XSLT_NSCOMP */ + +#ifdef XSLT_REFACTORED_XSLT_NSCOMP + +extern const xmlChar *xsltConstNamespaceNameXSLT; + +/** + * IS_XSLT_ELEM_FAST: + * + * quick test to detect XSLT elements + */ +#define IS_XSLT_ELEM_FAST(n) \ + (((n) != NULL) && ((n)->ns != NULL) && \ + ((n)->ns->href == xsltConstNamespaceNameXSLT)) + +/** + * IS_XSLT_ATTR_FAST: + * + * quick test to detect XSLT attributes + */ +#define IS_XSLT_ATTR_FAST(a) \ + (((a) != NULL) && ((a)->ns != NULL) && \ + ((a)->ns->href == xsltConstNamespaceNameXSLT)) + +/** + * XSLT_HAS_INTERNAL_NSMAP: + * + * check for namespace mapping + */ +#define XSLT_HAS_INTERNAL_NSMAP(s) \ + (((s) != NULL) && ((s)->principal) && \ + ((s)->principal->principalData) && \ + ((s)->principal->principalData->nsMap)) + +/** + * XSLT_GET_INTERNAL_NSMAP: + * + * get pointer to namespace map + */ +#define XSLT_GET_INTERNAL_NSMAP(s) ((s)->principal->principalData->nsMap) + +#else /* XSLT_REFACTORED_XSLT_NSCOMP */ + +/** + * IS_XSLT_ELEM_FAST: + * + * quick check whether this is an xslt element + */ +#define IS_XSLT_ELEM_FAST(n) \ + (((n) != NULL) && ((n)->ns != NULL) && \ + (xmlStrEqual((n)->ns->href, XSLT_NAMESPACE))) + +/** + * IS_XSLT_ATTR_FAST: + * + * quick check for xslt namespace attribute + */ +#define IS_XSLT_ATTR_FAST(a) \ + (((a) != NULL) && ((a)->ns != NULL) && \ + (xmlStrEqual((a)->ns->href, XSLT_NAMESPACE))) + + +#endif /* XSLT_REFACTORED_XSLT_NSCOMP */ + + +/** + * XSLT_REFACTORED_MANDATORY_VERSION: + * + * TODO: Currently disabled to surpress regression test failures, since + * the old behaviour was that a missing version attribute + * produced a only a warning and not an error, which was incerrect. + * So the regression tests need to be fixed if this is enabled. + */ +/* #define XSLT_REFACTORED_MANDATORY_VERSION */ + +/** + * xsltPointerList: + * + * Pointer-list for various purposes. + */ +typedef struct _xsltPointerList xsltPointerList; +typedef xsltPointerList *xsltPointerListPtr; +struct _xsltPointerList { + void **items; + int number; + int size; +}; + +#endif + +/** + * XSLT_REFACTORED_PARSING: + * + * Internal define to enable the refactored parts of Libxslt + * related to parsing. + */ +/* #define XSLT_REFACTORED_PARSING */ + +/** + * XSLT_MAX_SORT: + * + * Max number of specified xsl:sort on an element. + */ +#define XSLT_MAX_SORT 15 + +/** + * XSLT_PAT_NO_PRIORITY: + * + * Specific value for pattern without priority expressed. + */ +#define XSLT_PAT_NO_PRIORITY -12345789 + +/** + * xsltRuntimeExtra: + * + * Extra information added to the transformation context. + */ +typedef struct _xsltRuntimeExtra xsltRuntimeExtra; +typedef xsltRuntimeExtra *xsltRuntimeExtraPtr; +struct _xsltRuntimeExtra { + void *info; /* pointer to the extra data */ + xmlFreeFunc deallocate; /* pointer to the deallocation routine */ + union { /* dual-purpose field */ + void *ptr; /* data not needing deallocation */ + int ival; /* integer value storage */ + } val; +}; + +/** + * XSLT_RUNTIME_EXTRA_LST: + * @ctxt: the transformation context + * @nr: the index + * + * Macro used to access extra information stored in the context + */ +#define XSLT_RUNTIME_EXTRA_LST(ctxt, nr) (ctxt)->extras[(nr)].info +/** + * XSLT_RUNTIME_EXTRA_FREE: + * @ctxt: the transformation context + * @nr: the index + * + * Macro used to free extra information stored in the context + */ +#define XSLT_RUNTIME_EXTRA_FREE(ctxt, nr) (ctxt)->extras[(nr)].deallocate +/** + * XSLT_RUNTIME_EXTRA: + * @ctxt: the transformation context + * @nr: the index + * + * Macro used to define extra information stored in the context + */ +#define XSLT_RUNTIME_EXTRA(ctxt, nr, typ) (ctxt)->extras[(nr)].val.typ + +/** + * xsltTemplate: + * + * The in-memory structure corresponding to an XSLT Template. + */ +typedef struct _xsltTemplate xsltTemplate; +typedef xsltTemplate *xsltTemplatePtr; +struct _xsltTemplate { + struct _xsltTemplate *next;/* chained list sorted by priority */ + struct _xsltStylesheet *style;/* the containing stylesheet */ + xmlChar *match; /* the matching string */ + float priority; /* as given from the stylesheet, not computed */ + const xmlChar *name; /* the local part of the name QName */ + const xmlChar *nameURI; /* the URI part of the name QName */ + const xmlChar *mode;/* the local part of the mode QName */ + const xmlChar *modeURI;/* the URI part of the mode QName */ + xmlNodePtr content; /* the template replacement value */ + xmlNodePtr elem; /* the source element */ + + /* + * TODO: @inheritedNsNr and @inheritedNs won't be used in the + * refactored code. + */ + int inheritedNsNr; /* number of inherited namespaces */ + xmlNsPtr *inheritedNs;/* inherited non-excluded namespaces */ + + /* Profiling information */ + int nbCalls; /* the number of time the template was called */ + unsigned long time; /* the time spent in this template */ + void *params; /* xsl:param instructions */ + + int templNr; /* Nb of templates in the stack */ + int templMax; /* Size of the templtes stack */ + xsltTemplatePtr *templCalledTab; /* templates called */ + int *templCountTab; /* .. and how often */ + + /* Conflict resolution */ + int position; +}; + +/** + * xsltDecimalFormat: + * + * Data structure of decimal-format. + */ +typedef struct _xsltDecimalFormat xsltDecimalFormat; +typedef xsltDecimalFormat *xsltDecimalFormatPtr; +struct _xsltDecimalFormat { + struct _xsltDecimalFormat *next; /* chained list */ + xmlChar *name; + /* Used for interpretation of pattern */ + xmlChar *digit; + xmlChar *patternSeparator; + /* May appear in result */ + xmlChar *minusSign; + xmlChar *infinity; + xmlChar *noNumber; /* Not-a-number */ + /* Used for interpretation of pattern and may appear in result */ + xmlChar *decimalPoint; + xmlChar *grouping; + xmlChar *percent; + xmlChar *permille; + xmlChar *zeroDigit; + const xmlChar *nsUri; +}; + +/** + * xsltDocument: + * + * Data structure associated to a parsed document. + */ +typedef struct _xsltDocument xsltDocument; +typedef xsltDocument *xsltDocumentPtr; +struct _xsltDocument { + struct _xsltDocument *next; /* documents are kept in a chained list */ + int main; /* is this the main document */ + xmlDocPtr doc; /* the parsed document */ + void *keys; /* key tables storage */ + struct _xsltDocument *includes; /* subsidiary includes */ + int preproc; /* pre-processing already done */ + int nbKeysComputed; +}; + +/** + * xsltKeyDef: + * + * Representation of an xsl:key. + */ +typedef struct _xsltKeyDef xsltKeyDef; +typedef xsltKeyDef *xsltKeyDefPtr; +struct _xsltKeyDef { + struct _xsltKeyDef *next; + xmlNodePtr inst; + xmlChar *name; + xmlChar *nameURI; + xmlChar *match; + xmlChar *use; + xmlXPathCompExprPtr comp; + xmlXPathCompExprPtr usecomp; + xmlNsPtr *nsList; /* the namespaces in scope */ + int nsNr; /* the number of namespaces in scope */ +}; + +/** + * xsltKeyTable: + * + * Holds the computed keys for key definitions of the same QName. + * Is owned by an xsltDocument. + */ +typedef struct _xsltKeyTable xsltKeyTable; +typedef xsltKeyTable *xsltKeyTablePtr; +struct _xsltKeyTable { + struct _xsltKeyTable *next; + xmlChar *name; + xmlChar *nameURI; + xmlHashTablePtr keys; +}; + +/* + * The in-memory structure corresponding to an XSLT Stylesheet. + * NOTE: most of the content is simply linked from the doc tree + * structure, no specific allocation is made. + */ +typedef struct _xsltStylesheet xsltStylesheet; +typedef xsltStylesheet *xsltStylesheetPtr; + +typedef struct _xsltTransformContext xsltTransformContext; +typedef xsltTransformContext *xsltTransformContextPtr; + +/** + * xsltElemPreComp: + * + * The in-memory structure corresponding to element precomputed data, + * designed to be extended by extension implementors. + */ +typedef struct _xsltElemPreComp xsltElemPreComp; +typedef xsltElemPreComp *xsltElemPreCompPtr; + +/** + * xsltTransformFunction: + * @ctxt: the XSLT transformation context + * @node: the input node + * @inst: the stylesheet node + * @comp: the compiled information from the stylesheet + * + * Signature of the function associated to elements part of the + * stylesheet language like xsl:if or xsl:apply-templates. + */ +typedef void (*xsltTransformFunction) (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst, + xsltElemPreCompPtr comp); + +/** + * xsltSortFunc: + * @ctxt: a transformation context + * @sorts: the node-set to sort + * @nbsorts: the number of sorts + * + * Signature of the function to use during sorting + */ +typedef void (*xsltSortFunc) (xsltTransformContextPtr ctxt, xmlNodePtr *sorts, + int nbsorts); + +typedef enum { + XSLT_FUNC_COPY=1, + XSLT_FUNC_SORT, + XSLT_FUNC_TEXT, + XSLT_FUNC_ELEMENT, + XSLT_FUNC_ATTRIBUTE, + XSLT_FUNC_COMMENT, + XSLT_FUNC_PI, + XSLT_FUNC_COPYOF, + XSLT_FUNC_VALUEOF, + XSLT_FUNC_NUMBER, + XSLT_FUNC_APPLYIMPORTS, + XSLT_FUNC_CALLTEMPLATE, + XSLT_FUNC_APPLYTEMPLATES, + XSLT_FUNC_CHOOSE, + XSLT_FUNC_IF, + XSLT_FUNC_FOREACH, + XSLT_FUNC_DOCUMENT, + XSLT_FUNC_WITHPARAM, + XSLT_FUNC_PARAM, + XSLT_FUNC_VARIABLE, + XSLT_FUNC_WHEN, + XSLT_FUNC_EXTENSION +#ifdef XSLT_REFACTORED + , + XSLT_FUNC_OTHERWISE, + XSLT_FUNC_FALLBACK, + XSLT_FUNC_MESSAGE, + XSLT_FUNC_INCLUDE, + XSLT_FUNC_ATTRSET, + XSLT_FUNC_LITERAL_RESULT_ELEMENT, + XSLT_FUNC_UNKOWN_FORWARDS_COMPAT +#endif +} xsltStyleType; + +/** + * xsltElemPreCompDeallocator: + * @comp: the #xsltElemPreComp to free up + * + * Deallocates an #xsltElemPreComp structure. + */ +typedef void (*xsltElemPreCompDeallocator) (xsltElemPreCompPtr comp); + +/** + * xsltElemPreComp: + * + * The basic structure for compiled items of the AST of the XSLT processor. + * This structure is also intended to be extended by extension implementors. + * TODO: This is somehow not nice, since it has a "free" field, which + * derived stylesheet-structs do not have. + */ +struct _xsltElemPreComp { + xsltElemPreCompPtr next; /* next item in the global chained + list held by xsltStylesheet. */ + xsltStyleType type; /* type of the element */ + xsltTransformFunction func; /* handling function */ + xmlNodePtr inst; /* the node in the stylesheet's tree + corresponding to this item */ + + /* end of common part */ + xsltElemPreCompDeallocator free; /* the deallocator */ +}; + +/** + * xsltStylePreComp: + * + * The abstract basic structure for items of the XSLT processor. + * This includes: + * 1) compiled forms of XSLT instructions (xsl:if, xsl:attribute, etc.) + * 2) compiled forms of literal result elements + * 3) compiled forms of extension elements + */ +typedef struct _xsltStylePreComp xsltStylePreComp; +typedef xsltStylePreComp *xsltStylePreCompPtr; + +#ifdef XSLT_REFACTORED + +/* +* Some pointer-list utility functions. +*/ +XSLTPUBFUN xsltPointerListPtr XSLTCALL + xsltPointerListCreate (int initialSize); +XSLTPUBFUN void XSLTCALL + xsltPointerListFree (xsltPointerListPtr list); +XSLTPUBFUN void XSLTCALL + xsltPointerListClear (xsltPointerListPtr list); +XSLTPUBFUN int XSLTCALL + xsltPointerListAddSize (xsltPointerListPtr list, + void *item, + int initialSize); + +/************************************************************************ + * * + * Refactored structures * + * * + ************************************************************************/ + +typedef struct _xsltNsListContainer xsltNsListContainer; +typedef xsltNsListContainer *xsltNsListContainerPtr; +struct _xsltNsListContainer { + xmlNsPtr *list; + int totalNumber; + int xpathNumber; +}; + +/** + * XSLT_ITEM_COMPATIBILITY_FIELDS: + * + * Fields for API compatibility to the structure + * _xsltElemPreComp which is used for extension functions. + * Note that @next is used for storage; it does not reflect a next + * sibling in the tree. + * TODO: Evaluate if we really need such a compatibility. + */ +#define XSLT_ITEM_COMPATIBILITY_FIELDS \ + xsltElemPreCompPtr next;\ + xsltStyleType type;\ + xsltTransformFunction func;\ + xmlNodePtr inst; + +/** + * XSLT_ITEM_NAVIGATION_FIELDS: + * + * Currently empty. + * TODO: It is intended to hold navigational fields in the future. + */ +#define XSLT_ITEM_NAVIGATION_FIELDS +/* + xsltStylePreCompPtr parent;\ + xsltStylePreCompPtr children;\ + xsltStylePreCompPtr nextItem; +*/ + +/** + * XSLT_ITEM_NSINSCOPE_FIELDS: + * + * The in-scope namespaces. + */ +#define XSLT_ITEM_NSINSCOPE_FIELDS xsltNsListContainerPtr inScopeNs; + +/** + * XSLT_ITEM_COMMON_FIELDS: + * + * Common fields used for all items. + */ +#define XSLT_ITEM_COMMON_FIELDS \ + XSLT_ITEM_COMPATIBILITY_FIELDS \ + XSLT_ITEM_NAVIGATION_FIELDS \ + XSLT_ITEM_NSINSCOPE_FIELDS + +/** + * _xsltStylePreComp: + * + * The abstract basic structure for items of the XSLT processor. + * This includes: + * 1) compiled forms of XSLT instructions (e.g. xsl:if, xsl:attribute, etc.) + * 2) compiled forms of literal result elements + * 3) various properties for XSLT instructions (e.g. xsl:when, + * xsl:with-param) + * + * REVISIT TODO: Keep this structure equal to the fields + * defined by XSLT_ITEM_COMMON_FIELDS + */ +struct _xsltStylePreComp { + xsltElemPreCompPtr next; /* next item in the global chained + list held by xsltStylesheet */ + xsltStyleType type; /* type of the item */ + xsltTransformFunction func; /* handling function */ + xmlNodePtr inst; /* the node in the stylesheet's tree + corresponding to this item. */ + /* Currently no navigational fields. */ + xsltNsListContainerPtr inScopeNs; +}; + +/** + * xsltStyleBasicEmptyItem: + * + * Abstract structure only used as a short-cut for + * XSLT items with no extra fields. + * NOTE that it is intended that this structure looks the same as + * _xsltStylePreComp. + */ +typedef struct _xsltStyleBasicEmptyItem xsltStyleBasicEmptyItem; +typedef xsltStyleBasicEmptyItem *xsltStyleBasicEmptyItemPtr; + +struct _xsltStyleBasicEmptyItem { + XSLT_ITEM_COMMON_FIELDS +}; + +/** + * xsltStyleBasicExpressionItem: + * + * Abstract structure only used as a short-cut for + * XSLT items with just an expression. + */ +typedef struct _xsltStyleBasicExpressionItem xsltStyleBasicExpressionItem; +typedef xsltStyleBasicExpressionItem *xsltStyleBasicExpressionItemPtr; + +struct _xsltStyleBasicExpressionItem { + XSLT_ITEM_COMMON_FIELDS + + const xmlChar *select; /* TODO: Change this to "expression". */ + xmlXPathCompExprPtr comp; /* TODO: Change this to compExpr. */ +}; + +/************************************************************************ + * * + * XSLT-instructions/declarations * + * * + ************************************************************************/ + +/** + * xsltStyleItemElement: + * + * + * + * + * + */ +typedef struct _xsltStyleItemElement xsltStyleItemElement; +typedef xsltStyleItemElement *xsltStyleItemElementPtr; + +struct _xsltStyleItemElement { + XSLT_ITEM_COMMON_FIELDS + + const xmlChar *use; + int has_use; + const xmlChar *name; + int has_name; + const xmlChar *ns; + const xmlChar *nsPrefix; + int has_ns; +}; + +/** + * xsltStyleItemAttribute: + * + * + * + * + * + */ +typedef struct _xsltStyleItemAttribute xsltStyleItemAttribute; +typedef xsltStyleItemAttribute *xsltStyleItemAttributePtr; + +struct _xsltStyleItemAttribute { + XSLT_ITEM_COMMON_FIELDS + const xmlChar *name; + int has_name; + const xmlChar *ns; + const xmlChar *nsPrefix; + int has_ns; +}; + +/** + * xsltStyleItemText: + * + * + * + * + * + */ +typedef struct _xsltStyleItemText xsltStyleItemText; +typedef xsltStyleItemText *xsltStyleItemTextPtr; + +struct _xsltStyleItemText { + XSLT_ITEM_COMMON_FIELDS + int noescape; /* text */ +}; + +/** + * xsltStyleItemComment: + * + * + * + * + * + */ +typedef xsltStyleBasicEmptyItem xsltStyleItemComment; +typedef xsltStyleItemComment *xsltStyleItemCommentPtr; + +/** + * xsltStyleItemPI: + * + * + * + * + * + */ +typedef struct _xsltStyleItemPI xsltStyleItemPI; +typedef xsltStyleItemPI *xsltStyleItemPIPtr; + +struct _xsltStyleItemPI { + XSLT_ITEM_COMMON_FIELDS + const xmlChar *name; + int has_name; +}; + +/** + * xsltStyleItemApplyImports: + * + * + * + */ +typedef xsltStyleBasicEmptyItem xsltStyleItemApplyImports; +typedef xsltStyleItemApplyImports *xsltStyleItemApplyImportsPtr; + +/** + * xsltStyleItemApplyTemplates: + * + * + * + * + * + */ +typedef struct _xsltStyleItemApplyTemplates xsltStyleItemApplyTemplates; +typedef xsltStyleItemApplyTemplates *xsltStyleItemApplyTemplatesPtr; + +struct _xsltStyleItemApplyTemplates { + XSLT_ITEM_COMMON_FIELDS + + const xmlChar *mode; /* apply-templates */ + const xmlChar *modeURI; /* apply-templates */ + const xmlChar *select; /* sort, copy-of, value-of, apply-templates */ + xmlXPathCompExprPtr comp; /* a precompiled XPath expression */ + /* TODO: with-params */ +}; + +/** + * xsltStyleItemCallTemplate: + * + * + * + * + * + */ +typedef struct _xsltStyleItemCallTemplate xsltStyleItemCallTemplate; +typedef xsltStyleItemCallTemplate *xsltStyleItemCallTemplatePtr; + +struct _xsltStyleItemCallTemplate { + XSLT_ITEM_COMMON_FIELDS + + xsltTemplatePtr templ; /* call-template */ + const xmlChar *name; /* element, attribute, pi */ + int has_name; /* element, attribute, pi */ + const xmlChar *ns; /* element */ + int has_ns; /* element */ + /* TODO: with-params */ +}; + +/** + * xsltStyleItemCopy: + * + * + * + * + * + */ +typedef struct _xsltStyleItemCopy xsltStyleItemCopy; +typedef xsltStyleItemCopy *xsltStyleItemCopyPtr; + +struct _xsltStyleItemCopy { + XSLT_ITEM_COMMON_FIELDS + const xmlChar *use; /* copy, element */ + int has_use; /* copy, element */ +}; + +/** + * xsltStyleItemIf: + * + * + * + * + * + */ +typedef struct _xsltStyleItemIf xsltStyleItemIf; +typedef xsltStyleItemIf *xsltStyleItemIfPtr; + +struct _xsltStyleItemIf { + XSLT_ITEM_COMMON_FIELDS + + const xmlChar *test; /* if */ + xmlXPathCompExprPtr comp; /* a precompiled XPath expression */ +}; + + +/** + * xsltStyleItemCopyOf: + * + * + * + */ +typedef xsltStyleBasicExpressionItem xsltStyleItemCopyOf; +typedef xsltStyleItemCopyOf *xsltStyleItemCopyOfPtr; + +/** + * xsltStyleItemValueOf: + * + * + * + */ +typedef struct _xsltStyleItemValueOf xsltStyleItemValueOf; +typedef xsltStyleItemValueOf *xsltStyleItemValueOfPtr; + +struct _xsltStyleItemValueOf { + XSLT_ITEM_COMMON_FIELDS + + const xmlChar *select; + xmlXPathCompExprPtr comp; /* a precompiled XPath expression */ + int noescape; +}; + +/** + * xsltStyleItemNumber: + * + * + * + */ +typedef struct _xsltStyleItemNumber xsltStyleItemNumber; +typedef xsltStyleItemNumber *xsltStyleItemNumberPtr; + +struct _xsltStyleItemNumber { + XSLT_ITEM_COMMON_FIELDS + xsltNumberData numdata; /* number */ +}; + +/** + * xsltStyleItemChoose: + * + * + * + * + * + */ +typedef xsltStyleBasicEmptyItem xsltStyleItemChoose; +typedef xsltStyleItemChoose *xsltStyleItemChoosePtr; + +/** + * xsltStyleItemFallback: + * + * + * + * + * + */ +typedef xsltStyleBasicEmptyItem xsltStyleItemFallback; +typedef xsltStyleItemFallback *xsltStyleItemFallbackPtr; + +/** + * xsltStyleItemForEach: + * + * + * + * + * + */ +typedef xsltStyleBasicExpressionItem xsltStyleItemForEach; +typedef xsltStyleItemForEach *xsltStyleItemForEachPtr; + +/** + * xsltStyleItemMessage: + * + * + * + * + * + */ +typedef struct _xsltStyleItemMessage xsltStyleItemMessage; +typedef xsltStyleItemMessage *xsltStyleItemMessagePtr; + +struct _xsltStyleItemMessage { + XSLT_ITEM_COMMON_FIELDS + int terminate; +}; + +/** + * xsltStyleItemDocument: + * + * NOTE: This is not an instruction of XSLT 1.0. + */ +typedef struct _xsltStyleItemDocument xsltStyleItemDocument; +typedef xsltStyleItemDocument *xsltStyleItemDocumentPtr; + +struct _xsltStyleItemDocument { + XSLT_ITEM_COMMON_FIELDS + int ver11; /* assigned: in xsltDocumentComp; + read: nowhere; + TODO: Check if we need. */ + const xmlChar *filename; /* document URL */ + int has_filename; +}; + +/************************************************************************ + * * + * Non-instructions (actually properties of instructions/declarations) * + * * + ************************************************************************/ + +/** + * xsltStyleBasicItemVariable: + * + * Basic struct for xsl:variable, xsl:param and xsl:with-param. + * It's currently important to have equal fields, since + * xsltParseStylesheetCallerParam() is used with xsl:with-param from + * the xslt side and with xsl:param from the exslt side (in + * exsltFuncFunctionFunction()). + * + * FUTURE NOTE: In XSLT 2.0 xsl:param, xsl:variable and xsl:with-param + * have additional different fields. + */ +typedef struct _xsltStyleBasicItemVariable xsltStyleBasicItemVariable; +typedef xsltStyleBasicItemVariable *xsltStyleBasicItemVariablePtr; + +struct _xsltStyleBasicItemVariable { + XSLT_ITEM_COMMON_FIELDS + + const xmlChar *select; + xmlXPathCompExprPtr comp; + + const xmlChar *name; + int has_name; + const xmlChar *ns; + int has_ns; +}; + +/** + * xsltStyleItemVariable: + * + * + * + * + * + */ +typedef xsltStyleBasicItemVariable xsltStyleItemVariable; +typedef xsltStyleItemVariable *xsltStyleItemVariablePtr; + +/** + * xsltStyleItemParam: + * + * + * + * + * + */ +typedef struct _xsltStyleItemParam xsltStyleItemParam; +typedef xsltStyleItemParam *xsltStyleItemParamPtr; + +struct _xsltStyleItemParam { + XSLT_ITEM_COMMON_FIELDS + + const xmlChar *select; + xmlXPathCompExprPtr comp; + + const xmlChar *name; + int has_name; + const xmlChar *ns; + int has_ns; +}; + +/** + * xsltStyleItemWithParam: + * + * + * + * + */ +typedef xsltStyleBasicItemVariable xsltStyleItemWithParam; +typedef xsltStyleItemWithParam *xsltStyleItemWithParamPtr; + +/** + * xsltStyleItemSort: + * + * Reflects the XSLT xsl:sort item. + * Allowed parents: xsl:apply-templates, xsl:for-each + * + */ +typedef struct _xsltStyleItemSort xsltStyleItemSort; +typedef xsltStyleItemSort *xsltStyleItemSortPtr; + +struct _xsltStyleItemSort { + XSLT_ITEM_COMMON_FIELDS + + const xmlChar *stype; /* sort */ + int has_stype; /* sort */ + int number; /* sort */ + const xmlChar *order; /* sort */ + int has_order; /* sort */ + int descending; /* sort */ + const xmlChar *lang; /* sort */ + int has_lang; /* sort */ + const xmlChar *case_order; /* sort */ + int lower_first; /* sort */ + + const xmlChar *use; + int has_use; + + const xmlChar *select; /* sort, copy-of, value-of, apply-templates */ + + xmlXPathCompExprPtr comp; /* a precompiled XPath expression */ +}; + + +/** + * xsltStyleItemWhen: + * + * + * + * + * Allowed parent: xsl:choose + */ +typedef struct _xsltStyleItemWhen xsltStyleItemWhen; +typedef xsltStyleItemWhen *xsltStyleItemWhenPtr; + +struct _xsltStyleItemWhen { + XSLT_ITEM_COMMON_FIELDS + + const xmlChar *test; + xmlXPathCompExprPtr comp; +}; + +/** + * xsltStyleItemOtherwise: + * + * Allowed parent: xsl:choose + * + * + * + */ +typedef struct _xsltStyleItemOtherwise xsltStyleItemOtherwise; +typedef xsltStyleItemOtherwise *xsltStyleItemOtherwisePtr; + +struct _xsltStyleItemOtherwise { + XSLT_ITEM_COMMON_FIELDS +}; + +typedef struct _xsltStyleItemInclude xsltStyleItemInclude; +typedef xsltStyleItemInclude *xsltStyleItemIncludePtr; + +struct _xsltStyleItemInclude { + XSLT_ITEM_COMMON_FIELDS + xsltDocumentPtr include; +}; + +/************************************************************************ + * * + * XSLT elements in forwards-compatible mode * + * * + ************************************************************************/ + +typedef struct _xsltStyleItemUknown xsltStyleItemUknown; +typedef xsltStyleItemUknown *xsltStyleItemUknownPtr; +struct _xsltStyleItemUknown { + XSLT_ITEM_COMMON_FIELDS +}; + + +/************************************************************************ + * * + * Extension elements * + * * + ************************************************************************/ + +/* + * xsltStyleItemExtElement: + * + * Reflects extension elements. + * + * NOTE: Due to the fact that the structure xsltElemPreComp is most + * probably already heavily in use out there by users, so we cannot + * easily change it, we'll create an intermediate structure which will + * hold an xsltElemPreCompPtr. + * BIG NOTE: The only problem I see here is that the user processes the + * content of the stylesheet tree, possibly he'll lookup the node->psvi + * fields in order to find subsequent extension functions. + * In this case, the user's code will break, since the node->psvi + * field will hold now the xsltStyleItemExtElementPtr and not + * the xsltElemPreCompPtr. + * However the place where the structure is anchored in the node-tree, + * namely node->psvi, has beed already once been moved from node->_private + * to node->psvi, so we have a precedent here, which, I think, should allow + * us to change such semantics without headaches. + */ +typedef struct _xsltStyleItemExtElement xsltStyleItemExtElement; +typedef xsltStyleItemExtElement *xsltStyleItemExtElementPtr; +struct _xsltStyleItemExtElement { + XSLT_ITEM_COMMON_FIELDS + xsltElemPreCompPtr item; +}; + +/************************************************************************ + * * + * Literal result elements * + * * + ************************************************************************/ + +typedef struct _xsltEffectiveNs xsltEffectiveNs; +typedef xsltEffectiveNs *xsltEffectiveNsPtr; +struct _xsltEffectiveNs { + xsltEffectiveNsPtr nextInStore; /* storage next */ + xsltEffectiveNsPtr next; /* next item in the list */ + const xmlChar *prefix; + const xmlChar *nsName; + /* + * Indicates if eclared on the literal result element; dunno if really + * needed. + */ + int holdByElem; +}; + +/* + * Info for literal result elements. + * This will be set on the elem->psvi field and will be + * shared by literal result elements, which have the same + * excluded result namespaces; i.e., this *won't* be created uniquely + * for every literal result element. + */ +typedef struct _xsltStyleItemLRElementInfo xsltStyleItemLRElementInfo; +typedef xsltStyleItemLRElementInfo *xsltStyleItemLRElementInfoPtr; +struct _xsltStyleItemLRElementInfo { + XSLT_ITEM_COMMON_FIELDS + /* + * @effectiveNs is the set of effective ns-nodes + * on the literal result element, which will be added to the result + * element if not already existing in the result tree. + * This means that excluded namespaces (via exclude-result-prefixes, + * extension-element-prefixes and the XSLT namespace) not added + * to the set. + * Namespace-aliasing was applied on the @effectiveNs. + */ + xsltEffectiveNsPtr effectiveNs; + +}; + +#ifdef XSLT_REFACTORED + +typedef struct _xsltNsAlias xsltNsAlias; +typedef xsltNsAlias *xsltNsAliasPtr; +struct _xsltNsAlias { + xsltNsAliasPtr next; /* next in the list */ + xmlNsPtr literalNs; + xmlNsPtr targetNs; + xmlDocPtr docOfTargetNs; +}; +#endif + +#ifdef XSLT_REFACTORED_XSLT_NSCOMP + +typedef struct _xsltNsMap xsltNsMap; +typedef xsltNsMap *xsltNsMapPtr; +struct _xsltNsMap { + xsltNsMapPtr next; /* next in the list */ + xmlDocPtr doc; + xmlNodePtr elem; /* the element holding the ns-decl */ + xmlNsPtr ns; /* the xmlNs structure holding the XML namespace name */ + const xmlChar *origNsName; /* the original XML namespace name */ + const xmlChar *newNsName; /* the mapped XML namespace name */ +}; +#endif + +/************************************************************************ + * * + * Compile-time structures for *internal* use only * + * * + ************************************************************************/ + +typedef struct _xsltPrincipalStylesheetData xsltPrincipalStylesheetData; +typedef xsltPrincipalStylesheetData *xsltPrincipalStylesheetDataPtr; + +typedef struct _xsltNsList xsltNsList; +typedef xsltNsList *xsltNsListPtr; +struct _xsltNsList { + xsltNsListPtr next; /* next in the list */ + xmlNsPtr ns; +}; + +/* +* xsltVarInfo: +* +* Used at compilation time for parameters and variables. +*/ +typedef struct _xsltVarInfo xsltVarInfo; +typedef xsltVarInfo *xsltVarInfoPtr; +struct _xsltVarInfo { + xsltVarInfoPtr next; /* next in the list */ + xsltVarInfoPtr prev; + int depth; /* the depth in the tree */ + const xmlChar *name; + const xmlChar *nsName; +}; + +/** + * xsltCompilerNodeInfo: + * + * Per-node information during compile-time. + */ +typedef struct _xsltCompilerNodeInfo xsltCompilerNodeInfo; +typedef xsltCompilerNodeInfo *xsltCompilerNodeInfoPtr; +struct _xsltCompilerNodeInfo { + xsltCompilerNodeInfoPtr next; + xsltCompilerNodeInfoPtr prev; + xmlNodePtr node; + int depth; + xsltTemplatePtr templ; /* The owning template */ + int category; /* XSLT element, LR-element or + extension element */ + xsltStyleType type; + xsltElemPreCompPtr item; /* The compiled information */ + /* The current in-scope namespaces */ + xsltNsListContainerPtr inScopeNs; + /* The current excluded result namespaces */ + xsltPointerListPtr exclResultNs; + /* The current extension instruction namespaces */ + xsltPointerListPtr extElemNs; + + /* The current info for literal result elements. */ + xsltStyleItemLRElementInfoPtr litResElemInfo; + /* + * Set to 1 if in-scope namespaces changed, + * or excluded result namespaces changed, + * or extension element namespaces changed. + * This will trigger creation of new infos + * for literal result elements. + */ + int nsChanged; + int preserveWhitespace; + int stripWhitespace; + int isRoot; /* whether this is the stylesheet's root node */ + int forwardsCompat; /* whether forwards-compatible mode is enabled */ + /* whether the content of an extension element was processed */ + int extContentHandled; + /* the type of the current child */ + xsltStyleType curChildType; +}; + +/** + * XSLT_CCTXT: + * + * get pointer to compiler context + */ +#define XSLT_CCTXT(style) ((xsltCompilerCtxtPtr) style->compCtxt) + +typedef enum { + XSLT_ERROR_SEVERITY_ERROR = 0, + XSLT_ERROR_SEVERITY_WARNING +} xsltErrorSeverityType; + +typedef struct _xsltCompilerCtxt xsltCompilerCtxt; +typedef xsltCompilerCtxt *xsltCompilerCtxtPtr; +struct _xsltCompilerCtxt { + void *errorCtxt; /* user specific error context */ + /* + * used for error/warning reports; e.g. XSLT_ERROR_SEVERITY_WARNING */ + xsltErrorSeverityType errSeverity; + int warnings; /* TODO: number of warnings found at + compilation */ + int errors; /* TODO: number of errors found at + compilation */ + xmlDictPtr dict; + xsltStylesheetPtr style; + int simplified; /* whether this is a simplified stylesheet */ + /* TODO: structured/unstructured error contexts. */ + int depth; /* Current depth of processing */ + + xsltCompilerNodeInfoPtr inode; + xsltCompilerNodeInfoPtr inodeList; + xsltCompilerNodeInfoPtr inodeLast; + xsltPointerListPtr tmpList; /* Used for various purposes */ + /* + * The XSLT version as specified by the stylesheet's root element. + */ + int isInclude; + int hasForwardsCompat; /* whether forwards-compatible mode was used + in a parsing episode */ + int maxNodeInfos; /* TEMP TODO: just for the interest */ + int maxLREs; /* TEMP TODO: just for the interest */ + /* + * In order to keep the old behaviour, applying strict rules of + * the spec can be turned off. This has effect only on special + * mechanisms like whitespace-stripping in the stylesheet. + */ + int strict; + xsltPrincipalStylesheetDataPtr psData; + xsltStyleItemUknownPtr unknownItem; + int hasNsAliases; /* Indicator if there was an xsl:namespace-alias. */ + xsltNsAliasPtr nsAliases; + xsltVarInfoPtr ivars; /* Storage of local in-scope variables/params. */ + xsltVarInfoPtr ivar; /* topmost local variable/param. */ +}; + +#else /* XSLT_REFACTORED */ +/* +* The old structures before refactoring. +*/ + +/** + * _xsltStylePreComp: + * + * The in-memory structure corresponding to XSLT stylesheet constructs + * precomputed data. + */ +struct _xsltStylePreComp { + xsltElemPreCompPtr next; /* chained list */ + xsltStyleType type; /* type of the element */ + xsltTransformFunction func; /* handling function */ + xmlNodePtr inst; /* the instruction */ + + /* + * Pre computed values. + */ + + const xmlChar *stype; /* sort */ + int has_stype; /* sort */ + int number; /* sort */ + const xmlChar *order; /* sort */ + int has_order; /* sort */ + int descending; /* sort */ + const xmlChar *lang; /* sort */ + int has_lang; /* sort */ + const xmlChar *case_order; /* sort */ + int lower_first; /* sort */ + + const xmlChar *use; /* copy, element */ + int has_use; /* copy, element */ + + int noescape; /* text */ + + const xmlChar *name; /* element, attribute, pi */ + int has_name; /* element, attribute, pi */ + const xmlChar *ns; /* element */ + int has_ns; /* element */ + + const xmlChar *mode; /* apply-templates */ + const xmlChar *modeURI; /* apply-templates */ + + const xmlChar *test; /* if */ + + xsltTemplatePtr templ; /* call-template */ + + const xmlChar *select; /* sort, copy-of, value-of, apply-templates */ + + int ver11; /* document */ + const xmlChar *filename; /* document URL */ + int has_filename; /* document */ + + xsltNumberData numdata; /* number */ + + xmlXPathCompExprPtr comp; /* a precompiled XPath expression */ + xmlNsPtr *nsList; /* the namespaces in scope */ + int nsNr; /* the number of namespaces in scope */ +}; + +#endif /* XSLT_REFACTORED */ + + +/* + * The in-memory structure corresponding to an XSLT Variable + * or Param. + */ +typedef struct _xsltStackElem xsltStackElem; +typedef xsltStackElem *xsltStackElemPtr; +struct _xsltStackElem { + struct _xsltStackElem *next;/* chained list */ + xsltStylePreCompPtr comp; /* the compiled form */ + int computed; /* was the evaluation done */ + const xmlChar *name; /* the local part of the name QName */ + const xmlChar *nameURI; /* the URI part of the name QName */ + const xmlChar *select; /* the eval string */ + xmlNodePtr tree; /* the sequence constructor if no eval + string or the location */ + xmlXPathObjectPtr value; /* The value if computed */ + xmlDocPtr fragment; /* The Result Tree Fragments (needed for XSLT 1.0) + which are bound to the variable's lifetime. */ + int level; /* the depth in the tree; + -1 if persistent (e.g. a given xsl:with-param) */ + xsltTransformContextPtr context; /* The transformation context; needed to cache + the variables */ + int flags; +}; + +#ifdef XSLT_REFACTORED + +struct _xsltPrincipalStylesheetData { + /* + * Namespace dictionary for ns-prefixes and ns-names: + * TODO: Shared between stylesheets, and XPath mechanisms. + * Not used yet. + */ + xmlDictPtr namespaceDict; + /* + * Global list of in-scope namespaces. + */ + xsltPointerListPtr inScopeNamespaces; + /* + * Global list of information for [xsl:]excluded-result-prefixes. + */ + xsltPointerListPtr exclResultNamespaces; + /* + * Global list of information for [xsl:]extension-element-prefixes. + */ + xsltPointerListPtr extElemNamespaces; + xsltEffectiveNsPtr effectiveNs; +#ifdef XSLT_REFACTORED_XSLT_NSCOMP + /* + * Namespace name map to get rid of string comparison of namespace names. + */ + xsltNsMapPtr nsMap; +#endif +}; + + +#endif +/* + * Note that we added a @compCtxt field to anchor an stylesheet compilation + * context, since, due to historical reasons, various compile-time function + * take only the stylesheet as argument and not a compilation context. + */ +struct _xsltStylesheet { + /* + * The stylesheet import relation is kept as a tree. + */ + struct _xsltStylesheet *parent; + struct _xsltStylesheet *next; + struct _xsltStylesheet *imports; + + xsltDocumentPtr docList; /* the include document list */ + + /* + * General data on the style sheet document. + */ + xmlDocPtr doc; /* the parsed XML stylesheet */ + xmlHashTablePtr stripSpaces;/* the hash table of the strip-space and + preserve space elements */ + int stripAll; /* strip-space * (1) preserve-space * (-1) */ + xmlHashTablePtr cdataSection;/* the hash table of the cdata-section */ + + /* + * Global variable or parameters. + */ + xsltStackElemPtr variables; /* linked list of param and variables */ + + /* + * Template descriptions. + */ + xsltTemplatePtr templates; /* the ordered list of templates */ + xmlHashTablePtr templatesHash; /* hash table or wherever compiled + templates information is stored */ + struct _xsltCompMatch *rootMatch; /* template based on / */ + struct _xsltCompMatch *keyMatch; /* template based on key() */ + struct _xsltCompMatch *elemMatch; /* template based on * */ + struct _xsltCompMatch *attrMatch; /* template based on @* */ + struct _xsltCompMatch *parentMatch; /* template based on .. */ + struct _xsltCompMatch *textMatch; /* template based on text() */ + struct _xsltCompMatch *piMatch; /* template based on + processing-instruction() */ + struct _xsltCompMatch *commentMatch; /* template based on comment() */ + + /* + * Namespace aliases. + * NOTE: Not used in the refactored code. + */ + xmlHashTablePtr nsAliases; /* the namespace alias hash tables */ + + /* + * Attribute sets. + */ + xmlHashTablePtr attributeSets;/* the attribute sets hash tables */ + + /* + * Namespaces. + * TODO: Eliminate this. + */ + xmlHashTablePtr nsHash; /* the set of namespaces in use: + ATTENTION: This is used for + execution of XPath expressions; unfortunately + it restricts the stylesheet to have distinct + prefixes. + TODO: We need to get rid of this. + */ + void *nsDefs; /* ATTENTION TODO: This is currently used to store + xsltExtDefPtr (in extensions.c) and + *not* xmlNsPtr. + */ + + /* + * Key definitions. + */ + void *keys; /* key definitions */ + + /* + * Output related stuff. + */ + xmlChar *method; /* the output method */ + xmlChar *methodURI; /* associated namespace if any */ + xmlChar *version; /* version string */ + xmlChar *encoding; /* encoding string */ + int omitXmlDeclaration; /* omit-xml-declaration = "yes" | "no" */ + + /* + * Number formatting. + */ + xsltDecimalFormatPtr decimalFormat; + int standalone; /* standalone = "yes" | "no" */ + xmlChar *doctypePublic; /* doctype-public string */ + xmlChar *doctypeSystem; /* doctype-system string */ + int indent; /* should output being indented */ + xmlChar *mediaType; /* media-type string */ + + /* + * Precomputed blocks. + */ + xsltElemPreCompPtr preComps;/* list of precomputed blocks */ + int warnings; /* number of warnings found at compilation */ + int errors; /* number of errors found at compilation */ + + xmlChar *exclPrefix; /* last excluded prefixes */ + xmlChar **exclPrefixTab; /* array of excluded prefixes */ + int exclPrefixNr; /* number of excluded prefixes in scope */ + int exclPrefixMax; /* size of the array */ + + void *_private; /* user defined data */ + + /* + * Extensions. + */ + xmlHashTablePtr extInfos; /* the extension data */ + int extrasNr; /* the number of extras required */ + + /* + * For keeping track of nested includes + */ + xsltDocumentPtr includes; /* points to last nested include */ + + /* + * dictionary: shared between stylesheet, context and documents. + */ + xmlDictPtr dict; + /* + * precompiled attribute value templates. + */ + void *attVTs; + /* + * if namespace-alias has an alias for the default stylesheet prefix + * NOTE: Not used in the refactored code. + */ + const xmlChar *defaultAlias; + /* + * bypass pre-processing (already done) (used in imports) + */ + int nopreproc; + /* + * all document text strings were internalized + */ + int internalized; + /* + * Literal Result Element as Stylesheet c.f. section 2.3 + */ + int literal_result; + /* + * The principal stylesheet + */ + xsltStylesheetPtr principal; +#ifdef XSLT_REFACTORED + /* + * Compilation context used during compile-time. + */ + xsltCompilerCtxtPtr compCtxt; /* TODO: Change this to (void *). */ + + xsltPrincipalStylesheetDataPtr principalData; +#endif + /* + * Forwards-compatible processing + */ + int forwards_compatible; + + xmlHashTablePtr namedTemplates; /* hash table of named templates */ + + xmlXPathContextPtr xpathCtxt; + + unsigned long opLimit; + unsigned long opCount; +}; + +typedef struct _xsltTransformCache xsltTransformCache; +typedef xsltTransformCache *xsltTransformCachePtr; +struct _xsltTransformCache { + xmlDocPtr RVT; + int nbRVT; + xsltStackElemPtr stackItems; + int nbStackItems; +#ifdef XSLT_DEBUG_PROFILE_CACHE + int dbgCachedRVTs; + int dbgReusedRVTs; + int dbgCachedVars; + int dbgReusedVars; +#endif +}; + +/* + * The in-memory structure corresponding to an XSLT Transformation. + */ +typedef enum { + XSLT_OUTPUT_XML = 0, + XSLT_OUTPUT_HTML, + XSLT_OUTPUT_TEXT +} xsltOutputType; + +typedef void * +(*xsltNewLocaleFunc)(const xmlChar *lang, int lowerFirst); +typedef void +(*xsltFreeLocaleFunc)(void *locale); +typedef xmlChar * +(*xsltGenSortKeyFunc)(void *locale, const xmlChar *lang); + +typedef enum { + XSLT_STATE_OK = 0, + XSLT_STATE_ERROR, + XSLT_STATE_STOPPED +} xsltTransformState; + +struct _xsltTransformContext { + xsltStylesheetPtr style; /* the stylesheet used */ + xsltOutputType type; /* the type of output */ + + xsltTemplatePtr templ; /* the current template */ + int templNr; /* Nb of templates in the stack */ + int templMax; /* Size of the templtes stack */ + xsltTemplatePtr *templTab; /* the template stack */ + + xsltStackElemPtr vars; /* the current variable list */ + int varsNr; /* Nb of variable list in the stack */ + int varsMax; /* Size of the variable list stack */ + xsltStackElemPtr *varsTab; /* the variable list stack */ + int varsBase; /* the var base for current templ */ + + /* + * Extensions + */ + xmlHashTablePtr extFunctions; /* the extension functions */ + xmlHashTablePtr extElements; /* the extension elements */ + xmlHashTablePtr extInfos; /* the extension data */ + + const xmlChar *mode; /* the current mode */ + const xmlChar *modeURI; /* the current mode URI */ + + xsltDocumentPtr docList; /* the document list */ + + xsltDocumentPtr document; /* the current source document; can be NULL if an RTF */ + xmlNodePtr node; /* the current node being processed */ + xmlNodeSetPtr nodeList; /* the current node list */ + /* xmlNodePtr current; the node */ + + xmlDocPtr output; /* the resulting document */ + xmlNodePtr insert; /* the insertion node */ + + xmlXPathContextPtr xpathCtxt; /* the XPath context */ + xsltTransformState state; /* the current state */ + + /* + * Global variables + */ + xmlHashTablePtr globalVars; /* the global variables and params */ + + xmlNodePtr inst; /* the instruction in the stylesheet */ + + int xinclude; /* should XInclude be processed */ + + const char * outputFile; /* the output URI if known */ + + int profile; /* is this run profiled */ + long prof; /* the current profiled value */ + int profNr; /* Nb of templates in the stack */ + int profMax; /* Size of the templtaes stack */ + long *profTab; /* the profile template stack */ + + void *_private; /* user defined data */ + + int extrasNr; /* the number of extras used */ + int extrasMax; /* the number of extras allocated */ + xsltRuntimeExtraPtr extras; /* extra per runtime information */ + + xsltDocumentPtr styleList; /* the stylesheet docs list */ + void * sec; /* the security preferences if any */ + + xmlGenericErrorFunc error; /* a specific error handler */ + void * errctx; /* context for the error handler */ + + xsltSortFunc sortfunc; /* a ctxt specific sort routine */ + + /* + * handling of temporary Result Value Tree + * (XSLT 1.0 term: "Result Tree Fragment") + */ + xmlDocPtr tmpRVT; /* list of RVT without persistance */ + xmlDocPtr persistRVT; /* list of persistant RVTs */ + int ctxtflags; /* context processing flags */ + + /* + * Speed optimization when coalescing text nodes + */ + const xmlChar *lasttext; /* last text node content */ + int lasttsize; /* last text node size */ + int lasttuse; /* last text node use */ + /* + * Per Context Debugging + */ + int debugStatus; /* the context level debug status */ + unsigned long* traceCode; /* pointer to the variable holding the mask */ + + int parserOptions; /* parser options xmlParserOption */ + + /* + * dictionary: shared between stylesheet, context and documents. + */ + xmlDictPtr dict; + xmlDocPtr tmpDoc; /* Obsolete; not used in the library. */ + /* + * all document text strings are internalized + */ + int internalized; + int nbKeys; + int hasTemplKeyPatterns; + xsltTemplatePtr currentTemplateRule; /* the Current Template Rule */ + xmlNodePtr initialContextNode; + xmlDocPtr initialContextDoc; + xsltTransformCachePtr cache; + void *contextVariable; /* the current variable item */ + xmlDocPtr localRVT; /* list of local tree fragments; will be freed when + the instruction which created the fragment + exits */ + xmlDocPtr localRVTBase; /* Obsolete */ + int keyInitLevel; /* Needed to catch recursive keys issues */ + int depth; /* Needed to catch recursions */ + int maxTemplateDepth; + int maxTemplateVars; + unsigned long opLimit; + unsigned long opCount; + int sourceDocDirty; + unsigned long currentId; /* For generate-id() */ + + xsltNewLocaleFunc newLocale; + xsltFreeLocaleFunc freeLocale; + xsltGenSortKeyFunc genSortKey; +}; + +/** + * CHECK_STOPPED: + * + * Macro to check if the XSLT processing should be stopped. + * Will return from the function. + */ +#define CHECK_STOPPED if (ctxt->state == XSLT_STATE_STOPPED) return; + +/** + * CHECK_STOPPEDE: + * + * Macro to check if the XSLT processing should be stopped. + * Will goto the error: label. + */ +#define CHECK_STOPPEDE if (ctxt->state == XSLT_STATE_STOPPED) goto error; + +/** + * CHECK_STOPPED0: + * + * Macro to check if the XSLT processing should be stopped. + * Will return from the function with a 0 value. + */ +#define CHECK_STOPPED0 if (ctxt->state == XSLT_STATE_STOPPED) return(0); + +/* + * The macro XML_CAST_FPTR is a hack to avoid a gcc warning about + * possible incompatibilities between function pointers and object + * pointers. It is defined in libxml/hash.h within recent versions + * of libxml2, but is put here for compatibility. + */ +#ifndef XML_CAST_FPTR +/** + * XML_CAST_FPTR: + * @fptr: pointer to a function + * + * Macro to do a casting from an object pointer to a + * function pointer without encountering a warning from + * gcc + * + * #define XML_CAST_FPTR(fptr) (*(void **)(&fptr)) + * This macro violated ISO C aliasing rules (gcc4 on s390 broke) + * so it is disabled now + */ + +#define XML_CAST_FPTR(fptr) fptr +#endif +/* + * Functions associated to the internal types +xsltDecimalFormatPtr xsltDecimalFormatGetByName(xsltStylesheetPtr sheet, + xmlChar *name); + */ +XSLTPUBFUN xsltStylesheetPtr XSLTCALL + xsltNewStylesheet (void); +XSLTPUBFUN xsltStylesheetPtr XSLTCALL + xsltParseStylesheetFile (const xmlChar* filename); +XSLTPUBFUN void XSLTCALL + xsltFreeStylesheet (xsltStylesheetPtr style); +XSLTPUBFUN int XSLTCALL + xsltIsBlank (xmlChar *str); +XSLTPUBFUN void XSLTCALL + xsltFreeStackElemList (xsltStackElemPtr elem); +XSLTPUBFUN xsltDecimalFormatPtr XSLTCALL + xsltDecimalFormatGetByName(xsltStylesheetPtr style, + xmlChar *name); +XSLTPUBFUN xsltDecimalFormatPtr XSLTCALL + xsltDecimalFormatGetByQName(xsltStylesheetPtr style, + const xmlChar *nsUri, + const xmlChar *name); + +XSLTPUBFUN xsltStylesheetPtr XSLTCALL + xsltParseStylesheetProcess(xsltStylesheetPtr ret, + xmlDocPtr doc); +XSLTPUBFUN void XSLTCALL + xsltParseStylesheetOutput(xsltStylesheetPtr style, + xmlNodePtr cur); +XSLTPUBFUN xsltStylesheetPtr XSLTCALL + xsltParseStylesheetDoc (xmlDocPtr doc); +XSLTPUBFUN xsltStylesheetPtr XSLTCALL + xsltParseStylesheetImportedDoc(xmlDocPtr doc, + xsltStylesheetPtr style); +XSLTPUBFUN int XSLTCALL + xsltParseStylesheetUser(xsltStylesheetPtr style, + xmlDocPtr doc); +XSLTPUBFUN xsltStylesheetPtr XSLTCALL + xsltLoadStylesheetPI (xmlDocPtr doc); +XSLTPUBFUN void XSLTCALL + xsltNumberFormat (xsltTransformContextPtr ctxt, + xsltNumberDataPtr data, + xmlNodePtr node); +XSLTPUBFUN xmlXPathError XSLTCALL + xsltFormatNumberConversion(xsltDecimalFormatPtr self, + xmlChar *format, + double number, + xmlChar **result); + +XSLTPUBFUN void XSLTCALL + xsltParseTemplateContent(xsltStylesheetPtr style, + xmlNodePtr templ); +XSLTPUBFUN int XSLTCALL + xsltAllocateExtra (xsltStylesheetPtr style); +XSLTPUBFUN int XSLTCALL + xsltAllocateExtraCtxt (xsltTransformContextPtr ctxt); +/* + * Extra functions for Result Value Trees + */ +XSLTPUBFUN xmlDocPtr XSLTCALL + xsltCreateRVT (xsltTransformContextPtr ctxt); +XSLTPUBFUN int XSLTCALL + xsltRegisterTmpRVT (xsltTransformContextPtr ctxt, + xmlDocPtr RVT); +XSLTPUBFUN int XSLTCALL + xsltRegisterLocalRVT (xsltTransformContextPtr ctxt, + xmlDocPtr RVT); +XSLTPUBFUN int XSLTCALL + xsltRegisterPersistRVT (xsltTransformContextPtr ctxt, + xmlDocPtr RVT); +XSLTPUBFUN int XSLTCALL + xsltExtensionInstructionResultRegister( + xsltTransformContextPtr ctxt, + xmlXPathObjectPtr obj); +XSLTPUBFUN int XSLTCALL + xsltExtensionInstructionResultFinalize( + xsltTransformContextPtr ctxt); +XSLTPUBFUN int XSLTCALL + xsltFlagRVTs( + xsltTransformContextPtr ctxt, + xmlXPathObjectPtr obj, + int val); +XSLTPUBFUN void XSLTCALL + xsltFreeRVTs (xsltTransformContextPtr ctxt); +XSLTPUBFUN void XSLTCALL + xsltReleaseRVT (xsltTransformContextPtr ctxt, + xmlDocPtr RVT); +/* + * Extra functions for Attribute Value Templates + */ +XSLTPUBFUN void XSLTCALL + xsltCompileAttr (xsltStylesheetPtr style, + xmlAttrPtr attr); +XSLTPUBFUN xmlChar * XSLTCALL + xsltEvalAVT (xsltTransformContextPtr ctxt, + void *avt, + xmlNodePtr node); +XSLTPUBFUN void XSLTCALL + xsltFreeAVTList (void *avt); + +/* + * Extra function for successful xsltCleanupGlobals / xsltInit sequence. + */ + +XSLTPUBFUN void XSLTCALL + xsltUninit (void); + +/************************************************************************ + * * + * Compile-time functions for *internal* use only * + * * + ************************************************************************/ + +#ifdef XSLT_REFACTORED +XSLTPUBFUN void XSLTCALL + xsltParseSequenceConstructor( + xsltCompilerCtxtPtr cctxt, + xmlNodePtr start); +XSLTPUBFUN int XSLTCALL + xsltParseAnyXSLTElem (xsltCompilerCtxtPtr cctxt, + xmlNodePtr elem); +#ifdef XSLT_REFACTORED_XSLT_NSCOMP +XSLTPUBFUN int XSLTCALL + xsltRestoreDocumentNamespaces( + xsltNsMapPtr ns, + xmlDocPtr doc); +#endif +#endif /* XSLT_REFACTORED */ + +/************************************************************************ + * * + * Transformation-time functions for *internal* use only * + * * + ************************************************************************/ +XSLTPUBFUN int XSLTCALL + xsltInitCtxtKey (xsltTransformContextPtr ctxt, + xsltDocumentPtr doc, + xsltKeyDefPtr keyd); +XSLTPUBFUN int XSLTCALL + xsltInitAllDocKeys (xsltTransformContextPtr ctxt); +#ifdef __cplusplus +} +#endif + +#endif /* __XML_XSLT_H__ */ + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/xsltconfig.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/xsltconfig.h new file mode 100644 index 0000000..e05f253 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/xsltconfig.h @@ -0,0 +1,146 @@ +/* + * Summary: compile-time version information for the XSLT engine + * Description: compile-time version information for the XSLT engine + * this module is autogenerated. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_XSLTCONFIG_H__ +#define __XML_XSLTCONFIG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * LIBXSLT_DOTTED_VERSION: + * + * the version string like "1.2.3" + */ +#define LIBXSLT_DOTTED_VERSION "1.1.43" + +/** + * LIBXSLT_VERSION: + * + * the version number: 1.2.3 value is 10203 + */ +#define LIBXSLT_VERSION 10143 + +/** + * LIBXSLT_VERSION_STRING: + * + * the version number string, 1.2.3 value is "10203" + */ +#define LIBXSLT_VERSION_STRING "10143" + +/** + * LIBXSLT_VERSION_EXTRA: + * + * extra version information, used to show a Git commit description + */ +#define LIBXSLT_VERSION_EXTRA "" + +/** + * WITH_XSLT_DEBUG: + * + * Activate the compilation of the debug reporting. Speed penalty + * is insignifiant and being able to run xsltpoc -v is useful. On + * by default unless --without-debug is passed to configure + */ +#if 1 +#define WITH_XSLT_DEBUG +#endif + +/** + * XSLT_NEED_TRIO: + * + * should be activated if the existing libc library lacks some of the + * string formatting function, in that case reuse the Trio ones already + * compiled in the libxml2 library. + */ + +#if 0 +#define XSLT_NEED_TRIO +#endif +#ifdef __VMS +#define HAVE_SYS_STAT_H 1 +#ifndef XSLT_NEED_TRIO +#define XSLT_NEED_TRIO +#endif +#endif + +#ifdef XSLT_NEED_TRIO +#define TRIO_REPLACE_STDIO +#endif + +/** + * WITH_XSLT_DEBUGGER: + * + * Activate the compilation of the debugger support. Speed penalty + * is insignifiant. + * On by default unless --without-debugger is passed to configure + */ +#if 0 +#ifndef WITH_DEBUGGER +#define WITH_DEBUGGER +#endif +#endif + +/** + * WITH_PROFILER: + * + * Activate the compilation of the profiler. Speed penalty + * is insignifiant. + * On by default unless --without-profiler is passed to configure + */ +#if 1 +#ifndef WITH_PROFILER +#define WITH_PROFILER +#endif +#endif + +/** + * WITH_MODULES: + * + * Whether module support is configured into libxslt + * Note: no default module path for win32 platforms + */ +#if 0 +#ifndef WITH_MODULES +#define WITH_MODULES +#endif +#define LIBXSLT_DEFAULT_PLUGINS_PATH() "" +#endif + +/** + * LIBXSLT_ATTR_FORMAT: + * + * This macro is used to indicate to GCC the parameters are printf-like + */ +#ifdef __GNUC__ +#define LIBXSLT_ATTR_FORMAT(fmt,args) __attribute__((__format__(__printf__,fmt,args))) +#else +#define LIBXSLT_ATTR_FORMAT(fmt,args) +#endif + +/** + * LIBXSLT_PUBLIC: + * + * This macro is used to declare PUBLIC variables for Cygwin and for MSC on Windows + */ +#if !defined LIBXSLT_PUBLIC +#if (defined(__CYGWIN__) || defined _MSC_VER) && !defined IN_LIBXSLT && !defined LIBXSLT_STATIC +#define LIBXSLT_PUBLIC __declspec(dllimport) +#else +#define LIBXSLT_PUBLIC +#endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __XML_XSLTCONFIG_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/xsltexports.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/xsltexports.h new file mode 100644 index 0000000..95c352f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/xsltexports.h @@ -0,0 +1,64 @@ +/* + * Summary: macros for marking symbols as exportable/importable. + * Description: macros for marking symbols as exportable/importable. + * + * Copy: See Copyright for the status of this software. + */ + +#ifndef __XSLT_EXPORTS_H__ +#define __XSLT_EXPORTS_H__ + +#if defined(_WIN32) || defined(__CYGWIN__) +/** DOC_DISABLE */ + +#ifdef LIBXSLT_STATIC + #define XSLTPUBLIC +#elif defined(IN_LIBXSLT) + #define XSLTPUBLIC __declspec(dllexport) +#else + #define XSLTPUBLIC __declspec(dllimport) +#endif + +#define XSLTCALL __cdecl + +/** DOC_ENABLE */ +#else /* not Windows */ + +/** + * XSLTPUBLIC: + * + * Macro which declares a public symbol + */ +#define XSLTPUBLIC + +/** + * XSLTCALL: + * + * Macro which declares the calling convention for exported functions + */ +#define XSLTCALL + +#endif /* platform switch */ + +/* + * XSLTPUBFUN: + * + * Macro which declares an exportable function + */ +#define XSLTPUBFUN XSLTPUBLIC + +/** + * XSLTPUBVAR: + * + * Macro which declares an exportable variable + */ +#define XSLTPUBVAR XSLTPUBLIC extern + +/* Compatibility */ +#if !defined(LIBXSLT_PUBLIC) +#define LIBXSLT_PUBLIC XSLTPUBVAR +#endif + +#endif /* __XSLT_EXPORTS_H__ */ + + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/xsltlocale.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/xsltlocale.h new file mode 100644 index 0000000..c8be58d --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/xsltlocale.h @@ -0,0 +1,44 @@ +/* + * Summary: Locale handling + * Description: Interfaces for locale handling. Needed for language dependent + * sorting. + * + * Copy: See Copyright for the status of this software. + * + * Author: Nick Wellnhofer + */ + +#ifndef __XML_XSLTLOCALE_H__ +#define __XML_XSLTLOCALE_H__ + +#include +#include "xsltexports.h" + +#ifdef __cplusplus +extern "C" { +#endif + +XSLTPUBFUN void * XSLTCALL + xsltNewLocale (const xmlChar *langName, + int lowerFirst); +XSLTPUBFUN void XSLTCALL + xsltFreeLocale (void *locale); +XSLTPUBFUN xmlChar * XSLTCALL + xsltStrxfrm (void *locale, + const xmlChar *string); +XSLTPUBFUN void XSLTCALL + xsltFreeLocales (void); + +/* Backward compatibility */ +typedef void *xsltLocale; +typedef xmlChar xsltLocaleChar; +XSLTPUBFUN int XSLTCALL + xsltLocaleStrcmp (void *locale, + const xmlChar *str1, + const xmlChar *str2); + +#ifdef __cplusplus +} +#endif + +#endif /* __XML_XSLTLOCALE_H__ */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/xsltutils.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/xsltutils.h new file mode 100644 index 0000000..2514774 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/include/libxslt/xsltutils.h @@ -0,0 +1,343 @@ +/* + * Summary: set of utilities for the XSLT engine + * Description: interfaces for the utilities module of the XSLT engine. + * things like message handling, profiling, and other + * generally useful routines. + * + * Copy: See Copyright for the status of this software. + * + * Author: Daniel Veillard + */ + +#ifndef __XML_XSLTUTILS_H__ +#define __XML_XSLTUTILS_H__ + +#include +#include +#include +#include +#include "xsltexports.h" +#include "xsltInternals.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * XSLT_TODO: + * + * Macro to flag unimplemented blocks. + */ +#define XSLT_TODO \ + xsltGenericError(xsltGenericErrorContext, \ + "Unimplemented block at %s:%d\n", \ + __FILE__, __LINE__); + +/** + * XSLT_STRANGE: + * + * Macro to flag that a problem was detected internally. + */ +#define XSLT_STRANGE \ + xsltGenericError(xsltGenericErrorContext, \ + "Internal error at %s:%d\n", \ + __FILE__, __LINE__); + +/** + * IS_XSLT_ELEM: + * + * Checks that the element pertains to XSLT namespace. + */ +#define IS_XSLT_ELEM(n) \ + (((n) != NULL) && ((n)->type == XML_ELEMENT_NODE) && \ + ((n)->ns != NULL) && (xmlStrEqual((n)->ns->href, XSLT_NAMESPACE))) + +/** + * IS_XSLT_NAME: + * + * Checks the value of an element in XSLT namespace. + */ +#define IS_XSLT_NAME(n, val) \ + (xmlStrEqual((n)->name, (const xmlChar *) (val))) + +/** + * IS_XSLT_REAL_NODE: + * + * Check that a node is a 'real' one: document, element, text or attribute. + */ +#define IS_XSLT_REAL_NODE(n) \ + (((n) != NULL) && \ + (((n)->type == XML_ELEMENT_NODE) || \ + ((n)->type == XML_TEXT_NODE) || \ + ((n)->type == XML_CDATA_SECTION_NODE) || \ + ((n)->type == XML_ATTRIBUTE_NODE) || \ + ((n)->type == XML_DOCUMENT_NODE) || \ + ((n)->type == XML_HTML_DOCUMENT_NODE) || \ + ((n)->type == XML_COMMENT_NODE) || \ + ((n)->type == XML_PI_NODE))) + +/* + * Our own version of namespaced attributes lookup. + */ +XSLTPUBFUN xmlChar * XSLTCALL + xsltGetNsProp (xmlNodePtr node, + const xmlChar *name, + const xmlChar *nameSpace); +XSLTPUBFUN const xmlChar * XSLTCALL + xsltGetCNsProp (xsltStylesheetPtr style, + xmlNodePtr node, + const xmlChar *name, + const xmlChar *nameSpace); +XSLTPUBFUN int XSLTCALL + xsltGetUTF8Char (const unsigned char *utf, + int *len); +#ifdef IN_LIBXSLT +/** DOC_DISABLE */ +XSLTPUBFUN int XSLTCALL + xsltGetUTF8CharZ (const unsigned char *utf, + int *len); +/** DOC_ENABLE */ +#endif + +/* + * XSLT Debug Tracing Tracing Types + */ +typedef enum { + XSLT_TRACE_ALL = -1, + XSLT_TRACE_NONE = 0, + XSLT_TRACE_COPY_TEXT = 1<<0, + XSLT_TRACE_PROCESS_NODE = 1<<1, + XSLT_TRACE_APPLY_TEMPLATE = 1<<2, + XSLT_TRACE_COPY = 1<<3, + XSLT_TRACE_COMMENT = 1<<4, + XSLT_TRACE_PI = 1<<5, + XSLT_TRACE_COPY_OF = 1<<6, + XSLT_TRACE_VALUE_OF = 1<<7, + XSLT_TRACE_CALL_TEMPLATE = 1<<8, + XSLT_TRACE_APPLY_TEMPLATES = 1<<9, + XSLT_TRACE_CHOOSE = 1<<10, + XSLT_TRACE_IF = 1<<11, + XSLT_TRACE_FOR_EACH = 1<<12, + XSLT_TRACE_STRIP_SPACES = 1<<13, + XSLT_TRACE_TEMPLATES = 1<<14, + XSLT_TRACE_KEYS = 1<<15, + XSLT_TRACE_VARIABLES = 1<<16 +} xsltDebugTraceCodes; + +/** + * XSLT_TRACE: + * + * Control the type of xsl debugtrace messages emitted. + */ +#define XSLT_TRACE(ctxt,code,call) \ + if (ctxt->traceCode && (*(ctxt->traceCode) & code)) \ + call + +XSLTPUBFUN void XSLTCALL + xsltDebugSetDefaultTrace(xsltDebugTraceCodes val); +XSLTPUBFUN xsltDebugTraceCodes XSLTCALL + xsltDebugGetDefaultTrace(void); + +/* + * XSLT specific error and debug reporting functions. + */ +XSLTPUBVAR xmlGenericErrorFunc xsltGenericError; +XSLTPUBVAR void *xsltGenericErrorContext; +XSLTPUBVAR xmlGenericErrorFunc xsltGenericDebug; +XSLTPUBVAR void *xsltGenericDebugContext; + +XSLTPUBFUN void XSLTCALL + xsltPrintErrorContext (xsltTransformContextPtr ctxt, + xsltStylesheetPtr style, + xmlNodePtr node); +XSLTPUBFUN void XSLTCALL + xsltMessage (xsltTransformContextPtr ctxt, + xmlNodePtr node, + xmlNodePtr inst); +XSLTPUBFUN void XSLTCALL + xsltSetGenericErrorFunc (void *ctx, + xmlGenericErrorFunc handler); +XSLTPUBFUN void XSLTCALL + xsltSetGenericDebugFunc (void *ctx, + xmlGenericErrorFunc handler); +XSLTPUBFUN void XSLTCALL + xsltSetTransformErrorFunc (xsltTransformContextPtr ctxt, + void *ctx, + xmlGenericErrorFunc handler); +XSLTPUBFUN void XSLTCALL + xsltTransformError (xsltTransformContextPtr ctxt, + xsltStylesheetPtr style, + xmlNodePtr node, + const char *msg, + ...) LIBXSLT_ATTR_FORMAT(4,5); + +XSLTPUBFUN int XSLTCALL + xsltSetCtxtParseOptions (xsltTransformContextPtr ctxt, + int options); +/* + * Sorting. + */ + +XSLTPUBFUN void XSLTCALL + xsltDocumentSortFunction (xmlNodeSetPtr list); +XSLTPUBFUN void XSLTCALL + xsltSetSortFunc (xsltSortFunc handler); +XSLTPUBFUN void XSLTCALL + xsltSetCtxtSortFunc (xsltTransformContextPtr ctxt, + xsltSortFunc handler); +XSLTPUBFUN void XSLTCALL + xsltSetCtxtLocaleHandlers (xsltTransformContextPtr ctxt, + xsltNewLocaleFunc newLocale, + xsltFreeLocaleFunc freeLocale, + xsltGenSortKeyFunc genSortKey); +XSLTPUBFUN void XSLTCALL + xsltDefaultSortFunction (xsltTransformContextPtr ctxt, + xmlNodePtr *sorts, + int nbsorts); +XSLTPUBFUN void XSLTCALL + xsltDoSortFunction (xsltTransformContextPtr ctxt, + xmlNodePtr * sorts, + int nbsorts); +XSLTPUBFUN xmlXPathObjectPtr * XSLTCALL + xsltComputeSortResult (xsltTransformContextPtr ctxt, + xmlNodePtr sort); + +/* + * QNames handling. + */ + +XSLTPUBFUN const xmlChar * XSLTCALL + xsltSplitQName (xmlDictPtr dict, + const xmlChar *name, + const xmlChar **prefix); +XSLTPUBFUN const xmlChar * XSLTCALL + xsltGetQNameURI (xmlNodePtr node, + xmlChar **name); + +XSLTPUBFUN const xmlChar * XSLTCALL + xsltGetQNameURI2 (xsltStylesheetPtr style, + xmlNodePtr node, + const xmlChar **name); + +/* + * Output, reuse libxml I/O buffers. + */ +XSLTPUBFUN int XSLTCALL + xsltSaveResultTo (xmlOutputBufferPtr buf, + xmlDocPtr result, + xsltStylesheetPtr style); +XSLTPUBFUN int XSLTCALL + xsltSaveResultToFilename (const char *URI, + xmlDocPtr result, + xsltStylesheetPtr style, + int compression); +XSLTPUBFUN int XSLTCALL + xsltSaveResultToFile (FILE *file, + xmlDocPtr result, + xsltStylesheetPtr style); +XSLTPUBFUN int XSLTCALL + xsltSaveResultToFd (int fd, + xmlDocPtr result, + xsltStylesheetPtr style); +XSLTPUBFUN int XSLTCALL + xsltSaveResultToString (xmlChar **doc_txt_ptr, + int * doc_txt_len, + xmlDocPtr result, + xsltStylesheetPtr style); + +/* + * XPath interface + */ +XSLTPUBFUN xmlXPathCompExprPtr XSLTCALL + xsltXPathCompile (xsltStylesheetPtr style, + const xmlChar *str); +XSLTPUBFUN xmlXPathCompExprPtr XSLTCALL + xsltXPathCompileFlags (xsltStylesheetPtr style, + const xmlChar *str, + int flags); + +#ifdef IN_LIBXSLT +/** DOC_DISABLE */ +#define XSLT_SOURCE_NODE_MASK 15u +#define XSLT_SOURCE_NODE_HAS_KEY 1u +#define XSLT_SOURCE_NODE_HAS_ID 2u +int +xsltGetSourceNodeFlags(xmlNodePtr node); +int +xsltSetSourceNodeFlags(xsltTransformContextPtr ctxt, xmlNodePtr node, + int flags); +int +xsltClearSourceNodeFlags(xmlNodePtr node, int flags); +void ** +xsltGetPSVIPtr(xmlNodePtr cur); +/** DOC_ENABLE */ +#endif + +#ifdef WITH_PROFILER +/* + * Profiling. + */ +XSLTPUBFUN void XSLTCALL + xsltSaveProfiling (xsltTransformContextPtr ctxt, + FILE *output); +XSLTPUBFUN xmlDocPtr XSLTCALL + xsltGetProfileInformation (xsltTransformContextPtr ctxt); + +XSLTPUBFUN long XSLTCALL + xsltTimestamp (void); +XSLTPUBFUN void XSLTCALL + xsltCalibrateAdjust (long delta); +#endif + +/** + * XSLT_TIMESTAMP_TICS_PER_SEC: + * + * Sampling precision for profiling + */ +#define XSLT_TIMESTAMP_TICS_PER_SEC 100000l + +/* + * Hooks for the debugger. + */ + +typedef enum { + XSLT_DEBUG_NONE = 0, /* no debugging allowed */ + XSLT_DEBUG_INIT, + XSLT_DEBUG_STEP, + XSLT_DEBUG_STEPOUT, + XSLT_DEBUG_NEXT, + XSLT_DEBUG_STOP, + XSLT_DEBUG_CONT, + XSLT_DEBUG_RUN, + XSLT_DEBUG_RUN_RESTART, + XSLT_DEBUG_QUIT +} xsltDebugStatusCodes; + +XSLTPUBVAR int xslDebugStatus; + +typedef void (*xsltHandleDebuggerCallback) (xmlNodePtr cur, xmlNodePtr node, + xsltTemplatePtr templ, xsltTransformContextPtr ctxt); +typedef int (*xsltAddCallCallback) (xsltTemplatePtr templ, xmlNodePtr source); +typedef void (*xsltDropCallCallback) (void); + +XSLTPUBFUN int XSLTCALL + xsltGetDebuggerStatus (void); +#ifdef WITH_DEBUGGER +XSLTPUBFUN void XSLTCALL + xsltSetDebuggerStatus (int value); +XSLTPUBFUN int XSLTCALL + xsltSetDebuggerCallbacks (int no, void *block); +XSLTPUBFUN int XSLTCALL + xslAddCall (xsltTemplatePtr templ, + xmlNodePtr source); +XSLTPUBFUN void XSLTCALL + xslDropCall (void); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __XML_XSLTUTILS_H__ */ + + diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/libxml2_polyfill.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/libxml2_polyfill.c new file mode 100644 index 0000000..750b1b5 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/libxml2_polyfill.c @@ -0,0 +1,114 @@ +#include + +#ifndef HAVE_XMLCTXTSETOPTIONS +/* based on libxml2-2.14.0-dev (1d8bd126) parser.c xmlCtxtSetInternalOptions */ +int +xmlCtxtSetOptions(xmlParserCtxtPtr ctxt, int options) +{ + int keepMask = 0; + int allMask; + + if (ctxt == NULL) { + return (-1); + } + + /* + * XInclude options aren't handled by the parser. + * + * XML_PARSE_XINCLUDE + * XML_PARSE_NOXINCNODE + * XML_PARSE_NOBASEFIX + */ + allMask = XML_PARSE_RECOVER | + XML_PARSE_NOENT | + XML_PARSE_DTDLOAD | + XML_PARSE_DTDATTR | + XML_PARSE_DTDVALID | + XML_PARSE_NOERROR | + XML_PARSE_NOWARNING | + XML_PARSE_PEDANTIC | + XML_PARSE_NOBLANKS | +#ifdef LIBXML_SAX1_ENABLED + XML_PARSE_SAX1 | +#endif + XML_PARSE_NONET | + XML_PARSE_NODICT | + XML_PARSE_NSCLEAN | + XML_PARSE_NOCDATA | + XML_PARSE_COMPACT | + XML_PARSE_OLD10 | + XML_PARSE_HUGE | + XML_PARSE_OLDSAX | + XML_PARSE_IGNORE_ENC | + XML_PARSE_BIG_LINES; + + ctxt->options = (ctxt->options & keepMask) | (options & allMask); + + /* + * For some options, struct members are historically the source + * of truth. The values are initalized from global variables and + * old code could also modify them directly. Several older API + * functions that don't take an options argument rely on these + * deprecated mechanisms. + * + * Once public access to struct members and the globals are + * disabled, we can use the options bitmask as source of + * truth, making all these struct members obsolete. + * + * The XML_DETECT_IDS flags is misnamed. It simply enables + * loading of the external subset. + */ + ctxt->recovery = (options & XML_PARSE_RECOVER) ? 1 : 0; + ctxt->replaceEntities = (options & XML_PARSE_NOENT) ? 1 : 0; + ctxt->loadsubset = (options & XML_PARSE_DTDLOAD) ? XML_DETECT_IDS : 0; + ctxt->loadsubset |= (options & XML_PARSE_DTDATTR) ? XML_COMPLETE_ATTRS : 0; + ctxt->validate = (options & XML_PARSE_DTDVALID) ? 1 : 0; + ctxt->pedantic = (options & XML_PARSE_PEDANTIC) ? 1 : 0; + ctxt->keepBlanks = (options & XML_PARSE_NOBLANKS) ? 0 : 1; + ctxt->dictNames = (options & XML_PARSE_NODICT) ? 0 : 1; + + /* + * Changing SAX callbacks is a bad idea. This should be fixed. + */ + if (options & XML_PARSE_NOBLANKS) { + ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace; + } + if (options & XML_PARSE_NOCDATA) { + ctxt->sax->cdataBlock = NULL; + } + if (options & XML_PARSE_HUGE) { + if (ctxt->dict != NULL) { + xmlDictSetLimit(ctxt->dict, 0); + } + } + + ctxt->linenumbers = 1; + + return (options & ~allMask); +} +#endif + +#ifndef HAVE_XMLCTXTGETOPTIONS +int +xmlCtxtGetOptions(xmlParserCtxtPtr ctxt) +{ + return (ctxt->options); +} +#endif + +#ifndef HAVE_XMLSWITCHENCODINGNAME +int +xmlSwitchEncodingName(xmlParserCtxtPtr ctxt, const char *encoding) +{ + if (ctxt == NULL) { + return (-1); + } + + xmlCharEncodingHandlerPtr handler = xmlFindCharEncodingHandler(encoding); + if (handler == NULL) { + return (-1); + } + + return (xmlSwitchToEncoding(ctxt, handler)); +} +#endif diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/nokogiri.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/nokogiri.c new file mode 100644 index 0000000..a43813b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/nokogiri.c @@ -0,0 +1,294 @@ +#include + +VALUE mNokogiri ; +VALUE mNokogiriGumbo ; +VALUE mNokogiriHtml4 ; +VALUE mNokogiriHtml4Sax ; +VALUE mNokogiriHtml5 ; +VALUE mNokogiriXml ; +VALUE mNokogiriXmlSax ; +VALUE mNokogiriXmlXpath ; +VALUE mNokogiriXslt ; + +VALUE cNokogiriSyntaxError; +VALUE cNokogiriXmlCharacterData; +VALUE cNokogiriXmlElement; +VALUE cNokogiriXmlXpathSyntaxError; + +void noko_init_xml_attr(void); +void noko_init_xml_attribute_decl(void); +void noko_init_xml_cdata(void); +void noko_init_xml_comment(void); +void noko_init_xml_document(void); +void noko_init_xml_document_fragment(void); +void noko_init_xml_dtd(void); +void noko_init_xml_element_content(void); +void noko_init_xml_element_decl(void); +void noko_init_xml_encoding_handler(void); +void noko_init_xml_entity_decl(void); +void noko_init_xml_entity_reference(void); +void noko_init_xml_namespace(void); +void noko_init_xml_node(void); +void noko_init_xml_node_set(void); +void noko_init_xml_processing_instruction(void); +void noko_init_xml_reader(void); +void noko_init_xml_relax_ng(void); +void noko_init_xml_sax_parser(void); +void noko_init_xml_sax_parser_context(void); +void noko_init_xml_sax_push_parser(void); +void noko_init_xml_schema(void); +void noko_init_xml_syntax_error(void); +void noko_init_xml_text(void); +void noko_init_xml_xpath_context(void); +void noko_init_xslt_stylesheet(void); +void noko_init_html_document(void); +void noko_init_html_element_description(void); +void noko_init_html_entity_lookup(void); +void noko_init_html_sax_parser_context(void); +void noko_init_html_sax_push_parser(void); +void noko_init_html4_sax_parser(void); +void noko_init_gumbo(void); +void noko_init_test_global_handlers(void); + +static ID id_read, id_write, id_external_encoding; + + +static VALUE +noko_io_read_check(VALUE val) +{ + VALUE *args = (VALUE *)val; + return rb_funcall(args[0], id_read, 1, args[1]); +} + + +static VALUE +noko_io_read_failed(VALUE arg, VALUE exc) +{ + return Qundef; +} + + +int +noko_io_read(void *io, char *c_buffer, int c_buffer_len) +{ + VALUE rb_io = (VALUE)io; + VALUE rb_read_string, rb_args[2]; + size_t n_bytes_read, safe_len; + + rb_args[0] = rb_io; + rb_args[1] = INT2NUM(c_buffer_len); + + rb_read_string = rb_rescue(noko_io_read_check, (VALUE)rb_args, noko_io_read_failed, 0); + + if (NIL_P(rb_read_string)) { return 0; } + if (rb_read_string == Qundef) { return -1; } + if (TYPE(rb_read_string) != T_STRING) { return -1; } + + n_bytes_read = (size_t)RSTRING_LEN(rb_read_string); + safe_len = (n_bytes_read > (size_t)c_buffer_len) ? (size_t)c_buffer_len : n_bytes_read; + memcpy(c_buffer, StringValuePtr(rb_read_string), safe_len); + + return (int)safe_len; +} + + +static VALUE +noko_io_write_check(VALUE rb_args) +{ + VALUE rb_io = ((VALUE *)rb_args)[0]; + VALUE rb_output = ((VALUE *)rb_args)[1]; + return rb_funcall(rb_io, id_write, 1, rb_output); +} + + +static VALUE +noko_io_write_failed(VALUE arg, VALUE exc) +{ + return Qundef; +} + + +int +noko_io_write(void *io, char *c_buffer, int c_buffer_len) +{ + VALUE rb_args[2], rb_n_bytes_written; + VALUE rb_io = (VALUE)io; + VALUE rb_enc = Qnil; + rb_encoding *io_encoding; + + if (rb_respond_to(rb_io, id_external_encoding)) { + rb_enc = rb_funcall(rb_io, id_external_encoding, 0); + } + io_encoding = RB_NIL_P(rb_enc) ? rb_ascii8bit_encoding() : rb_to_encoding(rb_enc); + + rb_args[0] = rb_io; + rb_args[1] = rb_enc_str_new(c_buffer, (long)c_buffer_len, io_encoding); + + rb_n_bytes_written = rb_rescue(noko_io_write_check, (VALUE)rb_args, noko_io_write_failed, 0); + if (rb_n_bytes_written == Qundef) { return -1; } + + return NUM2INT(rb_n_bytes_written); +} + + +int +noko_io_close(void *io) +{ + return 0; +} + + +#if defined(_WIN32) && !defined(NOKOGIRI_PACKAGED_LIBRARIES) +# define NOKOGIRI_WINDOWS_DLLS 1 +#else +# define NOKOGIRI_WINDOWS_DLLS 0 +#endif + +// +// | dlls || true | false | +// | nlmm || | | +// |-----------++---------+---------| +// | NULL || default | ruby | +// | "random" || default | ruby | +// | "ruby" || ruby | ruby | +// | "default" || default | default | +// +// We choose *not* to use Ruby's memory management functions with windows DLLs because of this +// issue: https://github.com/sparklemotion/nokogiri/issues/2241 +// +static void +set_libxml_memory_management(void) +{ + const char *nlmm = getenv("NOKOGIRI_LIBXML_MEMORY_MANAGEMENT"); + if (nlmm) { + if (strcmp(nlmm, "default") == 0) { + goto libxml_uses_default_memory_management; + } else if (strcmp(nlmm, "ruby") == 0) { + goto libxml_uses_ruby_memory_management; + } + } + if (NOKOGIRI_WINDOWS_DLLS) { +libxml_uses_default_memory_management: + rb_const_set(mNokogiri, rb_intern("LIBXML_MEMORY_MANAGEMENT"), NOKOGIRI_STR_NEW2("default")); + return; + } else { +libxml_uses_ruby_memory_management: + rb_const_set(mNokogiri, rb_intern("LIBXML_MEMORY_MANAGEMENT"), NOKOGIRI_STR_NEW2("ruby")); + xmlMemSetup((xmlFreeFunc)ruby_xfree, (xmlMallocFunc)ruby_xmalloc, (xmlReallocFunc)ruby_xrealloc, ruby_strdup); + return; + } +} + + +void +Init_nokogiri(void) +{ + mNokogiri = rb_define_module("Nokogiri"); + mNokogiriGumbo = rb_define_module_under(mNokogiri, "Gumbo"); + mNokogiriHtml4 = rb_define_module_under(mNokogiri, "HTML4"); + mNokogiriHtml4Sax = rb_define_module_under(mNokogiriHtml4, "SAX"); + mNokogiriHtml5 = rb_define_module_under(mNokogiri, "HTML5"); + mNokogiriXml = rb_define_module_under(mNokogiri, "XML"); + mNokogiriXmlSax = rb_define_module_under(mNokogiriXml, "SAX"); + mNokogiriXmlXpath = rb_define_module_under(mNokogiriXml, "XPath"); + mNokogiriXslt = rb_define_module_under(mNokogiri, "XSLT"); + + set_libxml_memory_management(); /* must be before any function calls that might invoke xmlInitParser() */ + xmlInitParser(); + exsltRegisterAll(); + + rb_const_set(mNokogiri, rb_intern("LIBXML_COMPILED_VERSION"), NOKOGIRI_STR_NEW2(LIBXML_DOTTED_VERSION)); + rb_const_set(mNokogiri, rb_intern("LIBXML_LOADED_VERSION"), NOKOGIRI_STR_NEW2(xmlParserVersion)); + + rb_const_set(mNokogiri, rb_intern("LIBXSLT_COMPILED_VERSION"), NOKOGIRI_STR_NEW2(LIBXSLT_DOTTED_VERSION)); + rb_const_set(mNokogiri, rb_intern("LIBXSLT_LOADED_VERSION"), NOKOGIRI_STR_NEW2(xsltEngineVersion)); + + rb_const_set(mNokogiri, rb_intern("LIBXML_ZLIB_ENABLED"), + xmlHasFeature(XML_WITH_ZLIB) == 1 ? Qtrue : Qfalse); + +#ifdef NOKOGIRI_PACKAGED_LIBRARIES + rb_const_set(mNokogiri, rb_intern("PACKAGED_LIBRARIES"), Qtrue); +# ifdef NOKOGIRI_PRECOMPILED_LIBRARIES + rb_const_set(mNokogiri, rb_intern("PRECOMPILED_LIBRARIES"), Qtrue); +# else + rb_const_set(mNokogiri, rb_intern("PRECOMPILED_LIBRARIES"), Qfalse); +# endif + rb_const_set(mNokogiri, rb_intern("LIBXML2_PATCHES"), rb_str_split(NOKOGIRI_STR_NEW2(NOKOGIRI_LIBXML2_PATCHES), " ")); + rb_const_set(mNokogiri, rb_intern("LIBXSLT_PATCHES"), rb_str_split(NOKOGIRI_STR_NEW2(NOKOGIRI_LIBXSLT_PATCHES), " ")); +#else + rb_const_set(mNokogiri, rb_intern("PACKAGED_LIBRARIES"), Qfalse); + rb_const_set(mNokogiri, rb_intern("PRECOMPILED_LIBRARIES"), Qfalse); + rb_const_set(mNokogiri, rb_intern("LIBXML2_PATCHES"), Qnil); + rb_const_set(mNokogiri, rb_intern("LIBXSLT_PATCHES"), Qnil); +#endif + +#ifdef LIBXML_ICONV_ENABLED + rb_const_set(mNokogiri, rb_intern("LIBXML_ICONV_ENABLED"), Qtrue); +#else + rb_const_set(mNokogiri, rb_intern("LIBXML_ICONV_ENABLED"), Qfalse); +#endif + +#ifdef NOKOGIRI_OTHER_LIBRARY_VERSIONS + rb_const_set(mNokogiri, rb_intern("OTHER_LIBRARY_VERSIONS"), NOKOGIRI_STR_NEW2(NOKOGIRI_OTHER_LIBRARY_VERSIONS)); +#endif + + if (xsltExtModuleFunctionLookup((const xmlChar *)"date-time", EXSLT_DATE_NAMESPACE)) { + rb_const_set(mNokogiri, rb_intern("LIBXSLT_DATETIME_ENABLED"), Qtrue); + } else { + rb_const_set(mNokogiri, rb_intern("LIBXSLT_DATETIME_ENABLED"), Qfalse); + } + + cNokogiriSyntaxError = rb_define_class_under(mNokogiri, "SyntaxError", rb_eStandardError); + noko_init_xml_syntax_error(); + assert(cNokogiriXmlSyntaxError); + cNokogiriXmlXpathSyntaxError = rb_define_class_under(mNokogiriXmlXpath, "SyntaxError", cNokogiriXmlSyntaxError); + + noko_init_xml_element_content(); + noko_init_xml_encoding_handler(); + noko_init_xml_namespace(); + noko_init_xml_node_set(); + noko_init_xml_reader(); + + noko_init_xml_sax_parser(); + noko_init_html4_sax_parser(); + + noko_init_xml_xpath_context(); + noko_init_xslt_stylesheet(); + noko_init_html_element_description(); + noko_init_html_entity_lookup(); + + noko_init_xml_schema(); + noko_init_xml_relax_ng(); + + noko_init_xml_sax_parser_context(); + noko_init_html_sax_parser_context(); + + noko_init_xml_sax_push_parser(); + noko_init_html_sax_push_parser(); + + noko_init_xml_node(); + noko_init_xml_attr(); + noko_init_xml_attribute_decl(); + noko_init_xml_dtd(); + noko_init_xml_element_decl(); + noko_init_xml_entity_decl(); + noko_init_xml_entity_reference(); + noko_init_xml_processing_instruction(); + assert(cNokogiriXmlNode); + cNokogiriXmlElement = rb_define_class_under(mNokogiriXml, "Element", cNokogiriXmlNode); + cNokogiriXmlCharacterData = rb_define_class_under(mNokogiriXml, "CharacterData", cNokogiriXmlNode); + noko_init_xml_comment(); + noko_init_xml_text(); + noko_init_xml_cdata(); + + noko_init_xml_document_fragment(); + noko_init_xml_document(); + noko_init_html_document(); + noko_init_gumbo(); + + noko_init_test_global_handlers(); + + id_read = rb_intern("read"); + id_write = rb_intern("write"); + id_external_encoding = rb_intern("external_encoding"); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/nokogiri.h b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/nokogiri.h new file mode 100644 index 0000000..b75ebc4 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/nokogiri.h @@ -0,0 +1,238 @@ +#ifndef NOKOGIRI_NATIVE +#define NOKOGIRI_NATIVE + +#include // https://github.com/sparklemotion/nokogiri/issues/2696 + +#ifdef _MSC_VER +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif /* WIN32_LEAN_AND_MEAN */ + +# ifndef WIN32 +# define WIN32 +# endif /* WIN32 */ + +# include +# include +# include +#endif + +#ifdef _WIN32 +# define NOKOPUBFUN __declspec(dllexport) +# define NOKOPUBVAR __declspec(dllexport) extern +#else +# define NOKOPUBFUN +# define NOKOPUBVAR extern +#endif + +#include +#include +#include +#include +#include + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +/* libxml2_polyfill.c */ +#ifndef HAVE_XMLCTXTSETOPTIONS +int xmlCtxtSetOptions(xmlParserCtxtPtr ctxt, int options); +#endif +#ifndef HAVE_XMLCTXTGETOPTIONS +int xmlCtxtGetOptions(xmlParserCtxtPtr ctxt); +#endif +#ifndef HAVE_XMLSWITCHENCODINGNAME +int xmlSwitchEncodingName(xmlParserCtxtPtr ctxt, const char *encoding); +#endif + +#define XMLNS_PREFIX "xmlns" +#define XMLNS_PREFIX_LEN 6 /* including either colon or \0 */ + +#ifndef xmlErrorConstPtr +# if LIBXML_VERSION >= 21200 +# define xmlErrorConstPtr const xmlError * +# else +# define xmlErrorConstPtr xmlError * +# endif +#endif + +#include +#include +#include +#include +#include + +#define NOKOGIRI_STR_NEW2(str) NOKOGIRI_STR_NEW(str, strlen((const char *)(str))) +#define NOKOGIRI_STR_NEW(str, len) rb_external_str_new_with_enc((const char *)(str), (long)(len), rb_utf8_encoding()) +#define RBSTR_OR_QNIL(_str) (_str ? NOKOGIRI_STR_NEW2(_str) : Qnil) + +#ifndef NORETURN_DECL +# if defined(__GNUC__) +# define NORETURN_DECL __attribute__ ((noreturn)) +# else +# define NORETURN_DECL +# endif +#endif + +#ifndef PRINTFLIKE_DECL +# if defined(__GNUC__) +# define PRINTFLIKE_DECL(stringidx, argidx) __attribute__ ((format(printf,stringidx,argidx))) +# else +# define PRINTFLIKE_DECL(stringidx, argidx) +# endif +#endif + +#if defined(TRUFFLERUBY) && !defined(NOKOGIRI_PACKAGED_LIBRARIES) +# define TRUFFLERUBY_NOKOGIRI_SYSTEM_LIBRARIES +#endif + +NOKOPUBVAR VALUE mNokogiri ; +NOKOPUBVAR VALUE mNokogiriGumbo ; +NOKOPUBVAR VALUE mNokogiriHtml4 ; +NOKOPUBVAR VALUE mNokogiriHtml4Sax ; +NOKOPUBVAR VALUE mNokogiriHtml5 ; +NOKOPUBVAR VALUE mNokogiriXml ; +NOKOPUBVAR VALUE mNokogiriXmlSax ; +NOKOPUBVAR VALUE mNokogiriXmlXpath ; +NOKOPUBVAR VALUE mNokogiriXslt ; + +NOKOPUBVAR VALUE cNokogiriEncodingHandler; +NOKOPUBVAR VALUE cNokogiriSyntaxError; +NOKOPUBVAR VALUE cNokogiriXmlAttr; +NOKOPUBVAR VALUE cNokogiriXmlAttributeDecl; +NOKOPUBVAR VALUE cNokogiriXmlCData; +NOKOPUBVAR VALUE cNokogiriXmlCharacterData; +NOKOPUBVAR VALUE cNokogiriXmlComment; +NOKOPUBVAR VALUE cNokogiriXmlDocument ; +NOKOPUBVAR VALUE cNokogiriXmlDocumentFragment; +NOKOPUBVAR VALUE cNokogiriXmlDtd; +NOKOPUBVAR VALUE cNokogiriXmlElement ; +NOKOPUBVAR VALUE cNokogiriXmlElementContent; +NOKOPUBVAR VALUE cNokogiriXmlElementDecl; +NOKOPUBVAR VALUE cNokogiriXmlEntityDecl; +NOKOPUBVAR VALUE cNokogiriXmlEntityReference; +NOKOPUBVAR VALUE cNokogiriXmlNamespace ; +NOKOPUBVAR VALUE cNokogiriXmlNode ; +NOKOPUBVAR VALUE cNokogiriXmlNodeSet ; +NOKOPUBVAR VALUE cNokogiriXmlProcessingInstruction; +NOKOPUBVAR VALUE cNokogiriXmlReader; +NOKOPUBVAR VALUE cNokogiriXmlRelaxNG; +NOKOPUBVAR VALUE cNokogiriXmlSaxParser ; +NOKOPUBVAR VALUE cNokogiriXmlSaxParserContext; +NOKOPUBVAR VALUE cNokogiriXmlSaxPushParser ; +NOKOPUBVAR VALUE cNokogiriXmlSchema; +NOKOPUBVAR VALUE cNokogiriXmlSyntaxError; +NOKOPUBVAR VALUE cNokogiriXmlText ; +NOKOPUBVAR VALUE cNokogiriXmlXpathContext; +NOKOPUBVAR VALUE cNokogiriXmlXpathSyntaxError; +NOKOPUBVAR VALUE cNokogiriXsltStylesheet ; + +NOKOPUBVAR VALUE cNokogiriHtml4Document ; +NOKOPUBVAR VALUE cNokogiriHtml4SaxPushParser ; +NOKOPUBVAR VALUE cNokogiriHtml4ElementDescription ; +NOKOPUBVAR VALUE cNokogiriHtml4SaxParser; +NOKOPUBVAR VALUE cNokogiriHtml4SaxParserContext; +NOKOPUBVAR VALUE cNokogiriHtml5Document ; + +typedef struct _nokogiriTuple { + VALUE doc; + st_table *unlinkedNodes; + VALUE node_cache; +} nokogiriTuple; +typedef nokogiriTuple *nokogiriTuplePtr; + +typedef struct _libxmlStructuredErrorHandlerState { + void *user_data; + xmlStructuredErrorFunc handler; +} libxmlStructuredErrorHandlerState ; + +typedef struct _nokogiriXsltStylesheetTuple { + xsltStylesheetPtr ss; + VALUE func_instances; +} nokogiriXsltStylesheetTuple; + +void noko_xml_document_pin_node(xmlNodePtr); +void noko_xml_document_pin_namespace(xmlNsPtr, xmlDocPtr); +int noko_xml_document_has_wrapped_blank_nodes_p(xmlDocPtr c_document); + +int noko_io_read(void *ctx, char *buffer, int len); +int noko_io_write(void *ctx, char *buffer, int len); +int noko_io_close(void *ctx); + +#define Noko_Node_Get_Struct(obj,type,sval) ((sval) = (type*)DATA_PTR(obj)) +#define Noko_Namespace_Get_Struct(obj,type,sval) ((sval) = (type*)DATA_PTR(obj)) + +VALUE noko_xml_node_wrap(VALUE klass, xmlNodePtr node) ; +VALUE noko_xml_node_wrap_node_set_result(xmlNodePtr node, VALUE node_set) ; +VALUE noko_xml_node_attrs(xmlNodePtr node) ; + +VALUE noko_xml_namespace_wrap(xmlNsPtr node, xmlDocPtr doc); +VALUE noko_xml_namespace_wrap_xpath_copy(xmlNsPtr node); + +VALUE noko_xml_element_content_wrap(VALUE doc, xmlElementContentPtr element); + +VALUE noko_xml_node_set_wrap(xmlNodeSetPtr node_set, VALUE document) ; +xmlNodeSetPtr noko_xml_node_set_unwrap(VALUE rb_node_set) ; + +VALUE noko_xml_document_wrap_with_init_args(VALUE klass, xmlDocPtr doc, int argc, VALUE *argv); +VALUE noko_xml_document_wrap(VALUE klass, xmlDocPtr doc); +xmlDocPtr noko_xml_document_unwrap(VALUE rb_document); +NOKOPUBFUN VALUE Nokogiri_wrap_xml_document(VALUE klass, + xmlDocPtr doc); /* deprecated. use noko_xml_document_wrap() instead. */ + +xmlSAXHandlerPtr noko_xml_sax_parser_unwrap(VALUE rb_sax_handler); + +xmlParserCtxtPtr noko_xml_sax_push_parser_unwrap(VALUE rb_parser); + +VALUE noko_xml_sax_parser_context_wrap(VALUE klass, xmlParserCtxtPtr c_context); +xmlParserCtxtPtr noko_xml_sax_parser_context_unwrap(VALUE rb_context); +void noko_xml_sax_parser_context_set_encoding(xmlParserCtxtPtr c_context, VALUE rb_encoding); + +#define DOC_RUBY_OBJECT_TEST(x) ((nokogiriTuplePtr)(x->_private)) +#define DOC_RUBY_OBJECT(x) (((nokogiriTuplePtr)(x->_private))->doc) +#define DOC_UNLINKED_NODE_HASH(x) (((nokogiriTuplePtr)(x->_private))->unlinkedNodes) +#define DOC_NODE_CACHE(x) (((nokogiriTuplePtr)(x->_private))->node_cache) +#define NOKOGIRI_NAMESPACE_EH(node) ((node)->type == XML_NAMESPACE_DECL) + +#define DISCARD_CONST_QUAL(t, v) ((t)(uintptr_t)(v)) +#define DISCARD_CONST_QUAL_XMLCHAR(v) DISCARD_CONST_QUAL(xmlChar *, v) + +#if HAVE_RB_CATEGORY_WARNING +# define NOKO_WARN_DEPRECATION(message...) rb_category_warning(RB_WARN_CATEGORY_DEPRECATED, message) +#else +# define NOKO_WARN_DEPRECATION(message...) rb_warning(message) +#endif + +void noko__structured_error_func_save(libxmlStructuredErrorHandlerState *handler_state); +void noko__structured_error_func_save_and_set(libxmlStructuredErrorHandlerState *handler_state, void *user_data, + xmlStructuredErrorFunc handler); +void noko__structured_error_func_restore(libxmlStructuredErrorHandlerState *handler_state); +VALUE noko_xml_syntax_error__wrap(xmlErrorConstPtr error); +void noko__error_array_pusher(void *ctx, xmlErrorConstPtr error); +NORETURN_DECL void noko__error_raise(void *ctx, xmlErrorConstPtr error); +void Nokogiri_marshal_xpath_funcall_and_return_values(xmlXPathParserContextPtr ctx, int nargs, VALUE handler, + const char *function_name) ; + +#endif /* NOKOGIRI_NATIVE */ diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/test_global_handlers.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/test_global_handlers.c new file mode 100644 index 0000000..cec0915 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/test_global_handlers.c @@ -0,0 +1,40 @@ +#include + +static VALUE foreign_error_handler_block = Qnil; + +static void +foreign_error_handler(void *user_data, xmlErrorConstPtr c_error) +{ + rb_funcall(foreign_error_handler_block, rb_intern("call"), 0); +} + +/* + * call-seq: + * __foreign_error_handler { ... } -> nil + * + * Override libxml2's global error handlers to call the block. This method thus has very little + * value except to test that Nokogiri is properly setting error handlers elsewhere in the code. See + * test/helper.rb for how this is being used. + */ +static VALUE +rb_foreign_error_handler(VALUE klass) +{ + rb_need_block(); + foreign_error_handler_block = rb_block_proc(); + xmlSetStructuredErrorFunc(NULL, foreign_error_handler); + return Qnil; +} + +/* + * Document-module: Nokogiri::Test + * + * The Nokogiri::Test module should only be used for testing Nokogiri. + * Do NOT use this outside of the Nokogiri test suite. + */ +void +noko_init_test_global_handlers(void) +{ + VALUE mNokogiriTest = rb_define_module_under(mNokogiri, "Test"); + + rb_define_singleton_method(mNokogiriTest, "__foreign_error_handler", rb_foreign_error_handler, 0); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_attr.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_attr.c new file mode 100644 index 0000000..90eea3c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_attr.c @@ -0,0 +1,103 @@ +#include + +VALUE cNokogiriXmlAttr; + +/* + * call-seq: + * value=(content) + * + * Set the value for this Attr to +content+. Use +nil+ to remove the value + * (e.g., a HTML boolean attribute). + */ +static VALUE +set_value(VALUE self, VALUE content) +{ + xmlAttrPtr attr; + xmlChar *value; + xmlNode *cur; + + Noko_Node_Get_Struct(self, xmlAttr, attr); + + if (attr->children) { + xmlFreeNodeList(attr->children); + } + attr->children = attr->last = NULL; + + if (content == Qnil) { + return content; + } + + value = xmlEncodeEntitiesReentrant(attr->doc, (unsigned char *)StringValueCStr(content)); + if (xmlStrlen(value) == 0) { + attr->children = xmlNewDocText(attr->doc, value); + } else { + attr->children = xmlStringGetNodeList(attr->doc, value); + } + xmlFree(value); + + for (cur = attr->children; cur; cur = cur->next) { + cur->parent = (xmlNode *)attr; + cur->doc = attr->doc; + if (cur->next == NULL) { + attr->last = cur; + } + } + + return content; +} + +/* + * call-seq: + * new(document, name) + * + * Create a new Attr element on the +document+ with +name+ + */ +static VALUE +new (int argc, VALUE *argv, VALUE klass) +{ + xmlDocPtr xml_doc; + VALUE document; + VALUE name; + VALUE rest; + xmlAttrPtr node; + VALUE rb_node; + + rb_scan_args(argc, argv, "2*", &document, &name, &rest); + + if (! rb_obj_is_kind_of(document, cNokogiriXmlDocument)) { + rb_raise(rb_eArgError, "parameter must be a Nokogiri::XML::Document"); + } + + xml_doc = noko_xml_document_unwrap(document); + + node = xmlNewDocProp( + xml_doc, + (const xmlChar *)StringValueCStr(name), + NULL + ); + + noko_xml_document_pin_node((xmlNodePtr)node); + + rb_node = noko_xml_node_wrap(klass, (xmlNodePtr)node); + rb_obj_call_init(rb_node, argc, argv); + + if (rb_block_given_p()) { + rb_yield(rb_node); + } + + return rb_node; +} + +void +noko_init_xml_attr(void) +{ + assert(cNokogiriXmlNode); + /* + * Attr represents a Attr node in an xml document. + */ + cNokogiriXmlAttr = rb_define_class_under(mNokogiriXml, "Attr", cNokogiriXmlNode); + + rb_define_singleton_method(cNokogiriXmlAttr, "new", new, -1); + + rb_define_method(cNokogiriXmlAttr, "value=", set_value, 1); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_attribute_decl.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_attribute_decl.c new file mode 100644 index 0000000..3f9bebc --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_attribute_decl.c @@ -0,0 +1,70 @@ +#include + +VALUE cNokogiriXmlAttributeDecl; + +/* + * call-seq: + * attribute_type + * + * The attribute_type for this AttributeDecl + */ +static VALUE +attribute_type(VALUE self) +{ + xmlAttributePtr node; + Noko_Node_Get_Struct(self, xmlAttribute, node); + return INT2NUM(node->atype); +} + +/* + * call-seq: + * default + * + * The default value + */ +static VALUE +default_value(VALUE self) +{ + xmlAttributePtr node; + Noko_Node_Get_Struct(self, xmlAttribute, node); + + if (node->defaultValue) { return NOKOGIRI_STR_NEW2(node->defaultValue); } + return Qnil; +} + +/* + * call-seq: + * enumeration + * + * An enumeration of possible values + */ +static VALUE +enumeration(VALUE self) +{ + xmlAttributePtr node; + xmlEnumerationPtr enm; + VALUE list; + + Noko_Node_Get_Struct(self, xmlAttribute, node); + + list = rb_ary_new(); + enm = node->tree; + + while (enm) { + rb_ary_push(list, NOKOGIRI_STR_NEW2(enm->name)); + enm = enm->next; + } + + return list; +} + +void +noko_init_xml_attribute_decl(void) +{ + assert(cNokogiriXmlNode); + cNokogiriXmlAttributeDecl = rb_define_class_under(mNokogiriXml, "AttributeDecl", cNokogiriXmlNode); + + rb_define_method(cNokogiriXmlAttributeDecl, "attribute_type", attribute_type, 0); + rb_define_method(cNokogiriXmlAttributeDecl, "default", default_value, 0); + rb_define_method(cNokogiriXmlAttributeDecl, "enumeration", enumeration, 0); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_cdata.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_cdata.c new file mode 100644 index 0000000..4431d20 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_cdata.c @@ -0,0 +1,62 @@ +#include + +VALUE cNokogiriXmlCData; + +/* + * call-seq: + * new(document, content) + * + * Create a new CDATA element on the +document+ with +content+ + * + * If +content+ cannot be implicitly converted to a string, this method will + * raise a TypeError exception. + */ +static VALUE +rb_xml_cdata_s_new(int argc, VALUE *argv, VALUE klass) +{ + xmlDocPtr c_document; + xmlNodePtr c_node; + VALUE rb_document; + VALUE rb_content; + VALUE rb_rest; + VALUE rb_node; + + rb_scan_args(argc, argv, "2*", &rb_document, &rb_content, &rb_rest); + + Check_Type(rb_content, T_STRING); + if (!rb_obj_is_kind_of(rb_document, cNokogiriXmlNode)) { + rb_raise(rb_eTypeError, + "expected first parameter to be a Nokogiri::XML::Document, received %"PRIsVALUE, + rb_obj_class(rb_document)); + } + + if (!rb_obj_is_kind_of(rb_document, cNokogiriXmlDocument)) { + xmlNodePtr deprecated_node_type_arg; + NOKO_WARN_DEPRECATION("Passing a Node as the first parameter to CDATA.new is deprecated. Please pass a Document instead. This will become an error in Nokogiri v1.17.0."); // TODO: deprecated in v1.15.3, remove in v1.17.0 + Noko_Node_Get_Struct(rb_document, xmlNode, deprecated_node_type_arg); + c_document = deprecated_node_type_arg->doc; + } else { + c_document = noko_xml_document_unwrap(rb_document); + } + + c_node = xmlNewCDataBlock(c_document, (xmlChar *)StringValueCStr(rb_content), RSTRING_LENINT(rb_content)); + noko_xml_document_pin_node(c_node); + rb_node = noko_xml_node_wrap(klass, c_node); + rb_obj_call_init(rb_node, argc, argv); + + if (rb_block_given_p()) { rb_yield(rb_node); } + + return rb_node; +} + +void +noko_init_xml_cdata(void) +{ + assert(cNokogiriXmlText); + /* + * CData represents a CData node in an xml document. + */ + cNokogiriXmlCData = rb_define_class_under(mNokogiriXml, "CDATA", cNokogiriXmlText); + + rb_define_singleton_method(cNokogiriXmlCData, "new", rb_xml_cdata_s_new, -1); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_comment.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_comment.c new file mode 100644 index 0000000..211761c --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_comment.c @@ -0,0 +1,57 @@ +#include + +VALUE cNokogiriXmlComment; + +static ID document_id ; + +/* + * call-seq: + * new(document_or_node, content) + * + * Create a new Comment element on the +document+ with +content+. + * Alternatively, if a +node+ is passed, the +node+'s document is used. + */ +static VALUE +new (int argc, VALUE *argv, VALUE klass) +{ + xmlDocPtr xml_doc; + xmlNodePtr node; + VALUE document; + VALUE content; + VALUE rest; + VALUE rb_node; + + rb_scan_args(argc, argv, "2*", &document, &content, &rest); + + Check_Type(content, T_STRING); + if (rb_obj_is_kind_of(document, cNokogiriXmlNode)) { + document = rb_funcall(document, document_id, 0); + } else if (!rb_obj_is_kind_of(document, cNokogiriXmlDocument) + && !rb_obj_is_kind_of(document, cNokogiriXmlDocumentFragment)) { + rb_raise(rb_eArgError, "first argument must be a XML::Document or XML::Node"); + } + xml_doc = noko_xml_document_unwrap(document); + + node = xmlNewDocComment(xml_doc, (const xmlChar *)StringValueCStr(content)); + noko_xml_document_pin_node(node); + rb_node = noko_xml_node_wrap(klass, node); + rb_obj_call_init(rb_node, argc, argv); + + if (rb_block_given_p()) { rb_yield(rb_node); } + + return rb_node; +} + +void +noko_init_xml_comment(void) +{ + assert(cNokogiriXmlCharacterData); + /* + * Comment represents a comment node in an xml document. + */ + cNokogiriXmlComment = rb_define_class_under(mNokogiriXml, "Comment", cNokogiriXmlCharacterData); + + rb_define_singleton_method(cNokogiriXmlComment, "new", new, -1); + + document_id = rb_intern("document"); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_document.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_document.c new file mode 100644 index 0000000..7408193 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_document.c @@ -0,0 +1,784 @@ +#include + +VALUE cNokogiriXmlDocument ; + +static int +dealloc_node_i2(xmlNodePtr key, xmlNodePtr node, xmlDocPtr doc) +{ + switch (node->type) { + case XML_ATTRIBUTE_NODE: + xmlFreePropList((xmlAttrPtr)node); + break; + case XML_NAMESPACE_DECL: + xmlFreeNs((xmlNsPtr)node); + break; + case XML_DTD_NODE: + xmlFreeDtd((xmlDtdPtr)node); + break; + default: + if (node->parent == NULL) { + node->next = NULL; + node->prev = NULL; + xmlAddChild((xmlNodePtr)doc, node); + } + } + return ST_CONTINUE; +} + +static int +dealloc_node_i(st_data_t key, st_data_t node, st_data_t doc) +{ + return dealloc_node_i2((xmlNodePtr)key, (xmlNodePtr)node, (xmlDocPtr)doc); +} + +static void +remove_private(xmlNodePtr node) +{ + xmlNodePtr child; + + for (child = node->children; child; child = child->next) { + remove_private(child); + } + + if ((node->type == XML_ELEMENT_NODE || + node->type == XML_XINCLUDE_START || + node->type == XML_XINCLUDE_END) && + node->properties) { + for (child = (xmlNodePtr)node->properties; child; child = child->next) { + remove_private(child); + } + } + + node->_private = NULL; +} + +static void +mark(void *data) +{ + xmlDocPtr doc = (xmlDocPtr)data; + nokogiriTuplePtr tuple = (nokogiriTuplePtr)doc->_private; + if (tuple) { + rb_gc_mark(tuple->doc); + rb_gc_mark(tuple->node_cache); + } +} + +static void +dealloc(void *data) +{ + xmlDocPtr doc = (xmlDocPtr)data; + st_table *node_hash; + + node_hash = DOC_UNLINKED_NODE_HASH(doc); + + st_foreach(node_hash, dealloc_node_i, (st_data_t)doc); + st_free_table(node_hash); + + ruby_xfree(doc->_private); + +#if defined(__GNUC__) && __GNUC__ >= 5 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // xmlDeregisterNodeDefault is deprecated as of libxml2 2.11.0 +#endif + /* + * libxml-ruby < 3.0.0 uses xmlDeregisterNodeDefault. If the user is using one of those older + * versions, the registered callback from libxml-ruby will access the _private pointers set by + * nokogiri, which will result in segfaults. + * + * To avoid this, we need to clear the _private pointers from all nodes in this document tree + * before that callback gets invoked. + * + * libxml-ruby 3.0.0 was released in 2017-02, so at some point we can probably safely remove this + * safeguard (though probably pairing with a runtime check on the libxml-ruby version). + */ + if (xmlDeregisterNodeDefaultValue) { + remove_private((xmlNodePtr)doc); + } +#if defined(__GNUC__) && __GNUC__ >= 5 +#pragma GCC diagnostic pop +#endif + + xmlFreeDoc(doc); +} + +static size_t +memsize_node(const xmlNodePtr node) +{ + /* note we don't count namespace definitions, just going for a good-enough number here */ + xmlNodePtr child; + xmlAttrPtr property; + size_t memsize = 0; + + memsize += (size_t)xmlStrlen(node->name); + + if (node->type == XML_ELEMENT_NODE) { + for (property = node->properties; property; property = property->next) { + memsize += sizeof(xmlAttr) + memsize_node((xmlNodePtr)property); + } + } + if (node->type == XML_TEXT_NODE) { + memsize += (size_t)xmlStrlen(node->content); + } + for (child = node->children; child; child = child->next) { + memsize += sizeof(xmlNode) + memsize_node(child); + } + return memsize; +} + +static size_t +memsize(const void *data) +{ + xmlDocPtr doc = (const xmlDocPtr)data; + size_t memsize = sizeof(xmlDoc); + /* This may not account for all memory use */ + memsize += memsize_node((xmlNodePtr)doc); + return memsize; +} + +static const rb_data_type_t xml_doc_type = { + .wrap_struct_name = "xmlDoc", + .function = { + .dmark = mark, + .dfree = dealloc, + .dsize = memsize, + }, + // .flags = RUBY_TYPED_FREE_IMMEDIATELY, // TODO see https://github.com/sparklemotion/nokogiri/issues/2822 +}; + +static VALUE +_xml_document_alloc(VALUE klass) +{ + return TypedData_Wrap_Struct(klass, &xml_doc_type, NULL); +} + +static void +_xml_document_data_ptr_set(VALUE rb_document, xmlDocPtr c_document) +{ + nokogiriTuplePtr tuple; + + assert(DATA_PTR(rb_document) == NULL); + assert(c_document->_private == NULL); + + DATA_PTR(rb_document) = c_document; + + tuple = (nokogiriTuplePtr)ruby_xmalloc(sizeof(nokogiriTuple)); + tuple->doc = rb_document; + tuple->unlinkedNodes = st_init_numtable_with_size(128); + tuple->node_cache = rb_ary_new(); + + c_document->_private = tuple ; + + rb_iv_set(rb_document, "@node_cache", tuple->node_cache); + + return; +} + +/* :nodoc: */ +static VALUE +rb_xml_document_initialize_copy_with_args(VALUE rb_self, VALUE rb_other, VALUE rb_level) +{ + xmlDocPtr c_other, c_self; + int c_level; + + c_other = noko_xml_document_unwrap(rb_other); + c_level = (int)NUM2INT(rb_level); + + c_self = xmlCopyDoc(c_other, c_level); + if (c_self == NULL) { return Qnil; } + + c_self->type = c_other->type; + _xml_document_data_ptr_set(rb_self, c_self); + + return rb_self ; +} + +static void +recursively_remove_namespaces_from_node(xmlNodePtr node) +{ + xmlNodePtr child ; + xmlAttrPtr property ; + + xmlSetNs(node, NULL); + + for (child = node->children ; child ; child = child->next) { + recursively_remove_namespaces_from_node(child); + } + + if (((node->type == XML_ELEMENT_NODE) || + (node->type == XML_XINCLUDE_START) || + (node->type == XML_XINCLUDE_END)) && + node->nsDef) { + xmlNsPtr curr = node->nsDef; + while (curr) { + noko_xml_document_pin_namespace(curr, node->doc); + curr = curr->next; + } + node->nsDef = NULL; + } + + if (node->type == XML_ELEMENT_NODE && node->properties != NULL) { + property = node->properties ; + while (property != NULL) { + if (property->ns) { property->ns = NULL ; } + property = property->next ; + } + } +} + +/* + * call-seq: + * url + * + * Get the url name for this document. + */ +static VALUE +url(VALUE self) +{ + xmlDocPtr doc = noko_xml_document_unwrap(self); + + if (doc->URL) { return NOKOGIRI_STR_NEW2(doc->URL); } + + return Qnil; +} + +/* + * call-seq: + * root= + * + * Set the root element on this document + */ +static VALUE +rb_xml_document_root_set(VALUE self, VALUE rb_new_root) +{ + xmlDocPtr c_document; + xmlNodePtr c_new_root = NULL, c_current_root; + + c_document = noko_xml_document_unwrap(self); + + c_current_root = xmlDocGetRootElement(c_document); + if (c_current_root) { + xmlUnlinkNode(c_current_root); + noko_xml_document_pin_node(c_current_root); + } + + if (!NIL_P(rb_new_root)) { + if (!rb_obj_is_kind_of(rb_new_root, cNokogiriXmlNode)) { + rb_raise(rb_eArgError, + "expected Nokogiri::XML::Node but received %"PRIsVALUE, + rb_obj_class(rb_new_root)); + } + + Noko_Node_Get_Struct(rb_new_root, xmlNode, c_new_root); + + /* If the new root's document is not the same as the current document, + * then we need to dup the node in to this document. */ + if (c_new_root->doc != c_document) { + c_new_root = xmlDocCopyNode(c_new_root, c_document, 1); + if (!c_new_root) { + rb_raise(rb_eRuntimeError, "Could not reparent node (xmlDocCopyNode)"); + } + } + } + + xmlDocSetRootElement(c_document, c_new_root); + + return rb_new_root; +} + +/* + * call-seq: + * root + * + * Get the root node for this document. + */ +static VALUE +rb_xml_document_root(VALUE self) +{ + xmlDocPtr c_document; + xmlNodePtr c_root; + + c_document = noko_xml_document_unwrap(self); + + c_root = xmlDocGetRootElement(c_document); + if (!c_root) { + return Qnil; + } + + return noko_xml_node_wrap(Qnil, c_root) ; +} + +/* + * call-seq: + * encoding= encoding + * + * Set the encoding string for this Document + */ +static VALUE +set_encoding(VALUE self, VALUE encoding) +{ + xmlDocPtr doc = noko_xml_document_unwrap(self); + + if (doc->encoding) { + xmlFree(DISCARD_CONST_QUAL_XMLCHAR(doc->encoding)); + } + + doc->encoding = xmlStrdup((xmlChar *)StringValueCStr(encoding)); + + return encoding; +} + +/* + * call-seq: + * encoding + * + * Get the encoding for this Document + */ +static VALUE +encoding(VALUE self) +{ + xmlDocPtr doc = noko_xml_document_unwrap(self); + + if (!doc->encoding) { return Qnil; } + return NOKOGIRI_STR_NEW2(doc->encoding); +} + +/* + * call-seq: + * version + * + * Get the XML version for this Document + */ +static VALUE +version(VALUE self) +{ + xmlDocPtr doc = noko_xml_document_unwrap(self); + + if (!doc->version) { return Qnil; } + return NOKOGIRI_STR_NEW2(doc->version); +} + +/* + * call-seq: + * read_io(io, url, encoding, options) + * + * Create a new document from an IO object + */ +static VALUE +noko_xml_document_s_read_io(VALUE rb_class, + VALUE rb_io, + VALUE rb_url, + VALUE rb_encoding, + VALUE rb_options) +{ + /* TODO: deprecate this method, parse should be the preferred entry point. then we can make this + private. */ + libxmlStructuredErrorHandlerState handler_state; + VALUE rb_errors = rb_ary_new(); + + noko__structured_error_func_save_and_set(&handler_state, (void *)rb_errors, noko__error_array_pusher); + + const char *c_url = NIL_P(rb_url) ? NULL : StringValueCStr(rb_url); + const char *c_enc = NIL_P(rb_encoding) ? NULL : StringValueCStr(rb_encoding); + xmlDocPtr c_document = xmlReadIO( + (xmlInputReadCallback)noko_io_read, + (xmlInputCloseCallback)noko_io_close, + (void *)rb_io, + c_url, + c_enc, + (int)NUM2INT(rb_options) + ); + + noko__structured_error_func_restore(&handler_state); + + if (c_document == NULL) { + xmlFreeDoc(c_document); + + VALUE exception = rb_funcall(cNokogiriXmlSyntaxError, rb_intern("aggregate"), 1, rb_errors); + if (RB_TEST(exception)) { + rb_exc_raise(exception); + } else { + rb_raise(rb_eRuntimeError, "Could not parse document"); + } + } + + VALUE rb_document = noko_xml_document_wrap(rb_class, c_document); + rb_iv_set(rb_document, "@errors", rb_errors); + return rb_document; +} + +/* + * call-seq: + * read_memory(string, url, encoding, options) + * + * Create a new document from a String + */ +static VALUE +noko_xml_document_s_read_memory(VALUE rb_class, + VALUE rb_input, + VALUE rb_url, + VALUE rb_encoding, + VALUE rb_options) +{ + /* TODO: deprecate this method, parse should be the preferred entry point. then we can make this + private. */ + VALUE rb_errors = rb_ary_new(); + xmlSetStructuredErrorFunc((void *)rb_errors, noko__error_array_pusher); + + const char *c_buffer = StringValuePtr(rb_input); + const char *c_url = NIL_P(rb_url) ? NULL : StringValueCStr(rb_url); + const char *c_enc = NIL_P(rb_encoding) ? NULL : StringValueCStr(rb_encoding); + int c_buffer_len = (int)RSTRING_LEN(rb_input); + xmlDocPtr c_document = xmlReadMemory(c_buffer, c_buffer_len, c_url, c_enc, (int)NUM2INT(rb_options)); + + xmlSetStructuredErrorFunc(NULL, NULL); + + if (c_document == NULL) { + VALUE exception = rb_funcall(cNokogiriXmlSyntaxError, rb_intern("aggregate"), 1, rb_errors); + if (RB_TEST(exception)) { + rb_exc_raise(exception); + } else { + rb_raise(rb_eRuntimeError, "Could not parse document"); + } + } + + VALUE document = noko_xml_document_wrap(rb_class, c_document); + rb_iv_set(document, "@errors", rb_errors); + return document; +} + +/* + * call-seq: + * new(version = "1.0") + * + * Create a new empty document declaring XML version +version+. + */ +static VALUE +new (int argc, VALUE *argv, VALUE klass) +{ + xmlDocPtr doc; + VALUE version, rest, rb_doc ; + + rb_scan_args(argc, argv, "0*", &rest); + version = rb_ary_entry(rest, (long)0); + if (NIL_P(version)) { version = rb_str_new2("1.0"); } + + doc = xmlNewDoc((xmlChar *)StringValueCStr(version)); + rb_doc = noko_xml_document_wrap_with_init_args(klass, doc, argc, argv); + return rb_doc ; +} + +/* + * call-seq: + * remove_namespaces! + * + * Remove all namespaces from all nodes in the document. + * + * This could be useful for developers who either don't understand namespaces + * or don't care about them. + * + * The following example shows a use case, and you can decide for yourself + * whether this is a good thing or not: + * + * doc = Nokogiri::XML <<-EOXML + * + * + * Michelin Model XGV + * + * + * I'm a bicycle tire! + * + * + * EOXML + * + * doc.xpath("//tire").to_s # => "" + * doc.xpath("//part:tire", "part" => "http://general-motors.com/").to_s # => "Michelin Model XGV" + * doc.xpath("//part:tire", "part" => "http://schwinn.com/").to_s # => "I'm a bicycle tire!" + * + * doc.remove_namespaces! + * + * doc.xpath("//tire").to_s # => "Michelin Model XGVI'm a bicycle tire!" + * doc.xpath("//part:tire", "part" => "http://general-motors.com/").to_s # => "" + * doc.xpath("//part:tire", "part" => "http://schwinn.com/").to_s # => "" + * + * For more information on why this probably is *not* a good thing in general, + * please direct your browser to + * http://tenderlovemaking.com/2009/04/23/namespaces-in-xml.html + */ +static VALUE +remove_namespaces_bang(VALUE self) +{ + xmlDocPtr doc = noko_xml_document_unwrap(self); + + recursively_remove_namespaces_from_node((xmlNodePtr)doc); + return self; +} + +/* call-seq: + * doc.create_entity(name, type, external_id, system_id, content) + * + * Create a new entity named +name+. + * + * +type+ is an integer representing the type of entity to be created, and it defaults to + * +Nokogiri::XML::EntityDecl::INTERNAL_GENERAL+. See the constants on Nokogiri::XML::EntityDecl for + * more information. + * + * +external_id+, +system_id+, and +content+ set the External ID, System ID, + * and content respectively. All of these parameters are optional. + */ +static VALUE +noko_xml_document__create_entity(int argc, VALUE *argv, VALUE rb_document) +{ + VALUE rb_name; + VALUE rb_type; + VALUE rb_ext_id; + VALUE rb_sys_id; + VALUE rb_content; + + rb_scan_args(argc, argv, "14", + &rb_name, + &rb_type, &rb_ext_id, &rb_sys_id, &rb_content); + + xmlDocPtr c_document = noko_xml_document_unwrap(rb_document); + + libxmlStructuredErrorHandlerState handler_state; + VALUE rb_errors = rb_ary_new(); + noko__structured_error_func_save_and_set(&handler_state, (void *)rb_errors, noko__error_array_pusher); + + xmlEntityPtr c_entity = xmlAddDocEntity( + c_document, + (xmlChar *)(NIL_P(rb_name) ? NULL : StringValueCStr(rb_name)), + (int)(NIL_P(rb_type) ? XML_INTERNAL_GENERAL_ENTITY : NUM2INT(rb_type)), + (xmlChar *)(NIL_P(rb_ext_id) ? NULL : StringValueCStr(rb_ext_id)), + (xmlChar *)(NIL_P(rb_sys_id) ? NULL : StringValueCStr(rb_sys_id)), + (xmlChar *)(NIL_P(rb_content) ? NULL : StringValueCStr(rb_content)) + ); + + noko__structured_error_func_restore(&handler_state); + + if (NULL == c_entity) { + VALUE exception = rb_funcall(cNokogiriXmlSyntaxError, rb_intern("aggregate"), 1, rb_errors); + if (RB_TEST(exception)) { + rb_exc_raise(exception); + } else { + rb_raise(rb_eRuntimeError, "Could not create entity"); + } + } + + return noko_xml_node_wrap(cNokogiriXmlEntityDecl, (xmlNodePtr)c_entity); +} + +static int +block_caller(void *ctx, xmlNodePtr c_node, xmlNodePtr c_parent_node) +{ + VALUE block = (VALUE)ctx; + VALUE rb_node; + VALUE rb_parent_node; + VALUE ret; + + if (c_node->type == XML_NAMESPACE_DECL) { + rb_node = noko_xml_namespace_wrap((xmlNsPtr)c_node, c_parent_node->doc); + } else { + rb_node = noko_xml_node_wrap(Qnil, c_node); + } + rb_parent_node = c_parent_node ? noko_xml_node_wrap(Qnil, c_parent_node) : Qnil; + + ret = rb_funcall(block, rb_intern("call"), 2, rb_node, rb_parent_node); + + return (Qfalse == ret || Qnil == ret) ? 0 : 1; +} + +/* call-seq: + * doc.canonicalize(mode=XML_C14N_1_0,inclusive_namespaces=nil,with_comments=false) + * doc.canonicalize { |obj, parent| ... } + * + * Canonicalize a document and return the results. Takes an optional block + * that takes two parameters: the +obj+ and that node's +parent+. + * The +obj+ will be either a Nokogiri::XML::Node, or a Nokogiri::XML::Namespace + * The block must return a non-nil, non-false value if the +obj+ passed in + * should be included in the canonicalized document. + */ +static VALUE +rb_xml_document_canonicalize(int argc, VALUE *argv, VALUE self) +{ + VALUE rb_mode; + VALUE rb_namespaces; + VALUE rb_comments_p; + int c_mode = 0; + xmlChar **c_namespaces; + + xmlDocPtr c_doc; + xmlOutputBufferPtr c_obuf; + xmlC14NIsVisibleCallback c_callback_wrapper = NULL; + void *rb_callback = NULL; + + VALUE rb_cStringIO; + VALUE rb_io; + + rb_scan_args(argc, argv, "03", &rb_mode, &rb_namespaces, &rb_comments_p); + if (!NIL_P(rb_mode)) { + Check_Type(rb_mode, T_FIXNUM); + c_mode = NUM2INT(rb_mode); + } + if (!NIL_P(rb_namespaces)) { + Check_Type(rb_namespaces, T_ARRAY); + if (c_mode == XML_C14N_1_0 || c_mode == XML_C14N_1_1) { + rb_raise(rb_eRuntimeError, "This canonicalizer does not support this operation"); + } + } + + c_doc = noko_xml_document_unwrap(self); + + rb_cStringIO = rb_const_get_at(rb_cObject, rb_intern("StringIO")); + rb_io = rb_class_new_instance(0, 0, rb_cStringIO); + c_obuf = xmlAllocOutputBuffer(NULL); + + c_obuf->writecallback = (xmlOutputWriteCallback)noko_io_write; + c_obuf->closecallback = (xmlOutputCloseCallback)noko_io_close; + c_obuf->context = (void *)rb_io; + + if (rb_block_given_p()) { + c_callback_wrapper = block_caller; + rb_callback = (void *)rb_block_proc(); + } + + if (NIL_P(rb_namespaces)) { + c_namespaces = NULL; + } else { + long ns_len = RARRAY_LEN(rb_namespaces); + c_namespaces = ruby_xcalloc((size_t)ns_len + 1, sizeof(xmlChar *)); + for (int j = 0 ; j < ns_len ; j++) { + VALUE entry = rb_ary_entry(rb_namespaces, j); + c_namespaces[j] = (xmlChar *)StringValueCStr(entry); + } + } + + xmlC14NExecute(c_doc, c_callback_wrapper, rb_callback, + c_mode, + c_namespaces, + (int)RTEST(rb_comments_p), + c_obuf); + + ruby_xfree(c_namespaces); + xmlOutputBufferClose(c_obuf); + + return rb_funcall(rb_io, rb_intern("string"), 0); +} + +VALUE +noko_xml_document_wrap_with_init_args(VALUE klass, xmlDocPtr c_document, int argc, VALUE *argv) +{ + VALUE rb_document; + + if (!klass) { + klass = cNokogiriXmlDocument; + } + + rb_document = _xml_document_alloc(klass); + _xml_document_data_ptr_set(rb_document, c_document); + + rb_iv_set(rb_document, "@decorators", Qnil); + rb_iv_set(rb_document, "@errors", Qnil); + + rb_obj_call_init(rb_document, argc, argv); + + return rb_document ; +} + + +/* deprecated. use noko_xml_document_wrap() instead. */ +VALUE +Nokogiri_wrap_xml_document(VALUE klass, xmlDocPtr doc) +{ + /* TODO: deprecate this method in v2.0 */ + return noko_xml_document_wrap_with_init_args(klass, doc, 0, NULL); +} + +VALUE +noko_xml_document_wrap(VALUE klass, xmlDocPtr doc) +{ + return noko_xml_document_wrap_with_init_args(klass, doc, 0, NULL); +} + +xmlDocPtr +noko_xml_document_unwrap(VALUE rb_document) +{ + xmlDocPtr c_document; + TypedData_Get_Struct(rb_document, xmlDoc, &xml_doc_type, c_document); + return c_document; +} + +/* Schema creation will remove and deallocate "blank" nodes. + * If those blank nodes have been exposed to Ruby, they could get freed + * out from under the VALUE pointer. This function checks to see if any of + * those nodes have been exposed to Ruby, and if so we should raise an exception. + */ +int +noko_xml_document_has_wrapped_blank_nodes_p(xmlDocPtr c_document) +{ + VALUE cache = DOC_NODE_CACHE(c_document); + + if (NIL_P(cache)) { + return 0; + } + + for (long jnode = 0; jnode < RARRAY_LEN(cache); jnode++) { + xmlNodePtr node; + VALUE element = rb_ary_entry(cache, jnode); + + Noko_Node_Get_Struct(element, xmlNode, node); + if (xmlIsBlankNode(node)) { + return 1; + } + } + + return 0; +} + +void +noko_xml_document_pin_node(xmlNodePtr node) +{ + xmlDocPtr doc; + nokogiriTuplePtr tuple; + + doc = node->doc; + tuple = (nokogiriTuplePtr)doc->_private; + st_insert(tuple->unlinkedNodes, (st_data_t)node, (st_data_t)node); +} + + +void +noko_xml_document_pin_namespace(xmlNsPtr ns, xmlDocPtr doc) +{ + nokogiriTuplePtr tuple; + + tuple = (nokogiriTuplePtr)doc->_private; + st_insert(tuple->unlinkedNodes, (st_data_t)ns, (st_data_t)ns); +} + + +void +noko_init_xml_document(void) +{ + assert(cNokogiriXmlNode); + + cNokogiriXmlDocument = rb_define_class_under(mNokogiriXml, "Document", cNokogiriXmlNode); + + rb_define_alloc_func(cNokogiriXmlDocument, _xml_document_alloc); + + rb_define_singleton_method(cNokogiriXmlDocument, "read_memory", noko_xml_document_s_read_memory, 4); + rb_define_singleton_method(cNokogiriXmlDocument, "read_io", noko_xml_document_s_read_io, 4); + rb_define_singleton_method(cNokogiriXmlDocument, "new", new, -1); + + rb_define_method(cNokogiriXmlDocument, "root", rb_xml_document_root, 0); + rb_define_method(cNokogiriXmlDocument, "root=", rb_xml_document_root_set, 1); + rb_define_method(cNokogiriXmlDocument, "encoding", encoding, 0); + rb_define_method(cNokogiriXmlDocument, "encoding=", set_encoding, 1); + rb_define_method(cNokogiriXmlDocument, "version", version, 0); + rb_define_method(cNokogiriXmlDocument, "canonicalize", rb_xml_document_canonicalize, -1); + rb_define_method(cNokogiriXmlDocument, "url", url, 0); + rb_define_method(cNokogiriXmlDocument, "create_entity", noko_xml_document__create_entity, -1); + rb_define_method(cNokogiriXmlDocument, "remove_namespaces!", remove_namespaces_bang, 0); + + rb_define_protected_method(cNokogiriXmlDocument, "initialize_copy_with_args", rb_xml_document_initialize_copy_with_args, + 2); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_document_fragment.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_document_fragment.c new file mode 100644 index 0000000..3f28d28 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_document_fragment.c @@ -0,0 +1,29 @@ +#include + +VALUE cNokogiriXmlDocumentFragment; + +/* :nodoc: */ +static VALUE +noko_xml_document_fragment_s_native_new(VALUE klass, VALUE rb_doc) +{ + xmlDocPtr c_doc; + xmlNodePtr c_node; + VALUE rb_node; + + c_doc = noko_xml_document_unwrap(rb_doc); + c_node = xmlNewDocFragment(c_doc->doc); + noko_xml_document_pin_node(c_node); + rb_node = noko_xml_node_wrap(klass, c_node); + + return rb_node; +} + +void +noko_init_xml_document_fragment(void) +{ + assert(cNokogiriXmlNode); + + cNokogiriXmlDocumentFragment = rb_define_class_under(mNokogiriXml, "DocumentFragment", cNokogiriXmlNode); + + rb_define_singleton_method(cNokogiriXmlDocumentFragment, "native_new", noko_xml_document_fragment_s_native_new, 1); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_dtd.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_dtd.c new file mode 100644 index 0000000..d361020 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_dtd.c @@ -0,0 +1,208 @@ +#include + +VALUE cNokogiriXmlDtd; + +static void +notation_copier(void *c_notation_ptr, void *rb_hash_ptr, const xmlChar *name) +{ + VALUE rb_hash = (VALUE)rb_hash_ptr; + xmlNotationPtr c_notation = (xmlNotationPtr)c_notation_ptr; + VALUE rb_notation; + VALUE cNokogiriXmlNotation; + VALUE rb_constructor_args[3]; + + rb_constructor_args[0] = (c_notation->name ? NOKOGIRI_STR_NEW2(c_notation->name) : Qnil); + rb_constructor_args[1] = (c_notation->PublicID ? NOKOGIRI_STR_NEW2(c_notation->PublicID) : Qnil); + rb_constructor_args[2] = (c_notation->SystemID ? NOKOGIRI_STR_NEW2(c_notation->SystemID) : Qnil); + + cNokogiriXmlNotation = rb_const_get_at(mNokogiriXml, rb_intern("Notation")); + rb_notation = rb_class_new_instance(3, rb_constructor_args, cNokogiriXmlNotation); + + rb_hash_aset(rb_hash, NOKOGIRI_STR_NEW2(name), rb_notation); +} + +static void +element_copier(void *c_node_ptr, void *rb_hash_ptr, const xmlChar *c_name) +{ + VALUE rb_hash = (VALUE)rb_hash_ptr; + xmlNodePtr c_node = (xmlNodePtr)c_node_ptr; + + VALUE rb_node = noko_xml_node_wrap(Qnil, c_node); + + rb_hash_aset(rb_hash, NOKOGIRI_STR_NEW2(c_name), rb_node); +} + +/* + * call-seq: + * entities + * + * Get a hash of the elements for this DTD. + */ +static VALUE +entities(VALUE self) +{ + xmlDtdPtr dtd; + VALUE hash; + + Noko_Node_Get_Struct(self, xmlDtd, dtd); + + if (!dtd->entities) { return Qnil; } + + hash = rb_hash_new(); + + xmlHashScan((xmlHashTablePtr)dtd->entities, element_copier, (void *)hash); + + return hash; +} + +/* + * call-seq: + * notations() → Hash + * + * [Returns] All the notations for this DTD in a Hash of Notation +name+ to Notation. + */ +static VALUE +notations(VALUE self) +{ + xmlDtdPtr dtd; + VALUE hash; + + Noko_Node_Get_Struct(self, xmlDtd, dtd); + + if (!dtd->notations) { return Qnil; } + + hash = rb_hash_new(); + + xmlHashScan((xmlHashTablePtr)dtd->notations, notation_copier, (void *)hash); + + return hash; +} + +/* + * call-seq: + * attributes + * + * Get a hash of the attributes for this DTD. + */ +static VALUE +attributes(VALUE self) +{ + xmlDtdPtr dtd; + VALUE hash; + + Noko_Node_Get_Struct(self, xmlDtd, dtd); + + hash = rb_hash_new(); + + if (!dtd->attributes) { return hash; } + + xmlHashScan((xmlHashTablePtr)dtd->attributes, element_copier, (void *)hash); + + return hash; +} + +/* + * call-seq: + * elements + * + * Get a hash of the elements for this DTD. + */ +static VALUE +elements(VALUE self) +{ + xmlDtdPtr dtd; + VALUE hash; + + Noko_Node_Get_Struct(self, xmlDtd, dtd); + + if (!dtd->elements) { return Qnil; } + + hash = rb_hash_new(); + + xmlHashScan((xmlHashTablePtr)dtd->elements, element_copier, (void *)hash); + + return hash; +} + +/* + * call-seq: + * validate(document) + * + * Validate +document+ returning a list of errors + */ +static VALUE +validate(VALUE self, VALUE document) +{ + xmlDocPtr doc; + xmlDtdPtr dtd; + xmlValidCtxtPtr ctxt; + VALUE error_list; + + Noko_Node_Get_Struct(self, xmlDtd, dtd); + doc = noko_xml_document_unwrap(document); + error_list = rb_ary_new(); + + ctxt = xmlNewValidCtxt(); + + xmlSetStructuredErrorFunc((void *)error_list, noko__error_array_pusher); + + xmlValidateDtd(ctxt, doc, dtd); + + xmlSetStructuredErrorFunc(NULL, NULL); + + xmlFreeValidCtxt(ctxt); + + return error_list; +} + +/* + * call-seq: + * system_id + * + * Get the System ID for this DTD + */ +static VALUE +system_id(VALUE self) +{ + xmlDtdPtr dtd; + Noko_Node_Get_Struct(self, xmlDtd, dtd); + + if (!dtd->SystemID) { return Qnil; } + + return NOKOGIRI_STR_NEW2(dtd->SystemID); +} + +/* + * call-seq: + * external_id + * + * Get the External ID for this DTD + */ +static VALUE +external_id(VALUE self) +{ + xmlDtdPtr dtd; + Noko_Node_Get_Struct(self, xmlDtd, dtd); + + if (!dtd->ExternalID) { return Qnil; } + + return NOKOGIRI_STR_NEW2(dtd->ExternalID); +} + +void +noko_init_xml_dtd(void) +{ + assert(cNokogiriXmlNode); + /* + * Nokogiri::XML::DTD wraps DTD nodes in an XML document + */ + cNokogiriXmlDtd = rb_define_class_under(mNokogiriXml, "DTD", cNokogiriXmlNode); + + rb_define_method(cNokogiriXmlDtd, "notations", notations, 0); + rb_define_method(cNokogiriXmlDtd, "elements", elements, 0); + rb_define_method(cNokogiriXmlDtd, "entities", entities, 0); + rb_define_method(cNokogiriXmlDtd, "validate", validate, 1); + rb_define_method(cNokogiriXmlDtd, "attributes", attributes, 0); + rb_define_method(cNokogiriXmlDtd, "system_id", system_id, 0); + rb_define_method(cNokogiriXmlDtd, "external_id", external_id, 0); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_element_content.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_element_content.c new file mode 100644 index 0000000..b4fa884 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_element_content.c @@ -0,0 +1,131 @@ +#include + +VALUE cNokogiriXmlElementContent; + +static const rb_data_type_t xml_element_content_type = { + .wrap_struct_name = "xmlElementContent", + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +/* + * call-seq: + * name → String + * + * [Returns] The content element's +name+ + */ +static VALUE +get_name(VALUE self) +{ + xmlElementContentPtr elem; + TypedData_Get_Struct(self, xmlElementContent, &xml_element_content_type, elem); + + if (!elem->name) { return Qnil; } + return NOKOGIRI_STR_NEW2(elem->name); +} + +/* + * call-seq: + * type → Integer + * + * [Returns] The content element's +type+. Possible values are +PCDATA+, +ELEMENT+, +SEQ+, or +OR+. + */ +static VALUE +get_type(VALUE self) +{ + xmlElementContentPtr elem; + TypedData_Get_Struct(self, xmlElementContent, &xml_element_content_type, elem); + + return INT2NUM(elem->type); +} + +/* + * Get the first child. + */ +static VALUE +get_c1(VALUE self) +{ + xmlElementContentPtr elem; + TypedData_Get_Struct(self, xmlElementContent, &xml_element_content_type, elem); + + if (!elem->c1) { return Qnil; } + return noko_xml_element_content_wrap(rb_iv_get(self, "@document"), elem->c1); +} + +/* + * Get the second child. + */ +static VALUE +get_c2(VALUE self) +{ + xmlElementContentPtr elem; + TypedData_Get_Struct(self, xmlElementContent, &xml_element_content_type, elem); + + if (!elem->c2) { return Qnil; } + return noko_xml_element_content_wrap(rb_iv_get(self, "@document"), elem->c2); +} + +/* + * call-seq: + * occur → Integer + * + * [Returns] The content element's +occur+ flag. Possible values are +ONCE+, +OPT+, +MULT+ or +PLUS+. + */ +static VALUE +get_occur(VALUE self) +{ + xmlElementContentPtr elem; + TypedData_Get_Struct(self, xmlElementContent, &xml_element_content_type, elem); + + return INT2NUM(elem->ocur); +} + +/* + * call-seq: + * prefix → String + * + * [Returns] The content element's namespace +prefix+. + */ +static VALUE +get_prefix(VALUE self) +{ + xmlElementContentPtr elem; + TypedData_Get_Struct(self, xmlElementContent, &xml_element_content_type, elem); + + if (!elem->prefix) { return Qnil; } + + return NOKOGIRI_STR_NEW2(elem->prefix); +} + +/* + * create a Nokogiri::XML::ElementContent object around an +element+. + */ +VALUE +noko_xml_element_content_wrap(VALUE rb_document, xmlElementContentPtr c_element_content) +{ + VALUE elem = TypedData_Wrap_Struct( + cNokogiriXmlElementContent, + &xml_element_content_type, + c_element_content + ); + + /* keep a handle on the document for GC marking */ + rb_iv_set(elem, "@document", rb_document); + + return elem; +} + +void +noko_init_xml_element_content(void) +{ + cNokogiriXmlElementContent = rb_define_class_under(mNokogiriXml, "ElementContent", rb_cObject); + + rb_undef_alloc_func(cNokogiriXmlElementContent); + + rb_define_method(cNokogiriXmlElementContent, "name", get_name, 0); + rb_define_method(cNokogiriXmlElementContent, "type", get_type, 0); + rb_define_method(cNokogiriXmlElementContent, "occur", get_occur, 0); + rb_define_method(cNokogiriXmlElementContent, "prefix", get_prefix, 0); + + rb_define_private_method(cNokogiriXmlElementContent, "c1", get_c1, 0); + rb_define_private_method(cNokogiriXmlElementContent, "c2", get_c2, 0); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_element_decl.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_element_decl.c new file mode 100644 index 0000000..58981d3 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_element_decl.c @@ -0,0 +1,69 @@ +#include + +VALUE cNokogiriXmlElementDecl; + +static ID id_document; + +/* + * call-seq: + * element_type → Integer + * + * The element_type + */ +static VALUE +element_type(VALUE self) +{ + xmlElementPtr node; + Noko_Node_Get_Struct(self, xmlElement, node); + return INT2NUM(node->etype); +} + +/* + * call-seq: + * content → Nokogiri::XML::ElementContent + * + * [Returns] The root of this element declaration's content tree. + */ +static VALUE +content(VALUE self) +{ + xmlElementPtr node; + Noko_Node_Get_Struct(self, xmlElement, node); + + if (!node->content) { return Qnil; } + + return noko_xml_element_content_wrap( + rb_funcall(self, id_document, 0), + node->content + ); +} + +/* + * call-seq: + * prefix → String + * + * [Returns] The namespace +prefix+ for this element declaration. + */ +static VALUE +prefix(VALUE self) +{ + xmlElementPtr node; + Noko_Node_Get_Struct(self, xmlElement, node); + + if (!node->prefix) { return Qnil; } + + return NOKOGIRI_STR_NEW2(node->prefix); +} + +void +noko_init_xml_element_decl(void) +{ + assert(cNokogiriXmlNode); + cNokogiriXmlElementDecl = rb_define_class_under(mNokogiriXml, "ElementDecl", cNokogiriXmlNode); + + rb_define_method(cNokogiriXmlElementDecl, "element_type", element_type, 0); + rb_define_method(cNokogiriXmlElementDecl, "content", content, 0); + rb_define_method(cNokogiriXmlElementDecl, "prefix", prefix, 0); + + id_document = rb_intern("document"); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_encoding_handler.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_encoding_handler.c new file mode 100644 index 0000000..0992787 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_encoding_handler.c @@ -0,0 +1,112 @@ +#include + +VALUE cNokogiriEncodingHandler; + +static void +xml_encoding_handler_dealloc(void *data) +{ + /* make sure iconv handlers are cleaned up and freed */ + xmlCharEncodingHandlerPtr c_handler = data; + xmlCharEncCloseFunc(c_handler); +} + +static const rb_data_type_t xml_char_encoding_handler_type = { + .wrap_struct_name = "xmlCharEncodingHandler", + .function = { + .dfree = xml_encoding_handler_dealloc, + }, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + + +/* + * call-seq: Nokogiri::EncodingHandler.[](name) + * + * Get the encoding handler for +name+ + */ +static VALUE +rb_xml_encoding_handler_s_get(VALUE klass, VALUE key) +{ + xmlCharEncodingHandlerPtr handler; + + handler = xmlFindCharEncodingHandler(StringValueCStr(key)); + if (handler) { + return TypedData_Wrap_Struct(klass, &xml_char_encoding_handler_type, handler); + } + + return Qnil; +} + + +/* + * call-seq: Nokogiri::EncodingHandler.delete(name) + * + * Delete the encoding alias named +name+ + */ +static VALUE +rb_xml_encoding_handler_s_delete(VALUE klass, VALUE name) +{ + if (xmlDelEncodingAlias(StringValueCStr(name))) { return Qnil; } + + return Qtrue; +} + + +/* + * call-seq: Nokogiri::EncodingHandler.alias(real_name, alias_name) + * + * Alias encoding handler with name +real_name+ to name +alias_name+ + */ +static VALUE +rb_xml_encoding_handler_s_alias(VALUE klass, VALUE from, VALUE to) +{ + xmlAddEncodingAlias(StringValueCStr(from), StringValueCStr(to)); + + return to; +} + + +/* + * call-seq: Nokogiri::EncodingHandler.clear_aliases! + * + * Remove all encoding aliases. + */ +static VALUE +rb_xml_encoding_handler_s_clear_aliases(VALUE klass) +{ + xmlCleanupEncodingAliases(); + + return klass; +} + + +/* + * call-seq: name + * + * Get the name of this EncodingHandler + */ +static VALUE +rb_xml_encoding_handler_name(VALUE self) +{ + xmlCharEncodingHandlerPtr handler; + + TypedData_Get_Struct(self, xmlCharEncodingHandler, &xml_char_encoding_handler_type, handler); + + return NOKOGIRI_STR_NEW2(handler->name); +} + + +void +noko_init_xml_encoding_handler(void) +{ + cNokogiriEncodingHandler = rb_define_class_under(mNokogiri, "EncodingHandler", rb_cObject); + + rb_undef_alloc_func(cNokogiriEncodingHandler); + + rb_define_singleton_method(cNokogiriEncodingHandler, "[]", rb_xml_encoding_handler_s_get, 1); + rb_define_singleton_method(cNokogiriEncodingHandler, "delete", rb_xml_encoding_handler_s_delete, 1); + rb_define_singleton_method(cNokogiriEncodingHandler, "alias", rb_xml_encoding_handler_s_alias, 2); + rb_define_singleton_method(cNokogiriEncodingHandler, "clear_aliases!", rb_xml_encoding_handler_s_clear_aliases, 0); + + rb_define_method(cNokogiriEncodingHandler, "name", rb_xml_encoding_handler_name, 0); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_entity_decl.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_entity_decl.c new file mode 100644 index 0000000..4b7f407 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_entity_decl.c @@ -0,0 +1,112 @@ +#include + +VALUE cNokogiriXmlEntityDecl; + +/* + * call-seq: + * original_content + * + * Get the original_content before ref substitution + */ +static VALUE +original_content(VALUE self) +{ + xmlEntityPtr node; + Noko_Node_Get_Struct(self, xmlEntity, node); + + if (!node->orig) { return Qnil; } + + return NOKOGIRI_STR_NEW2(node->orig); +} + +/* + * call-seq: + * content + * + * Get the content + */ +static VALUE +get_content(VALUE self) +{ + xmlEntityPtr node; + Noko_Node_Get_Struct(self, xmlEntity, node); + + if (!node->content) { return Qnil; } + + return NOKOGIRI_STR_NEW(node->content, node->length); +} + +/* + * call-seq: + * entity_type + * + * Get the entity type + */ +static VALUE +entity_type(VALUE self) +{ + xmlEntityPtr node; + Noko_Node_Get_Struct(self, xmlEntity, node); + + return INT2NUM((int)node->etype); +} + +/* + * call-seq: + * external_id + * + * Get the external identifier for PUBLIC + */ +static VALUE +external_id(VALUE self) +{ + xmlEntityPtr node; + Noko_Node_Get_Struct(self, xmlEntity, node); + + if (!node->ExternalID) { return Qnil; } + + return NOKOGIRI_STR_NEW2(node->ExternalID); +} + +/* + * call-seq: + * system_id + * + * Get the URI for a SYSTEM or PUBLIC Entity + */ +static VALUE +system_id(VALUE self) +{ + xmlEntityPtr node; + Noko_Node_Get_Struct(self, xmlEntity, node); + + if (!node->SystemID) { return Qnil; } + + return NOKOGIRI_STR_NEW2(node->SystemID); +} + +void +noko_init_xml_entity_decl(void) +{ + assert(cNokogiriXmlNode); + cNokogiriXmlEntityDecl = rb_define_class_under(mNokogiriXml, "EntityDecl", cNokogiriXmlNode); + + rb_define_method(cNokogiriXmlEntityDecl, "original_content", original_content, 0); + rb_define_method(cNokogiriXmlEntityDecl, "content", get_content, 0); + rb_define_method(cNokogiriXmlEntityDecl, "entity_type", entity_type, 0); + rb_define_method(cNokogiriXmlEntityDecl, "external_id", external_id, 0); + rb_define_method(cNokogiriXmlEntityDecl, "system_id", system_id, 0); + + rb_const_set(cNokogiriXmlEntityDecl, rb_intern("INTERNAL_GENERAL"), + INT2NUM(XML_INTERNAL_GENERAL_ENTITY)); + rb_const_set(cNokogiriXmlEntityDecl, rb_intern("EXTERNAL_GENERAL_PARSED"), + INT2NUM(XML_EXTERNAL_GENERAL_PARSED_ENTITY)); + rb_const_set(cNokogiriXmlEntityDecl, rb_intern("EXTERNAL_GENERAL_UNPARSED"), + INT2NUM(XML_EXTERNAL_GENERAL_UNPARSED_ENTITY)); + rb_const_set(cNokogiriXmlEntityDecl, rb_intern("INTERNAL_PARAMETER"), + INT2NUM(XML_INTERNAL_PARAMETER_ENTITY)); + rb_const_set(cNokogiriXmlEntityDecl, rb_intern("EXTERNAL_PARAMETER"), + INT2NUM(XML_EXTERNAL_PARAMETER_ENTITY)); + rb_const_set(cNokogiriXmlEntityDecl, rb_intern("INTERNAL_PREDEFINED"), + INT2NUM(XML_INTERNAL_PREDEFINED_ENTITY)); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_entity_reference.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_entity_reference.c new file mode 100644 index 0000000..3fcc3e5 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_entity_reference.c @@ -0,0 +1,50 @@ +#include + +VALUE cNokogiriXmlEntityReference; + +/* + * call-seq: + * new(document, content) + * + * Create a new EntityReference element on the +document+ with +name+ + */ +static VALUE +new (int argc, VALUE *argv, VALUE klass) +{ + xmlDocPtr xml_doc; + xmlNodePtr node; + VALUE document; + VALUE name; + VALUE rest; + VALUE rb_node; + + rb_scan_args(argc, argv, "2*", &document, &name, &rest); + + xml_doc = noko_xml_document_unwrap(document); + + node = xmlNewReference( + xml_doc, + (const xmlChar *)StringValueCStr(name) + ); + + noko_xml_document_pin_node(node); + + rb_node = noko_xml_node_wrap(klass, node); + rb_obj_call_init(rb_node, argc, argv); + + if (rb_block_given_p()) { rb_yield(rb_node); } + + return rb_node; +} + +void +noko_init_xml_entity_reference(void) +{ + assert(cNokogiriXmlNode); + /* + * EntityReference represents an EntityReference node in an xml document. + */ + cNokogiriXmlEntityReference = rb_define_class_under(mNokogiriXml, "EntityReference", cNokogiriXmlNode); + + rb_define_singleton_method(cNokogiriXmlEntityReference, "new", new, -1); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_namespace.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_namespace.c new file mode 100644 index 0000000..b16ad45 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_namespace.c @@ -0,0 +1,181 @@ +#include + +/* + * The lifecycle of a Namespace node is more complicated than other Nodes, for two reasons: + * + * 1. the underlying C structure has a different layout than all the other node structs, with the + * `_private` member where we store a pointer to Ruby object data not being in first position. + * 2. xmlNs structures returned in an xmlNodeset from an XPath query are copies of the document's + * namespaces, and so do not share the same memory lifecycle as everything else in a document. + * + * As a result of 1, you may see special handling of XML_NAMESPACE_DECL node types throughout the + * Nokogiri C code, though I intend to wrap up that logic in ruby_object_{get,set} functions + * shortly. + * + * As a result of 2, you will see we have special handling in this file and in xml_node_set.c to + * carefully manage the memory lifecycle of xmlNs structs to match the Ruby object's GC + * lifecycle. In xml_node_set.c we have local versions of xmlXPathNodeSetDel() and + * xmlXPathFreeNodeSet() that avoid freeing xmlNs structs in the node set. In this file, we decide + * whether or not to call dealloc_namespace() depending on whether the xmlNs struct appears to be + * in an xmlNodeSet (and thus the result of an XPath query) or not. + * + * Yes, this is madness. + */ + +VALUE cNokogiriXmlNamespace ; + +static void +_xml_namespace_dealloc(void *ptr) +{ + /* + * this deallocator is only used for namespace nodes that are part of an xpath + * node set. see noko_xml_namespace_wrap(). + */ + xmlNsPtr ns = ptr; + + if (ns->href) { + xmlFree(DISCARD_CONST_QUAL_XMLCHAR(ns->href)); + } + if (ns->prefix) { + xmlFree(DISCARD_CONST_QUAL_XMLCHAR(ns->prefix)); + } + xmlFree(ns); +} + +static void +_xml_namespace_update_references(void *ptr) +{ + xmlNsPtr ns = ptr; + if (ns->_private) { + ns->_private = (void *)rb_gc_location((VALUE)ns->_private); + } +} + +static const rb_data_type_t xml_ns_type_with_free = { + .wrap_struct_name = "xmlNs (with free)", + .function = { + .dfree = _xml_namespace_dealloc, + .dcompact = _xml_namespace_update_references, + }, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static const rb_data_type_t xml_ns_type_without_free = { + .wrap_struct_name = "xmlNs (without free)", + .function = { + .dcompact = _xml_namespace_update_references, + }, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +/* + * :call-seq: + * prefix() → String or nil + * + * Return the prefix for this Namespace, or +nil+ if there is no prefix (e.g., default namespace). + * + * *Example* + * + * doc = Nokogiri::XML.parse(<<~XML) + * + * + * + * + * + * XML + * + * doc.root.elements.first.namespace.prefix + * # => nil + * + * doc.root.elements.last.namespace.prefix + * # => "noko" + */ +static VALUE +prefix(VALUE self) +{ + xmlNsPtr ns; + + Noko_Namespace_Get_Struct(self, xmlNs, ns); + if (!ns->prefix) { return Qnil; } + + return NOKOGIRI_STR_NEW2(ns->prefix); +} + +/* + * :call-seq: + * href() → String + * + * Returns the URI reference for this Namespace. + * + * *Example* + * + * doc = Nokogiri::XML.parse(<<~XML) + * + * + * + * + * + * XML + * + * doc.root.elements.first.namespace.href + * # => "http://nokogiri.org/ns/default" + * + * doc.root.elements.last.namespace.href + * # => "http://nokogiri.org/ns/noko" + */ +static VALUE +href(VALUE self) +{ + xmlNsPtr ns; + + Noko_Namespace_Get_Struct(self, xmlNs, ns); + if (!ns->href) { return Qnil; } + + return NOKOGIRI_STR_NEW2(ns->href); +} + +VALUE +noko_xml_namespace_wrap(xmlNsPtr c_namespace, xmlDocPtr c_document) +{ + VALUE rb_namespace; + + if (c_namespace->_private) { + return (VALUE)c_namespace->_private; + } + + if (c_document) { + rb_namespace = TypedData_Wrap_Struct(cNokogiriXmlNamespace, + &xml_ns_type_without_free, + c_namespace); + + if (DOC_RUBY_OBJECT_TEST(c_document)) { + rb_iv_set(rb_namespace, "@document", DOC_RUBY_OBJECT(c_document)); + rb_ary_push(DOC_NODE_CACHE(c_document), rb_namespace); + } + } else { + rb_namespace = TypedData_Wrap_Struct(cNokogiriXmlNamespace, + &xml_ns_type_with_free, + c_namespace); + } + + c_namespace->_private = (void *)rb_namespace; + + return rb_namespace; +} + +VALUE +noko_xml_namespace_wrap_xpath_copy(xmlNsPtr c_namespace) +{ + return noko_xml_namespace_wrap(c_namespace, NULL); +} + +void +noko_init_xml_namespace(void) +{ + cNokogiriXmlNamespace = rb_define_class_under(mNokogiriXml, "Namespace", rb_cObject); + + rb_undef_alloc_func(cNokogiriXmlNamespace); + + rb_define_method(cNokogiriXmlNamespace, "prefix", prefix, 0); + rb_define_method(cNokogiriXmlNamespace, "href", href, 0); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_node.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_node.c new file mode 100644 index 0000000..111e8f7 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_node.c @@ -0,0 +1,2459 @@ +#include + +#include + +// :stopdoc: + +VALUE cNokogiriXmlNode ; +static ID id_decorate, id_decorate_bang; + +typedef xmlNodePtr(*pivot_reparentee_func)(xmlNodePtr, xmlNodePtr); + +static void +_xml_node_mark(void *ptr) +{ + xmlNodePtr node = ptr; + + if (!DOC_RUBY_OBJECT_TEST(node->doc)) { + return; + } + + xmlDocPtr doc = node->doc; + if (doc->type == XML_DOCUMENT_NODE || doc->type == XML_HTML_DOCUMENT_NODE) { + if (DOC_RUBY_OBJECT_TEST(doc)) { + rb_gc_mark(DOC_RUBY_OBJECT(doc)); + } + } else if (node->doc->_private) { + rb_gc_mark((VALUE)doc->_private); + } +} + +static void +_xml_node_update_references(void *ptr) +{ + xmlNodePtr node = ptr; + + if (node->_private) { + node->_private = (void *)rb_gc_location((VALUE)node->_private); + } +} + +static const rb_data_type_t xml_node_type = { + .wrap_struct_name = "xmlNode", + .function = { + .dmark = _xml_node_mark, + .dcompact = _xml_node_update_references, + }, + .flags = RUBY_TYPED_FREE_IMMEDIATELY, +}; + +static VALUE +_xml_node_alloc(VALUE klass) +{ + return TypedData_Wrap_Struct(klass, &xml_node_type, NULL); +} + +static void +_xml_node_data_ptr_set(VALUE rb_node, xmlNodePtr c_node) +{ + assert(DATA_PTR(rb_node) == NULL); + assert(c_node->_private == NULL); + + DATA_PTR(rb_node) = c_node; + c_node->_private = (void *)rb_node; + + return; +} + +static void +relink_namespace(xmlNodePtr reparented) +{ + xmlNodePtr child; + xmlAttrPtr attr; + + if (reparented->type != XML_ATTRIBUTE_NODE && + reparented->type != XML_ELEMENT_NODE) { return; } + + if (reparented->ns == NULL || reparented->ns->prefix == NULL) { + xmlNsPtr ns = NULL; + xmlChar *name = NULL, *prefix = NULL; + + name = xmlSplitQName2(reparented->name, &prefix); + + if (reparented->type == XML_ATTRIBUTE_NODE) { + if (prefix == NULL || strcmp((char *)prefix, XMLNS_PREFIX) == 0) { + xmlFree(name); + xmlFree(prefix); + return; + } + } + + ns = xmlSearchNs(reparented->doc, reparented, prefix); + + if (ns != NULL) { + xmlNodeSetName(reparented, name); + xmlSetNs(reparented, ns); + } + + xmlFree(name); + xmlFree(prefix); + } + + /* Avoid segv when relinking against unlinked nodes. */ + if (reparented->type != XML_ELEMENT_NODE || !reparented->parent) { return; } + + /* Make sure that our reparented node has the correct namespaces */ + if (!reparented->ns && + (reparented->doc != (xmlDocPtr)reparented->parent) && + (rb_iv_get(DOC_RUBY_OBJECT(reparented->doc), "@namespace_inheritance") == Qtrue)) { + xmlSetNs(reparented, reparented->parent->ns); + } + + /* Search our parents for an existing definition */ + if (reparented->nsDef) { + xmlNsPtr curr = reparented->nsDef; + xmlNsPtr prev = NULL; + + while (curr) { + xmlNsPtr ns = xmlSearchNsByHref( + reparented->doc, + reparented->parent, + curr->href + ); + /* If we find the namespace is already declared, remove it from this + * definition list. */ + if (ns && ns != curr && xmlStrEqual(ns->prefix, curr->prefix)) { + if (prev) { + prev->next = curr->next; + } else { + reparented->nsDef = curr->next; + } + noko_xml_document_pin_namespace(curr, reparented->doc); + } else { + prev = curr; + } + curr = curr->next; + } + } + + /* + * Search our parents for an existing definition of current namespace, + * because the definition it's pointing to may have just been removed nsDef. + * + * And although that would technically probably be OK, I'd feel better if we + * referred to a namespace that's still present in a node's nsDef somewhere + * in the doc. + */ + if (reparented->ns) { + xmlNsPtr ns = xmlSearchNs(reparented->doc, reparented, reparented->ns->prefix); + if (ns + && ns != reparented->ns + && xmlStrEqual(ns->prefix, reparented->ns->prefix) + && xmlStrEqual(ns->href, reparented->ns->href) + ) { + xmlSetNs(reparented, ns); + } + } + + /* Only walk all children if there actually is a namespace we need to */ + /* reparent. */ + if (NULL == reparented->ns) { return; } + + /* When a node gets reparented, walk its children to make sure that */ + /* their namespaces are reparented as well. */ + child = reparented->children; + while (NULL != child) { + relink_namespace(child); + child = child->next; + } + + if (reparented->type == XML_ELEMENT_NODE) { + attr = reparented->properties; + while (NULL != attr) { + relink_namespace((xmlNodePtr)attr); + attr = attr->next; + } + } +} + + +/* internal function meant to wrap xmlReplaceNode + and fix some issues we have with libxml2 merging nodes */ +static xmlNodePtr +xmlReplaceNodeWrapper(xmlNodePtr pivot, xmlNodePtr new_node) +{ + xmlNodePtr retval ; + + retval = xmlReplaceNode(pivot, new_node) ; + + if (retval == pivot) { + retval = new_node ; /* return semantics for reparent_node_with */ + } + + /* work around libxml2 issue: https://bugzilla.gnome.org/show_bug.cgi?id=615612 */ + if (retval && retval->type == XML_TEXT_NODE) { + if (retval->prev && retval->prev->type == XML_TEXT_NODE) { + retval = xmlTextMerge(retval->prev, retval); + } + if (retval->next && retval->next->type == XML_TEXT_NODE) { + retval = xmlTextMerge(retval, retval->next); + } + } + + return retval ; +} + + +static void +raise_if_ancestor_of_self(xmlNodePtr self) +{ + for (xmlNodePtr ancestor = self->parent ; ancestor ; ancestor = ancestor->parent) { + if (self == ancestor) { + rb_raise(rb_eRuntimeError, "cycle detected: node '%s' is an ancestor of itself", self->name); + } + } +} + + +static VALUE +reparent_node_with(VALUE pivot_obj, VALUE reparentee_obj, pivot_reparentee_func prf) +{ + VALUE reparented_obj ; + xmlNodePtr reparentee, original_reparentee, pivot, reparented, next_text, new_next_text, parent ; + int original_ns_prefix_is_default = 0 ; + + if (!rb_obj_is_kind_of(reparentee_obj, cNokogiriXmlNode)) { + rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node"); + } + if (rb_obj_is_kind_of(reparentee_obj, cNokogiriXmlDocument)) { + rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node"); + } + + Noko_Node_Get_Struct(reparentee_obj, xmlNode, reparentee); + Noko_Node_Get_Struct(pivot_obj, xmlNode, pivot); + + /* + * Check if nodes given are appropriate to have a parent-child + * relationship, based on the DOM specification. + * + * cf. http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#ID-1590626202 + */ + if (prf == xmlAddChild) { + parent = pivot; + } else { + parent = pivot->parent; + } + + if (parent) { + switch (parent->type) { + case XML_DOCUMENT_NODE: + case XML_HTML_DOCUMENT_NODE: + switch (reparentee->type) { + case XML_ELEMENT_NODE: + case XML_PI_NODE: + case XML_COMMENT_NODE: + case XML_DOCUMENT_TYPE_NODE: + /* + * The DOM specification says no to adding text-like nodes + * directly to a document, but we allow it for compatibility. + */ + case XML_TEXT_NODE: + case XML_CDATA_SECTION_NODE: + case XML_ENTITY_REF_NODE: + goto ok; + default: + break; + } + break; + case XML_DOCUMENT_FRAG_NODE: + case XML_ENTITY_REF_NODE: + case XML_ELEMENT_NODE: + switch (reparentee->type) { + case XML_ELEMENT_NODE: + case XML_PI_NODE: + case XML_COMMENT_NODE: + case XML_TEXT_NODE: + case XML_CDATA_SECTION_NODE: + case XML_ENTITY_REF_NODE: + goto ok; + default: + break; + } + break; + case XML_ATTRIBUTE_NODE: + switch (reparentee->type) { + case XML_TEXT_NODE: + case XML_ENTITY_REF_NODE: + goto ok; + default: + break; + } + break; + case XML_TEXT_NODE: + /* + * xmlAddChild() breaks the DOM specification in that it allows + * adding a text node to another, in which case text nodes are + * coalesced, but since our JRuby version does not support such + * operation, we should inhibit it. + */ + break; + default: + break; + } + + rb_raise(rb_eArgError, "cannot reparent %s there", rb_obj_classname(reparentee_obj)); + } + +ok: + original_reparentee = reparentee; + + if (reparentee->doc != pivot->doc || reparentee->type == XML_TEXT_NODE) { + /* + * if the reparentee is a text node, there's a very good chance it will be + * merged with an adjacent text node after being reparented, and in that case + * libxml will free the underlying C struct. + * + * since we clearly have a ruby object which references the underlying + * memory, we can't let the C struct get freed. let's pickle the original + * reparentee by rooting it; and then we'll reparent a duplicate of the + * node that we don't care about preserving. + * + * alternatively, if the reparentee is from a different document than the + * pivot node, libxml2 is going to get confused about which document's + * "dictionary" the node's strings belong to (this is an otherwise + * uninteresting libxml2 implementation detail). as a result, we cannot + * reparent the actual reparentee, so we reparent a duplicate. + */ + if (reparentee->type == XML_TEXT_NODE && reparentee->_private) { + /* + * additionally, since we know this C struct isn't going to be related to + * a Ruby object anymore, let's break the relationship on this end as + * well. + * + * this is not absolutely necessary unless libxml-ruby is also in effect, + * in which case its global callback `rxml_node_deregisterNode` will try + * to do things to our data. + * + * for more details on this particular (and particularly nasty) edge + * case, see: + * + * https://github.com/sparklemotion/nokogiri/issues/1426 + */ + reparentee->_private = NULL ; + } + + if (reparentee->ns != NULL && reparentee->ns->prefix == NULL) { + original_ns_prefix_is_default = 1; + } + + noko_xml_document_pin_node(reparentee); + + if (!(reparentee = xmlDocCopyNode(reparentee, pivot->doc, 1))) { + rb_raise(rb_eRuntimeError, "Could not reparent node (xmlDocCopyNode)"); + } + + if (original_ns_prefix_is_default && reparentee->ns != NULL && reparentee->ns->prefix != NULL) { + /* + * issue #391, where new node's prefix may become the string "default" + * see libxml2 tree.c xmlNewReconciliedNs which implements this behavior. + */ + xmlFree(DISCARD_CONST_QUAL_XMLCHAR(reparentee->ns->prefix)); + reparentee->ns->prefix = NULL; + } + } + + xmlUnlinkNode(original_reparentee); + + if (prf != xmlAddPrevSibling && prf != xmlAddNextSibling && prf != xmlAddChild + && reparentee->type == XML_TEXT_NODE && pivot->next && pivot->next->type == XML_TEXT_NODE) { + /* + * libxml merges text nodes in a right-to-left fashion, meaning that if + * there are two text nodes who would be adjacent, the right (or following, + * or next) node will be merged into the left (or preceding, or previous) + * node. + * + * and by "merged" I mean the string contents will be concatenated onto the + * left node's contents, and then the node will be freed. + * + * which means that if we have a ruby object wrapped around the right node, + * its memory would be freed out from under it. + * + * so, we detect this edge case and unlink-and-root the text node before it gets + * merged. then we dup the node and insert that duplicate back into the + * document where the real node was. + * + * yes, this is totally lame. + */ + next_text = pivot->next ; + new_next_text = xmlDocCopyNode(next_text, pivot->doc, 1) ; + + xmlUnlinkNode(next_text); + noko_xml_document_pin_node(next_text); + + xmlAddNextSibling(pivot, new_next_text); + } + + if (!(reparented = (*prf)(pivot, reparentee))) { + rb_raise(rb_eRuntimeError, "Could not reparent node"); + } + + /* + * make sure the ruby object is pointed at the just-reparented node, which + * might be a duplicate (see above) or might be the result of merging + * adjacent text nodes. + */ + DATA_PTR(reparentee_obj) = reparented ; + reparented_obj = noko_xml_node_wrap(Qnil, reparented); + + rb_funcall(reparented_obj, id_decorate_bang, 0); + + /* if we've created a cycle, raise an exception */ + raise_if_ancestor_of_self(reparented); + + relink_namespace(reparented); + + return reparented_obj ; +} + +// :startdoc: + +/* + * :call-seq: + * add_namespace_definition(prefix, href) → Nokogiri::XML::Namespace + * add_namespace(prefix, href) → Nokogiri::XML::Namespace + * + * :category: Manipulating Document Structure + * + * Adds a namespace definition to this node with +prefix+ using +href+ value, as if this node had + * included an attribute "xmlns:prefix=href". + * + * A default namespace definition for this node can be added by passing +nil+ for +prefix+. + * + * [Parameters] + * - +prefix+ (String, +nil+) An {XML Name}[https://www.w3.org/TR/xml-names/#ns-decl] + * - +href+ (String) The {URI reference}[https://www.w3.org/TR/xml-names/#sec-namespaces] + * + * [Returns] The new Nokogiri::XML::Namespace + * + * *Example:* adding a non-default namespace definition + * + * doc = Nokogiri::XML("") + * inventory = doc.at_css("inventory") + * inventory.add_namespace_definition("automobile", "http://alices-autos.com/") + * inventory.add_namespace_definition("bicycle", "http://bobs-bikes.com/") + * inventory.add_child("Michelin model XGV, size 75R") + * doc.to_xml + * # => "\n" + + * # "\n" + + * # " \n" + + * # " Michelin model XGV, size 75R\n" + + * # " \n" + + * # "\n" + * + * *Example:* adding a default namespace definition + * + * doc = Nokogiri::XML("Michelin model XGV, size 75R") + * doc.at_css("tire").add_namespace_definition(nil, "http://bobs-bikes.com/") + * doc.to_xml + * # => "\n" + + * # "\n" + + * # " \n" + + * # " Michelin model XGV, size 75R\n" + + * # " \n" + + * # "\n" + * + */ +static VALUE +rb_xml_node_add_namespace_definition(VALUE rb_node, VALUE rb_prefix, VALUE rb_href) +{ + xmlNodePtr c_node, element; + xmlNsPtr c_namespace; + const xmlChar *c_prefix = (const xmlChar *)(NIL_P(rb_prefix) ? NULL : StringValueCStr(rb_prefix)); + + Noko_Node_Get_Struct(rb_node, xmlNode, c_node); + element = c_node ; + + c_namespace = xmlSearchNs(c_node->doc, c_node, c_prefix); + + if (!c_namespace) { + if (c_node->type != XML_ELEMENT_NODE) { + element = c_node->parent; + } + c_namespace = xmlNewNs(element, (const xmlChar *)StringValueCStr(rb_href), c_prefix); + } + + if (!c_namespace) { + return Qnil ; + } + + if (NIL_P(rb_prefix) || c_node != element) { + xmlSetNs(c_node, c_namespace); + } + + return noko_xml_namespace_wrap(c_namespace, c_node->doc); +} + + +/* + * :call-seq: attribute(name) → Nokogiri::XML::Attr + * + * :category: Working With Node Attributes + * + * [Returns] Attribute (Nokogiri::XML::Attr) belonging to this node with name +name+. + * + * ⚠ Note that attribute namespaces are ignored and only the simple (non-namespace-prefixed) name is + * used to find a matching attribute. In case of a simple name collision, only one of the matching + * attributes will be returned. In this case, you will need to use #attribute_with_ns. + * + * *Example:* + * + * doc = Nokogiri::XML("") + * child = doc.at_css("child") + * child.attribute("size") # => # + * child.attribute("class") # => # + * + * *Example* showing that namespaced attributes will not be returned: + * + * ⚠ Note that only one of the two matching attributes is returned. + * + * doc = Nokogiri::XML(<<~EOF) + * + * + * + * EOF + * doc.at_css("child").attribute("size") + * # => #(Attr:0x550 { + * # name = "size", + * # namespace = #(Namespace:0x564 { + * # prefix = "width", + * # href = "http://example.com/widths" + * # }), + * # value = "broad" + * # }) + */ +static VALUE +rb_xml_node_attribute(VALUE self, VALUE name) +{ + xmlNodePtr node; + xmlAttrPtr prop; + Noko_Node_Get_Struct(self, xmlNode, node); + prop = xmlHasProp(node, (xmlChar *)StringValueCStr(name)); + + if (! prop) { return Qnil; } + return noko_xml_node_wrap(Qnil, (xmlNodePtr)prop); +} + + +/* + * :call-seq: attribute_nodes() → Array + * + * :category: Working With Node Attributes + * + * [Returns] Attributes (an Array of Nokogiri::XML::Attr) belonging to this node. + * + * Note that this is the preferred alternative to #attributes when the simple + * (non-namespace-prefixed) attribute names may collide. + * + * *Example:* + * + * Contrast this with the colliding-name example from #attributes. + * + * doc = Nokogiri::XML(<<~EOF) + * + * + * + * EOF + * doc.at_css("child").attribute_nodes + * # => [#(Attr:0x550 { + * # name = "size", + * # namespace = #(Namespace:0x564 { + * # prefix = "width", + * # href = "http://example.com/widths" + * # }), + * # value = "broad" + * # }), + * # #(Attr:0x578 { + * # name = "size", + * # namespace = #(Namespace:0x58c { + * # prefix = "height", + * # href = "http://example.com/heights" + * # }), + * # value = "tall" + * # })] + */ +static VALUE +rb_xml_node_attribute_nodes(VALUE rb_node) +{ + xmlNodePtr c_node; + + Noko_Node_Get_Struct(rb_node, xmlNode, c_node); + + return noko_xml_node_attrs(c_node); +} + + +/* + * :call-seq: attribute_with_ns(name, namespace) → Nokogiri::XML::Attr + * + * :category: Working With Node Attributes + * + * [Returns] + * Attribute (Nokogiri::XML::Attr) belonging to this node with matching +name+ and +namespace+. + * + * [Parameters] + * - +name+ (String): the simple (non-namespace-prefixed) name of the attribute + * - +namespace+ (String): the URI of the attribute's namespace + * + * See related: #attribute + * + * *Example:* + * + * doc = Nokogiri::XML(<<~EOF) + * + * + * + * EOF + * doc.at_css("child").attribute_with_ns("size", "http://example.com/widths") + * # => #(Attr:0x550 { + * # name = "size", + * # namespace = #(Namespace:0x564 { + * # prefix = "width", + * # href = "http://example.com/widths" + * # }), + * # value = "broad" + * # }) + * doc.at_css("child").attribute_with_ns("size", "http://example.com/heights") + * # => #(Attr:0x578 { + * # name = "size", + * # namespace = #(Namespace:0x58c { + * # prefix = "height", + * # href = "http://example.com/heights" + * # }), + * # value = "tall" + * # }) + */ +static VALUE +rb_xml_node_attribute_with_ns(VALUE self, VALUE name, VALUE namespace) +{ + xmlNodePtr node; + xmlAttrPtr prop; + Noko_Node_Get_Struct(self, xmlNode, node); + prop = xmlHasNsProp(node, (xmlChar *)StringValueCStr(name), + NIL_P(namespace) ? NULL : (xmlChar *)StringValueCStr(namespace)); + + if (! prop) { return Qnil; } + return noko_xml_node_wrap(Qnil, (xmlNodePtr)prop); +} + + + +/* + * call-seq: blank? → Boolean + * + * [Returns] +true+ if the node is an empty or whitespace-only text or cdata node, else +false+. + * + * *Example:* + * + * Nokogiri("").root.child.blank? # => false + * Nokogiri("\t \n").root.child.blank? # => true + * Nokogiri("").root.child.blank? # => true + * Nokogiri("not-blank").root.child + * .tap { |n| n.content = "" }.blank # => true + */ +static VALUE +rb_xml_node_blank_eh(VALUE self) +{ + xmlNodePtr node; + Noko_Node_Get_Struct(self, xmlNode, node); + return (1 == xmlIsBlankNode(node)) ? Qtrue : Qfalse ; +} + + +/* + * :call-seq: child() → Nokogiri::XML::Node + * + * :category: Traversing Document Structure + * + * [Returns] First of this node's children, or +nil+ if there are no children + * + * This is a convenience method and is equivalent to: + * + * node.children.first + * + * See related: #children + */ +static VALUE +rb_xml_node_child(VALUE self) +{ + xmlNodePtr node, child; + Noko_Node_Get_Struct(self, xmlNode, node); + + child = node->children; + if (!child) { return Qnil; } + + return noko_xml_node_wrap(Qnil, child); +} + + +/* + * :call-seq: children() → Nokogiri::XML::NodeSet + * + * :category: Traversing Document Structure + * + * [Returns] Nokogiri::XML::NodeSet containing this node's children. + */ +static VALUE +rb_xml_node_children(VALUE self) +{ + xmlNodePtr node; + xmlNodePtr child; + xmlNodeSetPtr set; + VALUE document; + VALUE node_set; + + Noko_Node_Get_Struct(self, xmlNode, node); + + child = node->children; + set = xmlXPathNodeSetCreate(child); + + document = DOC_RUBY_OBJECT(node->doc); + + if (!child) { return noko_xml_node_set_wrap(set, document); } + + child = child->next; + while (NULL != child) { + xmlXPathNodeSetAddUnique(set, child); + child = child->next; + } + + node_set = noko_xml_node_set_wrap(set, document); + + return node_set; +} + + +/* + * :call-seq: + * content() → String + * inner_text() → String + * text() → String + * to_str() → String + * + * [Returns] + * Contents of all the text nodes in this node's subtree, concatenated together into a single + * String. + * + * ⚠ Note that entities will _always_ be expanded in the returned String. + * + * See related: #inner_html + * + * *Example* of how entities are handled: + * + * Note that < becomes < in the returned String. + * + * doc = Nokogiri::XML.fragment("a < b") + * doc.at_css("child").content + * # => "a < b" + * + * *Example* of how a subtree is handled: + * + * Note that the tags are omitted and only the text node contents are returned, + * concatenated into a single string. + * + * doc = Nokogiri::XML.fragment("first second") + * doc.at_css("child").content + * # => "first second" + */ +static VALUE +rb_xml_node_content(VALUE self) +{ + xmlNodePtr node; + xmlChar *content; + + Noko_Node_Get_Struct(self, xmlNode, node); + + content = xmlNodeGetContent(node); + if (content) { + VALUE rval = NOKOGIRI_STR_NEW2(content); + xmlFree(content); + return rval; + } + return Qnil; +} + + +/* + * :call-seq: document() → Nokogiri::XML::Document + * + * :category: Traversing Document Structure + * + * [Returns] Parent Nokogiri::XML::Document for this node + */ +static VALUE +rb_xml_node_document(VALUE self) +{ + xmlNodePtr node; + Noko_Node_Get_Struct(self, xmlNode, node); + return DOC_RUBY_OBJECT(node->doc); +} + +/* + * :call-seq: pointer_id() → Integer + * + * [Returns] + * A unique id for this node based on the internal memory structures. This method is used by #== + * to determine node identity. + */ +static VALUE +rb_xml_node_pointer_id(VALUE self) +{ + xmlNodePtr node; + Noko_Node_Get_Struct(self, xmlNode, node); + + return rb_uint2inum((uintptr_t)(node)); +} + +/* + * :call-seq: encode_special_chars(string) → String + * + * Encode any special characters in +string+ + */ +static VALUE +encode_special_chars(VALUE self, VALUE string) +{ + xmlNodePtr node; + xmlChar *encoded; + VALUE encoded_str; + + Noko_Node_Get_Struct(self, xmlNode, node); + encoded = xmlEncodeSpecialChars( + node->doc, + (const xmlChar *)StringValueCStr(string) + ); + + encoded_str = NOKOGIRI_STR_NEW2(encoded); + xmlFree(encoded); + + return encoded_str; +} + +/* + * :call-seq: + * create_internal_subset(name, external_id, system_id) + * + * Create the internal subset of a document. + * + * doc.create_internal_subset("chapter", "-//OASIS//DTD DocBook XML//EN", "chapter.dtd") + * # => + * + * doc.create_internal_subset("chapter", nil, "chapter.dtd") + * # => + */ +static VALUE +create_internal_subset(VALUE self, VALUE name, VALUE external_id, VALUE system_id) +{ + xmlNodePtr node; + xmlDocPtr doc; + xmlDtdPtr dtd; + + Noko_Node_Get_Struct(self, xmlNode, node); + + doc = node->doc; + + if (xmlGetIntSubset(doc)) { + rb_raise(rb_eRuntimeError, "Document already has an internal subset"); + } + + dtd = xmlCreateIntSubset( + doc, + NIL_P(name) ? NULL : (const xmlChar *)StringValueCStr(name), + NIL_P(external_id) ? NULL : (const xmlChar *)StringValueCStr(external_id), + NIL_P(system_id) ? NULL : (const xmlChar *)StringValueCStr(system_id) + ); + + if (!dtd) { return Qnil; } + + return noko_xml_node_wrap(Qnil, (xmlNodePtr)dtd); +} + +/* + * :call-seq: + * create_external_subset(name, external_id, system_id) + * + * Create an external subset + */ +static VALUE +create_external_subset(VALUE self, VALUE name, VALUE external_id, VALUE system_id) +{ + xmlNodePtr node; + xmlDocPtr doc; + xmlDtdPtr dtd; + + Noko_Node_Get_Struct(self, xmlNode, node); + + doc = node->doc; + + if (doc->extSubset) { + rb_raise(rb_eRuntimeError, "Document already has an external subset"); + } + + dtd = xmlNewDtd( + doc, + NIL_P(name) ? NULL : (const xmlChar *)StringValueCStr(name), + NIL_P(external_id) ? NULL : (const xmlChar *)StringValueCStr(external_id), + NIL_P(system_id) ? NULL : (const xmlChar *)StringValueCStr(system_id) + ); + + if (!dtd) { return Qnil; } + + return noko_xml_node_wrap(Qnil, (xmlNodePtr)dtd); +} + +/* + * :call-seq: + * external_subset() + * + * Get the external subset + */ +static VALUE +external_subset(VALUE self) +{ + xmlNodePtr node; + xmlDocPtr doc; + xmlDtdPtr dtd; + + Noko_Node_Get_Struct(self, xmlNode, node); + + if (!node->doc) { return Qnil; } + + doc = node->doc; + dtd = doc->extSubset; + + if (!dtd) { return Qnil; } + + return noko_xml_node_wrap(Qnil, (xmlNodePtr)dtd); +} + +/* + * :call-seq: + * internal_subset() + * + * Get the internal subset + */ +static VALUE +internal_subset(VALUE self) +{ + xmlNodePtr node; + xmlDocPtr doc; + xmlDtdPtr dtd; + + Noko_Node_Get_Struct(self, xmlNode, node); + + if (!node->doc) { return Qnil; } + + doc = node->doc; + dtd = xmlGetIntSubset(doc); + + if (!dtd) { return Qnil; } + + return noko_xml_node_wrap(Qnil, (xmlNodePtr)dtd); +} + +/* :nodoc: */ +static VALUE +rb_xml_node_initialize_copy_with_args(VALUE rb_self, VALUE rb_other, VALUE rb_level, VALUE rb_new_parent_doc) +{ + xmlNodePtr c_self, c_other; + int c_level; + xmlDocPtr c_new_parent_doc; + VALUE rb_node_cache; + + Noko_Node_Get_Struct(rb_other, xmlNode, c_other); + c_level = (int)NUM2INT(rb_level); + c_new_parent_doc = noko_xml_document_unwrap(rb_new_parent_doc); + + c_self = xmlDocCopyNode(c_other, c_new_parent_doc, c_level); + if (c_self == NULL) { return Qnil; } + + _xml_node_data_ptr_set(rb_self, c_self); + noko_xml_document_pin_node(c_self); + + rb_node_cache = DOC_NODE_CACHE(c_new_parent_doc); + rb_ary_push(rb_node_cache, rb_self); + rb_funcall(rb_new_parent_doc, id_decorate, 1, rb_self); + + return rb_self; +} + +/* + * :call-seq: + * unlink() → self + * + * Unlink this node from its current context. + */ +static VALUE +unlink_node(VALUE self) +{ + xmlNodePtr node; + Noko_Node_Get_Struct(self, xmlNode, node); + xmlUnlinkNode(node); + noko_xml_document_pin_node(node); + return self; +} + + +/* + * call-seq: + * next_sibling + * + * Returns the next sibling node + */ +static VALUE +next_sibling(VALUE self) +{ + xmlNodePtr node, sibling; + Noko_Node_Get_Struct(self, xmlNode, node); + + sibling = node->next; + if (!sibling) { return Qnil; } + + return noko_xml_node_wrap(Qnil, sibling) ; +} + +/* + * call-seq: + * previous_sibling + * + * Returns the previous sibling node + */ +static VALUE +previous_sibling(VALUE self) +{ + xmlNodePtr node, sibling; + Noko_Node_Get_Struct(self, xmlNode, node); + + sibling = node->prev; + if (!sibling) { return Qnil; } + + return noko_xml_node_wrap(Qnil, sibling); +} + +/* + * call-seq: + * next_element + * + * Returns the next Nokogiri::XML::Element type sibling node. + */ +static VALUE +next_element(VALUE self) +{ + xmlNodePtr node, sibling; + Noko_Node_Get_Struct(self, xmlNode, node); + + sibling = xmlNextElementSibling(node); + if (!sibling) { return Qnil; } + + return noko_xml_node_wrap(Qnil, sibling); +} + +/* + * call-seq: + * previous_element + * + * Returns the previous Nokogiri::XML::Element type sibling node. + */ +static VALUE +previous_element(VALUE self) +{ + xmlNodePtr node, sibling; + Noko_Node_Get_Struct(self, xmlNode, node); + + sibling = xmlPreviousElementSibling(node); + if (!sibling) { return Qnil; } + + return noko_xml_node_wrap(Qnil, sibling); +} + +/* :nodoc: */ +static VALUE +replace(VALUE self, VALUE new_node) +{ + VALUE reparent = reparent_node_with(self, new_node, xmlReplaceNodeWrapper); + + xmlNodePtr pivot; + Noko_Node_Get_Struct(self, xmlNode, pivot); + noko_xml_document_pin_node(pivot); + + return reparent; +} + +/* + * :call-seq: + * element_children() → NodeSet + * elements() → NodeSet + * + * [Returns] + * The node's child elements as a NodeSet. Only children that are elements will be returned, which + * notably excludes Text nodes. + * + * *Example:* + * + * Note that #children returns the Text node "hello" while #element_children does not. + * + * div = Nokogiri::HTML5("
helloworld").at_css("div") + * div.element_children + * # => [#]>] + * div.children + * # => [#, + * # #]>] + */ +static VALUE +rb_xml_node_element_children(VALUE self) +{ + xmlNodePtr node; + xmlNodePtr child; + xmlNodeSetPtr set; + VALUE document; + VALUE node_set; + + Noko_Node_Get_Struct(self, xmlNode, node); + + child = xmlFirstElementChild(node); + set = xmlXPathNodeSetCreate(child); + + document = DOC_RUBY_OBJECT(node->doc); + + if (!child) { return noko_xml_node_set_wrap(set, document); } + + child = xmlNextElementSibling(child); + while (NULL != child) { + xmlXPathNodeSetAddUnique(set, child); + child = xmlNextElementSibling(child); + } + + node_set = noko_xml_node_set_wrap(set, document); + + return node_set; +} + +/* + * :call-seq: + * first_element_child() → Node + * + * [Returns] The first child Node that is an element. + * + * *Example:* + * + * Note that the "hello" child, which is a Text node, is skipped and the element is + * returned. + * + * div = Nokogiri::HTML5("
helloworld").at_css("div") + * div.first_element_child + * # => #(Element:0x3c { name = "span", children = [ #(Text "world")] }) + */ +static VALUE +rb_xml_node_first_element_child(VALUE self) +{ + xmlNodePtr node, child; + Noko_Node_Get_Struct(self, xmlNode, node); + + child = xmlFirstElementChild(node); + if (!child) { return Qnil; } + + return noko_xml_node_wrap(Qnil, child); +} + +/* + * :call-seq: + * last_element_child() → Node + * + * [Returns] The last child Node that is an element. + * + * *Example:* + * + * Note that the "hello" child, which is a Text node, is skipped and the yes + * element is returned. + * + * div = Nokogiri::HTML5("
noyesskip
").at_css("div") + * div.last_element_child + * # => #(Element:0x3c { name = "span", children = [ #(Text "yes")] }) + */ +static VALUE +rb_xml_node_last_element_child(VALUE self) +{ + xmlNodePtr node, child; + Noko_Node_Get_Struct(self, xmlNode, node); + + child = xmlLastElementChild(node); + if (!child) { return Qnil; } + + return noko_xml_node_wrap(Qnil, child); +} + +/* + * call-seq: + * key?(attribute) + * + * Returns true if +attribute+ is set + */ +static VALUE +key_eh(VALUE self, VALUE attribute) +{ + xmlNodePtr node; + Noko_Node_Get_Struct(self, xmlNode, node); + if (xmlHasProp(node, (xmlChar *)StringValueCStr(attribute))) { + return Qtrue; + } + return Qfalse; +} + +/* + * call-seq: + * namespaced_key?(attribute, namespace) + * + * Returns true if +attribute+ is set with +namespace+ + */ +static VALUE +namespaced_key_eh(VALUE self, VALUE attribute, VALUE namespace) +{ + xmlNodePtr node; + Noko_Node_Get_Struct(self, xmlNode, node); + if (xmlHasNsProp(node, (xmlChar *)StringValueCStr(attribute), + NIL_P(namespace) ? NULL : (xmlChar *)StringValueCStr(namespace))) { + return Qtrue; + } + return Qfalse; +} + +/* + * call-seq: + * []=(property, value) + * + * Set the +property+ to +value+ + */ +static VALUE +set(VALUE self, VALUE property, VALUE value) +{ + xmlNodePtr node, cur; + xmlAttrPtr prop; + Noko_Node_Get_Struct(self, xmlNode, node); + + /* If a matching attribute node already exists, then xmlSetProp will destroy + * the existing node's children. However, if Nokogiri has a node object + * pointing to one of those children, we are left with a broken reference. + * + * We can avoid this by unlinking these nodes first. + */ + if (node->type != XML_ELEMENT_NODE) { + return (Qnil); + } + prop = xmlHasProp(node, (xmlChar *)StringValueCStr(property)); + if (prop && prop->children) { + for (cur = prop->children; cur; cur = cur->next) { + if (cur->_private) { + noko_xml_document_pin_node(cur); + xmlUnlinkNode(cur); + } + } + } + + xmlSetProp(node, (xmlChar *)StringValueCStr(property), + (xmlChar *)StringValueCStr(value)); + + return value; +} + +/* + * call-seq: + * get(attribute) + * + * Get the value for +attribute+ + */ +static VALUE +get(VALUE self, VALUE rattribute) +{ + xmlNodePtr node; + xmlChar *value = 0; + VALUE rvalue; + xmlChar *colon; + xmlChar *attribute, *attr_name, *prefix; + xmlNsPtr ns; + + if (NIL_P(rattribute)) { return Qnil; } + + Noko_Node_Get_Struct(self, xmlNode, node); + attribute = xmlCharStrdup(StringValueCStr(rattribute)); + + colon = DISCARD_CONST_QUAL_XMLCHAR(xmlStrchr(attribute, (const xmlChar)':')); + if (colon) { + /* split the attribute string into separate prefix and name by + * null-terminating the prefix at the colon */ + prefix = attribute; + attr_name = colon + 1; + (*colon) = 0; + + ns = xmlSearchNs(node->doc, node, prefix); + if (ns) { + value = xmlGetNsProp(node, attr_name, ns->href); + } else { + value = xmlGetProp(node, (xmlChar *)StringValueCStr(rattribute)); + } + } else { + value = xmlGetNoNsProp(node, attribute); + } + + xmlFree((void *)attribute); + if (!value) { return Qnil; } + + rvalue = NOKOGIRI_STR_NEW2(value); + xmlFree((void *)value); + + return rvalue ; +} + +/* + * call-seq: + * set_namespace(namespace) + * + * Set the namespace to +namespace+ + */ +static VALUE +set_namespace(VALUE self, VALUE namespace) +{ + xmlNodePtr node; + xmlNsPtr ns = NULL; + + Noko_Node_Get_Struct(self, xmlNode, node); + + if (!NIL_P(namespace)) { + Noko_Namespace_Get_Struct(namespace, xmlNs, ns); + } + + xmlSetNs(node, ns); + + return self; +} + +/* + * :call-seq: + * namespace() → Namespace + * + * [Returns] The Namespace of the element or attribute node, or +nil+ if there is no namespace. + * + * *Example:* + * + * doc = Nokogiri::XML(<<~EOF) + * + * + * + * + * + * EOF + * doc.at_xpath("//first").namespace + * # => nil + * doc.at_xpath("//xmlns:second", "xmlns" => "http://example.com/child").namespace + * # => #(Namespace:0x3c { href = "http://example.com/child" }) + * doc.at_xpath("//foo:third", "foo" => "http://example.com/foo").namespace + * # => #(Namespace:0x50 { prefix = "foo", href = "http://example.com/foo" }) + */ +static VALUE +rb_xml_node_namespace(VALUE rb_node) +{ + xmlNodePtr c_node ; + Noko_Node_Get_Struct(rb_node, xmlNode, c_node); + + if (c_node->ns) { + return noko_xml_namespace_wrap(c_node->ns, c_node->doc); + } + + return Qnil ; +} + +/* + * :call-seq: + * namespace_definitions() → Array + * + * [Returns] + * Namespaces that are defined directly on this node, as an Array of Namespace objects. The array + * will be empty if no namespaces are defined on this node. + * + * *Example:* + * + * doc = Nokogiri::XML(<<~EOF) + * + * + * + * + * + * EOF + * doc.at_xpath("//root:first", "root" => "http://example.com/root").namespace_definitions + * # => [] + * doc.at_xpath("//xmlns:second", "xmlns" => "http://example.com/child").namespace_definitions + * # => [#(Namespace:0x3c { href = "http://example.com/child" }), + * # #(Namespace:0x50 { + * # prefix = "unused", + * # href = "http://example.com/unused" + * # })] + * doc.at_xpath("//foo:third", "foo" => "http://example.com/foo").namespace_definitions + * # => [#(Namespace:0x64 { prefix = "foo", href = "http://example.com/foo" })] + */ +static VALUE +namespace_definitions(VALUE rb_node) +{ + /* this code in the mode of xmlHasProp() */ + xmlNodePtr c_node ; + xmlNsPtr c_namespace; + VALUE definitions = rb_ary_new(); + + Noko_Node_Get_Struct(rb_node, xmlNode, c_node); + + c_namespace = c_node->nsDef; + if (!c_namespace) { + return definitions; + } + + while (c_namespace != NULL) { + rb_ary_push(definitions, noko_xml_namespace_wrap(c_namespace, c_node->doc)); + c_namespace = c_namespace->next; + } + + return definitions; +} + +/* + * :call-seq: + * namespace_scopes() → Array + * + * [Returns] Array of all the Namespaces on this node and its ancestors. + * + * See also #namespaces + * + * *Example:* + * + * doc = Nokogiri::XML(<<~EOF) + * + * + * + * + * + * EOF + * doc.at_xpath("//root:first", "root" => "http://example.com/root").namespace_scopes + * # => [#(Namespace:0x3c { href = "http://example.com/root" }), + * # #(Namespace:0x50 { prefix = "bar", href = "http://example.com/bar" })] + * doc.at_xpath("//child:second", "child" => "http://example.com/child").namespace_scopes + * # => [#(Namespace:0x64 { href = "http://example.com/child" }), + * # #(Namespace:0x50 { prefix = "bar", href = "http://example.com/bar" })] + * doc.at_xpath("//root:third", "root" => "http://example.com/root").namespace_scopes + * # => [#(Namespace:0x78 { prefix = "foo", href = "http://example.com/foo" }), + * # #(Namespace:0x3c { href = "http://example.com/root" }), + * # #(Namespace:0x50 { prefix = "bar", href = "http://example.com/bar" })] + */ +static VALUE +rb_xml_node_namespace_scopes(VALUE rb_node) +{ + xmlNodePtr c_node ; + xmlNsPtr *namespaces; + VALUE scopes = rb_ary_new(); + int j; + + Noko_Node_Get_Struct(rb_node, xmlNode, c_node); + + namespaces = xmlGetNsList(c_node->doc, c_node); + if (!namespaces) { + return scopes; + } + + for (j = 0 ; namespaces[j] != NULL ; ++j) { + rb_ary_push(scopes, noko_xml_namespace_wrap(namespaces[j], c_node->doc)); + } + + xmlFree(namespaces); + return scopes; +} + +/* + * call-seq: + * node_type + * + * Get the type for this Node + */ +static VALUE +node_type(VALUE self) +{ + xmlNodePtr node; + Noko_Node_Get_Struct(self, xmlNode, node); + return INT2NUM(node->type); +} + +/* + * call-seq: + * native_content=(input) + * + * Set the content of this node to +input+. + * + * [Parameters] + * - +input+ (String) The new content for this node. + * + * ⚠ This method behaves differently depending on the node type. For Text, CDATA, Comment, and + * ProcessingInstruction nodes, it treats the input as raw content, which means that the final DOM + * will contain the entity-escaped version of the input (see example below). For Element and Attr + * nodes, it treats the input as parsed content and expects it to be valid markup that is already + * entity-escaped. + * + * 💡 Use Node#content= for a more consistent API across node types. + * + * [Example] + * Note the behavior differences of this method between Text and Element nodes: + * + * doc = Nokogiri::HTML::Document.parse(<<~HTML) + * + * + *
asdf
+ *
asdf
+ * HTML + * + * text_node = doc.at_css("div#first").children.first + * div_node = doc.at_css("div#second") + * + * value = "You & Me" + * + * text_node.native_content = value + * div_node.native_content = value + * + * doc.css("div").to_html + * # => "
You &amp; Me
+ * #
You & Me
" + * + * See also: #content= + */ +static VALUE +set_native_content(VALUE self, VALUE content) +{ + xmlNodePtr node, child, next ; + Noko_Node_Get_Struct(self, xmlNode, node); + + child = node->children; + while (NULL != child) { + next = child->next ; + xmlUnlinkNode(child) ; + noko_xml_document_pin_node(child); + child = next ; + } + + xmlNodeSetContent(node, (xmlChar *)StringValueCStr(content)); + return content; +} + +/* + * call-seq: + * lang= + * + * Set the language of a node, i.e. the values of the xml:lang attribute. + */ +static VALUE +set_lang(VALUE self_rb, VALUE lang_rb) +{ + xmlNodePtr self ; + xmlChar *lang ; + + Noko_Node_Get_Struct(self_rb, xmlNode, self); + lang = (xmlChar *)StringValueCStr(lang_rb); + + xmlNodeSetLang(self, lang); + + return Qnil ; +} + +/* + * call-seq: + * lang + * + * Searches the language of a node, i.e. the values of the xml:lang attribute or + * the one carried by the nearest ancestor. + */ +static VALUE +get_lang(VALUE self_rb) +{ + xmlNodePtr self ; + xmlChar *lang ; + VALUE lang_rb ; + + Noko_Node_Get_Struct(self_rb, xmlNode, self); + + lang = xmlNodeGetLang(self); + if (lang) { + lang_rb = NOKOGIRI_STR_NEW2(lang); + xmlFree(lang); + return lang_rb ; + } + + return Qnil ; +} + +/* :nodoc: */ +static VALUE +add_child(VALUE self, VALUE new_child) +{ + return reparent_node_with(self, new_child, xmlAddChild); +} + +/* + * call-seq: + * parent + * + * Get the parent Node for this Node + */ +static VALUE +get_parent(VALUE self) +{ + xmlNodePtr node, parent; + Noko_Node_Get_Struct(self, xmlNode, node); + + parent = node->parent; + if (!parent) { return Qnil; } + + return noko_xml_node_wrap(Qnil, parent) ; +} + +/* + * call-seq: + * name=(new_name) + * + * Set the name for this Node + */ +static VALUE +set_name(VALUE self, VALUE new_name) +{ + xmlNodePtr node; + Noko_Node_Get_Struct(self, xmlNode, node); + xmlNodeSetName(node, (xmlChar *)StringValueCStr(new_name)); + return new_name; +} + +/* + * call-seq: + * name + * + * Returns the name for this Node + */ +static VALUE +get_name(VALUE self) +{ + xmlNodePtr node; + Noko_Node_Get_Struct(self, xmlNode, node); + if (node->name) { + return NOKOGIRI_STR_NEW2(node->name); + } + return Qnil; +} + +/* + * call-seq: + * path + * + * Returns the path associated with this Node + */ +static VALUE +rb_xml_node_path(VALUE rb_node) +{ + xmlNodePtr c_node; + xmlChar *c_path ; + VALUE rval; + + Noko_Node_Get_Struct(rb_node, xmlNode, c_node); + + c_path = xmlGetNodePath(c_node); + if (c_path == NULL) { + // see https://github.com/sparklemotion/nokogiri/issues/2250 + // this behavior is clearly undesirable, but is what libxml <= 2.9.10 returned, and so we + // do this for now to preserve the behavior across libxml2 versions. + rval = NOKOGIRI_STR_NEW2("?"); + } else { + rval = NOKOGIRI_STR_NEW2(c_path); + xmlFree(c_path); + } + + return rval ; +} + +/* :nodoc: */ +static VALUE +add_next_sibling(VALUE self, VALUE new_sibling) +{ + return reparent_node_with(self, new_sibling, xmlAddNextSibling) ; +} + +/* :nodoc: */ +static VALUE +add_previous_sibling(VALUE self, VALUE new_sibling) +{ + return reparent_node_with(self, new_sibling, xmlAddPrevSibling) ; +} + +/* + * call-seq: + * native_write_to(io, encoding, options) + * + * Write this Node to +io+ with +encoding+ and +options+ + */ +static VALUE +native_write_to( + VALUE self, + VALUE io, + VALUE encoding, + VALUE indent_string, + VALUE options +) +{ + xmlNodePtr node; + const char *before_indent; + xmlSaveCtxtPtr savectx; + + Noko_Node_Get_Struct(self, xmlNode, node); + + xmlIndentTreeOutput = 1; + + before_indent = xmlTreeIndentString; + + xmlTreeIndentString = StringValueCStr(indent_string); + + savectx = xmlSaveToIO( + (xmlOutputWriteCallback)noko_io_write, + (xmlOutputCloseCallback)noko_io_close, + (void *)io, + RTEST(encoding) ? StringValueCStr(encoding) : NULL, + (int)NUM2INT(options) + ); + + xmlSaveTree(savectx, node); + xmlSaveClose(savectx); + + xmlTreeIndentString = before_indent; + return io; +} + + +static inline void +output_partial_string(VALUE out, char const *str, size_t length) +{ + if (length) { + rb_enc_str_buf_cat(out, str, (long)length, rb_utf8_encoding()); + } +} + +static inline void +output_char(VALUE out, char ch) +{ + output_partial_string(out, &ch, 1); +} + +static inline void +output_string(VALUE out, char const *str) +{ + output_partial_string(out, str, strlen(str)); +} + +static inline void +output_tagname(VALUE out, xmlNodePtr elem) +{ + // Elements in the HTML, MathML, and SVG namespaces do not use a namespace + // prefix in the HTML syntax. + char const *name = (char const *)elem->name; + xmlNsPtr ns = elem->ns; + if (ns && ns->href && ns->prefix + && strcmp((char const *)ns->href, "http://www.w3.org/1999/xhtml") + && strcmp((char const *)ns->href, "http://www.w3.org/1998/Math/MathML") + && strcmp((char const *)ns->href, "http://www.w3.org/2000/svg")) { + output_string(out, (char const *)elem->ns->prefix); + output_char(out, ':'); + char const *colon = strchr(name, ':'); + if (colon) { + name = colon + 1; + } + } + output_string(out, name); +} + +static inline void +output_attr_name(VALUE out, xmlAttrPtr attr) +{ + xmlNsPtr ns = attr->ns; + char const *name = (char const *)attr->name; + if (ns && ns->href) { + char const *uri = (char const *)ns->href; + char const *localname = strchr(name, ':'); + if (localname) { + ++localname; + } else { + localname = name; + } + + if (!strcmp(uri, "http://www.w3.org/XML/1998/namespace")) { + output_string(out, "xml:"); + name = localname; + } else if (!strcmp(uri, "http://www.w3.org/2000/xmlns/")) { + // xmlns:xmlns -> xmlns + // xmlns:foo -> xmlns:foo + if (strcmp(localname, "xmlns")) { + output_string(out, "xmlns:"); + } + name = localname; + } else if (!strcmp(uri, "http://www.w3.org/1999/xlink")) { + output_string(out, "xlink:"); + name = localname; + } else if (ns->prefix) { + output_string(out, (char const *)ns->prefix); + output_char(out, ':'); + name = localname; + } + } + output_string(out, name); +} + +static void +output_escaped_string(VALUE out, xmlChar const *start, bool attr) +{ + xmlChar const *next = start; + int ch; + + while ((ch = *next) != 0) { + char const *replacement = NULL; + size_t replaced_bytes = 1; + if (ch == '&') { + replacement = "&"; + } else if (ch == 0xC2 && next[1] == 0xA0) { + // U+00A0 NO-BREAK SPACE has the UTF-8 encoding C2 A0. + replacement = " "; + replaced_bytes = 2; + } else if (attr && ch == '"') { + replacement = """; + } else if (!attr && ch == '<') { + replacement = "<"; + } else if (!attr && ch == '>') { + replacement = ">"; + } else { + ++next; + continue; + } + output_partial_string(out, (char const *)start, (size_t)(next - start)); + output_string(out, replacement); + next += replaced_bytes; + start = next; + } + output_partial_string(out, (char const *)start, (size_t)(next - start)); +} + +static bool +should_prepend_newline(xmlNodePtr node) +{ + char const *name = (char const *)node->name; + xmlNodePtr child = node->children; + + if (!name || !child || (strcmp(name, "pre") && strcmp(name, "textarea") && strcmp(name, "listing"))) { + return false; + } + + return child->type == XML_TEXT_NODE && child->content && child->content[0] == '\n'; +} + +static VALUE +rb_prepend_newline(VALUE self) +{ + xmlNodePtr node; + Noko_Node_Get_Struct(self, xmlNode, node); + return should_prepend_newline(node) ? Qtrue : Qfalse; +} + +static bool +is_one_of(xmlNodePtr node, char const *const *tagnames, size_t num_tagnames) +{ + char const *name = (char const *)node->name; + if (name == NULL) { // fragments don't have a name + return false; + } + + if (node->ns != NULL) { + // if the node has a namespace, it's in a foreign context and is not one of the HTML tags we're + // matching against. + return false; + } + + for (size_t idx = 0; idx < num_tagnames; ++idx) { + if (!strcmp(name, tagnames[idx])) { + return true; + } + } + return false; +} + +static void +output_node( + VALUE out, + xmlNodePtr node, + bool preserve_newline +) +{ + static char const *const VOID_ELEMENTS[] = { + "area", "base", "basefont", "bgsound", "br", "col", "embed", "frame", "hr", + "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr", + }; + + static char const *const UNESCAPED_TEXT_ELEMENTS[] = { + "style", "script", "xmp", "iframe", "noembed", "noframes", "plaintext", "noscript", + }; + + switch (node->type) { + case XML_ELEMENT_NODE: + // Serialize the start tag. + output_char(out, '<'); + output_tagname(out, node); + + // Add attributes. + for (xmlAttrPtr attr = node->properties; attr; attr = attr->next) { + output_char(out, ' '); + output_node(out, (xmlNodePtr)attr, preserve_newline); + } + output_char(out, '>'); + + // Add children and end tag if element is not void. + if (!is_one_of(node, VOID_ELEMENTS, sizeof VOID_ELEMENTS / sizeof VOID_ELEMENTS[0])) { + if (preserve_newline && should_prepend_newline(node)) { + output_char(out, '\n'); + } + for (xmlNodePtr child = node->children; child; child = child->next) { + output_node(out, child, preserve_newline); + } + output_string(out, "'); + } + break; + + case XML_ATTRIBUTE_NODE: { + xmlAttrPtr attr = (xmlAttrPtr)node; + output_attr_name(out, attr); + if (attr->children) { + output_string(out, "=\""); + xmlChar *value = xmlNodeListGetString(attr->doc, attr->children, 1); + output_escaped_string(out, value, true); + xmlFree(value); + output_char(out, '"'); + } else { + // Output name="" + output_string(out, "=\"\""); + } + } + break; + + case XML_TEXT_NODE: + if (node->parent + && is_one_of(node->parent, UNESCAPED_TEXT_ELEMENTS, + sizeof UNESCAPED_TEXT_ELEMENTS / sizeof UNESCAPED_TEXT_ELEMENTS[0])) { + output_string(out, (char const *)node->content); + } else { + output_escaped_string(out, node->content, false); + } + break; + + case XML_CDATA_SECTION_NODE: + output_string(out, "content); + output_string(out, "]]>"); + break; + + case XML_COMMENT_NODE: + output_string(out, ""); + break; + + case XML_PI_NODE: + output_string(out, "content); + output_char(out, '>'); + break; + + case XML_DOCUMENT_TYPE_NODE: + case XML_DTD_NODE: + output_string(out, "name); + output_string(out, ">"); + break; + + case XML_DOCUMENT_NODE: + case XML_DOCUMENT_FRAG_NODE: + case XML_HTML_DOCUMENT_NODE: + for (xmlNodePtr child = node->children; child; child = child->next) { + output_node(out, child, preserve_newline); + } + break; + + default: + rb_raise(rb_eRuntimeError, "Unsupported document node (%d); this is a bug in Nokogiri", node->type); + break; + } +} + +static VALUE +html_standard_serialize( + VALUE self, + VALUE preserve_newline +) +{ + xmlNodePtr node; + Noko_Node_Get_Struct(self, xmlNode, node); + VALUE output = rb_str_buf_new(4096); + output_node(output, node, RTEST(preserve_newline)); + return output; +} + +/* + * :call-seq: + * line() → Integer + * + * [Returns] The line number of this Node. + * + * --- + * + * ⚠ The CRuby and JRuby implementations differ in important ways! + * + * Semantic differences: + * - The CRuby method reflects the node's line number in the parsed string + * - The JRuby method reflects the node's line number in the final DOM structure after + * corrections have been applied + * + * Performance differences: + * - The CRuby method is {O(1)}[https://en.wikipedia.org/wiki/Time_complexity#Constant_time] + * (constant time) + * - The JRuby method is {O(n)}[https://en.wikipedia.org/wiki/Time_complexity#Linear_time] (linear + * time, where n is the number of nodes before/above the element in the DOM) + * + * If you'd like to help improve the JRuby implementation, please review these issues and reach out + * to the maintainers: + * - https://github.com/sparklemotion/nokogiri/issues/1223 + * - https://github.com/sparklemotion/nokogiri/pull/2177 + * - https://github.com/sparklemotion/nokogiri/issues/2380 + */ +static VALUE +rb_xml_node_line(VALUE rb_node) +{ + xmlNodePtr c_node; + Noko_Node_Get_Struct(rb_node, xmlNode, c_node); + + return LONG2NUM(xmlGetLineNo(c_node)); +} + +/* + * call-seq: + * line=(num) + * + * Sets the line for this Node. num must be less than 65535. + */ +static VALUE +rb_xml_node_line_set(VALUE rb_node, VALUE rb_line_number) +{ + xmlNodePtr c_node; + int line_number = NUM2INT(rb_line_number); + + Noko_Node_Get_Struct(rb_node, xmlNode, c_node); + + // libxml2 optionally uses xmlNode.psvi to store longer line numbers, but only for text nodes. + // search for "psvi" in SAX2.c and tree.c to learn more. + if (line_number < 65535) { + c_node->line = (short unsigned)line_number; + } else { + c_node->line = 65535; + if (c_node->type == XML_TEXT_NODE) { + c_node->psvi = (void *)(ptrdiff_t)line_number; + } + } + + return rb_line_number; +} + +/* :nodoc: documented in lib/nokogiri/xml/node.rb */ +static VALUE +rb_xml_node_new(int argc, VALUE *argv, VALUE klass) +{ + xmlNodePtr c_document_node; + xmlNodePtr c_node; + VALUE rb_name; + VALUE rb_document_node; + VALUE rest; + VALUE rb_node; + + rb_scan_args(argc, argv, "2*", &rb_name, &rb_document_node, &rest); + + if (!rb_obj_is_kind_of(rb_document_node, cNokogiriXmlNode)) { + rb_raise(rb_eArgError, "document must be a Nokogiri::XML::Node"); + } + if (!rb_obj_is_kind_of(rb_document_node, cNokogiriXmlDocument)) { + NOKO_WARN_DEPRECATION("Passing a Node as the second parameter to Node.new is deprecated. Please pass a Document instead, or prefer an alternative constructor like Node#add_child. This will become an error in Nokogiri v1.17.0."); // TODO: deprecated in v1.13.0, remove in v1.17.0 + } + Noko_Node_Get_Struct(rb_document_node, xmlNode, c_document_node); + + c_node = xmlNewNode(NULL, (xmlChar *)StringValueCStr(rb_name)); + c_node->doc = c_document_node->doc; + noko_xml_document_pin_node(c_node); + + rb_node = noko_xml_node_wrap( + klass == cNokogiriXmlNode ? (VALUE)NULL : klass, + c_node + ); + rb_obj_call_init(rb_node, argc, argv); + + if (rb_block_given_p()) { rb_yield(rb_node); } + + return rb_node; +} + +/* + * call-seq: + * dump_html + * + * Returns the Node as html. + */ +static VALUE +dump_html(VALUE self) +{ + xmlBufferPtr buf ; + xmlNodePtr node ; + VALUE html; + + Noko_Node_Get_Struct(self, xmlNode, node); + + buf = xmlBufferCreate() ; + htmlNodeDump(buf, node->doc, node); + html = NOKOGIRI_STR_NEW2(xmlBufferContent(buf)); + xmlBufferFree(buf); + return html ; +} + +/* + * call-seq: + * compare(other) + * + * Compare this Node to +other+ with respect to their Document + */ +static VALUE +compare(VALUE self, VALUE _other) +{ + xmlNodePtr node, other; + Noko_Node_Get_Struct(self, xmlNode, node); + Noko_Node_Get_Struct(_other, xmlNode, other); + + return INT2NUM(xmlXPathCmpNodes(other, node)); +} + + +/* + * call-seq: + * process_xincludes(flags) + * + * Loads and substitutes all xinclude elements below the node. The + * parser context will be initialized with +flags+. + */ +static VALUE +noko_xml_node__process_xincludes(VALUE rb_node, VALUE rb_flags) +{ + int status ; + xmlNodePtr c_node; + VALUE rb_errors = rb_ary_new(); + libxmlStructuredErrorHandlerState handler_state; + + Noko_Node_Get_Struct(rb_node, xmlNode, c_node); + + noko__structured_error_func_save_and_set(&handler_state, (void *)rb_errors, noko__error_array_pusher); + + status = xmlXIncludeProcessTreeFlags(c_node, (int)NUM2INT(rb_flags)); + + noko__structured_error_func_restore(&handler_state); + + if (status < 0) { + VALUE exception = rb_funcall(cNokogiriXmlSyntaxError, rb_intern("aggregate"), 1, rb_errors); + + if (RB_TEST(exception)) { + rb_exc_raise(exception); + } else { + rb_raise(rb_eRuntimeError, "Could not perform xinclude substitution"); + } + } + + return rb_node; +} + + +/* TODO: DOCUMENT ME */ +static VALUE +in_context(VALUE self, VALUE _str, VALUE _options) +{ + xmlNodePtr node, list = 0, tmp, child_iter, node_children, doc_children; + xmlNodeSetPtr set; + xmlParserErrors error; + VALUE doc, err; + int doc_is_empty; + + Noko_Node_Get_Struct(self, xmlNode, node); + + doc = DOC_RUBY_OBJECT(node->doc); + err = rb_iv_get(doc, "@errors"); + doc_is_empty = (node->doc->children == NULL) ? 1 : 0; + node_children = node->children; + doc_children = node->doc->children; + + xmlSetStructuredErrorFunc((void *)err, noko__error_array_pusher); + + /* This function adds a fake node to the child of +node+. If the parser + * does not exit cleanly with XML_ERR_OK, the list is freed. This can + * leave the child pointers in a bad state if they were originally empty. + * + * http://git.gnome.org/browse/libxml2/tree/parser.c#n13177 + * */ + error = xmlParseInNodeContext(node, StringValuePtr(_str), + (int)RSTRING_LEN(_str), + (int)NUM2INT(_options), &list); + + /* xmlParseInNodeContext should not mutate the original document or node, + * so reassigning these pointers should be OK. The reason we're reassigning + * is because if there were errors, it's possible for the child pointers + * to be manipulated. */ + if (error != XML_ERR_OK) { + node->doc->children = doc_children; + node->children = node_children; + } + + /* make sure parent/child pointers are coherent so an unlink will work + * properly (#331) + */ + child_iter = node->doc->children ; + while (child_iter) { + child_iter->parent = (xmlNodePtr)node->doc; + child_iter = child_iter->next; + } + + xmlSetStructuredErrorFunc(NULL, NULL); + + /* + * Workaround for a libxml2 bug where a parsing error may leave a broken + * node reference in node->doc->children. + * + * https://bugzilla.gnome.org/show_bug.cgi?id=668155 + * + * This workaround is limited to when a parse error occurs, the document + * went from having no children to having children, and the context node is + * part of a document fragment. + * + * TODO: This was fixed in libxml 2.8.0 by 71a243d + */ + if (error != XML_ERR_OK && doc_is_empty && node->doc->children != NULL) { + child_iter = node; + while (child_iter->parent) { + child_iter = child_iter->parent; + } + + if (child_iter->type == XML_DOCUMENT_FRAG_NODE) { + node->doc->children = NULL; + } + } + + /* FIXME: This probably needs to handle more constants... */ + switch (error) { + case XML_ERR_INTERNAL_ERROR: + case XML_ERR_NO_MEMORY: + rb_raise(rb_eRuntimeError, "error parsing fragment (%d)", error); + break; + default: + break; + } + + set = xmlXPathNodeSetCreate(NULL); + + while (list) { + tmp = list->next; + list->next = NULL; + xmlXPathNodeSetAddUnique(set, list); + noko_xml_document_pin_node(list); + list = tmp; + } + + return noko_xml_node_set_wrap(set, doc); +} + +/* :nodoc: */ +VALUE +rb_xml_node_data_ptr_eh(VALUE self) +{ + xmlNodePtr c_node; + Noko_Node_Get_Struct(self, xmlNode, c_node); + return c_node ? Qtrue : Qfalse; +} + +VALUE +noko_xml_node_wrap(VALUE rb_class, xmlNodePtr c_node) +{ + VALUE rb_document, rb_node_cache, rb_node; + nokogiriTuplePtr node_has_a_document; + xmlDocPtr c_doc; + + assert(c_node); + + if (c_node->type == XML_DOCUMENT_NODE || c_node->type == XML_HTML_DOCUMENT_NODE) { + return DOC_RUBY_OBJECT(c_node->doc); + } + + c_doc = c_node->doc; + + // Nodes yielded from XML::Reader don't have a fully-realized Document + node_has_a_document = DOC_RUBY_OBJECT_TEST(c_doc); + + if (c_node->_private && node_has_a_document) { + return (VALUE)c_node->_private; + } + + if (!RTEST(rb_class)) { + switch (c_node->type) { + case XML_ELEMENT_NODE: + rb_class = cNokogiriXmlElement; + break; + case XML_TEXT_NODE: + rb_class = cNokogiriXmlText; + break; + case XML_ATTRIBUTE_NODE: + rb_class = cNokogiriXmlAttr; + break; + case XML_ENTITY_REF_NODE: + rb_class = cNokogiriXmlEntityReference; + break; + case XML_COMMENT_NODE: + rb_class = cNokogiriXmlComment; + break; + case XML_DOCUMENT_FRAG_NODE: + rb_class = cNokogiriXmlDocumentFragment; + break; + case XML_PI_NODE: + rb_class = cNokogiriXmlProcessingInstruction; + break; + case XML_ENTITY_DECL: + rb_class = cNokogiriXmlEntityDecl; + break; + case XML_CDATA_SECTION_NODE: + rb_class = cNokogiriXmlCData; + break; + case XML_DTD_NODE: + rb_class = cNokogiriXmlDtd; + break; + case XML_ATTRIBUTE_DECL: + rb_class = cNokogiriXmlAttributeDecl; + break; + case XML_ELEMENT_DECL: + rb_class = cNokogiriXmlElementDecl; + break; + default: + rb_class = cNokogiriXmlNode; + } + } + + rb_node = _xml_node_alloc(rb_class); + _xml_node_data_ptr_set(rb_node, c_node); + + if (node_has_a_document) { + rb_document = DOC_RUBY_OBJECT(c_doc); + rb_node_cache = DOC_NODE_CACHE(c_doc); + rb_ary_push(rb_node_cache, rb_node); + rb_funcall(rb_document, id_decorate, 1, rb_node); + } + + return rb_node ; +} + + +/* + * return Array containing the node's attributes + */ +VALUE +noko_xml_node_attrs(xmlNodePtr c_node) +{ + VALUE rb_properties = rb_ary_new(); + xmlAttrPtr c_property; + + c_property = c_node->properties ; + while (c_property != NULL) { + rb_ary_push(rb_properties, noko_xml_node_wrap(Qnil, (xmlNodePtr)c_property)); + c_property = c_property->next ; + } + + return rb_properties; +} + +void +noko_init_xml_node(void) +{ + cNokogiriXmlNode = rb_define_class_under(mNokogiriXml, "Node", rb_cObject); + + rb_define_alloc_func(cNokogiriXmlNode, _xml_node_alloc); + + rb_define_singleton_method(cNokogiriXmlNode, "new", rb_xml_node_new, -1); + + rb_define_method(cNokogiriXmlNode, "add_namespace_definition", rb_xml_node_add_namespace_definition, 2); + rb_define_method(cNokogiriXmlNode, "attribute", rb_xml_node_attribute, 1); + rb_define_method(cNokogiriXmlNode, "attribute_nodes", rb_xml_node_attribute_nodes, 0); + rb_define_method(cNokogiriXmlNode, "attribute_with_ns", rb_xml_node_attribute_with_ns, 2); + rb_define_method(cNokogiriXmlNode, "blank?", rb_xml_node_blank_eh, 0); + rb_define_method(cNokogiriXmlNode, "child", rb_xml_node_child, 0); + rb_define_method(cNokogiriXmlNode, "children", rb_xml_node_children, 0); + rb_define_method(cNokogiriXmlNode, "content", rb_xml_node_content, 0); + rb_define_method(cNokogiriXmlNode, "create_external_subset", create_external_subset, 3); + rb_define_method(cNokogiriXmlNode, "create_internal_subset", create_internal_subset, 3); + rb_define_method(cNokogiriXmlNode, "data_ptr?", rb_xml_node_data_ptr_eh, 0); + rb_define_method(cNokogiriXmlNode, "document", rb_xml_node_document, 0); + rb_define_method(cNokogiriXmlNode, "element_children", rb_xml_node_element_children, 0); + rb_define_method(cNokogiriXmlNode, "encode_special_chars", encode_special_chars, 1); + rb_define_method(cNokogiriXmlNode, "external_subset", external_subset, 0); + rb_define_method(cNokogiriXmlNode, "first_element_child", rb_xml_node_first_element_child, 0); + rb_define_method(cNokogiriXmlNode, "internal_subset", internal_subset, 0); + rb_define_method(cNokogiriXmlNode, "key?", key_eh, 1); + rb_define_method(cNokogiriXmlNode, "lang", get_lang, 0); + rb_define_method(cNokogiriXmlNode, "lang=", set_lang, 1); + rb_define_method(cNokogiriXmlNode, "last_element_child", rb_xml_node_last_element_child, 0); + rb_define_method(cNokogiriXmlNode, "line", rb_xml_node_line, 0); + rb_define_method(cNokogiriXmlNode, "line=", rb_xml_node_line_set, 1); + rb_define_method(cNokogiriXmlNode, "namespace", rb_xml_node_namespace, 0); + rb_define_method(cNokogiriXmlNode, "namespace_definitions", namespace_definitions, 0); + rb_define_method(cNokogiriXmlNode, "namespace_scopes", rb_xml_node_namespace_scopes, 0); + rb_define_method(cNokogiriXmlNode, "namespaced_key?", namespaced_key_eh, 2); + rb_define_method(cNokogiriXmlNode, "native_content=", set_native_content, 1); + rb_define_method(cNokogiriXmlNode, "next_element", next_element, 0); + rb_define_method(cNokogiriXmlNode, "next_sibling", next_sibling, 0); + rb_define_method(cNokogiriXmlNode, "node_name", get_name, 0); + rb_define_method(cNokogiriXmlNode, "node_name=", set_name, 1); + rb_define_method(cNokogiriXmlNode, "node_type", node_type, 0); + rb_define_method(cNokogiriXmlNode, "parent", get_parent, 0); + rb_define_method(cNokogiriXmlNode, "path", rb_xml_node_path, 0); + rb_define_method(cNokogiriXmlNode, "pointer_id", rb_xml_node_pointer_id, 0); + rb_define_method(cNokogiriXmlNode, "previous_element", previous_element, 0); + rb_define_method(cNokogiriXmlNode, "previous_sibling", previous_sibling, 0); + rb_define_method(cNokogiriXmlNode, "unlink", unlink_node, 0); + + rb_define_protected_method(cNokogiriXmlNode, "initialize_copy_with_args", rb_xml_node_initialize_copy_with_args, 3); + + rb_define_private_method(cNokogiriXmlNode, "add_child_node", add_child, 1); + rb_define_private_method(cNokogiriXmlNode, "add_next_sibling_node", add_next_sibling, 1); + rb_define_private_method(cNokogiriXmlNode, "add_previous_sibling_node", add_previous_sibling, 1); + rb_define_private_method(cNokogiriXmlNode, "compare", compare, 1); + rb_define_private_method(cNokogiriXmlNode, "dump_html", dump_html, 0); + rb_define_private_method(cNokogiriXmlNode, "get", get, 1); + rb_define_private_method(cNokogiriXmlNode, "in_context", in_context, 2); + rb_define_private_method(cNokogiriXmlNode, "native_write_to", native_write_to, 4); + rb_define_private_method(cNokogiriXmlNode, "prepend_newline?", rb_prepend_newline, 0); + rb_define_private_method(cNokogiriXmlNode, "html_standard_serialize", html_standard_serialize, 1); + rb_define_private_method(cNokogiriXmlNode, "process_xincludes", noko_xml_node__process_xincludes, 1); + rb_define_private_method(cNokogiriXmlNode, "replace_node", replace, 1); + rb_define_private_method(cNokogiriXmlNode, "set", set, 2); + rb_define_private_method(cNokogiriXmlNode, "set_namespace", set_namespace, 1); + + id_decorate = rb_intern("decorate"); + id_decorate_bang = rb_intern("decorate!"); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_node_set.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_node_set.c new file mode 100644 index 0000000..de1beeb --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_node_set.c @@ -0,0 +1,518 @@ +#include + +VALUE cNokogiriXmlNodeSet ; + +static ID decorate ; + +static void +Check_Node_Set_Node_Type(VALUE node) +{ + if (!(rb_obj_is_kind_of(node, cNokogiriXmlNode) || + rb_obj_is_kind_of(node, cNokogiriXmlNamespace))) { + rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node or Nokogiri::XML::Namespace"); + } +} + + +static +VALUE +ruby_object_get(xmlNodePtr c_node) +{ + /* see xmlElementType in libxml2 tree.h */ + switch (c_node->type) { + case XML_NAMESPACE_DECL: + /* _private is later in the namespace struct */ + return (VALUE)(((xmlNsPtr)c_node)->_private); + + case XML_DOCUMENT_NODE: + case XML_HTML_DOCUMENT_NODE: + /* in documents we use _private to store a tuple */ + if (DOC_RUBY_OBJECT_TEST(((xmlDocPtr)c_node))) { + return DOC_RUBY_OBJECT((xmlDocPtr)c_node); + } + return (VALUE)NULL; + + default: + return (VALUE)(c_node->_private); + } +} + + +static void +xml_node_set_mark(void *data) +{ + xmlNodeSetPtr node_set = data; + VALUE rb_node; + int jnode; + + for (jnode = 0; jnode < node_set->nodeNr; jnode++) { + rb_node = ruby_object_get(node_set->nodeTab[jnode]); + if (rb_node) { + rb_gc_mark(rb_node); + } + } +} + +static void +xml_node_set_deallocate(void *data) +{ + xmlNodeSetPtr node_set = data; + /* + * For reasons outlined in xml_namespace.c, here we reproduce xmlXPathFreeNodeSet() except for the + * offending call to xmlXPathNodeSetFreeNs(). + */ + if (node_set->nodeTab != NULL) { + xmlFree(node_set->nodeTab); + } + + xmlFree(node_set); +} + +static const rb_data_type_t xml_node_set_type = { + .wrap_struct_name = "xmlNodeSet", + .function = { + .dmark = xml_node_set_mark, + .dfree = xml_node_set_deallocate, + }, + .flags = RUBY_TYPED_FREE_IMMEDIATELY, +}; + +static VALUE +xml_node_set_allocate(VALUE klass) +{ + return TypedData_Wrap_Struct(klass, &xml_node_set_type, xmlXPathNodeSetCreate(NULL)); +} + +/* :nodoc: */ +static VALUE +rb_xml_node_set_initialize_copy(VALUE rb_self, VALUE rb_other) +{ + xmlNodeSetPtr c_self, c_other; + VALUE rb_document; + + TypedData_Get_Struct(rb_self, xmlNodeSet, &xml_node_set_type, c_self); + TypedData_Get_Struct(rb_other, xmlNodeSet, &xml_node_set_type, c_other); + + xmlXPathNodeSetMerge(c_self, c_other); + + rb_document = rb_iv_get(rb_other, "@document"); + if (!NIL_P(rb_document)) { + rb_iv_set(rb_self, "@document", rb_document); + rb_funcall(rb_document, decorate, 1, rb_self); + } + + return rb_self; +} + +static void +xpath_node_set_del(xmlNodeSetPtr cur, xmlNodePtr val) +{ + /* + * For reasons outlined in xml_namespace.c, here we reproduce xmlXPathNodeSetDel() except for the + * offending call to xmlXPathNodeSetFreeNs(). + */ + int i; + + if (cur == NULL) { return; } + if (val == NULL) { return; } + + /* + * find node in nodeTab + */ + for (i = 0; i < cur->nodeNr; i++) + if (cur->nodeTab[i] == val) { break; } + + if (i >= cur->nodeNr) { /* not found */ + return; + } + cur->nodeNr--; + for (; i < cur->nodeNr; i++) { + cur->nodeTab[i] = cur->nodeTab[i + 1]; + } + cur->nodeTab[cur->nodeNr] = NULL; +} + +/* + * call-seq: + * length + * + * Get the length of the node set + */ +static VALUE +length(VALUE rb_self) +{ + xmlNodeSetPtr c_self; + + TypedData_Get_Struct(rb_self, xmlNodeSet, &xml_node_set_type, c_self); + + return c_self ? INT2NUM(c_self->nodeNr) : INT2NUM(0); +} + +/* + * call-seq: + * push(node) + * + * Append +node+ to the NodeSet. + */ +static VALUE +push(VALUE rb_self, VALUE rb_node) +{ + xmlNodeSetPtr c_self; + xmlNodePtr node; + + Check_Node_Set_Node_Type(rb_node); + + TypedData_Get_Struct(rb_self, xmlNodeSet, &xml_node_set_type, c_self); + Noko_Node_Get_Struct(rb_node, xmlNode, node); + + xmlXPathNodeSetAdd(c_self, node); + + return rb_self; +} + +/* + * call-seq: + * delete(node) + * + * Delete +node+ from the Nodeset, if it is a member. Returns the deleted node + * if found, otherwise returns nil. + */ +static VALUE +delete (VALUE rb_self, VALUE rb_node) +{ + xmlNodeSetPtr c_self; + xmlNodePtr node; + + Check_Node_Set_Node_Type(rb_node); + + TypedData_Get_Struct(rb_self, xmlNodeSet, &xml_node_set_type, c_self); + Noko_Node_Get_Struct(rb_node, xmlNode, node); + + if (xmlXPathNodeSetContains(c_self, node)) { + xpath_node_set_del(c_self, node); + return rb_node; + } + return Qnil ; +} + + +/* + * call-seq: + * &(node_set) + * + * Set Intersection — Returns a new NodeSet containing nodes common to the two NodeSets. + */ +static VALUE +intersection(VALUE rb_self, VALUE rb_other) +{ + xmlNodeSetPtr c_self, c_other ; + xmlNodeSetPtr intersection; + + if (!rb_obj_is_kind_of(rb_other, cNokogiriXmlNodeSet)) { + rb_raise(rb_eArgError, "node_set must be a Nokogiri::XML::NodeSet"); + } + + TypedData_Get_Struct(rb_self, xmlNodeSet, &xml_node_set_type, c_self); + TypedData_Get_Struct(rb_other, xmlNodeSet, &xml_node_set_type, c_other); + + intersection = xmlXPathIntersection(c_self, c_other); + return noko_xml_node_set_wrap(intersection, rb_iv_get(rb_self, "@document")); +} + + +/* + * call-seq: + * include?(node) + * + * Returns true if any member of node set equals +node+. + */ +static VALUE +include_eh(VALUE rb_self, VALUE rb_node) +{ + xmlNodeSetPtr c_self; + xmlNodePtr node; + + Check_Node_Set_Node_Type(rb_node); + + TypedData_Get_Struct(rb_self, xmlNodeSet, &xml_node_set_type, c_self); + Noko_Node_Get_Struct(rb_node, xmlNode, node); + + return (xmlXPathNodeSetContains(c_self, node) ? Qtrue : Qfalse); +} + + +/* + * call-seq: + * |(node_set) + * + * Returns a new set built by merging the set and the elements of the given + * set. + */ +static VALUE +rb_xml_node_set_union(VALUE rb_self, VALUE rb_other) +{ + xmlNodeSetPtr c_self, c_other; + xmlNodeSetPtr c_new_node_set; + + if (!rb_obj_is_kind_of(rb_other, cNokogiriXmlNodeSet)) { + rb_raise(rb_eArgError, "node_set must be a Nokogiri::XML::NodeSet"); + } + + TypedData_Get_Struct(rb_self, xmlNodeSet, &xml_node_set_type, c_self); + TypedData_Get_Struct(rb_other, xmlNodeSet, &xml_node_set_type, c_other); + + c_new_node_set = xmlXPathNodeSetMerge(NULL, c_self); + c_new_node_set = xmlXPathNodeSetMerge(c_new_node_set, c_other); + + return noko_xml_node_set_wrap(c_new_node_set, rb_iv_get(rb_self, "@document")); +} + +/* + * call-seq: + * -(node_set) + * + * Difference - returns a new NodeSet that is a copy of this NodeSet, removing + * each item that also appears in +node_set+ + */ +static VALUE +minus(VALUE rb_self, VALUE rb_other) +{ + xmlNodeSetPtr c_self, c_other; + xmlNodeSetPtr new; + int j ; + + if (!rb_obj_is_kind_of(rb_other, cNokogiriXmlNodeSet)) { + rb_raise(rb_eArgError, "node_set must be a Nokogiri::XML::NodeSet"); + } + + TypedData_Get_Struct(rb_self, xmlNodeSet, &xml_node_set_type, c_self); + TypedData_Get_Struct(rb_other, xmlNodeSet, &xml_node_set_type, c_other); + + new = xmlXPathNodeSetMerge(NULL, c_self); + for (j = 0 ; j < c_other->nodeNr ; ++j) { + xpath_node_set_del(new, c_other->nodeTab[j]); + } + + return noko_xml_node_set_wrap(new, rb_iv_get(rb_self, "@document")); +} + + +static VALUE +index_at(VALUE rb_self, long offset) +{ + xmlNodeSetPtr c_self; + + TypedData_Get_Struct(rb_self, xmlNodeSet, &xml_node_set_type, c_self); + + if (offset >= c_self->nodeNr || abs((int)offset) > c_self->nodeNr) { + return Qnil; + } + + if (offset < 0) { offset += c_self->nodeNr ; } + + return noko_xml_node_wrap_node_set_result(c_self->nodeTab[offset], rb_self); +} + +static VALUE +subseq(VALUE rb_self, long beg, long len) +{ + long j; + xmlNodeSetPtr c_self; + xmlNodeSetPtr new_set ; + + TypedData_Get_Struct(rb_self, xmlNodeSet, &xml_node_set_type, c_self); + + if (beg > c_self->nodeNr) { return Qnil ; } + if (beg < 0 || len < 0) { return Qnil ; } + + if ((beg + len) > c_self->nodeNr) { + len = c_self->nodeNr - beg ; + } + + new_set = xmlXPathNodeSetCreate(NULL); + for (j = beg ; j < beg + len ; ++j) { + xmlXPathNodeSetAddUnique(new_set, c_self->nodeTab[j]); + } + return noko_xml_node_set_wrap(new_set, rb_iv_get(rb_self, "@document")); +} + +/* + * call-seq: + * [index] -> Node or nil + * [start, length] -> NodeSet or nil + * [range] -> NodeSet or nil + * slice(index) -> Node or nil + * slice(start, length) -> NodeSet or nil + * slice(range) -> NodeSet or nil + * + * Element reference - returns the node at +index+, or returns a NodeSet + * containing nodes starting at +start+ and continuing for +length+ elements, or + * returns a NodeSet containing nodes specified by +range+. Negative +indices+ + * count backward from the end of the +node_set+ (-1 is the last node). Returns + * nil if the +index+ (or +start+) are out of range. + */ +static VALUE +slice(int argc, VALUE *argv, VALUE rb_self) +{ + VALUE arg ; + long beg, len ; + xmlNodeSetPtr c_self; + + TypedData_Get_Struct(rb_self, xmlNodeSet, &xml_node_set_type, c_self); + + if (argc == 2) { + beg = NUM2LONG(argv[0]); + len = NUM2LONG(argv[1]); + if (beg < 0) { + beg += c_self->nodeNr ; + } + return subseq(rb_self, beg, len); + } + + if (argc != 1) { + rb_scan_args(argc, argv, "11", NULL, NULL); + } + arg = argv[0]; + + if (FIXNUM_P(arg)) { + return index_at(rb_self, FIX2LONG(arg)); + } + + /* if arg is Range */ + switch (rb_range_beg_len(arg, &beg, &len, (long)c_self->nodeNr, 0)) { + case Qfalse: + break; + case Qnil: + return Qnil; + default: + return subseq(rb_self, beg, len); + } + + return index_at(rb_self, NUM2LONG(arg)); +} + + +/* + * call-seq: + * to_a + * + * Return this list as an Array + */ +static VALUE +to_array(VALUE rb_self) +{ + xmlNodeSetPtr c_self ; + VALUE list; + int i; + + TypedData_Get_Struct(rb_self, xmlNodeSet, &xml_node_set_type, c_self); + + list = rb_ary_new2(c_self->nodeNr); + for (i = 0; i < c_self->nodeNr; i++) { + VALUE elt = noko_xml_node_wrap_node_set_result(c_self->nodeTab[i], rb_self); + rb_ary_push(list, elt); + } + + return list; +} + +/* + * call-seq: + * unlink + * + * Unlink this NodeSet and all Node objects it contains from their current context. + */ +static VALUE +unlink_nodeset(VALUE rb_self) +{ + xmlNodeSetPtr c_self; + int j, nodeNr ; + + TypedData_Get_Struct(rb_self, xmlNodeSet, &xml_node_set_type, c_self); + + nodeNr = c_self->nodeNr ; + for (j = 0 ; j < nodeNr ; j++) { + if (! NOKOGIRI_NAMESPACE_EH(c_self->nodeTab[j])) { + VALUE node ; + xmlNodePtr node_ptr; + node = noko_xml_node_wrap(Qnil, c_self->nodeTab[j]); + rb_funcall(node, rb_intern("unlink"), 0); /* modifies the C struct out from under the object */ + Noko_Node_Get_Struct(node, xmlNode, node_ptr); + c_self->nodeTab[j] = node_ptr ; + } + } + return rb_self ; +} + + +VALUE +noko_xml_node_set_wrap(xmlNodeSetPtr c_node_set, VALUE document) +{ + int j; + VALUE rb_node_set ; + + if (c_node_set == NULL) { + rb_node_set = xml_node_set_allocate(cNokogiriXmlNodeSet); + } else { + rb_node_set = TypedData_Wrap_Struct(cNokogiriXmlNodeSet, &xml_node_set_type, c_node_set); + } + + if (!NIL_P(document)) { + rb_iv_set(rb_node_set, "@document", document); + rb_funcall(document, decorate, 1, rb_node_set); + } + + if (c_node_set) { + /* create ruby objects for all the results, so they'll be marked during the GC mark phase */ + for (j = 0 ; j < c_node_set->nodeNr ; j++) { + noko_xml_node_wrap_node_set_result(c_node_set->nodeTab[j], rb_node_set); + } + } + + return rb_node_set ; +} + + +VALUE +noko_xml_node_wrap_node_set_result(xmlNodePtr node, VALUE node_set) +{ + if (NOKOGIRI_NAMESPACE_EH(node)) { + return noko_xml_namespace_wrap_xpath_copy((xmlNsPtr)node); + } else { + return noko_xml_node_wrap(Qnil, node); + } +} + + +xmlNodeSetPtr +noko_xml_node_set_unwrap(VALUE rb_node_set) +{ + xmlNodeSetPtr c_node_set; + TypedData_Get_Struct(rb_node_set, xmlNodeSet, &xml_node_set_type, c_node_set); + return c_node_set; +} + + +void +noko_init_xml_node_set(void) +{ + cNokogiriXmlNodeSet = rb_define_class_under(mNokogiriXml, "NodeSet", rb_cObject); + + rb_define_alloc_func(cNokogiriXmlNodeSet, xml_node_set_allocate); + + rb_define_method(cNokogiriXmlNodeSet, "&", intersection, 1); + rb_define_method(cNokogiriXmlNodeSet, "-", minus, 1); + rb_define_method(cNokogiriXmlNodeSet, "[]", slice, -1); + rb_define_method(cNokogiriXmlNodeSet, "delete", delete, 1); + rb_define_method(cNokogiriXmlNodeSet, "include?", include_eh, 1); + rb_define_method(cNokogiriXmlNodeSet, "length", length, 0); + rb_define_method(cNokogiriXmlNodeSet, "push", push, 1); + rb_define_method(cNokogiriXmlNodeSet, "slice", slice, -1); + rb_define_method(cNokogiriXmlNodeSet, "to_a", to_array, 0); + rb_define_method(cNokogiriXmlNodeSet, "unlink", unlink_nodeset, 0); + rb_define_method(cNokogiriXmlNodeSet, "|", rb_xml_node_set_union, 1); + + rb_define_private_method(cNokogiriXmlNodeSet, "initialize_copy", rb_xml_node_set_initialize_copy, 1); + + decorate = rb_intern("decorate"); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_processing_instruction.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_processing_instruction.c new file mode 100644 index 0000000..6bcf15f --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_processing_instruction.c @@ -0,0 +1,54 @@ +#include + +VALUE cNokogiriXmlProcessingInstruction; + +/* + * call-seq: + * new(document, name, content) + * + * Create a new ProcessingInstruction element on the +document+ with +name+ + * and +content+ + */ +static VALUE +new (int argc, VALUE *argv, VALUE klass) +{ + xmlDocPtr xml_doc; + xmlNodePtr node; + VALUE document; + VALUE name; + VALUE content; + VALUE rest; + VALUE rb_node; + + rb_scan_args(argc, argv, "3*", &document, &name, &content, &rest); + + xml_doc = noko_xml_document_unwrap(document); + + node = xmlNewDocPI( + xml_doc, + (const xmlChar *)StringValueCStr(name), + (const xmlChar *)StringValueCStr(content) + ); + + noko_xml_document_pin_node(node); + + rb_node = noko_xml_node_wrap(klass, node); + rb_obj_call_init(rb_node, argc, argv); + + if (rb_block_given_p()) { rb_yield(rb_node); } + + return rb_node; +} + +void +noko_init_xml_processing_instruction(void) +{ + assert(cNokogiriXmlNode); + /* + * ProcessingInstruction represents a ProcessingInstruction node in an xml + * document. + */ + cNokogiriXmlProcessingInstruction = rb_define_class_under(mNokogiriXml, "ProcessingInstruction", cNokogiriXmlNode); + + rb_define_singleton_method(cNokogiriXmlProcessingInstruction, "new", new, -1); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_reader.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_reader.c new file mode 100644 index 0000000..aa85749 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_reader.c @@ -0,0 +1,777 @@ +#include + +VALUE cNokogiriXmlReader; + +static void +xml_reader_deallocate(void *data) +{ + // free the document separately because we _may_ have triggered preservation by calling + // xmlTextReaderCurrentDoc during a read_more. + xmlTextReaderPtr reader = data; + xmlDocPtr doc = xmlTextReaderCurrentDoc(reader); + xmlFreeTextReader(reader); + if (doc) { + xmlFreeDoc(doc); + } +} + +static const rb_data_type_t xml_text_reader_type = { + .wrap_struct_name = "xmlTextReader", + .function = { + .dfree = xml_reader_deallocate, + }, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static int +has_attributes(xmlTextReaderPtr reader) +{ + /* + * this implementation of xmlTextReaderHasAttributes explicitly includes + * namespaces and properties, because some earlier versions ignore + * namespaces. + */ + xmlNodePtr node ; + node = xmlTextReaderCurrentNode(reader); + if (node == NULL) { + return (0); + } + + if ((node->type == XML_ELEMENT_NODE) && + ((node->properties != NULL) || (node->nsDef != NULL))) { + return (1); + } + return (0); +} + +// TODO: merge this function into the `namespaces` method implementation +static void +Nokogiri_xml_node_namespaces(xmlNodePtr node, VALUE attr_hash) +{ + xmlNsPtr ns; + VALUE key; + + if (node->type != XML_ELEMENT_NODE) { return ; } + + ns = node->nsDef; + while (ns != NULL) { + + key = rb_enc_str_new_cstr(XMLNS_PREFIX, rb_utf8_encoding()); + if (ns->prefix) { + rb_str_cat_cstr(key, ":"); + rb_str_cat_cstr(key, (const char *)ns->prefix); + } + + key = rb_str_conv_enc(key, rb_utf8_encoding(), rb_default_internal_encoding()); + rb_hash_aset(attr_hash, + key, + (ns->href ? NOKOGIRI_STR_NEW2(ns->href) : Qnil) + ); + ns = ns->next ; + } +} + + +/* + * call-seq: + * default? + * + * Was an attribute generated from the default value in the DTD or schema? + */ +static VALUE +default_eh(VALUE self) +{ + xmlTextReaderPtr reader; + int eh; + + TypedData_Get_Struct(self, xmlTextReader, &xml_text_reader_type, reader); + eh = xmlTextReaderIsDefault(reader); + if (eh == 0) { return Qfalse; } + if (eh == 1) { return Qtrue; } + + return Qnil; +} + +/* + * call-seq: + * value? + * + * Does this node have a text value? + */ +static VALUE +value_eh(VALUE self) +{ + xmlTextReaderPtr reader; + int eh; + + TypedData_Get_Struct(self, xmlTextReader, &xml_text_reader_type, reader); + eh = xmlTextReaderHasValue(reader); + if (eh == 0) { return Qfalse; } + if (eh == 1) { return Qtrue; } + + return Qnil; +} + +/* + * call-seq: + * attributes? + * + * Does this node have attributes? + */ +static VALUE +attributes_eh(VALUE self) +{ + xmlTextReaderPtr reader; + int eh; + + TypedData_Get_Struct(self, xmlTextReader, &xml_text_reader_type, reader); + eh = has_attributes(reader); + if (eh == 0) { return Qfalse; } + if (eh == 1) { return Qtrue; } + + return Qnil; +} + +/* + * call-seq: + * namespaces + * + * Get a hash of namespaces for this Node + */ +static VALUE +rb_xml_reader_namespaces(VALUE rb_reader) +{ + VALUE rb_namespaces = rb_hash_new() ; + xmlTextReaderPtr c_reader; + xmlNodePtr c_node; + VALUE rb_errors; + + TypedData_Get_Struct(rb_reader, xmlTextReader, &xml_text_reader_type, c_reader); + + if (! has_attributes(c_reader)) { + return rb_namespaces ; + } + + rb_errors = rb_funcall(rb_reader, rb_intern("errors"), 0); + + xmlSetStructuredErrorFunc((void *)rb_errors, noko__error_array_pusher); + c_node = xmlTextReaderExpand(c_reader); + xmlSetStructuredErrorFunc(NULL, NULL); + + if (c_node == NULL) { + if (RARRAY_LEN(rb_errors) > 0) { + VALUE rb_error = rb_ary_entry(rb_errors, 0); + VALUE exception_message = rb_funcall(rb_error, rb_intern("to_s"), 0); + rb_exc_raise(rb_class_new_instance(1, &exception_message, cNokogiriXmlSyntaxError)); + } + return Qnil; + } + + Nokogiri_xml_node_namespaces(c_node, rb_namespaces); + + return rb_namespaces ; +} + +/* + :call-seq: attribute_hash() → Hash + + Get the attributes of the current node as a Hash of names and values. + + See related: #attributes and #namespaces + */ +static VALUE +rb_xml_reader_attribute_hash(VALUE rb_reader) +{ + VALUE rb_attributes = rb_hash_new(); + xmlTextReaderPtr c_reader; + xmlNodePtr c_node; + xmlAttrPtr c_property; + VALUE rb_errors; + + TypedData_Get_Struct(rb_reader, xmlTextReader, &xml_text_reader_type, c_reader); + + if (!has_attributes(c_reader)) { + return rb_attributes; + } + + rb_errors = rb_funcall(rb_reader, rb_intern("errors"), 0); + + xmlSetStructuredErrorFunc((void *)rb_errors, noko__error_array_pusher); + c_node = xmlTextReaderExpand(c_reader); + xmlSetStructuredErrorFunc(NULL, NULL); + + if (c_node == NULL) { + if (RARRAY_LEN(rb_errors) > 0) { + VALUE rb_error = rb_ary_entry(rb_errors, 0); + VALUE exception_message = rb_funcall(rb_error, rb_intern("to_s"), 0); + rb_exc_raise(rb_class_new_instance(1, &exception_message, cNokogiriXmlSyntaxError)); + } + return Qnil; + } + + c_property = c_node->properties; + while (c_property != NULL) { + VALUE rb_name = NOKOGIRI_STR_NEW2(c_property->name); + VALUE rb_value = Qnil; + xmlChar *c_value = xmlNodeGetContent((xmlNode *)c_property); + + if (c_value) { + rb_value = NOKOGIRI_STR_NEW2(c_value); + xmlFree(c_value); + } + + rb_hash_aset(rb_attributes, rb_name, rb_value); + + c_property = c_property->next; + } + + return rb_attributes; +} + +/* + * call-seq: + * attribute_at(index) + * + * Get the value of attribute at +index+ + */ +static VALUE +attribute_at(VALUE self, VALUE index) +{ + xmlTextReaderPtr reader; + xmlChar *value; + VALUE rb_value; + + TypedData_Get_Struct(self, xmlTextReader, &xml_text_reader_type, reader); + + if (NIL_P(index)) { return Qnil; } + index = rb_Integer(index); + + value = xmlTextReaderGetAttributeNo( + reader, + (int)NUM2INT(index) + ); + if (value == NULL) { return Qnil; } + + rb_value = NOKOGIRI_STR_NEW2(value); + xmlFree(value); + return rb_value; +} + +/* + * call-seq: + * attribute(name) + * + * Get the value of attribute named +name+ + */ +static VALUE +reader_attribute(VALUE self, VALUE name) +{ + xmlTextReaderPtr reader; + xmlChar *value ; + VALUE rb_value; + + TypedData_Get_Struct(self, xmlTextReader, &xml_text_reader_type, reader); + + if (NIL_P(name)) { return Qnil; } + name = StringValue(name) ; + + value = xmlTextReaderGetAttribute(reader, (xmlChar *)StringValueCStr(name)); + if (value == NULL) { return Qnil; } + + rb_value = NOKOGIRI_STR_NEW2(value); + xmlFree(value); + return rb_value; +} + +/* + * call-seq: + * attribute_count + * + * Get the number of attributes for the current node + */ +static VALUE +attribute_count(VALUE self) +{ + xmlTextReaderPtr reader; + int count; + + TypedData_Get_Struct(self, xmlTextReader, &xml_text_reader_type, reader); + count = xmlTextReaderAttributeCount(reader); + if (count == -1) { return Qnil; } + + return INT2NUM(count); +} + +/* + * call-seq: + * depth + * + * Get the depth of the node + */ +static VALUE +depth(VALUE self) +{ + xmlTextReaderPtr reader; + int depth; + + TypedData_Get_Struct(self, xmlTextReader, &xml_text_reader_type, reader); + depth = xmlTextReaderDepth(reader); + if (depth == -1) { return Qnil; } + + return INT2NUM(depth); +} + +/* + * call-seq: + * xml_version + * + * Get the XML version of the document being read + */ +static VALUE +xml_version(VALUE self) +{ + xmlTextReaderPtr reader; + const char *version; + + TypedData_Get_Struct(self, xmlTextReader, &xml_text_reader_type, reader); + version = (const char *)xmlTextReaderConstXmlVersion(reader); + if (version == NULL) { return Qnil; } + + return NOKOGIRI_STR_NEW2(version); +} + +/* + * call-seq: + * lang + * + * Get the xml:lang scope within which the node resides. + */ +static VALUE +lang(VALUE self) +{ + xmlTextReaderPtr reader; + const char *lang; + + TypedData_Get_Struct(self, xmlTextReader, &xml_text_reader_type, reader); + lang = (const char *)xmlTextReaderConstXmlLang(reader); + if (lang == NULL) { return Qnil; } + + return NOKOGIRI_STR_NEW2(lang); +} + +/* + * call-seq: + * value + * + * Get the text value of the node if present. Returns a utf-8 encoded string. + */ +static VALUE +value(VALUE self) +{ + xmlTextReaderPtr reader; + const char *value; + + TypedData_Get_Struct(self, xmlTextReader, &xml_text_reader_type, reader); + value = (const char *)xmlTextReaderConstValue(reader); + if (value == NULL) { return Qnil; } + + return NOKOGIRI_STR_NEW2(value); +} + +/* + * call-seq: + * prefix + * + * Get the shorthand reference to the namespace associated with the node. + */ +static VALUE +prefix(VALUE self) +{ + xmlTextReaderPtr reader; + const char *prefix; + + TypedData_Get_Struct(self, xmlTextReader, &xml_text_reader_type, reader); + prefix = (const char *)xmlTextReaderConstPrefix(reader); + if (prefix == NULL) { return Qnil; } + + return NOKOGIRI_STR_NEW2(prefix); +} + +/* + * call-seq: + * namespace_uri + * + * Get the URI defining the namespace associated with the node + */ +static VALUE +namespace_uri(VALUE self) +{ + xmlTextReaderPtr reader; + const char *uri; + + TypedData_Get_Struct(self, xmlTextReader, &xml_text_reader_type, reader); + uri = (const char *)xmlTextReaderConstNamespaceUri(reader); + if (uri == NULL) { return Qnil; } + + return NOKOGIRI_STR_NEW2(uri); +} + +/* + * call-seq: + * local_name + * + * Get the local name of the node + */ +static VALUE +local_name(VALUE self) +{ + xmlTextReaderPtr reader; + const char *name; + + TypedData_Get_Struct(self, xmlTextReader, &xml_text_reader_type, reader); + name = (const char *)xmlTextReaderConstLocalName(reader); + if (name == NULL) { return Qnil; } + + return NOKOGIRI_STR_NEW2(name); +} + +/* + * call-seq: + * name + * + * Get the name of the node. Returns a utf-8 encoded string. + */ +static VALUE +name(VALUE self) +{ + xmlTextReaderPtr reader; + const char *name; + + TypedData_Get_Struct(self, xmlTextReader, &xml_text_reader_type, reader); + name = (const char *)xmlTextReaderConstName(reader); + if (name == NULL) { return Qnil; } + + return NOKOGIRI_STR_NEW2(name); +} + +/* + * call-seq: + * base_uri + * + * Get the xml:base of the node + */ +static VALUE +rb_xml_reader_base_uri(VALUE rb_reader) +{ + VALUE rb_base_uri; + xmlTextReaderPtr c_reader; + xmlChar *c_base_uri; + + TypedData_Get_Struct(rb_reader, xmlTextReader, &xml_text_reader_type, c_reader); + + c_base_uri = xmlTextReaderBaseUri(c_reader); + if (c_base_uri == NULL) { + return Qnil; + } + + rb_base_uri = NOKOGIRI_STR_NEW2(c_base_uri); + xmlFree(c_base_uri); + + return rb_base_uri; +} + +/* + * call-seq: + * state + * + * Get the state of the reader + */ +static VALUE +state(VALUE self) +{ + xmlTextReaderPtr reader; + TypedData_Get_Struct(self, xmlTextReader, &xml_text_reader_type, reader); + return INT2NUM(xmlTextReaderReadState(reader)); +} + +/* + * call-seq: + * node_type + * + * Get the type of readers current node + */ +static VALUE +node_type(VALUE self) +{ + xmlTextReaderPtr reader; + TypedData_Get_Struct(self, xmlTextReader, &xml_text_reader_type, reader); + return INT2NUM(xmlTextReaderNodeType(reader)); +} + +/* + * call-seq: + * read + * + * Move the Reader forward through the XML document. + */ +static VALUE +read_more(VALUE rb_reader) +{ + xmlTextReaderPtr c_reader; + libxmlStructuredErrorHandlerState handler_state; + + TypedData_Get_Struct(rb_reader, xmlTextReader, &xml_text_reader_type, c_reader); + + VALUE rb_errors = rb_funcall(rb_reader, rb_intern("errors"), 0); + noko__structured_error_func_save_and_set(&handler_state, (void *)rb_errors, noko__error_array_pusher); + + int status = xmlTextReaderRead(c_reader); + + noko__structured_error_func_restore(&handler_state); + + xmlDocPtr c_document = xmlTextReaderCurrentDoc(c_reader); + if (c_document && c_document->encoding == NULL) { + VALUE constructor_encoding = rb_iv_get(rb_reader, "@encoding"); + if (RTEST(constructor_encoding)) { + c_document->encoding = xmlStrdup(BAD_CAST StringValueCStr(constructor_encoding)); + } else { + rb_iv_set(rb_reader, "@encoding", NOKOGIRI_STR_NEW2("UTF-8")); + c_document->encoding = xmlStrdup(BAD_CAST "UTF-8"); + } + } + + if (status == 1) { return rb_reader; } + if (status == 0) { return Qnil; } + + /* if we're here, there was an error */ + VALUE exception = rb_funcall(cNokogiriXmlSyntaxError, rb_intern("aggregate"), 1, rb_errors); + if (RB_TEST(exception)) { + rb_exc_raise(exception); + } else { + rb_raise(rb_eRuntimeError, "Error pulling: %d", status); + } +} + +/* + * call-seq: + * inner_xml + * + * Read the contents of the current node, including child nodes and markup. + * Returns a utf-8 encoded string. + */ +static VALUE +inner_xml(VALUE self) +{ + xmlTextReaderPtr reader; + xmlChar *value; + VALUE str; + + TypedData_Get_Struct(self, xmlTextReader, &xml_text_reader_type, reader); + + value = xmlTextReaderReadInnerXml(reader); + + str = Qnil; + if (value) { + str = NOKOGIRI_STR_NEW2((char *)value); + xmlFree(value); + } + + return str; +} + +/* + * call-seq: + * outer_xml + * + * Read the current node and its contents, including child nodes and markup. + * Returns a utf-8 encoded string. + */ +static VALUE +outer_xml(VALUE self) +{ + xmlTextReaderPtr reader; + xmlChar *value; + VALUE str = Qnil; + + TypedData_Get_Struct(self, xmlTextReader, &xml_text_reader_type, reader); + + value = xmlTextReaderReadOuterXml(reader); + + if (value) { + str = NOKOGIRI_STR_NEW2((char *)value); + xmlFree(value); + } + return str; +} + +/* + * call-seq: + * from_memory(string, url = nil, encoding = nil, options = 0) + * + * Create a new Reader to parse a String. + */ +static VALUE +from_memory(int argc, VALUE *argv, VALUE klass) +{ + /* TODO: deprecate this method, since Reader.new can handle both memory and IO. It can then + * become private. */ + VALUE rb_buffer, rb_url, encoding, rb_options; + xmlTextReaderPtr reader; + const char *c_url = NULL; + const char *c_encoding = NULL; + int c_options = 0; + VALUE rb_reader, args[3]; + + rb_scan_args(argc, argv, "13", &rb_buffer, &rb_url, &encoding, &rb_options); + + if (!RTEST(rb_buffer)) { rb_raise(rb_eArgError, "string cannot be nil"); } + if (RTEST(rb_url)) { c_url = StringValueCStr(rb_url); } + if (RTEST(encoding)) { c_encoding = StringValueCStr(encoding); } + if (RTEST(rb_options)) { c_options = (int)NUM2INT(rb_options); } + + reader = xmlReaderForMemory( + StringValuePtr(rb_buffer), + (int)RSTRING_LEN(rb_buffer), + c_url, + c_encoding, + c_options + ); + + if (reader == NULL) { + xmlFreeTextReader(reader); + rb_raise(rb_eRuntimeError, "couldn't create a parser"); + } + + rb_reader = TypedData_Wrap_Struct(klass, &xml_text_reader_type, reader); + args[0] = rb_buffer; + args[1] = rb_url; + args[2] = encoding; + rb_obj_call_init(rb_reader, 3, args); + + return rb_reader; +} + +/* + * call-seq: + * from_io(io, url = nil, encoding = nil, options = 0) + * + * Create a new Reader to parse an IO stream. + */ +static VALUE +from_io(int argc, VALUE *argv, VALUE klass) +{ + /* TODO: deprecate this method, since Reader.new can handle both memory and IO. It can then + * become private. */ + VALUE rb_io, rb_url, encoding, rb_options; + xmlTextReaderPtr reader; + const char *c_url = NULL; + const char *c_encoding = NULL; + int c_options = 0; + VALUE rb_reader, args[3]; + + rb_scan_args(argc, argv, "13", &rb_io, &rb_url, &encoding, &rb_options); + + if (!RTEST(rb_io)) { rb_raise(rb_eArgError, "io cannot be nil"); } + if (RTEST(rb_url)) { c_url = StringValueCStr(rb_url); } + if (RTEST(encoding)) { c_encoding = StringValueCStr(encoding); } + if (RTEST(rb_options)) { c_options = (int)NUM2INT(rb_options); } + + reader = xmlReaderForIO( + (xmlInputReadCallback)noko_io_read, + (xmlInputCloseCallback)noko_io_close, + (void *)rb_io, + c_url, + c_encoding, + c_options + ); + + if (reader == NULL) { + xmlFreeTextReader(reader); + rb_raise(rb_eRuntimeError, "couldn't create a parser"); + } + + rb_reader = TypedData_Wrap_Struct(klass, &xml_text_reader_type, reader); + args[0] = rb_io; + args[1] = rb_url; + args[2] = encoding; + rb_obj_call_init(rb_reader, 3, args); + + return rb_reader; +} + +/* + * call-seq: + * reader.empty_element? # => true or false + * + * Returns true if the current node is empty, otherwise false. + */ +static VALUE +empty_element_p(VALUE self) +{ + xmlTextReaderPtr reader; + + TypedData_Get_Struct(self, xmlTextReader, &xml_text_reader_type, reader); + + if (xmlTextReaderIsEmptyElement(reader)) { + return Qtrue; + } + + return Qfalse; +} + +static VALUE +rb_xml_reader_encoding(VALUE rb_reader) +{ + xmlTextReaderPtr c_reader; + const char *parser_encoding; + VALUE constructor_encoding; + + TypedData_Get_Struct(rb_reader, xmlTextReader, &xml_text_reader_type, c_reader); + parser_encoding = (const char *)xmlTextReaderConstEncoding(c_reader); + if (parser_encoding) { + return NOKOGIRI_STR_NEW2(parser_encoding); + } + + constructor_encoding = rb_iv_get(rb_reader, "@encoding"); + if (RTEST(constructor_encoding)) { + return constructor_encoding; + } + + return Qnil; +} + +void +noko_init_xml_reader(void) +{ + cNokogiriXmlReader = rb_define_class_under(mNokogiriXml, "Reader", rb_cObject); + + rb_undef_alloc_func(cNokogiriXmlReader); + + rb_define_singleton_method(cNokogiriXmlReader, "from_memory", from_memory, -1); + rb_define_singleton_method(cNokogiriXmlReader, "from_io", from_io, -1); + + rb_define_method(cNokogiriXmlReader, "attribute", reader_attribute, 1); + rb_define_method(cNokogiriXmlReader, "attribute_at", attribute_at, 1); + rb_define_method(cNokogiriXmlReader, "attribute_count", attribute_count, 0); + rb_define_method(cNokogiriXmlReader, "attribute_hash", rb_xml_reader_attribute_hash, 0); + rb_define_method(cNokogiriXmlReader, "attributes?", attributes_eh, 0); + rb_define_method(cNokogiriXmlReader, "base_uri", rb_xml_reader_base_uri, 0); + rb_define_method(cNokogiriXmlReader, "default?", default_eh, 0); + rb_define_method(cNokogiriXmlReader, "depth", depth, 0); + rb_define_method(cNokogiriXmlReader, "empty_element?", empty_element_p, 0); + rb_define_method(cNokogiriXmlReader, "encoding", rb_xml_reader_encoding, 0); + rb_define_method(cNokogiriXmlReader, "inner_xml", inner_xml, 0); + rb_define_method(cNokogiriXmlReader, "lang", lang, 0); + rb_define_method(cNokogiriXmlReader, "local_name", local_name, 0); + rb_define_method(cNokogiriXmlReader, "name", name, 0); + rb_define_method(cNokogiriXmlReader, "namespace_uri", namespace_uri, 0); + rb_define_method(cNokogiriXmlReader, "namespaces", rb_xml_reader_namespaces, 0); + rb_define_method(cNokogiriXmlReader, "node_type", node_type, 0); + rb_define_method(cNokogiriXmlReader, "outer_xml", outer_xml, 0); + rb_define_method(cNokogiriXmlReader, "prefix", prefix, 0); + rb_define_method(cNokogiriXmlReader, "read", read_more, 0); + rb_define_method(cNokogiriXmlReader, "state", state, 0); + rb_define_method(cNokogiriXmlReader, "value", value, 0); + rb_define_method(cNokogiriXmlReader, "value?", value_eh, 0); + rb_define_method(cNokogiriXmlReader, "xml_version", xml_version, 0); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_relax_ng.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_relax_ng.c new file mode 100644 index 0000000..07b0567 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_relax_ng.c @@ -0,0 +1,149 @@ +#include + +VALUE cNokogiriXmlRelaxNG; + +static void +_noko_xml_relax_ng_deallocate(void *data) +{ + xmlRelaxNGPtr schema = data; + xmlRelaxNGFree(schema); +} + +static const rb_data_type_t xml_relax_ng_type = { + .wrap_struct_name = "xmlRelaxNG", + .function = { + .dfree = _noko_xml_relax_ng_deallocate, + }, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static VALUE +noko_xml_relax_ng__validate_document(VALUE self, VALUE document) +{ + xmlDocPtr doc; + xmlRelaxNGPtr schema; + VALUE errors; + xmlRelaxNGValidCtxtPtr valid_ctxt; + + TypedData_Get_Struct(self, xmlRelaxNG, &xml_relax_ng_type, schema); + doc = noko_xml_document_unwrap(document); + + errors = rb_ary_new(); + + valid_ctxt = xmlRelaxNGNewValidCtxt(schema); + + if (NULL == valid_ctxt) { + /* we have a problem */ + rb_raise(rb_eRuntimeError, "Could not create a validation context"); + } + + xmlRelaxNGSetValidStructuredErrors( + valid_ctxt, + noko__error_array_pusher, + (void *)errors + ); + + xmlRelaxNGValidateDoc(valid_ctxt, doc); + + xmlRelaxNGFreeValidCtxt(valid_ctxt); + + return errors; +} + +static VALUE +_noko_xml_relax_ng_parse_schema( + VALUE rb_class, + xmlRelaxNGParserCtxtPtr c_parser_context, + VALUE rb_parse_options +) +{ + VALUE rb_errors; + VALUE rb_schema; + xmlRelaxNGPtr c_schema; + libxmlStructuredErrorHandlerState handler_state; + + if (NIL_P(rb_parse_options)) { + rb_parse_options = rb_const_get_at( + rb_const_get_at(mNokogiriXml, rb_intern("ParseOptions")), + rb_intern("DEFAULT_SCHEMA") + ); + } + + rb_errors = rb_ary_new(); + + noko__structured_error_func_save_and_set(&handler_state, (void *)rb_errors, noko__error_array_pusher); + xmlRelaxNGSetParserStructuredErrors( + c_parser_context, + noko__error_array_pusher, + (void *)rb_errors + ); + + c_schema = xmlRelaxNGParse(c_parser_context); + + xmlRelaxNGFreeParserCtxt(c_parser_context); + noko__structured_error_func_restore(&handler_state); + + if (NULL == c_schema) { + VALUE exception = rb_funcall(cNokogiriXmlSyntaxError, rb_intern("aggregate"), 1, rb_errors); + + if (RB_TEST(exception)) { + rb_exc_raise(exception); + } else { + rb_raise(rb_eRuntimeError, "Could not parse document"); + } + } + + rb_schema = TypedData_Wrap_Struct(rb_class, &xml_relax_ng_type, c_schema); + rb_iv_set(rb_schema, "@errors", rb_errors); + rb_iv_set(rb_schema, "@parse_options", rb_parse_options); + + return rb_schema; +} + +/* + * :call-seq: + * from_document(document) → Nokogiri::XML::RelaxNG + * from_document(document, parse_options) → Nokogiri::XML::RelaxNG + * + * Parse a RELAX NG schema definition from a Document to create a new Nokogiri::XML::RelaxNG. + * + * [Parameters] + * - +document+ (XML::Document) A document containing the RELAX NG schema definition + * - +parse_options+ (Nokogiri::XML::ParseOptions) + * Defaults to ParseOptions::DEFAULT_SCHEMA ⚠ Unused + * + * [Returns] Nokogiri::XML::RelaxNG + * + * ⚠ +parse_options+ is currently unused by this method and is present only as a placeholder for + * future functionality. + */ +static VALUE +noko_xml_relax_ng_s_from_document(int argc, VALUE *argv, VALUE rb_class) +{ + /* TODO: deprecate this method and put file-or-string logic into .new so that becomes the + * preferred entry point, and this can become a private method */ + VALUE rb_document; + VALUE rb_parse_options; + xmlDocPtr c_document; + xmlRelaxNGParserCtxtPtr c_parser_context; + + rb_scan_args(argc, argv, "11", &rb_document, &rb_parse_options); + + c_document = noko_xml_document_unwrap(rb_document); + c_document = c_document->doc; /* In case someone passes us a node. ugh. */ + + c_parser_context = xmlRelaxNGNewDocParserCtxt(c_document); + + return _noko_xml_relax_ng_parse_schema(rb_class, c_parser_context, rb_parse_options); +} + +void +noko_init_xml_relax_ng(void) +{ + assert(cNokogiriXmlSchema); + cNokogiriXmlRelaxNG = rb_define_class_under(mNokogiriXml, "RelaxNG", cNokogiriXmlSchema); + + rb_define_singleton_method(cNokogiriXmlRelaxNG, "from_document", noko_xml_relax_ng_s_from_document, -1); + + rb_define_private_method(cNokogiriXmlRelaxNG, "validate_document", noko_xml_relax_ng__validate_document, 1); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_sax_parser.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_sax_parser.c new file mode 100644 index 0000000..ec2d2ad --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_sax_parser.c @@ -0,0 +1,403 @@ +#include + +VALUE cNokogiriXmlSaxParser ; + +static ID id_start_document; +static ID id_end_document; +static ID id_start_element; +static ID id_end_element; +static ID id_start_element_namespace; +static ID id_end_element_namespace; +static ID id_comment; +static ID id_characters; +static ID id_xmldecl; +static ID id_error; +static ID id_warning; +static ID id_cdata_block; +static ID id_processing_instruction; +static ID id_reference; + +static size_t +xml_sax_parser_memsize(const void *data) +{ + return sizeof(xmlSAXHandler); +} + +/* Used by Nokogiri::XML::SAX::Parser and Nokogiri::HTML::SAX::Parser */ +static const rb_data_type_t xml_sax_parser_type = { + .wrap_struct_name = "xmlSAXHandler", + .function = { + .dfree = RUBY_TYPED_DEFAULT_FREE, + .dsize = xml_sax_parser_memsize + }, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED +}; + +static void +noko_xml_sax_parser_start_document_callback(void *ctx) +{ + xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr)ctx; + VALUE self = (VALUE)ctxt->_private; + VALUE doc = rb_iv_get(self, "@document"); + + xmlSAX2StartDocument(ctx); + + if (ctxt->standalone != -1) { /* -1 means there was no declaration */ + VALUE encoding = Qnil ; + VALUE standalone = Qnil; + VALUE version; + + if (ctxt->encoding) { + encoding = NOKOGIRI_STR_NEW2(ctxt->encoding) ; + } else if (ctxt->input && ctxt->input->encoding) { // unnecessary after v2.12.0 / gnome/libxml2@ec7be506 + encoding = NOKOGIRI_STR_NEW2(ctxt->input->encoding) ; + } + + version = ctxt->version ? NOKOGIRI_STR_NEW2(ctxt->version) : Qnil; + + /* TODO try using xmlSAX2IsStandalone */ + switch (ctxt->standalone) { + case 0: + standalone = NOKOGIRI_STR_NEW2("no"); + break; + case 1: + standalone = NOKOGIRI_STR_NEW2("yes"); + break; + } + + rb_funcall(doc, id_xmldecl, 3, version, encoding, standalone); + } + + rb_funcall(doc, id_start_document, 0); +} + +static void +noko_xml_sax_parser_end_document_callback(void *ctx) +{ + xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr)ctx; + VALUE self = (VALUE)ctxt->_private; + VALUE doc = rb_iv_get(self, "@document"); + + rb_funcall(doc, id_end_document, 0); +} + +static void +noko_xml_sax_parser_start_element_callback(void *ctx, const xmlChar *name, const xmlChar **atts) +{ + xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr)ctx; + VALUE self = (VALUE)ctxt->_private; + VALUE doc = rb_iv_get(self, "@document"); + + VALUE attributes = rb_ary_new(); + const xmlChar *attr; + int i = 0; + if (atts) { + while ((attr = atts[i]) != NULL) { + const xmlChar *val = atts[i + 1]; + VALUE value = val != NULL ? NOKOGIRI_STR_NEW2(val) : Qnil; + rb_ary_push(attributes, rb_ary_new3(2, NOKOGIRI_STR_NEW2(attr), value)); + i += 2; + } + } + + rb_funcall(doc, + id_start_element, + 2, + NOKOGIRI_STR_NEW2(name), + attributes + ); +} + +static void +noko_xml_sax_parser_end_element_callback(void *ctx, const xmlChar *name) +{ + xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr)ctx; + VALUE self = (VALUE)ctxt->_private; + VALUE doc = rb_iv_get(self, "@document"); + + rb_funcall(doc, id_end_element, 1, NOKOGIRI_STR_NEW2(name)); +} + +static VALUE +xml_sax_parser_marshal_attributes(int attributes_len, const xmlChar **c_attributes) +{ + VALUE rb_array = rb_ary_new2((long)attributes_len); + VALUE cNokogiriXmlSaxParserAttribute; + + cNokogiriXmlSaxParserAttribute = rb_const_get_at(cNokogiriXmlSaxParser, rb_intern("Attribute")); + if (c_attributes) { + /* Each attribute is an array of [localname, prefix, URI, value, end] */ + int i; + for (i = 0; i < attributes_len * 5; i += 5) { + VALUE rb_constructor_args[4], rb_attribute; + + rb_constructor_args[0] = RBSTR_OR_QNIL(c_attributes[i + 0]); /* localname */ + rb_constructor_args[1] = RBSTR_OR_QNIL(c_attributes[i + 1]); /* prefix */ + rb_constructor_args[2] = RBSTR_OR_QNIL(c_attributes[i + 2]); /* URI */ + + /* value */ + rb_constructor_args[3] = NOKOGIRI_STR_NEW((const char *)c_attributes[i + 3], + (c_attributes[i + 4] - c_attributes[i + 3])); + + rb_attribute = rb_class_new_instance(4, rb_constructor_args, cNokogiriXmlSaxParserAttribute); + rb_ary_push(rb_array, rb_attribute); + } + } + + return rb_array; +} + +static void +noko_xml_sax_parser_start_element_ns_callback( + void *ctx, + const xmlChar *localname, + const xmlChar *prefix, + const xmlChar *uri, + int nb_namespaces, + const xmlChar **namespaces, + int nb_attributes, + int nb_defaulted, + const xmlChar **attributes) +{ + xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr)ctx; + VALUE self = (VALUE)ctxt->_private; + VALUE doc = rb_iv_get(self, "@document"); + + VALUE attribute_ary = xml_sax_parser_marshal_attributes(nb_attributes, attributes); + + VALUE ns_list = rb_ary_new2((long)nb_namespaces); + + if (namespaces) { + int i; + for (i = 0; i < nb_namespaces * 2; i += 2) { + rb_ary_push(ns_list, + rb_ary_new3((long)2, + RBSTR_OR_QNIL(namespaces[i + 0]), + RBSTR_OR_QNIL(namespaces[i + 1]) + ) + ); + } + } + + rb_funcall(doc, + id_start_element_namespace, + 5, + NOKOGIRI_STR_NEW2(localname), + attribute_ary, + RBSTR_OR_QNIL(prefix), + RBSTR_OR_QNIL(uri), + ns_list + ); +} + +/** + * end_element_ns was borrowed heavily from libxml-ruby. + */ +static void +noko_xml_sax_parser_end_element_ns_callback( + void *ctx, + const xmlChar *localname, + const xmlChar *prefix, + const xmlChar *uri) +{ + xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr)ctx; + VALUE self = (VALUE)ctxt->_private; + VALUE doc = rb_iv_get(self, "@document"); + + rb_funcall(doc, id_end_element_namespace, 3, + NOKOGIRI_STR_NEW2(localname), + RBSTR_OR_QNIL(prefix), + RBSTR_OR_QNIL(uri) + ); +} + +static void +noko_xml_sax_parser_characters_callback(void *ctx, const xmlChar *ch, int len) +{ + xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr)ctx; + VALUE self = (VALUE)ctxt->_private; + VALUE doc = rb_iv_get(self, "@document"); + + VALUE str = NOKOGIRI_STR_NEW(ch, len); + rb_funcall(doc, id_characters, 1, str); +} + +static void +noko_xml_sax_parser_comment_callback(void *ctx, const xmlChar *value) +{ + xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr)ctx; + VALUE self = (VALUE)ctxt->_private; + VALUE doc = rb_iv_get(self, "@document"); + + VALUE str = NOKOGIRI_STR_NEW2(value); + rb_funcall(doc, id_comment, 1, str); +} + +PRINTFLIKE_DECL(2, 3) +static void +noko_xml_sax_parser_warning_callback(void *ctx, const char *msg, ...) +{ + xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr)ctx; + VALUE self = (VALUE)ctxt->_private; + VALUE doc = rb_iv_get(self, "@document"); + + VALUE rb_message; + +#ifdef TRUFFLERUBY_NOKOGIRI_SYSTEM_LIBRARIES + /* It is not currently possible to pass var args from native + functions to sulong, so we work around the issue here. */ + rb_message = rb_sprintf("warning_func: %s", msg); +#else + va_list args; + va_start(args, msg); + rb_message = rb_vsprintf(msg, args); + va_end(args); +#endif + + rb_funcall(doc, id_warning, 1, rb_message); +} + +PRINTFLIKE_DECL(2, 3) +static void +noko_xml_sax_parser_error_callback(void *ctx, const char *msg, ...) +{ + xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr)ctx; + VALUE self = (VALUE)ctxt->_private; + VALUE doc = rb_iv_get(self, "@document"); + + VALUE rb_message; + +#ifdef TRUFFLERUBY_NOKOGIRI_SYSTEM_LIBRARIES + /* It is not currently possible to pass var args from native + functions to sulong, so we work around the issue here. */ + rb_message = rb_sprintf("error_func: %s", msg); +#else + va_list args; + va_start(args, msg); + rb_message = rb_vsprintf(msg, args); + va_end(args); +#endif + + rb_funcall(doc, id_error, 1, rb_message); +} + +static void +noko_xml_sax_parser_cdata_block_callback(void *ctx, const xmlChar *value, int len) +{ + xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr)ctx; + VALUE self = (VALUE)ctxt->_private; + VALUE doc = rb_iv_get(self, "@document"); + + VALUE string = NOKOGIRI_STR_NEW(value, len); + rb_funcall(doc, id_cdata_block, 1, string); +} + +static void +noko_xml_sax_parser_processing_instruction_callback(void *ctx, const xmlChar *name, const xmlChar *content) +{ + xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr)ctx; + VALUE self = (VALUE)ctxt->_private; + VALUE doc = rb_iv_get(self, "@document"); + + VALUE rb_content = content ? NOKOGIRI_STR_NEW2(content) : Qnil; + + rb_funcall(doc, + id_processing_instruction, + 2, + NOKOGIRI_STR_NEW2(name), + rb_content + ); +} + +static void +noko_xml_sax_parser_reference_callback(void *ctx, const xmlChar *name) +{ + xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr)ctx; + xmlEntityPtr entity = xmlSAX2GetEntity(ctxt, name); + + VALUE self = (VALUE)ctxt->_private; + VALUE doc = rb_iv_get(self, "@document"); + + if (entity && entity->content) { + rb_funcall(doc, id_reference, 2, NOKOGIRI_STR_NEW2(entity->name), NOKOGIRI_STR_NEW2(entity->content)); + } else { + rb_funcall(doc, id_reference, 2, NOKOGIRI_STR_NEW2(name), Qnil); + } +} + +static VALUE +noko_xml_sax_parser__initialize_native(VALUE self) +{ + xmlSAXHandlerPtr handler = noko_xml_sax_parser_unwrap(self); + + handler->startDocument = noko_xml_sax_parser_start_document_callback; + handler->endDocument = noko_xml_sax_parser_end_document_callback; + handler->startElement = noko_xml_sax_parser_start_element_callback; + handler->endElement = noko_xml_sax_parser_end_element_callback; + handler->startElementNs = noko_xml_sax_parser_start_element_ns_callback; + handler->endElementNs = noko_xml_sax_parser_end_element_ns_callback; + handler->characters = noko_xml_sax_parser_characters_callback; + handler->comment = noko_xml_sax_parser_comment_callback; + handler->warning = noko_xml_sax_parser_warning_callback; + handler->error = noko_xml_sax_parser_error_callback; + handler->cdataBlock = noko_xml_sax_parser_cdata_block_callback; + handler->processingInstruction = noko_xml_sax_parser_processing_instruction_callback; + handler->reference = noko_xml_sax_parser_reference_callback; + + /* use some of libxml2's default callbacks to managed DTDs and entities */ + handler->getEntity = xmlSAX2GetEntity; + handler->internalSubset = xmlSAX2InternalSubset; + handler->externalSubset = xmlSAX2ExternalSubset; + handler->isStandalone = xmlSAX2IsStandalone; + handler->hasInternalSubset = xmlSAX2HasInternalSubset; + handler->hasExternalSubset = xmlSAX2HasExternalSubset; + handler->resolveEntity = xmlSAX2ResolveEntity; + handler->getParameterEntity = xmlSAX2GetParameterEntity; + handler->entityDecl = xmlSAX2EntityDecl; + handler->unparsedEntityDecl = xmlSAX2UnparsedEntityDecl; + + handler->initialized = XML_SAX2_MAGIC; + + return self; +} + +static VALUE +noko_xml_sax_parser_allocate(VALUE klass) +{ + xmlSAXHandlerPtr handler; + return TypedData_Make_Struct(klass, xmlSAXHandler, &xml_sax_parser_type, handler); +} + +xmlSAXHandlerPtr +noko_xml_sax_parser_unwrap(VALUE rb_sax_handler) +{ + xmlSAXHandlerPtr c_sax_handler; + TypedData_Get_Struct(rb_sax_handler, xmlSAXHandler, &xml_sax_parser_type, c_sax_handler); + return c_sax_handler; +} + +void +noko_init_xml_sax_parser(void) +{ + cNokogiriXmlSaxParser = rb_define_class_under(mNokogiriXmlSax, "Parser", rb_cObject); + + rb_define_alloc_func(cNokogiriXmlSaxParser, noko_xml_sax_parser_allocate); + + rb_define_private_method(cNokogiriXmlSaxParser, "initialize_native", + noko_xml_sax_parser__initialize_native, 0); + + id_start_document = rb_intern("start_document"); + id_end_document = rb_intern("end_document"); + id_start_element = rb_intern("start_element"); + id_end_element = rb_intern("end_element"); + id_comment = rb_intern("comment"); + id_characters = rb_intern("characters"); + id_xmldecl = rb_intern("xmldecl"); + id_error = rb_intern("error"); + id_warning = rb_intern("warning"); + id_cdata_block = rb_intern("cdata_block"); + id_start_element_namespace = rb_intern("start_element_namespace"); + id_end_element_namespace = rb_intern("end_element_namespace"); + id_processing_instruction = rb_intern("processing_instruction"); + id_reference = rb_intern("reference"); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_sax_parser_context.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_sax_parser_context.c new file mode 100644 index 0000000..0d2b65b --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_sax_parser_context.c @@ -0,0 +1,396 @@ +#include + +VALUE cNokogiriXmlSaxParserContext ; + +static ID id_read; + +static void +xml_sax_parser_context_type_free(void *data) +{ + xmlParserCtxtPtr ctxt = data; + ctxt->sax = NULL; + if (ctxt->myDoc) { + xmlFreeDoc(ctxt->myDoc); + } + if (ctxt) { + xmlFreeParserCtxt(ctxt); + } +} + +/* + * note that htmlParserCtxtPtr == xmlParserCtxtPtr and xmlFreeParserCtxt() == htmlFreeParserCtxt() + * so we use this type for both XML::SAX::ParserContext and HTML::SAX::ParserContext + */ +static const rb_data_type_t xml_sax_parser_context_type = { + .wrap_struct_name = "xmlParserCtxt", + .function = { + .dfree = xml_sax_parser_context_type_free, + }, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +xmlParserCtxtPtr +noko_xml_sax_parser_context_unwrap(VALUE rb_context) +{ + xmlParserCtxtPtr c_context; + TypedData_Get_Struct(rb_context, xmlParserCtxt, &xml_sax_parser_context_type, c_context); + return c_context; +} + +VALUE +noko_xml_sax_parser_context_wrap(VALUE klass, xmlParserCtxtPtr c_context) +{ + return TypedData_Wrap_Struct(klass, &xml_sax_parser_context_type, c_context); +} + +void +noko_xml_sax_parser_context_set_encoding(xmlParserCtxtPtr c_context, VALUE rb_encoding) +{ + if (!NIL_P(rb_encoding)) { + VALUE rb_encoding_name = rb_funcall(rb_encoding, rb_intern("name"), 0); + + char *encoding_name = StringValueCStr(rb_encoding_name); + if (encoding_name) { + libxmlStructuredErrorHandlerState handler_state; + VALUE rb_errors = rb_ary_new(); + + noko__structured_error_func_save_and_set(&handler_state, (void *)rb_errors, noko__error_array_pusher); + + int result = xmlSwitchEncodingName(c_context, encoding_name); + + noko__structured_error_func_restore(&handler_state); + + if (result != 0) { + xmlFreeParserCtxt(c_context); + + VALUE exception = rb_funcall(cNokogiriXmlSyntaxError, rb_intern("aggregate"), 1, rb_errors); + if (!NIL_P(exception)) { + rb_exc_raise(exception); + } else { + rb_raise(rb_eRuntimeError, "could not set encoding"); + } + } + } + } +} + +/* :nodoc: */ +static VALUE +noko_xml_sax_parser_context_s_native_io(VALUE rb_class, VALUE rb_io, VALUE rb_encoding) +{ + if (!rb_respond_to(rb_io, id_read)) { + rb_raise(rb_eTypeError, "argument expected to respond to :read"); + } + + if (!NIL_P(rb_encoding) && !rb_obj_is_kind_of(rb_encoding, rb_cEncoding)) { + rb_raise(rb_eTypeError, "argument must be an Encoding object"); + } + + xmlParserCtxtPtr c_context = + xmlCreateIOParserCtxt(NULL, NULL, + (xmlInputReadCallback)noko_io_read, + (xmlInputCloseCallback)noko_io_close, + (void *)rb_io, XML_CHAR_ENCODING_NONE); + if (!c_context) { + rb_raise(rb_eRuntimeError, "failed to create xml sax parser context"); + } + + noko_xml_sax_parser_context_set_encoding(c_context, rb_encoding); + + if (c_context->sax) { + xmlFree(c_context->sax); + c_context->sax = NULL; + } + + VALUE rb_context = noko_xml_sax_parser_context_wrap(rb_class, c_context); + rb_iv_set(rb_context, "@input", rb_io); + + return rb_context; +} + +/* :nodoc: */ +static VALUE +noko_xml_sax_parser_context_s_native_file(VALUE rb_class, VALUE rb_path, VALUE rb_encoding) +{ + if (!NIL_P(rb_encoding) && !rb_obj_is_kind_of(rb_encoding, rb_cEncoding)) { + rb_raise(rb_eTypeError, "argument must be an Encoding object"); + } + + xmlParserCtxtPtr c_context = xmlCreateFileParserCtxt(StringValueCStr(rb_path)); + if (!c_context) { + rb_raise(rb_eRuntimeError, "failed to create xml sax parser context"); + } + + noko_xml_sax_parser_context_set_encoding(c_context, rb_encoding); + + if (c_context->sax) { + xmlFree(c_context->sax); + c_context->sax = NULL; + } + + return noko_xml_sax_parser_context_wrap(rb_class, c_context); +} + +/* :nodoc: */ +static VALUE +noko_xml_sax_parser_context_s_native_memory(VALUE rb_class, VALUE rb_input, VALUE rb_encoding) +{ + Check_Type(rb_input, T_STRING); + if (!(int)RSTRING_LEN(rb_input)) { + rb_raise(rb_eRuntimeError, "input string cannot be empty"); + } + + if (!NIL_P(rb_encoding) && !rb_obj_is_kind_of(rb_encoding, rb_cEncoding)) { + rb_raise(rb_eTypeError, "argument must be an Encoding object"); + } + + xmlParserCtxtPtr c_context = + xmlCreateMemoryParserCtxt(StringValuePtr(rb_input), (int)RSTRING_LEN(rb_input)); + if (!c_context) { + rb_raise(rb_eRuntimeError, "failed to create xml sax parser context"); + } + + noko_xml_sax_parser_context_set_encoding(c_context, rb_encoding); + + if (c_context->sax) { + xmlFree(c_context->sax); + c_context->sax = NULL; + } + + VALUE rb_context = noko_xml_sax_parser_context_wrap(rb_class, c_context); + rb_iv_set(rb_context, "@input", rb_input); + + return rb_context; +} + +/* + * call-seq: + * parse_with(sax_handler) + * + * Use +sax_handler+ and parse the current document + * + * 💡 Calling this method directly is discouraged. Use Nokogiri::XML::SAX::Parser methods which are + * more convenient for most use cases. + */ +static VALUE +noko_xml_sax_parser_context__parse_with(VALUE rb_context, VALUE rb_sax_parser) +{ + xmlParserCtxtPtr c_context; + xmlSAXHandlerPtr sax; + + if (!rb_obj_is_kind_of(rb_sax_parser, cNokogiriXmlSaxParser)) { + rb_raise(rb_eArgError, "argument must be a Nokogiri::XML::SAX::Parser"); + } + + c_context = noko_xml_sax_parser_context_unwrap(rb_context); + sax = noko_xml_sax_parser_unwrap(rb_sax_parser); + + c_context->sax = sax; + c_context->userData = c_context; /* so we can use libxml2/SAX2.c handlers if we want to */ + c_context->_private = (void *)rb_sax_parser; + + xmlSetStructuredErrorFunc(NULL, NULL); + + /* although we're calling back into Ruby here, we don't need to worry about exceptions, because we + * don't have any cleanup to do. The only memory we need to free is handled by + * xml_sax_parser_context_type_free */ + xmlParseDocument(c_context); + + return Qnil; +} + +/* + * call-seq: + * replace_entities=(value) + * + * See Document@Entity+Handling for an explanation of the behavior controlled by this flag. + * + * [Parameters] + * - +value+ (Boolean) Whether external parsed entities will be resolved. + * + * ⚠ It is UNSAFE to set this option to +true+ when parsing untrusted documents. The option + * defaults to +false+ for this reason. + * + * This option is perhaps misnamed by the libxml2 author, since it controls resolution and not + * replacement. + * + * [Example] + * Because this class is generally not instantiated directly, you would typically set this option + * via the block argument to Nokogiri::XML::SAX::Parser.parse et al: + * + * parser = Nokogiri::XML::SAX::Parser.new(document_handler) + * parser.parse(xml) do |ctx| + * ctx.replace_entities = true # this is UNSAFE for untrusted documents! + * end + */ +static VALUE +noko_xml_sax_parser_context__replace_entities_set(VALUE rb_context, VALUE rb_value) +{ + int error; + xmlParserCtxtPtr ctxt = noko_xml_sax_parser_context_unwrap(rb_context); + + if (RB_TEST(rb_value)) { + error = xmlCtxtSetOptions(ctxt, xmlCtxtGetOptions(ctxt) | XML_PARSE_NOENT); + } else { + error = xmlCtxtSetOptions(ctxt, xmlCtxtGetOptions(ctxt) & ~XML_PARSE_NOENT); + } + + if (error) { + rb_raise(rb_eRuntimeError, "failed to set parser context options (%x)", error); + } + + return rb_value; +} + +/* + * call-seq: + * replace_entities + * + * See Document@Entity+Handling for an explanation of the behavior controlled by this flag. + * + * [Returns] (Boolean) Value of the parse option. (Default +false+) + * + * This option is perhaps misnamed by the libxml2 author, since it controls resolution and not + * replacement. + */ +static VALUE +noko_xml_sax_parser_context__replace_entities_get(VALUE rb_context) +{ + xmlParserCtxtPtr ctxt = noko_xml_sax_parser_context_unwrap(rb_context); + + if (xmlCtxtGetOptions(ctxt) & XML_PARSE_NOENT) { + return Qtrue; + } else { + return Qfalse; + } +} + +/* + * call-seq: line + * + * [Returns] (Integer) the line number of the line being currently parsed. + */ +static VALUE +noko_xml_sax_parser_context__line(VALUE rb_context) +{ + xmlParserInputPtr io; + xmlParserCtxtPtr ctxt = noko_xml_sax_parser_context_unwrap(rb_context); + + io = ctxt->input; + if (io) { + return INT2NUM(io->line); + } + + return Qnil; +} + +/* + * call-seq: column + * + * [Returns] (Integer) the column number of the column being currently parsed. + */ +static VALUE +noko_xml_sax_parser_context__column(VALUE rb_context) +{ + xmlParserCtxtPtr ctxt = noko_xml_sax_parser_context_unwrap(rb_context); + xmlParserInputPtr io; + + io = ctxt->input; + if (io) { + return INT2NUM(io->col); + } + + return Qnil; +} + +/* + * call-seq: + * recovery=(value) + * + * Controls whether this parser will recover from parsing errors. If set to +true+, the parser will + * invoke the SAX::Document#error callback and continue processing the file. If set to +false+, the + * parser will stop processing the file on the first parsing error. + * + * [Parameters] + * - +value+ (Boolean) Recover from parsing errors. (Default is +false+ for XML and +true+ for HTML.) + * + * [Returns] (Boolean) The passed +value+. + * + * [Example] + * Because this class is generally not instantiated directly, you would typically set this option + * via the block argument to Nokogiri::XML::SAX::Parser.parse et al: + * + * parser = Nokogiri::XML::SAX::Parser.new(document_handler) + * parser.parse(xml) do |ctx| + * ctx.recovery = true + * end + */ +static VALUE +noko_xml_sax_parser_context__recovery_set(VALUE rb_context, VALUE rb_value) +{ + int error; + xmlParserCtxtPtr ctxt = noko_xml_sax_parser_context_unwrap(rb_context); + + if (RB_TEST(rb_value)) { + error = xmlCtxtSetOptions(ctxt, xmlCtxtGetOptions(ctxt) | XML_PARSE_RECOVER); + } else { + error = xmlCtxtSetOptions(ctxt, xmlCtxtGetOptions(ctxt) & ~XML_PARSE_RECOVER); + } + + if (error) { + rb_raise(rb_eRuntimeError, "failed to set parser context options (%x)", error); + } + + return rb_value; +} + +/* + * call-seq: + * recovery + * + * Inspect whether this parser will recover from parsing errors. If set to +true+, the parser will + * invoke the SAX::Document#error callback and continue processing the file. If set to +false+, the + * parser will stop processing the file on the first parsing error. + * + * [Returns] (Boolean) Whether this parser will recover from parsing errors. + * + * Default is +false+ for XML and +true+ for HTML. + */ +static VALUE +noko_xml_sax_parser_context__recovery_get(VALUE rb_context) +{ + xmlParserCtxtPtr ctxt = noko_xml_sax_parser_context_unwrap(rb_context); + + if (xmlCtxtGetOptions(ctxt) & XML_PARSE_RECOVER) { + return Qtrue; + } else { + return Qfalse; + } +} + +void +noko_init_xml_sax_parser_context(void) +{ + cNokogiriXmlSaxParserContext = rb_define_class_under(mNokogiriXmlSax, "ParserContext", rb_cObject); + + rb_undef_alloc_func(cNokogiriXmlSaxParserContext); + + rb_define_singleton_method(cNokogiriXmlSaxParserContext, "native_io", + noko_xml_sax_parser_context_s_native_io, 2); + rb_define_singleton_method(cNokogiriXmlSaxParserContext, "native_memory", + noko_xml_sax_parser_context_s_native_memory, 2); + rb_define_singleton_method(cNokogiriXmlSaxParserContext, "native_file", + noko_xml_sax_parser_context_s_native_file, 2); + + rb_define_method(cNokogiriXmlSaxParserContext, "parse_with", noko_xml_sax_parser_context__parse_with, 1); + rb_define_method(cNokogiriXmlSaxParserContext, "replace_entities=", + noko_xml_sax_parser_context__replace_entities_set, 1); + rb_define_method(cNokogiriXmlSaxParserContext, "replace_entities", + noko_xml_sax_parser_context__replace_entities_get, 0); + rb_define_method(cNokogiriXmlSaxParserContext, "recovery=", noko_xml_sax_parser_context__recovery_set, 1); + rb_define_method(cNokogiriXmlSaxParserContext, "recovery", noko_xml_sax_parser_context__recovery_get, 0); + rb_define_method(cNokogiriXmlSaxParserContext, "line", noko_xml_sax_parser_context__line, 0); + rb_define_method(cNokogiriXmlSaxParserContext, "column", noko_xml_sax_parser_context__column, 0); + + id_read = rb_intern("read"); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_sax_push_parser.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_sax_push_parser.c new file mode 100644 index 0000000..e6bffbf --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_sax_push_parser.c @@ -0,0 +1,206 @@ +#include + +VALUE cNokogiriXmlSaxPushParser ; + +static void +xml_sax_push_parser_free(void *data) +{ + xmlParserCtxtPtr ctx = data; + if (ctx->myDoc) { + xmlFreeDoc(ctx->myDoc); + } + if (ctx) { + xmlFreeParserCtxt(ctx); + } +} + +static const rb_data_type_t xml_sax_push_parser_type = { + .wrap_struct_name = "xmlParserCtxt", + .function = { + .dfree = xml_sax_push_parser_free, + }, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static VALUE +xml_sax_push_parser_allocate(VALUE klass) +{ + return TypedData_Wrap_Struct(klass, &xml_sax_push_parser_type, NULL); +} + +xmlParserCtxtPtr +noko_xml_sax_push_parser_unwrap(VALUE rb_parser) +{ + xmlParserCtxtPtr c_parser; + TypedData_Get_Struct(rb_parser, xmlParserCtxt, &xml_sax_push_parser_type, c_parser); + return c_parser; +} + +/* + * Write +chunk+ to PushParser. +last_chunk+ triggers the end_document handle + */ +static VALUE +noko_xml_sax_push_parser__native_write(VALUE self, VALUE _chunk, VALUE _last_chunk) +{ + xmlParserCtxtPtr ctx; + const char *chunk = NULL; + int size = 0; + + ctx = noko_xml_sax_push_parser_unwrap(self); + + if (Qnil != _chunk) { + chunk = StringValuePtr(_chunk); + size = (int)RSTRING_LEN(_chunk); + } + + xmlSetStructuredErrorFunc(NULL, NULL); + + if (xmlParseChunk(ctx, chunk, size, Qtrue == _last_chunk ? 1 : 0)) { + if (!(xmlCtxtGetOptions(ctx) & XML_PARSE_RECOVER)) { + xmlErrorConstPtr e = xmlCtxtGetLastError(ctx); + noko__error_raise(NULL, e); + } + } + + return self; +} + +/* + * call-seq: + * initialize_native(xml_sax, filename) + * + * Initialize the push parser with +xml_sax+ using +filename+ + */ +static VALUE +noko_xml_sax_push_parser__initialize_native(VALUE self, VALUE _xml_sax, VALUE _filename) +{ + xmlSAXHandlerPtr sax; + const char *filename = NULL; + xmlParserCtxtPtr ctx; + + sax = noko_xml_sax_parser_unwrap(_xml_sax); + + if (_filename != Qnil) { filename = StringValueCStr(_filename); } + + ctx = xmlCreatePushParserCtxt( + sax, + NULL, + NULL, + 0, + filename + ); + if (ctx == NULL) { + rb_raise(rb_eRuntimeError, "Could not create a parser context"); + } + + ctx->userData = ctx; + ctx->_private = (void *)_xml_sax; + + DATA_PTR(self) = ctx; + return self; +} + +static VALUE +noko_xml_sax_push_parser__options_get(VALUE self) +{ + xmlParserCtxtPtr ctx; + + ctx = noko_xml_sax_push_parser_unwrap(self); + + return INT2NUM(xmlCtxtGetOptions(ctx)); +} + +static VALUE +noko_xml_sax_push_parser__options_set(VALUE self, VALUE options) +{ + int error; + xmlParserCtxtPtr ctx; + + ctx = noko_xml_sax_push_parser_unwrap(self); + + error = xmlCtxtSetOptions(ctx, (int)NUM2INT(options)); + if (error) { + rb_raise(rb_eRuntimeError, "Cannot set XML parser context options (%x)", error); + } + + return Qnil; +} + +/* + * call-seq: + * replace_entities + * + * See Document@Entity+Handling for an explanation of the behavior controlled by this flag. + * + * [Returns] (Boolean) Value of the parse option. (Default +false+) + * + * This option is perhaps misnamed by the libxml2 author, since it controls resolution and not + * replacement. + */ +static VALUE +noko_xml_sax_push_parser__replace_entities_get(VALUE self) +{ + xmlParserCtxtPtr ctxt = noko_xml_sax_push_parser_unwrap(self); + + if (xmlCtxtGetOptions(ctxt) & XML_PARSE_NOENT) { + return Qtrue; + } else { + return Qfalse; + } +} + +/* + * call-seq: + * replace_entities=(value) + * + * See Document@Entity+Handling for an explanation of the behavior controlled by this flag. + * + * [Parameters] + * - +value+ (Boolean) Whether external parsed entities will be resolved. + * + * ⚠ It is UNSAFE to set this option to +true+ when parsing untrusted documents. The option + * defaults to +false+ for this reason. + * + * This option is perhaps misnamed by the libxml2 author, since it controls resolution and not + * replacement. + */ +static VALUE +noko_xml_sax_push_parser__replace_entities_set(VALUE self, VALUE value) +{ + int error; + xmlParserCtxtPtr ctxt = noko_xml_sax_push_parser_unwrap(self); + + if (RB_TEST(value)) { + error = xmlCtxtSetOptions(ctxt, xmlCtxtGetOptions(ctxt) | XML_PARSE_NOENT); + } else { + error = xmlCtxtSetOptions(ctxt, xmlCtxtGetOptions(ctxt) & ~XML_PARSE_NOENT); + } + + if (error) { + rb_raise(rb_eRuntimeError, "failed to set parser context options (%x)", error); + } + + return value; +} + +void +noko_init_xml_sax_push_parser(void) +{ + cNokogiriXmlSaxPushParser = rb_define_class_under(mNokogiriXmlSax, "PushParser", rb_cObject); + + rb_define_alloc_func(cNokogiriXmlSaxPushParser, xml_sax_push_parser_allocate); + + rb_define_method(cNokogiriXmlSaxPushParser, "options", + noko_xml_sax_push_parser__options_get, 0); + rb_define_method(cNokogiriXmlSaxPushParser, "options=", + noko_xml_sax_push_parser__options_set, 1); + rb_define_method(cNokogiriXmlSaxPushParser, "replace_entities", + noko_xml_sax_push_parser__replace_entities_get, 0); + rb_define_method(cNokogiriXmlSaxPushParser, "replace_entities=", + noko_xml_sax_push_parser__replace_entities_set, 1); + + rb_define_private_method(cNokogiriXmlSaxPushParser, "initialize_native", + noko_xml_sax_push_parser__initialize_native, 2); + rb_define_private_method(cNokogiriXmlSaxPushParser, "native_write", + noko_xml_sax_push_parser__native_write, 2); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_schema.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_schema.c new file mode 100644 index 0000000..b2bded9 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_schema.c @@ -0,0 +1,226 @@ +#include + +VALUE cNokogiriXmlSchema; + +static void +xml_schema_deallocate(void *data) +{ + xmlSchemaPtr schema = data; + xmlSchemaFree(schema); +} + +static const rb_data_type_t xml_schema_type = { + .wrap_struct_name = "xmlSchema", + .function = { + .dfree = xml_schema_deallocate, + }, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static VALUE +noko_xml_schema__validate_document(VALUE self, VALUE document) +{ + xmlDocPtr doc; + xmlSchemaPtr schema; + xmlSchemaValidCtxtPtr valid_ctxt; + VALUE errors; + + TypedData_Get_Struct(self, xmlSchema, &xml_schema_type, schema); + doc = noko_xml_document_unwrap(document); + + errors = rb_ary_new(); + + valid_ctxt = xmlSchemaNewValidCtxt(schema); + + if (NULL == valid_ctxt) { + /* we have a problem */ + rb_raise(rb_eRuntimeError, "Could not create a validation context"); + } + + xmlSchemaSetValidStructuredErrors( + valid_ctxt, + noko__error_array_pusher, + (void *)errors + ); + + int status = xmlSchemaValidateDoc(valid_ctxt, doc); + + xmlSchemaFreeValidCtxt(valid_ctxt); + + if (status != 0) { + if (RARRAY_LEN(errors) == 0) { + rb_ary_push(errors, rb_str_new2("Could not validate document")); + } + } + + return errors; +} + +static VALUE +noko_xml_schema__validate_file(VALUE self, VALUE rb_filename) +{ + xmlSchemaPtr schema; + xmlSchemaValidCtxtPtr valid_ctxt; + const char *filename ; + VALUE errors; + + TypedData_Get_Struct(self, xmlSchema, &xml_schema_type, schema); + filename = (const char *)StringValueCStr(rb_filename) ; + + errors = rb_ary_new(); + + valid_ctxt = xmlSchemaNewValidCtxt(schema); + + if (NULL == valid_ctxt) { + /* we have a problem */ + rb_raise(rb_eRuntimeError, "Could not create a validation context"); + } + + xmlSchemaSetValidStructuredErrors( + valid_ctxt, + noko__error_array_pusher, + (void *)errors + ); + + int status = xmlSchemaValidateFile(valid_ctxt, filename, 0); + + xmlSchemaFreeValidCtxt(valid_ctxt); + + if (status != 0) { + if (RARRAY_LEN(errors) == 0) { + rb_ary_push(errors, rb_str_new2("Could not validate file.")); + } + } + + return errors; +} + +static VALUE +xml_schema_parse_schema( + VALUE rb_class, + xmlSchemaParserCtxtPtr c_parser_context, + VALUE rb_parse_options +) +{ + xmlExternalEntityLoader saved_loader = 0; + libxmlStructuredErrorHandlerState handler_state; + + if (NIL_P(rb_parse_options)) { + rb_parse_options = rb_const_get_at( + rb_const_get_at(mNokogiriXml, rb_intern("ParseOptions")), + rb_intern("DEFAULT_SCHEMA") + ); + } + int c_parse_options = (int)NUM2INT(rb_funcall(rb_parse_options, rb_intern("to_i"), 0)); + + VALUE rb_errors = rb_ary_new(); + noko__structured_error_func_save_and_set(&handler_state, (void *)rb_errors, noko__error_array_pusher); + + xmlSchemaSetParserStructuredErrors( + c_parser_context, + noko__error_array_pusher, + (void *)rb_errors + ); + + if (c_parse_options & XML_PARSE_NONET) { + saved_loader = xmlGetExternalEntityLoader(); + xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader); + } + + xmlSchemaPtr c_schema = xmlSchemaParse(c_parser_context); + + if (saved_loader) { + xmlSetExternalEntityLoader(saved_loader); + } + + xmlSchemaFreeParserCtxt(c_parser_context); + noko__structured_error_func_restore(&handler_state); + + if (NULL == c_schema) { + VALUE exception = rb_funcall(cNokogiriXmlSyntaxError, rb_intern("aggregate"), 1, rb_errors); + if (RB_TEST(exception)) { + rb_exc_raise(exception); + } else { + rb_raise(rb_eRuntimeError, "Could not parse document"); + } + } + + VALUE rb_schema = TypedData_Wrap_Struct(rb_class, &xml_schema_type, c_schema); + rb_iv_set(rb_schema, "@errors", rb_errors); + rb_iv_set(rb_schema, "@parse_options", rb_parse_options); + + return rb_schema; +} + +/* + * :call-seq: + * from_document(input) → Nokogiri::XML::Schema + * from_document(input, parse_options) → Nokogiri::XML::Schema + * + * Parse an \XSD schema definition from a Document to create a new Nokogiri::XML::Schema + * + * [Parameters] + * - +input+ (XML::Document) A document containing the \XSD schema definition + * - +parse_options+ (Nokogiri::XML::ParseOptions) + * Defaults to Nokogiri::XML::ParseOptions::DEFAULT_SCHEMA + * + * [Returns] Nokogiri::XML::Schema + */ +static VALUE +noko_xml_schema_s_from_document(int argc, VALUE *argv, VALUE rb_class) +{ + /* TODO: deprecate this method and put file-or-string logic into .new so that becomes the + * preferred entry point, and this can become a private method */ + VALUE rb_document; + VALUE rb_parse_options; + VALUE rb_schema; + xmlDocPtr c_document; + xmlSchemaParserCtxtPtr c_parser_context; + int defensive_copy_p = 0; + + rb_scan_args(argc, argv, "11", &rb_document, &rb_parse_options); + + if (!rb_obj_is_kind_of(rb_document, cNokogiriXmlNode)) { + rb_raise(rb_eTypeError, + "expected parameter to be a Nokogiri::XML::Document, received %"PRIsVALUE, + rb_obj_class(rb_document)); + } + + if (!rb_obj_is_kind_of(rb_document, cNokogiriXmlDocument)) { + xmlNodePtr deprecated_node_type_arg; + NOKO_WARN_DEPRECATION("Passing a Node as the first parameter to Schema.from_document is deprecated. Please pass a Document instead. This will become an error in Nokogiri v1.17.0."); // TODO: deprecated in v1.15.3, remove in v1.17.0 + Noko_Node_Get_Struct(rb_document, xmlNode, deprecated_node_type_arg); + c_document = deprecated_node_type_arg->doc; + } else { + c_document = noko_xml_document_unwrap(rb_document); + } + + if (noko_xml_document_has_wrapped_blank_nodes_p(c_document)) { + // see https://github.com/sparklemotion/nokogiri/pull/2001 + c_document = xmlCopyDoc(c_document, 1); + defensive_copy_p = 1; + } + + c_parser_context = xmlSchemaNewDocParserCtxt(c_document); + rb_schema = xml_schema_parse_schema(rb_class, c_parser_context, rb_parse_options); + + if (defensive_copy_p) { + xmlFreeDoc(c_document); + c_document = NULL; + } + + return rb_schema; +} + +void +noko_init_xml_schema(void) +{ + cNokogiriXmlSchema = rb_define_class_under(mNokogiriXml, "Schema", rb_cObject); + + rb_undef_alloc_func(cNokogiriXmlSchema); + + rb_define_singleton_method(cNokogiriXmlSchema, "from_document", noko_xml_schema_s_from_document, -1); + + rb_define_private_method(cNokogiriXmlSchema, "validate_document", noko_xml_schema__validate_document, 1); + rb_define_private_method(cNokogiriXmlSchema, "validate_file", noko_xml_schema__validate_file, 1); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_syntax_error.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_syntax_error.c new file mode 100644 index 0000000..d0a3bf8 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_syntax_error.c @@ -0,0 +1,93 @@ +#include + +VALUE cNokogiriXmlSyntaxError; + +void +noko__structured_error_func_save(libxmlStructuredErrorHandlerState *handler_state) +{ + /* this method is tightly coupled to the implementation of xmlSetStructuredErrorFunc */ + handler_state->user_data = xmlStructuredErrorContext; + handler_state->handler = xmlStructuredError; +} + +void +noko__structured_error_func_save_and_set( + libxmlStructuredErrorHandlerState *handler_state, + void *user_data, + xmlStructuredErrorFunc handler +) +{ + noko__structured_error_func_save(handler_state); + xmlSetStructuredErrorFunc(user_data, handler); +} + +void +noko__structured_error_func_restore(libxmlStructuredErrorHandlerState *handler_state) +{ + xmlSetStructuredErrorFunc(handler_state->user_data, handler_state->handler); +} + +void +noko__error_array_pusher(void *ctx, xmlErrorConstPtr error) +{ + VALUE list = (VALUE)ctx; + Check_Type(list, T_ARRAY); + rb_ary_push(list, noko_xml_syntax_error__wrap(error)); +} + +void +noko__error_raise(void *ctx, xmlErrorConstPtr error) +{ + rb_exc_raise(noko_xml_syntax_error__wrap(error)); +} + +VALUE +noko_xml_syntax_error__wrap(xmlErrorConstPtr error) +{ + xmlChar *c_path ; + VALUE msg, e, klass; + + klass = cNokogiriXmlSyntaxError; + + if (error && error->domain == XML_FROM_XPATH) { + klass = cNokogiriXmlXpathSyntaxError; + } + + msg = (error && error->message) ? NOKOGIRI_STR_NEW2(error->message) : Qnil; + + e = rb_class_new_instance( + 1, + &msg, + klass + ); + + if (error) { + c_path = xmlGetNodePath(error->node); + + rb_iv_set(e, "@domain", INT2NUM(error->domain)); + rb_iv_set(e, "@code", INT2NUM(error->code)); + rb_iv_set(e, "@level", INT2NUM((short)error->level)); + rb_iv_set(e, "@file", RBSTR_OR_QNIL(error->file)); + rb_iv_set(e, "@line", INT2NUM(error->line)); + rb_iv_set(e, "@path", RBSTR_OR_QNIL(c_path)); + rb_iv_set(e, "@str1", RBSTR_OR_QNIL(error->str1)); + rb_iv_set(e, "@str2", RBSTR_OR_QNIL(error->str2)); + rb_iv_set(e, "@str3", RBSTR_OR_QNIL(error->str3)); + rb_iv_set(e, "@int1", INT2NUM(error->int1)); + rb_iv_set(e, "@column", INT2NUM(error->int2)); + + xmlFree(c_path); + } + + return e; +} + +void +noko_init_xml_syntax_error(void) +{ + assert(cNokogiriSyntaxError); + /* + * The XML::SyntaxError is raised on parse errors + */ + cNokogiriXmlSyntaxError = rb_define_class_under(mNokogiriXml, "SyntaxError", cNokogiriSyntaxError); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_text.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_text.c new file mode 100644 index 0000000..e15de27 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_text.c @@ -0,0 +1,59 @@ +#include + +VALUE cNokogiriXmlText ; + +/* + * call-seq: + * new(content, document) + * + * Create a new Text element on the +document+ with +content+ + */ +static VALUE +rb_xml_text_s_new(int argc, VALUE *argv, VALUE klass) +{ + xmlDocPtr c_document; + xmlNodePtr c_node; + VALUE rb_string; + VALUE rb_document; + VALUE rb_rest; + VALUE rb_node; + + rb_scan_args(argc, argv, "2*", &rb_string, &rb_document, &rb_rest); + + Check_Type(rb_string, T_STRING); + if (!rb_obj_is_kind_of(rb_document, cNokogiriXmlNode)) { + rb_raise(rb_eTypeError, + "expected second parameter to be a Nokogiri::XML::Document, received %"PRIsVALUE, + rb_obj_class(rb_document)); + } + + if (!rb_obj_is_kind_of(rb_document, cNokogiriXmlDocument)) { + xmlNodePtr deprecated_node_type_arg; + NOKO_WARN_DEPRECATION("Passing a Node as the second parameter to Text.new is deprecated. Please pass a Document instead. This will become an error in Nokogiri v1.17.0."); // TODO: deprecated in v1.15.3, remove in v1.17.0 + Noko_Node_Get_Struct(rb_document, xmlNode, deprecated_node_type_arg); + c_document = deprecated_node_type_arg->doc; + } else { + c_document = noko_xml_document_unwrap(rb_document); + } + + c_node = xmlNewDocText(c_document, (xmlChar *)StringValueCStr(rb_string)); + noko_xml_document_pin_node(c_node); + rb_node = noko_xml_node_wrap(klass, c_node) ; + rb_obj_call_init(rb_node, argc, argv); + + if (rb_block_given_p()) { rb_yield(rb_node); } + + return rb_node; +} + +void +noko_init_xml_text(void) +{ + assert(cNokogiriXmlCharacterData); + /* + * Wraps Text nodes. + */ + cNokogiriXmlText = rb_define_class_under(mNokogiriXml, "Text", cNokogiriXmlCharacterData); + + rb_define_singleton_method(cNokogiriXmlText, "new", rb_xml_text_s_new, -1); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_xpath_context.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_xpath_context.c new file mode 100644 index 0000000..8f71c2e --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xml_xpath_context.c @@ -0,0 +1,486 @@ +#include + +VALUE cNokogiriXmlXpathContext; + +/* + * these constants have matching declarations in + * ext/java/nokogiri/internals/NokogiriNamespaceContext.java + */ +static const xmlChar *NOKOGIRI_PREFIX = (const xmlChar *)"nokogiri"; +static const xmlChar *NOKOGIRI_URI = (const xmlChar *)"http://www.nokogiri.org/default_ns/ruby/extensions_functions"; +static const xmlChar *NOKOGIRI_BUILTIN_PREFIX = (const xmlChar *)"nokogiri-builtin"; +static const xmlChar *NOKOGIRI_BUILTIN_URI = (const xmlChar *)"https://www.nokogiri.org/default_ns/ruby/builtins"; + +static void +_noko_xml_xpath_context_dfree(void *data) +{ + xmlXPathContextPtr c_context = data; + xmlXPathFreeContext(c_context); +} + +static const rb_data_type_t _noko_xml_xpath_context_type = { + .wrap_struct_name = "xmlXPathContext", + .function = { + .dfree = _noko_xml_xpath_context_dfree, + }, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +/* find a CSS class in an HTML element's `class` attribute */ +static const xmlChar * +_noko_xml_xpath_context__css_class(const xmlChar *str, const xmlChar *val) +{ + int val_len; + + if (str == NULL) { return (NULL); } + if (val == NULL) { return (NULL); } + + val_len = xmlStrlen(val); + if (val_len == 0) { return (str); } + + while (*str != 0) { + if ((*str == *val) && !xmlStrncmp(str, val, val_len)) { + const xmlChar *next_byte = str + val_len; + + /* only match if the next byte is whitespace or end of string */ + if ((*next_byte == 0) || (IS_BLANK_CH(*next_byte))) { + return ((const xmlChar *)str); + } + } + + /* advance str to whitespace */ + while ((*str != 0) && !IS_BLANK_CH(*str)) { + str++; + } + + /* advance str to start of next word or end of string */ + while ((*str != 0) && IS_BLANK_CH(*str)) { + str++; + } + } + + return (NULL); +} + +/* xmlXPathFunction to wrap _noko_xml_xpath_context__css_class() */ +static void +noko_xml_xpath_context_xpath_func_css_class(xmlXPathParserContextPtr ctxt, int nargs) +{ + xmlXPathObjectPtr hay, needle; + + CHECK_ARITY(2); + + CAST_TO_STRING; + needle = valuePop(ctxt); + if ((needle == NULL) || (needle->type != XPATH_STRING)) { + xmlXPathFreeObject(needle); + XP_ERROR(XPATH_INVALID_TYPE); + } + + CAST_TO_STRING; + hay = valuePop(ctxt); + if ((hay == NULL) || (hay->type != XPATH_STRING)) { + xmlXPathFreeObject(hay); + xmlXPathFreeObject(needle); + XP_ERROR(XPATH_INVALID_TYPE); + } + + if (_noko_xml_xpath_context__css_class(hay->stringval, needle->stringval)) { + valuePush(ctxt, xmlXPathNewBoolean(1)); + } else { + valuePush(ctxt, xmlXPathNewBoolean(0)); + } + + xmlXPathFreeObject(hay); + xmlXPathFreeObject(needle); +} + + +/* xmlXPathFunction to select nodes whose local name matches, for HTML5 CSS queries that should + * ignore namespaces */ +static void +noko_xml_xpath_context_xpath_func_local_name_is(xmlXPathParserContextPtr ctxt, int nargs) +{ + xmlXPathObjectPtr element_name; + + assert(ctxt->context->node); + + CHECK_ARITY(1); + CAST_TO_STRING; + CHECK_TYPE(XPATH_STRING); + element_name = valuePop(ctxt); + + valuePush( + ctxt, + xmlXPathNewBoolean(xmlStrEqual(ctxt->context->node->name, element_name->stringval)) + ); + + xmlXPathFreeObject(element_name); +} + + +/* + * call-seq: + * register_ns(prefix, uri) → Nokogiri::XML::XPathContext + * + * Register the namespace with +prefix+ and +uri+ for use in future queries. + * Passing a uri of +nil+ will unregister the namespace. + * + * [Returns] +self+ + */ +static VALUE +noko_xml_xpath_context_register_ns(VALUE rb_context, VALUE prefix, VALUE uri) +{ + xmlXPathContextPtr c_context; + const xmlChar *ns_uri; + + TypedData_Get_Struct(rb_context, xmlXPathContext, &_noko_xml_xpath_context_type, c_context); + + if (NIL_P(uri)) { + ns_uri = NULL; + } else { + ns_uri = (const xmlChar *)StringValueCStr(uri); + } + + xmlXPathRegisterNs(c_context, (const xmlChar *)StringValueCStr(prefix), ns_uri); + + return rb_context; +} + +/* + * call-seq: + * register_variable(name, value) → Nokogiri::XML::XPathContext + * + * Register the variable +name+ with +value+ for use in future queries. + * Passing a value of +nil+ will unregister the variable. + * + * [Returns] +self+ + */ +static VALUE +noko_xml_xpath_context_register_variable(VALUE rb_context, VALUE name, VALUE value) +{ + xmlXPathContextPtr c_context; + xmlXPathObjectPtr xmlValue; + + TypedData_Get_Struct(rb_context, xmlXPathContext, &_noko_xml_xpath_context_type, c_context); + + if (NIL_P(value)) { + xmlValue = NULL; + } else { + xmlValue = xmlXPathNewCString(StringValueCStr(value)); + } + + xmlXPathRegisterVariable(c_context, (const xmlChar *)StringValueCStr(name), xmlValue); + + return rb_context; +} + + +/* + * convert an XPath object into a Ruby object of the appropriate type. + * returns Qundef if no conversion was possible. + */ +static VALUE +_noko_xml_xpath_context__xpath2ruby(xmlXPathObjectPtr c_xpath_object, xmlXPathContextPtr c_context) +{ + VALUE rb_retval; + + assert(c_context->doc); + assert(DOC_RUBY_OBJECT_TEST(c_context->doc)); + + switch (c_xpath_object->type) { + case XPATH_STRING: + rb_retval = NOKOGIRI_STR_NEW2(c_xpath_object->stringval); + xmlFree(c_xpath_object->stringval); + return rb_retval; + + case XPATH_NODESET: + return noko_xml_node_set_wrap( + c_xpath_object->nodesetval, + DOC_RUBY_OBJECT(c_context->doc) + ); + + case XPATH_NUMBER: + return rb_float_new(c_xpath_object->floatval); + + case XPATH_BOOLEAN: + return (c_xpath_object->boolval == 1) ? Qtrue : Qfalse; + + default: + return Qundef; + } +} + +void +Nokogiri_marshal_xpath_funcall_and_return_values( + xmlXPathParserContextPtr ctxt, + int argc, + VALUE rb_xpath_handler, + const char *method_name +) +{ + VALUE rb_retval; + VALUE *argv; + VALUE rb_node_set = Qnil; + xmlNodeSetPtr c_node_set = NULL; + xmlXPathObjectPtr c_xpath_object; + + assert(ctxt->context->doc); + assert(DOC_RUBY_OBJECT_TEST(ctxt->context->doc)); + + argv = (VALUE *)ruby_xcalloc((size_t)argc, sizeof(VALUE)); + for (int j = 0 ; j < argc ; ++j) { + rb_gc_register_address(&argv[j]); + } + + for (int j = argc - 1 ; j >= 0 ; --j) { + c_xpath_object = valuePop(ctxt); + argv[j] = _noko_xml_xpath_context__xpath2ruby(c_xpath_object, ctxt->context); + if (argv[j] == Qundef) { + argv[j] = NOKOGIRI_STR_NEW2(xmlXPathCastToString(c_xpath_object)); + } + xmlXPathFreeNodeSetList(c_xpath_object); + } + + rb_retval = rb_funcall2( + rb_xpath_handler, + rb_intern((const char *)method_name), + argc, + argv + ); + + for (int j = 0 ; j < argc ; ++j) { + rb_gc_unregister_address(&argv[j]); + } + ruby_xfree(argv); + + switch (TYPE(rb_retval)) { + case T_FLOAT: + case T_BIGNUM: + case T_FIXNUM: + xmlXPathReturnNumber(ctxt, NUM2DBL(rb_retval)); + break; + case T_STRING: + xmlXPathReturnString(ctxt, xmlCharStrdup(StringValueCStr(rb_retval))); + break; + case T_TRUE: + xmlXPathReturnTrue(ctxt); + break; + case T_FALSE: + xmlXPathReturnFalse(ctxt); + break; + case T_NIL: + break; + case T_ARRAY: { + VALUE construct_args[2] = { DOC_RUBY_OBJECT(ctxt->context->doc), rb_retval }; + rb_node_set = rb_class_new_instance(2, construct_args, cNokogiriXmlNodeSet); + c_node_set = noko_xml_node_set_unwrap(rb_node_set); + xmlXPathReturnNodeSet(ctxt, xmlXPathNodeSetMerge(NULL, c_node_set)); + } + break; + case T_DATA: + if (rb_obj_is_kind_of(rb_retval, cNokogiriXmlNodeSet)) { + c_node_set = noko_xml_node_set_unwrap(rb_retval); + /* Copy the node set, otherwise it will get GC'd. */ + xmlXPathReturnNodeSet(ctxt, xmlXPathNodeSetMerge(NULL, c_node_set)); + break; + } + default: + rb_raise(rb_eRuntimeError, "Invalid return type"); + } +} + +static void +_noko_xml_xpath_context__handler_invoker(xmlXPathParserContextPtr ctxt, int argc) +{ + VALUE rb_xpath_handler = Qnil; + const char *method_name = NULL ; + + assert(ctxt); + assert(ctxt->context); + assert(ctxt->context->userData); + assert(ctxt->context->function); + + rb_xpath_handler = (VALUE)(ctxt->context->userData); + method_name = (const char *)(ctxt->context->function); + + Nokogiri_marshal_xpath_funcall_and_return_values( + ctxt, + argc, + rb_xpath_handler, + method_name + ); +} + +static xmlXPathFunction +_noko_xml_xpath_context_handler_lookup(void *data, const xmlChar *c_name, const xmlChar *c_ns_uri) +{ + VALUE rb_handler = (VALUE)data; + if (rb_respond_to(rb_handler, rb_intern((const char *)c_name))) { + if (c_ns_uri == NULL) { + NOKO_WARN_DEPRECATION("A custom XPath or CSS handler function named '%s' is being invoked without a namespace. Please update your query to reference this function as 'nokogiri:%s'. Invoking custom handler functions without a namespace is deprecated and will become an error in Nokogiri v1.17.0.", + c_name, c_name); // TODO deprecated in v1.15.0, remove in v1.19.0 + } + return _noko_xml_xpath_context__handler_invoker; + } + + return NULL; +} + +PRINTFLIKE_DECL(2, 3) +static void +_noko_xml_xpath_context__generic_exception_pusher(void *data, const char *msg, ...) +{ + VALUE rb_errors = (VALUE)data; + VALUE rb_message; + VALUE rb_exception; + + Check_Type(rb_errors, T_ARRAY); + +#ifdef TRUFFLERUBY_NOKOGIRI_SYSTEM_LIBRARIES + /* It is not currently possible to pass var args from native + functions to sulong, so we work around the issue here. */ + rb_message = rb_sprintf("_noko_xml_xpath_context__generic_exception_pusher: %s", msg); +#else + va_list args; + va_start(args, msg); + rb_message = rb_vsprintf(msg, args); + va_end(args); +#endif + + rb_exception = rb_exc_new_str(cNokogiriXmlXpathSyntaxError, rb_message); + rb_ary_push(rb_errors, rb_exception); +} + +/* + * call-seq: + * evaluate(search_path, handler = nil) → Object + * + * Evaluate the +search_path+ query. + * + * [Returns] an object of the appropriate type for the query, which could be +NodeSet+, a +String+, + * a +Float+, or a boolean. + */ +static VALUE +noko_xml_xpath_context_evaluate(int argc, VALUE *argv, VALUE rb_context) +{ + xmlXPathContextPtr c_context; + VALUE rb_expression = Qnil; + VALUE rb_function_lookup_handler = Qnil; + xmlChar *c_expression_str = NULL; + VALUE rb_errors = rb_ary_new(); + xmlXPathObjectPtr c_xpath_object; + VALUE rb_xpath_object = Qnil; + + TypedData_Get_Struct(rb_context, xmlXPathContext, &_noko_xml_xpath_context_type, c_context); + + rb_scan_args(argc, argv, "11", &rb_expression, &rb_function_lookup_handler); + + c_expression_str = (xmlChar *)StringValueCStr(rb_expression); + + if (Qnil != rb_function_lookup_handler) { + /* FIXME: not sure if this is the correct place to shove private data. */ + c_context->userData = (void *)rb_function_lookup_handler; + xmlXPathRegisterFuncLookup( + c_context, + _noko_xml_xpath_context_handler_lookup, + (void *)rb_function_lookup_handler + ); + } + + /* TODO: use xmlXPathSetErrorHandler (as of 2.13.0) */ + xmlSetStructuredErrorFunc((void *)rb_errors, noko__error_array_pusher); + xmlSetGenericErrorFunc((void *)rb_errors, _noko_xml_xpath_context__generic_exception_pusher); + + c_xpath_object = xmlXPathEvalExpression(c_expression_str, c_context); + + xmlSetStructuredErrorFunc(NULL, NULL); + xmlSetGenericErrorFunc(NULL, NULL); + + xmlXPathRegisterFuncLookup(c_context, NULL, NULL); + + if (c_xpath_object == NULL) { + rb_exc_raise(rb_ary_entry(rb_errors, 0)); + } + + rb_xpath_object = _noko_xml_xpath_context__xpath2ruby(c_xpath_object, c_context); + if (rb_xpath_object == Qundef) { + rb_xpath_object = noko_xml_node_set_wrap(NULL, DOC_RUBY_OBJECT(c_context->doc)); + } + + xmlXPathFreeNodeSetList(c_xpath_object); + + return rb_xpath_object; +} + +/* + * call-seq: + * new(node) + * + * Create a new XPathContext with +node+ as the context node. + */ +static VALUE +noko_xml_xpath_context_new(VALUE klass, VALUE rb_node) +{ + xmlNodePtr c_node; + xmlXPathContextPtr c_context; + VALUE rb_context; + + Noko_Node_Get_Struct(rb_node, xmlNode, c_node); + +#if LIBXML_VERSION < 21000 + xmlXPathInit(); /* deprecated in 40483d0 */ +#endif + + c_context = xmlXPathNewContext(c_node->doc); + c_context->node = c_node; + + xmlXPathRegisterNs(c_context, NOKOGIRI_PREFIX, NOKOGIRI_URI); + xmlXPathRegisterNs(c_context, NOKOGIRI_BUILTIN_PREFIX, NOKOGIRI_BUILTIN_URI); + + xmlXPathRegisterFuncNS(c_context, + (const xmlChar *)"css-class", NOKOGIRI_BUILTIN_URI, + noko_xml_xpath_context_xpath_func_css_class); + xmlXPathRegisterFuncNS(c_context, + (const xmlChar *)"local-name-is", NOKOGIRI_BUILTIN_URI, + noko_xml_xpath_context_xpath_func_local_name_is); + + rb_context = TypedData_Wrap_Struct(klass, &_noko_xml_xpath_context_type, c_context); + + return rb_context; +} + + +/* :nodoc: */ +static VALUE +noko_xml_xpath_context_set_node(VALUE rb_context, VALUE rb_node) +{ + xmlNodePtr c_node; + xmlXPathContextPtr c_context; + + TypedData_Get_Struct(rb_context, xmlXPathContext, &_noko_xml_xpath_context_type, c_context); + Noko_Node_Get_Struct(rb_node, xmlNode, c_node); + + c_context->doc = c_node->doc; + c_context->node = c_node; + + return rb_node; +} + +void +noko_init_xml_xpath_context(void) +{ + /* + * XPathContext is the entry point for searching a +Document+ by using XPath. + */ + cNokogiriXmlXpathContext = rb_define_class_under(mNokogiriXml, "XPathContext", rb_cObject); + + rb_undef_alloc_func(cNokogiriXmlXpathContext); + + rb_define_singleton_method(cNokogiriXmlXpathContext, "new", noko_xml_xpath_context_new, 1); + + rb_define_method(cNokogiriXmlXpathContext, "evaluate", noko_xml_xpath_context_evaluate, -1); + rb_define_method(cNokogiriXmlXpathContext, "register_variable", noko_xml_xpath_context_register_variable, 2); + rb_define_method(cNokogiriXmlXpathContext, "register_ns", noko_xml_xpath_context_register_ns, 2); + rb_define_method(cNokogiriXmlXpathContext, "node=", noko_xml_xpath_context_set_node, 1); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xslt_stylesheet.c b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xslt_stylesheet.c new file mode 100644 index 0000000..903f729 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/ext/nokogiri/xslt_stylesheet.c @@ -0,0 +1,421 @@ +#include + +VALUE cNokogiriXsltStylesheet; + +static void +mark(void *data) +{ + nokogiriXsltStylesheetTuple *wrapper = (nokogiriXsltStylesheetTuple *)data; + rb_gc_mark(wrapper->func_instances); +} + +static void +dealloc(void *data) +{ + nokogiriXsltStylesheetTuple *wrapper = (nokogiriXsltStylesheetTuple *)data; + xsltStylesheetPtr doc = wrapper->ss; + xsltFreeStylesheet(doc); + ruby_xfree(wrapper); +} + +static const rb_data_type_t nokogiri_xslt_stylesheet_tuple_type = { + .wrap_struct_name = "nokogiriXsltStylesheetTuple", + .function = { + .dmark = mark, + .dfree = dealloc, + }, + .flags = RUBY_TYPED_FREE_IMMEDIATELY +}; + +PRINTFLIKE_DECL(2, 3) +static void +xslt_generic_error_handler(void *ctx, const char *msg, ...) +{ + VALUE message; + +#ifdef TRUFFLERUBY_NOKOGIRI_SYSTEM_LIBRARIES + /* It is not currently possible to pass var args from native + functions to sulong, so we work around the issue here. */ + message = rb_sprintf("xslt_generic_error_handler: %s", msg); +#else + va_list args; + va_start(args, msg); + message = rb_vsprintf(msg, args); + va_end(args); +#endif + + rb_str_concat((VALUE)ctx, message); +} + +VALUE +Nokogiri_wrap_xslt_stylesheet(xsltStylesheetPtr ss) +{ + VALUE self; + nokogiriXsltStylesheetTuple *wrapper; + + self = TypedData_Make_Struct( + cNokogiriXsltStylesheet, + nokogiriXsltStylesheetTuple, + &nokogiri_xslt_stylesheet_tuple_type, + wrapper + ); + + ss->_private = (void *)self; + wrapper->ss = ss; + wrapper->func_instances = rb_ary_new(); + + return self; +} + +/* + * call-seq: + * parse_stylesheet_doc(document) + * + * Parse an XSLT::Stylesheet from +document+. + * + * [Parameters] + * - +document+ (Nokogiri::XML::Document) the document to be parsed. + * + * [Returns] Nokogiri::XSLT::Stylesheet + */ +static VALUE +parse_stylesheet_doc(VALUE klass, VALUE xmldocobj) +{ + xmlDocPtr xml, xml_cpy; + VALUE errstr, exception; + xsltStylesheetPtr ss ; + + xml = noko_xml_document_unwrap(xmldocobj); + + errstr = rb_str_new(0, 0); + xsltSetGenericErrorFunc((void *)errstr, xslt_generic_error_handler); + + xml_cpy = xmlCopyDoc(xml, 1); /* 1 => recursive */ + ss = xsltParseStylesheetDoc(xml_cpy); + + xsltSetGenericErrorFunc(NULL, NULL); + + if (!ss) { + xmlFreeDoc(xml_cpy); + exception = rb_exc_new3(rb_eRuntimeError, errstr); + rb_exc_raise(exception); + } + + return Nokogiri_wrap_xslt_stylesheet(ss); +} + + +/* + * call-seq: + * serialize(document) + * + * Serialize +document+ to an xml string, as specified by the +method+ parameter in the Stylesheet. + */ +static VALUE +rb_xslt_stylesheet_serialize(VALUE self, VALUE xmlobj) +{ + xmlDocPtr xml ; + nokogiriXsltStylesheetTuple *wrapper; + xmlChar *doc_ptr ; + int doc_len ; + VALUE rval ; + + xml = noko_xml_document_unwrap(xmlobj); + TypedData_Get_Struct( + self, + nokogiriXsltStylesheetTuple, + &nokogiri_xslt_stylesheet_tuple_type, + wrapper + ); + xsltSaveResultToString(&doc_ptr, &doc_len, xml, wrapper->ss); + rval = NOKOGIRI_STR_NEW(doc_ptr, doc_len); + xmlFree(doc_ptr); + return rval ; +} + +/* + * call-seq: + * transform(document) + * transform(document, params = {}) + * + * Transform an XML::Document as defined by an XSLT::Stylesheet. + * + * [Parameters] + * - +document+ (Nokogiri::XML::Document) the document to be transformed. + * - +params+ (Hash, Array) strings used as XSLT parameters. + * + * [Returns] Nokogiri::XML::Document + * + * *Example* of basic transformation: + * + * xslt = <<~XSLT + * + * + * + * + * + * + * + *

+ *
    + * + *
  1. + *
    + *
+ * + * + *
+ * XSLT + * + * xml = <<~XML + * + * + * + * EMP0001 + * Accountant + * + * + * EMP0002 + * Developer + * + * + * XML + * + * doc = Nokogiri::XML::Document.parse(xml) + * stylesheet = Nokogiri::XSLT.parse(xslt) + * + * ⚠ Note that the +h1+ element is empty because no param has been provided! + * + * stylesheet.transform(doc).to_xml + * # => "\n" + + * # "

\n" + + * # "
    \n" + + * # "
  1. EMP0001
  2. \n" + + * # "
  3. EMP0002
  4. \n" + + * # "
\n" + + * # "\n" + * + * *Example* of using an input parameter hash: + * + * ⚠ The title is populated, but note how we need to quote-escape the value. + * + * stylesheet.transform(doc, { "title" => "'Employee List'" }).to_xml + * # => "\n" + + * # "

Employee List

\n" + + * # "
    \n" + + * # "
  1. EMP0001
  2. \n" + + * # "
  3. EMP0002
  4. \n" + + * # "
\n" + + * # "\n" + * + * *Example* using the XSLT.quote_params helper method to safely quote-escape strings: + * + * stylesheet.transform(doc, Nokogiri::XSLT.quote_params({ "title" => "Aaron's List" })).to_xml + * # => "\n" + + * # "

Aaron's List

\n" + + * # "
    \n" + + * # "
  1. EMP0001
  2. \n" + + * # "
  3. EMP0002
  4. \n" + + * # "
\n" + + * # "\n" + * + * *Example* using an array of XSLT parameters + * + * You can also use an array if you want to. + * + * stylesheet.transform(doc, ["title", "'Employee List'"]).to_xml + * # => "\n" + + * # "

Employee List

\n" + + * # "
    \n" + + * # "
  1. EMP0001
  2. \n" + + * # "
  3. EMP0002
  4. \n" + + * # "
\n" + + * # "\n" + * + * Or pass an array to XSLT.quote_params: + * + * stylesheet.transform(doc, Nokogiri::XSLT.quote_params(["title", "Aaron's List"])).to_xml + * # => "\n" + + * # "

Aaron's List

\n" + + * # "
    \n" + + * # "
  1. EMP0001
  2. \n" + + * # "
  3. EMP0002
  4. \n" + + * # "
\n" + + * # "\n" + * + * See: Nokogiri::XSLT.quote_params + */ +static VALUE +rb_xslt_stylesheet_transform(int argc, VALUE *argv, VALUE self) +{ + VALUE rb_document, rb_param, rb_error_str; + xmlDocPtr c_document ; + xmlDocPtr c_result_document ; + nokogiriXsltStylesheetTuple *wrapper; + const char **params ; + long param_len, j ; + int parse_error_occurred ; + int defensive_copy_p = 0; + + rb_scan_args(argc, argv, "11", &rb_document, &rb_param); + if (NIL_P(rb_param)) { rb_param = rb_ary_new2(0L) ; } + if (!rb_obj_is_kind_of(rb_document, cNokogiriXmlDocument)) { + rb_raise(rb_eArgError, "argument must be a Nokogiri::XML::Document"); + } + + /* handle hashes as arguments. */ + if (T_HASH == TYPE(rb_param)) { + rb_param = rb_funcall(rb_param, rb_intern("to_a"), 0); + rb_param = rb_funcall(rb_param, rb_intern("flatten"), 0); + } + + Check_Type(rb_param, T_ARRAY); + + c_document = noko_xml_document_unwrap(rb_document); + TypedData_Get_Struct(self, nokogiriXsltStylesheetTuple, &nokogiri_xslt_stylesheet_tuple_type, wrapper); + + param_len = RARRAY_LEN(rb_param); + params = ruby_xcalloc((size_t)param_len + 1, sizeof(char *)); + for (j = 0 ; j < param_len ; j++) { + VALUE entry = rb_ary_entry(rb_param, j); + const char *ptr = StringValueCStr(entry); + params[j] = ptr; + } + params[param_len] = 0 ; + + xsltTransformContextPtr c_transform_context = xsltNewTransformContext(wrapper->ss, c_document); + if (xsltNeedElemSpaceHandling(c_transform_context) && + noko_xml_document_has_wrapped_blank_nodes_p(c_document)) { + // see https://github.com/sparklemotion/nokogiri/issues/2800 + c_document = xmlCopyDoc(c_document, 1); + defensive_copy_p = 1; + } + xsltFreeTransformContext(c_transform_context); + + rb_error_str = rb_str_new(0, 0); + xsltSetGenericErrorFunc((void *)rb_error_str, xslt_generic_error_handler); + xmlSetGenericErrorFunc((void *)rb_error_str, xslt_generic_error_handler); + + c_result_document = xsltApplyStylesheet(wrapper->ss, c_document, params); + + ruby_xfree(params); + if (defensive_copy_p) { + xmlFreeDoc(c_document); + c_document = NULL; + } + + xsltSetGenericErrorFunc(NULL, NULL); + xmlSetGenericErrorFunc(NULL, NULL); + + parse_error_occurred = (Qfalse == rb_funcall(rb_error_str, rb_intern("empty?"), 0)); + + if (parse_error_occurred) { + rb_exc_raise(rb_exc_new3(rb_eRuntimeError, rb_error_str)); + } + + return noko_xml_document_wrap((VALUE)0, c_result_document) ; +} + +static void +method_caller(xmlXPathParserContextPtr ctxt, int nargs) +{ + VALUE handler; + const char *function_name; + xsltTransformContextPtr transform; + const xmlChar *functionURI; + + transform = xsltXPathGetTransformContext(ctxt); + functionURI = ctxt->context->functionURI; + handler = (VALUE)xsltGetExtData(transform, functionURI); + function_name = (const char *)(ctxt->context->function); + + Nokogiri_marshal_xpath_funcall_and_return_values( + ctxt, + nargs, + handler, + (const char *)function_name + ); +} + +static void * +initFunc(xsltTransformContextPtr ctxt, const xmlChar *uri) +{ + VALUE modules = rb_iv_get(mNokogiriXslt, "@modules"); + VALUE obj = rb_hash_aref(modules, rb_str_new2((const char *)uri)); + VALUE args = { Qfalse }; + VALUE methods = rb_funcall(obj, rb_intern("instance_methods"), 1, args); + VALUE inst; + nokogiriXsltStylesheetTuple *wrapper; + int i; + + for (i = 0; i < RARRAY_LEN(methods); i++) { + VALUE method_name = rb_obj_as_string(rb_ary_entry(methods, i)); + xsltRegisterExtFunction( + ctxt, + (unsigned char *)StringValueCStr(method_name), + uri, + method_caller + ); + } + + TypedData_Get_Struct( + (VALUE)ctxt->style->_private, + nokogiriXsltStylesheetTuple, + &nokogiri_xslt_stylesheet_tuple_type, + wrapper + ); + inst = rb_class_new_instance(0, NULL, obj); + rb_ary_push(wrapper->func_instances, inst); + + return (void *)inst; +} + +static void +shutdownFunc(xsltTransformContextPtr ctxt, + const xmlChar *uri, void *data) +{ + nokogiriXsltStylesheetTuple *wrapper; + + TypedData_Get_Struct( + (VALUE)ctxt->style->_private, + nokogiriXsltStylesheetTuple, + &nokogiri_xslt_stylesheet_tuple_type, + wrapper + ); + + rb_ary_clear(wrapper->func_instances); +} + +/* docstring is in lib/nokogiri/xslt.rb */ +static VALUE +rb_xslt_s_register(VALUE self, VALUE uri, VALUE obj) +{ + VALUE modules = rb_iv_get(self, "@modules"); + if (NIL_P(modules)) { + rb_raise(rb_eRuntimeError, "internal error: @modules not set"); + } + + rb_hash_aset(modules, uri, obj); + xsltRegisterExtModule( + (unsigned char *)StringValueCStr(uri), + initFunc, + shutdownFunc + ); + return self; +} + +void +noko_init_xslt_stylesheet(void) +{ + rb_define_singleton_method(mNokogiriXslt, "register", rb_xslt_s_register, 2); + rb_iv_set(mNokogiriXslt, "@modules", rb_hash_new()); + + cNokogiriXsltStylesheet = rb_define_class_under(mNokogiriXslt, "Stylesheet", rb_cObject); + + rb_undef_alloc_func(cNokogiriXsltStylesheet); + + rb_define_singleton_method(cNokogiriXsltStylesheet, "parse_stylesheet_doc", parse_stylesheet_doc, 1); + rb_define_method(cNokogiriXsltStylesheet, "serialize", rb_xslt_stylesheet_serialize, 1); + rb_define_method(cNokogiriXsltStylesheet, "transform", rb_xslt_stylesheet_transform, -1); +} diff --git a/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/gumbo-parser/CHANGES.md b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/gumbo-parser/CHANGES.md new file mode 100644 index 0000000..277b3a2 --- /dev/null +++ b/vendor/bundle/ruby/3.2.0/gems/nokogiri-1.18.10-x86_64-linux-gnu/gumbo-parser/CHANGES.md @@ -0,0 +1,63 @@ +## Gumbo 0.10.1 (2015-04-30) + +Same as 0.10.0, but with the version number bumped because the last version-number commit to v0.9.4 makes GitHub think that v0.9.4 is the latest version and so it's not highlighted on the webpage. + +## Gumbo 0.10.0 (2015-04-30) + +* Full support for `