From f82e2b6d16ce2106c1e72f5017f627ee09ad6042 Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Tue, 22 Oct 2024 16:35:54 -0500 Subject: [PATCH] Update fiddle to 1.1.4 * Fixes issue at build time where mkmf required fileutils but it was not installed yet (ruby/fiddle#153). * Fixes issue related to reline where missing native libraries did not raise error and fall back correctly (ruby/reline#766). * Switches fiddle to a default gem. --- .gitignore | 1 + lib/pom.rb | 2 +- lib/pom.xml | 16 + lib/ruby/stdlib/fiddle.rb | 100 ------ lib/ruby/stdlib/fiddle/closure.rb | 49 --- lib/ruby/stdlib/fiddle/cparser.rb | 264 -------------- lib/ruby/stdlib/fiddle/function.rb | 29 -- lib/ruby/stdlib/fiddle/import.rb | 320 ----------------- lib/ruby/stdlib/fiddle/pack.rb | 136 -------- lib/ruby/stdlib/fiddle/struct.rb | 539 ----------------------------- lib/ruby/stdlib/fiddle/types.rb | 73 ---- lib/ruby/stdlib/fiddle/value.rb | 122 ------- lib/ruby/stdlib/fiddle/version.rb | 3 - 13 files changed, 18 insertions(+), 1636 deletions(-) delete mode 100644 lib/ruby/stdlib/fiddle.rb delete mode 100644 lib/ruby/stdlib/fiddle/closure.rb delete mode 100644 lib/ruby/stdlib/fiddle/cparser.rb delete mode 100644 lib/ruby/stdlib/fiddle/function.rb delete mode 100644 lib/ruby/stdlib/fiddle/import.rb delete mode 100644 lib/ruby/stdlib/fiddle/pack.rb delete mode 100644 lib/ruby/stdlib/fiddle/struct.rb delete mode 100644 lib/ruby/stdlib/fiddle/types.rb delete mode 100644 lib/ruby/stdlib/fiddle/value.rb delete mode 100644 lib/ruby/stdlib/fiddle/version.rb diff --git a/.gitignore b/.gitignore index 765e1261268..d4928df5968 100644 --- a/.gitignore +++ b/.gitignore @@ -73,6 +73,7 @@ lib/ruby/stdlib/English* lib/ruby/stdlib/erb* lib/ruby/stdlib/error_highlight* lib/ruby/stdlib/ffi* +lib/ruby/stdlib/fiddle* lib/ruby/stdlib/fileutils* lib/ruby/stdlib/find* lib/ruby/stdlib/forwardable* diff --git a/lib/pom.rb b/lib/pom.rb index ea04a1c4d63..d910b800bd0 100644 --- a/lib/pom.rb +++ b/lib/pom.rb @@ -44,7 +44,7 @@ def log(message=nil) # https://github.com/ruby/fcntl/issues/9 # ['fcntl', '1.0.1'], ['ffi', '1.16.3'], - # ['fiddle', '1.1.0'], + ['fiddle', '1.1.4'], ['fileutils', '1.6.0'], ['find', '0.1.1'], ['forwardable', '1.3.2'], diff --git a/lib/pom.xml b/lib/pom.xml index 561ac3b2ae0..fedb1636185 100644 --- a/lib/pom.xml +++ b/lib/pom.xml @@ -265,6 +265,19 @@ DO NOT MODIFY - GENERATED CODE + + rubygems + fiddle + 1.1.4 + gem + provided + + + rubygems + jar-dependencies + + + rubygems fileutils @@ -1097,6 +1110,7 @@ DO NOT MODIFY - GENERATED CODE specifications/erb-2.2.3* specifications/error_highlight-0.3.0* specifications/ffi-1.16.3* + specifications/fiddle-1.1.4* specifications/fileutils-1.6.0* specifications/find-0.1.1* specifications/forwardable-1.3.2* @@ -1176,6 +1190,7 @@ DO NOT MODIFY - GENERATED CODE gems/erb-2.2.3*/**/* gems/error_highlight-0.3.0*/**/* gems/ffi-1.16.3*/**/* + gems/fiddle-1.1.4*/**/* gems/fileutils-1.6.0*/**/* gems/find-0.1.1*/**/* gems/forwardable-1.3.2*/**/* @@ -1255,6 +1270,7 @@ DO NOT MODIFY - GENERATED CODE cache/erb-2.2.3* cache/error_highlight-0.3.0* cache/ffi-1.16.3* + cache/fiddle-1.1.4* cache/fileutils-1.6.0* cache/find-0.1.1* cache/forwardable-1.3.2* diff --git a/lib/ruby/stdlib/fiddle.rb b/lib/ruby/stdlib/fiddle.rb deleted file mode 100644 index 2d49cd3fd7c..00000000000 --- a/lib/ruby/stdlib/fiddle.rb +++ /dev/null @@ -1,100 +0,0 @@ -# frozen_string_literal: true -require 'fiddle.so' unless RUBY_ENGINE == 'jruby' -require 'fiddle/jruby' if RUBY_ENGINE == 'jruby' -require 'fiddle/closure' -require 'fiddle/function' -require 'fiddle/version' - -module Fiddle - if WINDOWS - # Returns the last win32 +Error+ of the current executing +Thread+ or nil - # if none - def self.win32_last_error - if RUBY_ENGINE == 'jruby' - errno = FFI.errno - errno == 0 ? nil : errno - else - Thread.current[:__FIDDLE_WIN32_LAST_ERROR__] - end - end - - # Sets the last win32 +Error+ of the current executing +Thread+ to +error+ - def self.win32_last_error= error - if RUBY_ENGINE == 'jruby' - errno = FFI.errno - errno == 0 ? nil : errno - else - Thread.current[:__FIDDLE_WIN32_LAST_ERROR__] = error - end - end - - # Returns the last win32 socket +Error+ of the current executing - # +Thread+ or nil if none - def self.win32_last_socket_error - if RUBY_ENGINE == 'jruby' - errno = FFI.errno - errno == 0 ? nil : errno - else - Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__] - end - end - - # Sets the last win32 socket +Error+ of the current executing - # +Thread+ to +error+ - def self.win32_last_socket_error= error - if RUBY_ENGINE == 'jruby' - errno = FFI.errno - errno == 0 ? nil : errno - else - Thread.current[:__FIDDLE_WIN32_LAST_SOCKET_ERROR__] = error - end - end - end - - # Returns the last +Error+ of the current executing +Thread+ or nil if none - def self.last_error - if RUBY_ENGINE == 'jruby' - errno = FFI.errno - errno == 0 ? nil : errno - errno - else - Thread.current[:__FIDDLE_LAST_ERROR__] - end - end - - # Sets the last +Error+ of the current executing +Thread+ to +error+ - def self.last_error= error - if RUBY_ENGINE == 'jruby' - FFI.errno = error || 0 - else - Thread.current[:__DL2_LAST_ERROR__] = error - Thread.current[:__FIDDLE_LAST_ERROR__] = error - end - end - - # call-seq: dlopen(library) => Fiddle::Handle - # - # Creates a new handler that opens +library+, and returns an instance of - # Fiddle::Handle. - # - # If +nil+ is given for the +library+, Fiddle::Handle::DEFAULT is used, which - # is the equivalent to RTLD_DEFAULT. See man 3 dlopen for more. - # - # lib = Fiddle.dlopen(nil) - # - # The default is dependent on OS, and provide a handle for all libraries - # already loaded. For example, in most cases you can use this to access - # +libc+ functions, or ruby functions like +rb_str_new+. - # - # See Fiddle::Handle.new for more. - def dlopen library - Fiddle::Handle.new library - end - module_function :dlopen - - # Add constants for backwards compat - - RTLD_GLOBAL = Handle::RTLD_GLOBAL # :nodoc: - RTLD_LAZY = Handle::RTLD_LAZY # :nodoc: - RTLD_NOW = Handle::RTLD_NOW # :nodoc: -end diff --git a/lib/ruby/stdlib/fiddle/closure.rb b/lib/ruby/stdlib/fiddle/closure.rb deleted file mode 100644 index c865a63c20f..00000000000 --- a/lib/ruby/stdlib/fiddle/closure.rb +++ /dev/null @@ -1,49 +0,0 @@ -# frozen_string_literal: true -module Fiddle - class Closure - - # the C type of the return of the FFI closure - attr_reader :ctype - - # arguments of the FFI closure - attr_reader :args - - # Extends Fiddle::Closure to allow for building the closure in a block - class BlockCaller < Fiddle::Closure - - # == Description - # - # Construct a new BlockCaller object. - # - # * +ctype+ is the C type to be returned - # * +args+ are passed the callback - # * +abi+ is the abi of the closure - # - # If there is an error in preparing the +ffi_cif+ or +ffi_prep_closure+, - # then a RuntimeError will be raised. - # - # == Example - # - # include Fiddle - # - # cb = Closure::BlockCaller.new(TYPE_INT, [TYPE_INT]) do |one| - # one - # end - # - # func = Function.new(cb, [TYPE_INT], TYPE_INT) - # - def initialize ctype, args, abi = Fiddle::Function::DEFAULT, &block - super(ctype, args, abi) - @block = block - end - - # Calls the constructed BlockCaller, with +args+ - # - # For an example see Fiddle::Closure::BlockCaller.new - # - def call *args - @block.call(*args) - end - end - end -end diff --git a/lib/ruby/stdlib/fiddle/cparser.rb b/lib/ruby/stdlib/fiddle/cparser.rb deleted file mode 100644 index 93a05513c90..00000000000 --- a/lib/ruby/stdlib/fiddle/cparser.rb +++ /dev/null @@ -1,264 +0,0 @@ -# frozen_string_literal: true -module Fiddle - # A mixin that provides methods for parsing C struct and prototype signatures. - # - # == Example - # require 'fiddle/import' - # - # include Fiddle::CParser - # #=> Object - # - # parse_ctype('int') - # #=> Fiddle::TYPE_INT - # - # parse_struct_signature(['int i', 'char c']) - # #=> [[Fiddle::TYPE_INT, Fiddle::TYPE_CHAR], ["i", "c"]] - # - # parse_signature('double sum(double, double)') - # #=> ["sum", Fiddle::TYPE_DOUBLE, [Fiddle::TYPE_DOUBLE, Fiddle::TYPE_DOUBLE]] - # - module CParser - # Parses a C struct's members - # - # Example: - # require 'fiddle/import' - # - # include Fiddle::CParser - # #=> Object - # - # parse_struct_signature(['int i', 'char c']) - # #=> [[Fiddle::TYPE_INT, Fiddle::TYPE_CHAR], ["i", "c"]] - # - # parse_struct_signature(['char buffer[80]']) - # #=> [[[Fiddle::TYPE_CHAR, 80]], ["buffer"]] - # - def parse_struct_signature(signature, tymap=nil) - if signature.is_a?(String) - signature = split_arguments(signature, /[,;]/) - elsif signature.is_a?(Hash) - signature = [signature] - end - mems = [] - tys = [] - signature.each{|msig| - msig = compact(msig) if msig.is_a?(String) - case msig - when Hash - msig.each do |struct_name, struct_signature| - struct_name = struct_name.to_s if struct_name.is_a?(Symbol) - struct_name = compact(struct_name) - struct_count = nil - if struct_name =~ /^([\w\*\s]+)\[(\d+)\]$/ - struct_count = $2.to_i - struct_name = $1 - end - if struct_signature.respond_to?(:entity_class) - struct_type = struct_signature - else - parsed_struct = parse_struct_signature(struct_signature, tymap) - struct_type = CStructBuilder.create(CStruct, *parsed_struct) - end - if struct_count - ty = [struct_type, struct_count] - else - ty = struct_type - end - mems.push([struct_name, struct_type.members]) - tys.push(ty) - end - when /^[\w\*\s]+[\*\s](\w+)$/ - mems.push($1) - tys.push(parse_ctype(msig, tymap)) - when /^[\w\*\s]+\(\*(\w+)\)\(.*?\)$/ - mems.push($1) - tys.push(parse_ctype(msig, tymap)) - when /^([\w\*\s]+[\*\s])(\w+)\[(\d+)\]$/ - mems.push($2) - tys.push([parse_ctype($1.strip, tymap), $3.to_i]) - when /^([\w\*\s]+)\[(\d+)\](\w+)$/ - mems.push($3) - tys.push([parse_ctype($1.strip, tymap), $2.to_i]) - else - raise(RuntimeError,"can't parse the struct member: #{msig}") - end - } - return tys, mems - end - - # Parses a C prototype signature - # - # If Hash +tymap+ is provided, the return value and the arguments from the - # +signature+ are expected to be keys, and the value will be the C type to - # be looked up. - # - # Example: - # require 'fiddle/import' - # - # include Fiddle::CParser - # #=> Object - # - # parse_signature('double sum(double, double)') - # #=> ["sum", Fiddle::TYPE_DOUBLE, [Fiddle::TYPE_DOUBLE, Fiddle::TYPE_DOUBLE]] - # - # parse_signature('void update(void (*cb)(int code))') - # #=> ["update", Fiddle::TYPE_VOID, [Fiddle::TYPE_VOIDP]] - # - # parse_signature('char (*getbuffer(void))[80]') - # #=> ["getbuffer", Fiddle::TYPE_VOIDP, []] - # - def parse_signature(signature, tymap=nil) - tymap ||= {} - case compact(signature) - when /^(?:[\w\*\s]+)\(\*(\w+)\((.*?)\)\)(?:\[\w*\]|\(.*?\));?$/ - func, args = $1, $2 - return [func, TYPE_VOIDP, split_arguments(args).collect {|arg| parse_ctype(arg, tymap)}] - when /^([\w\*\s]+[\*\s])(\w+)\((.*?)\);?$/ - ret, func, args = $1.strip, $2, $3 - return [func, parse_ctype(ret, tymap), split_arguments(args).collect {|arg| parse_ctype(arg, tymap)}] - else - raise(RuntimeError,"can't parse the function prototype: #{signature}") - end - end - - # Given a String of C type +ty+, returns the corresponding Fiddle constant. - # - # +ty+ can also accept an Array of C type Strings, and will be returned in - # a corresponding Array. - # - # If Hash +tymap+ is provided, +ty+ is expected to be the key, and the - # value will be the C type to be looked up. - # - # Example: - # require 'fiddle/import' - # - # include Fiddle::CParser - # #=> Object - # - # parse_ctype('int') - # #=> Fiddle::TYPE_INT - # - # parse_ctype('double diff') - # #=> Fiddle::TYPE_DOUBLE - # - # parse_ctype('unsigned char byte') - # #=> -Fiddle::TYPE_CHAR - # - # parse_ctype('const char* const argv[]') - # #=> -Fiddle::TYPE_VOIDP - # - def parse_ctype(ty, tymap=nil) - tymap ||= {} - if ty.is_a?(Array) - return [parse_ctype(ty[0], tymap), ty[1]] - end - ty = ty.gsub(/\Aconst\s+/, "") - case ty - when 'void' - return TYPE_VOID - when /\A(?:(?:signed\s+)?long\s+long(?:\s+int\s+)?|int64_t)(?:\s+\w+)?\z/ - unless Fiddle.const_defined?(:TYPE_LONG_LONG) - raise(RuntimeError, "unsupported type: #{ty}") - end - return TYPE_LONG_LONG - when /\A(?:unsigned\s+long\s+long(?:\s+int\s+)?|uint64_t)(?:\s+\w+)?\z/ - unless Fiddle.const_defined?(:TYPE_LONG_LONG) - raise(RuntimeError, "unsupported type: #{ty}") - end - return -TYPE_LONG_LONG - when /\A(?:signed\s+)?long(?:\s+int\s+)?(?:\s+\w+)?\z/ - return TYPE_LONG - when /\Aunsigned\s+long(?:\s+int\s+)?(?:\s+\w+)?\z/ - return -TYPE_LONG - when /\A(?:signed\s+)?int(?:\s+\w+)?\z/ - return TYPE_INT - when /\A(?:unsigned\s+int|uint)(?:\s+\w+)?\z/ - return -TYPE_INT - when /\A(?:signed\s+)?short(?:\s+int\s+)?(?:\s+\w+)?\z/ - return TYPE_SHORT - when /\Aunsigned\s+short(?:\s+int\s+)?(?:\s+\w+)?\z/ - return -TYPE_SHORT - when /\A(?:signed\s+)?char(?:\s+\w+)?\z/ - return TYPE_CHAR - when /\Aunsigned\s+char(?:\s+\w+)?\z/ - return -TYPE_CHAR - when /\Aint8_t(?:\s+\w+)?\z/ - unless Fiddle.const_defined?(:TYPE_INT8_T) - raise(RuntimeError, "unsupported type: #{ty}") - end - return TYPE_INT8_T - when /\Auint8_t(?:\s+\w+)?\z/ - unless Fiddle.const_defined?(:TYPE_INT8_T) - raise(RuntimeError, "unsupported type: #{ty}") - end - return -TYPE_INT8_T - when /\Aint16_t(?:\s+\w+)?\z/ - unless Fiddle.const_defined?(:TYPE_INT16_T) - raise(RuntimeError, "unsupported type: #{ty}") - end - return TYPE_INT16_T - when /\Auint16_t(?:\s+\w+)?\z/ - unless Fiddle.const_defined?(:TYPE_INT16_T) - raise(RuntimeError, "unsupported type: #{ty}") - end - return -TYPE_INT16_T - when /\Aint32_t(?:\s+\w+)?\z/ - unless Fiddle.const_defined?(:TYPE_INT32_T) - raise(RuntimeError, "unsupported type: #{ty}") - end - return TYPE_INT32_T - when /\Auint32_t(?:\s+\w+)?\z/ - unless Fiddle.const_defined?(:TYPE_INT32_T) - raise(RuntimeError, "unsupported type: #{ty}") - end - return -TYPE_INT32_T - when /\Aint64_t(?:\s+\w+)?\z/ - unless Fiddle.const_defined?(:TYPE_INT64_T) - raise(RuntimeError, "unsupported type: #{ty}") - end - return TYPE_INT64_T - when /\Auint64_t(?:\s+\w+)?\z/ - unless Fiddle.const_defined?(:TYPE_INT64_T) - raise(RuntimeError, "unsupported type: #{ty}") - end - return -TYPE_INT64_T - when /\Afloat(?:\s+\w+)?\z/ - return TYPE_FLOAT - when /\Adouble(?:\s+\w+)?\z/ - return TYPE_DOUBLE - when /\Asize_t(?:\s+\w+)?\z/ - return TYPE_SIZE_T - when /\Assize_t(?:\s+\w+)?\z/ - return TYPE_SSIZE_T - when /\Aptrdiff_t(?:\s+\w+)?\z/ - return TYPE_PTRDIFF_T - when /\Aintptr_t(?:\s+\w+)?\z/ - return TYPE_INTPTR_T - when /\Auintptr_t(?:\s+\w+)?\z/ - return TYPE_UINTPTR_T - when /\*/, /\[[\s\d]*\]/ - return TYPE_VOIDP - when "..." - return TYPE_VARIADIC - else - ty = ty.split(' ', 2)[0] - if( tymap[ty] ) - return parse_ctype(tymap[ty], tymap) - else - raise(DLError, "unknown type: #{ty}") - end - end - end - - private - - def split_arguments(arguments, sep=',') - return [] if arguments.strip == 'void' - arguments.scan(/([\w\*\s]+\(\*\w*\)\(.*?\)|[\w\*\s\[\]]+|\.\.\.)(?:#{sep}\s*|\z)/).collect {|m| m[0]} - end - - def compact(signature) - signature.gsub(/\s+/, ' ').gsub(/\s*([\(\)\[\]\*,;])\s*/, '\1').strip - end - - end -end diff --git a/lib/ruby/stdlib/fiddle/function.rb b/lib/ruby/stdlib/fiddle/function.rb deleted file mode 100644 index dc2e3e6bf57..00000000000 --- a/lib/ruby/stdlib/fiddle/function.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true -module Fiddle - class Function - # The ABI of the Function. - attr_reader :abi - - # The address of this function - attr_reader :ptr - - # The name of this function - attr_reader :name - - # Whether GVL is needed to call this function - def need_gvl? - @need_gvl - end - - # The integer memory location of this function - def to_i - ptr.to_i - end - - # Turn this function in to a proc - def to_proc - this = self - lambda { |*args| this.call(*args) } - end - end -end diff --git a/lib/ruby/stdlib/fiddle/import.rb b/lib/ruby/stdlib/fiddle/import.rb deleted file mode 100644 index 09ffcef544c..00000000000 --- a/lib/ruby/stdlib/fiddle/import.rb +++ /dev/null @@ -1,320 +0,0 @@ -# frozen_string_literal: true -require 'fiddle' -require 'fiddle/struct' -require 'fiddle/cparser' - -module Fiddle - - # Used internally by Fiddle::Importer - class CompositeHandler - # Create a new handler with the open +handlers+ - # - # Used internally by Fiddle::Importer.dlload - def initialize(handlers) - @handlers = handlers - end - - # Array of the currently loaded libraries. - def handlers() - @handlers - end - - # Returns the address as an Integer from any handlers with the function - # named +symbol+. - # - # Raises a DLError if the handle is closed. - def sym(symbol) - @handlers.each{|handle| - if( handle ) - begin - addr = handle.sym(symbol) - return addr - rescue DLError - end - end - } - return nil - end - - # See Fiddle::CompositeHandler.sym - def [](symbol) - sym(symbol) - end - end - - # A DSL that provides the means to dynamically load libraries and build - # modules around them including calling extern functions within the C - # library that has been loaded. - # - # == Example - # - # require 'fiddle' - # require 'fiddle/import' - # - # module LibSum - # extend Fiddle::Importer - # dlload './libsum.so' - # extern 'double sum(double*, int)' - # extern 'double split(double)' - # end - # - module Importer - include Fiddle - include CParser - extend Importer - - attr_reader :type_alias - private :type_alias - - # Creates an array of handlers for the given +libs+, can be an instance of - # Fiddle::Handle, Fiddle::Importer, or will create a new instance of - # Fiddle::Handle using Fiddle.dlopen - # - # Raises a DLError if the library cannot be loaded. - # - # See Fiddle.dlopen - def dlload(*libs) - handles = libs.collect{|lib| - case lib - when nil - nil - when Handle - lib - when Importer - lib.handlers - else - Fiddle.dlopen(lib) - end - }.flatten() - @handler = CompositeHandler.new(handles) - @func_map = {} - @type_alias = {} - end - - # Sets the type alias for +alias_type+ as +orig_type+ - def typealias(alias_type, orig_type) - @type_alias[alias_type] = orig_type - end - - # Returns the sizeof +ty+, using Fiddle::Importer.parse_ctype to determine - # the C type and the appropriate Fiddle constant. - def sizeof(ty) - case ty - when String - ty = parse_ctype(ty, type_alias).abs() - case ty - when TYPE_CHAR - return SIZEOF_CHAR - when TYPE_SHORT - return SIZEOF_SHORT - when TYPE_INT - return SIZEOF_INT - when TYPE_LONG - return SIZEOF_LONG - when TYPE_FLOAT - return SIZEOF_FLOAT - when TYPE_DOUBLE - return SIZEOF_DOUBLE - when TYPE_VOIDP - return SIZEOF_VOIDP - when TYPE_CONST_STRING - return SIZEOF_CONST_STRING - else - if defined?(TYPE_LONG_LONG) and - ty == TYPE_LONG_LONG - return SIZEOF_LONG_LONG - else - raise(DLError, "unknown type: #{ty}") - end - end - when Class - if( ty.instance_methods().include?(:to_ptr) ) - return ty.size() - end - end - return Pointer[ty].size() - end - - def parse_bind_options(opts) - h = {} - while( opt = opts.shift() ) - case opt - when :stdcall, :cdecl - h[:call_type] = opt - when :carried, :temp, :temporal, :bind - h[:callback_type] = opt - h[:carrier] = opts.shift() - else - h[opt] = true - end - end - h - end - private :parse_bind_options - - # :stopdoc: - CALL_TYPE_TO_ABI = Hash.new { |h, k| - raise RuntimeError, "unsupported call type: #{k}" - }.merge({ :stdcall => Function.const_defined?(:STDCALL) ? Function::STDCALL : - Function::DEFAULT, - :cdecl => Function::DEFAULT, - nil => Function::DEFAULT - }).freeze - private_constant :CALL_TYPE_TO_ABI - # :startdoc: - - # Creates a global method from the given C +signature+. - def extern(signature, *opts) - symname, ctype, argtype = parse_signature(signature, type_alias) - opt = parse_bind_options(opts) - f = import_function(symname, ctype, argtype, opt[:call_type]) - name = symname.gsub(/@.+/,'') - @func_map[name] = f - # define_method(name){|*args,&block| f.call(*args,&block)} - begin - /^(.+?):(\d+)/ =~ caller.first - file, line = $1, $2.to_i - rescue - file, line = __FILE__, __LINE__+3 - end - module_eval(<<-EOS, file, line) - def #{name}(*args, &block) - @func_map['#{name}'].call(*args,&block) - end - EOS - module_function(name) - f - end - - # Creates a global method from the given C +signature+ using the given - # +opts+ as bind parameters with the given block. - def bind(signature, *opts, &blk) - name, ctype, argtype = parse_signature(signature, type_alias) - h = parse_bind_options(opts) - case h[:callback_type] - when :bind, nil - f = bind_function(name, ctype, argtype, h[:call_type], &blk) - else - raise(RuntimeError, "unknown callback type: #{h[:callback_type]}") - end - @func_map[name] = f - #define_method(name){|*args,&block| f.call(*args,&block)} - begin - /^(.+?):(\d+)/ =~ caller.first - file, line = $1, $2.to_i - rescue - file, line = __FILE__, __LINE__+3 - end - module_eval(<<-EOS, file, line) - def #{name}(*args,&block) - @func_map['#{name}'].call(*args,&block) - end - EOS - module_function(name) - f - end - - # Creates a class to wrap the C struct described by +signature+. - # - # MyStruct = struct ['int i', 'char c'] - def struct(signature) - tys, mems = parse_struct_signature(signature, type_alias) - Fiddle::CStructBuilder.create(CStruct, tys, mems) - end - - # Creates a class to wrap the C union described by +signature+. - # - # MyUnion = union ['int i', 'char c'] - def union(signature) - tys, mems = parse_struct_signature(signature, type_alias) - Fiddle::CStructBuilder.create(CUnion, tys, mems) - end - - # Returns the function mapped to +name+, that was created by either - # Fiddle::Importer.extern or Fiddle::Importer.bind - def [](name) - @func_map[name] - end - - # Creates a class to wrap the C struct with the value +ty+ - # - # See also Fiddle::Importer.struct - def create_value(ty, val=nil) - s = struct([ty + " value"]) - ptr = s.malloc() - if( val ) - ptr.value = val - end - return ptr - end - alias value create_value - - # Returns a new instance of the C struct with the value +ty+ at the +addr+ - # address. - def import_value(ty, addr) - s = struct([ty + " value"]) - ptr = s.new(addr) - return ptr - end - - - # The Fiddle::CompositeHandler instance - # - # Will raise an error if no handlers are open. - def handler - (@handler ||= nil) or raise "call dlload before importing symbols and functions" - end - - # Returns a new Fiddle::Pointer instance at the memory address of the given - # +name+ symbol. - # - # Raises a DLError if the +name+ doesn't exist. - # - # See Fiddle::CompositeHandler.sym and Fiddle::Handle.sym - def import_symbol(name) - addr = handler.sym(name) - if( !addr ) - raise(DLError, "cannot find the symbol: #{name}") - end - Pointer.new(addr) - end - - # Returns a new Fiddle::Function instance at the memory address of the given - # +name+ function. - # - # Raises a DLError if the +name+ doesn't exist. - # - # * +argtype+ is an Array of arguments, passed to the +name+ function. - # * +ctype+ is the return type of the function - # * +call_type+ is the ABI of the function - # - # See also Fiddle:Function.new - # - # See Fiddle::CompositeHandler.sym and Fiddle::Handler.sym - def import_function(name, ctype, argtype, call_type = nil) - addr = handler.sym(name) - if( !addr ) - raise(DLError, "cannot find the function: #{name}()") - end - Function.new(addr, argtype, ctype, CALL_TYPE_TO_ABI[call_type], - name: name) - end - - # Returns a new closure wrapper for the +name+ function. - # - # * +ctype+ is the return type of the function - # * +argtype+ is an Array of arguments, passed to the callback function - # * +call_type+ is the abi of the closure - # * +block+ is passed to the callback - # - # See Fiddle::Closure - def bind_function(name, ctype, argtype, call_type = nil, &block) - abi = CALL_TYPE_TO_ABI[call_type] - closure = Class.new(Fiddle::Closure) { - define_method(:call, block) - }.new(ctype, argtype, abi) - - Function.new(closure, argtype, ctype, abi, name: name) - end - end -end diff --git a/lib/ruby/stdlib/fiddle/pack.rb b/lib/ruby/stdlib/fiddle/pack.rb deleted file mode 100644 index 22eccedb769..00000000000 --- a/lib/ruby/stdlib/fiddle/pack.rb +++ /dev/null @@ -1,136 +0,0 @@ -# frozen_string_literal: true -require 'fiddle' - -module Fiddle - module PackInfo # :nodoc: all - ALIGN_MAP = { - TYPE_VOIDP => ALIGN_VOIDP, - TYPE_CHAR => ALIGN_CHAR, - TYPE_SHORT => ALIGN_SHORT, - TYPE_INT => ALIGN_INT, - TYPE_LONG => ALIGN_LONG, - TYPE_FLOAT => ALIGN_FLOAT, - TYPE_DOUBLE => ALIGN_DOUBLE, - -TYPE_CHAR => ALIGN_CHAR, - -TYPE_SHORT => ALIGN_SHORT, - -TYPE_INT => ALIGN_INT, - -TYPE_LONG => ALIGN_LONG, - } - - PACK_MAP = { - TYPE_VOIDP => "l!", - TYPE_CHAR => "c", - TYPE_SHORT => "s!", - TYPE_INT => "i!", - TYPE_LONG => "l!", - TYPE_FLOAT => "f", - TYPE_DOUBLE => "d", - -TYPE_CHAR => "c", - -TYPE_SHORT => "s!", - -TYPE_INT => "i!", - -TYPE_LONG => "l!", - } - - SIZE_MAP = { - TYPE_VOIDP => SIZEOF_VOIDP, - TYPE_CHAR => SIZEOF_CHAR, - TYPE_SHORT => SIZEOF_SHORT, - TYPE_INT => SIZEOF_INT, - TYPE_LONG => SIZEOF_LONG, - TYPE_FLOAT => SIZEOF_FLOAT, - TYPE_DOUBLE => SIZEOF_DOUBLE, - -TYPE_CHAR => SIZEOF_CHAR, - -TYPE_SHORT => SIZEOF_SHORT, - -TYPE_INT => SIZEOF_INT, - -TYPE_LONG => SIZEOF_LONG, - } - if defined?(TYPE_LONG_LONG) - ALIGN_MAP[TYPE_LONG_LONG] = ALIGN_MAP[-TYPE_LONG_LONG] = ALIGN_LONG_LONG - PACK_MAP[TYPE_LONG_LONG] = PACK_MAP[-TYPE_LONG_LONG] = "q" - SIZE_MAP[TYPE_LONG_LONG] = SIZE_MAP[-TYPE_LONG_LONG] = SIZEOF_LONG_LONG - PACK_MAP[TYPE_VOIDP] = "q" if SIZEOF_LONG_LONG == SIZEOF_VOIDP - end - - def align(addr, align) - d = addr % align - if( d == 0 ) - addr - else - addr + (align - d) - end - end - module_function :align - end - - class Packer # :nodoc: all - include PackInfo - - def self.[](*types) - new(types) - end - - def initialize(types) - parse_types(types) - end - - def size() - @size - end - - def pack(ary) - case SIZEOF_VOIDP - when SIZEOF_LONG - ary.pack(@template) - else - if defined?(TYPE_LONG_LONG) and - SIZEOF_VOIDP == SIZEOF_LONG_LONG - ary.pack(@template) - else - raise(RuntimeError, "sizeof(void*)?") - end - end - end - - def unpack(ary) - case SIZEOF_VOIDP - when SIZEOF_LONG - ary.join().unpack(@template) - else - if defined?(TYPE_LONG_LONG) and - SIZEOF_VOIDP == SIZEOF_LONG_LONG - ary.join().unpack(@template) - else - raise(RuntimeError, "sizeof(void*)?") - end - end - end - - private - - def parse_types(types) - @template = "".dup - addr = 0 - types.each{|t| - orig_addr = addr - if( t.is_a?(Array) ) - addr = align(orig_addr, ALIGN_MAP[TYPE_VOIDP]) - else - addr = align(orig_addr, ALIGN_MAP[t]) - end - d = addr - orig_addr - if( d > 0 ) - @template << "x#{d}" - end - if( t.is_a?(Array) ) - @template << (PACK_MAP[t[0]] * t[1]) - addr += (SIZE_MAP[t[0]] * t[1]) - else - @template << PACK_MAP[t] - addr += SIZE_MAP[t] - end - } - addr = align(addr, ALIGN_MAP[TYPE_VOIDP]) - @size = addr - end - end -end diff --git a/lib/ruby/stdlib/fiddle/struct.rb b/lib/ruby/stdlib/fiddle/struct.rb deleted file mode 100644 index 6d05bbd7421..00000000000 --- a/lib/ruby/stdlib/fiddle/struct.rb +++ /dev/null @@ -1,539 +0,0 @@ -# frozen_string_literal: true -require 'fiddle' -require 'fiddle/value' -require 'fiddle/pack' - -module Fiddle - # A base class for objects representing a C structure - class CStruct - include Enumerable - - # accessor to Fiddle::CStructEntity - def CStruct.entity_class - CStructEntity - end - - def self.offsetof(name, members, types) # :nodoc: - offset = 0 - worklist = name.split('.') - this_type = self - while search_name = worklist.shift - index = 0 - member_index = members.index(search_name) - - unless member_index - # Possibly a sub-structure - member_index = members.index { |member_name, _| - member_name == search_name - } - return unless member_index - end - - types.each { |type, count = 1| - orig_offset = offset - if type.respond_to?(:entity_class) - align = type.alignment - type_size = type.size - else - align = PackInfo::ALIGN_MAP[type] - type_size = PackInfo::SIZE_MAP[type] - end - - # Unions shouldn't advance the offset - if this_type.entity_class == CUnionEntity - type_size = 0 - end - - offset = PackInfo.align(orig_offset, align) - - if worklist.empty? - return offset if index == member_index - else - if index == member_index - subtype = types[member_index] - members = subtype.members - types = subtype.types - this_type = subtype - break - end - end - - offset += (type_size * count) - index += 1 - } - end - nil - end - - def each - return enum_for(__function__) unless block_given? - - self.class.members.each do |name,| - yield(self[name]) - end - end - - def each_pair - return enum_for(__function__) unless block_given? - - self.class.members.each do |name,| - yield(name, self[name]) - end - end - - def to_h - hash = {} - each_pair do |name, value| - hash[name] = unstruct(value) - end - hash - end - - def replace(another) - if another.nil? - self.class.members.each do |name,| - self[name] = nil - end - elsif another.respond_to?(:each_pair) - another.each_pair do |name, value| - self[name] = value - end - else - another.each do |name, value| - self[name] = value - end - end - self - end - - private - def unstruct(value) - case value - when CStruct - value.to_h - when Array - value.collect do |v| - unstruct(v) - end - else - value - end - end - end - - # A base class for objects representing a C union - class CUnion - # accessor to Fiddle::CUnionEntity - def CUnion.entity_class - CUnionEntity - end - - def self.offsetof(name, members, types) # :nodoc: - 0 - end - end - - # Wrapper for arrays within a struct - class StructArray < Array - include ValueUtil - - def initialize(ptr, type, initial_values) - @ptr = ptr - @type = type - @is_struct = @type.respond_to?(:entity_class) - if @is_struct - super(initial_values) - else - @size = Fiddle::PackInfo::SIZE_MAP[type] - @pack_format = Fiddle::PackInfo::PACK_MAP[type] - super(initial_values.collect { |v| unsigned_value(v, type) }) - end - end - - def to_ptr - @ptr - end - - def []=(index, value) - if index < 0 || index >= size - raise IndexError, 'index %d outside of array bounds 0...%d' % [index, size] - end - - if @is_struct - self[index].replace(value) - else - to_ptr[index * @size, @size] = [value].pack(@pack_format) - super(index, value) - end - end - end - - # Used to construct C classes (CUnion, CStruct, etc) - # - # Fiddle::Importer#struct and Fiddle::Importer#union wrap this functionality in an - # easy-to-use manner. - module CStructBuilder - # Construct a new class given a C: - # * class +klass+ (CUnion, CStruct, or other that provide an - # #entity_class) - # * +types+ (Fiddle::TYPE_INT, Fiddle::TYPE_SIZE_T, etc., see the C types - # constants) - # * corresponding +members+ - # - # Fiddle::Importer#struct and Fiddle::Importer#union wrap this functionality in an - # easy-to-use manner. - # - # Examples: - # - # require 'fiddle/struct' - # require 'fiddle/cparser' - # - # include Fiddle::CParser - # - # types, members = parse_struct_signature(['int i','char c']) - # - # MyStruct = Fiddle::CStructBuilder.create(Fiddle::CUnion, types, members) - # - # MyStruct.malloc(Fiddle::RUBY_FREE) do |obj| - # ... - # end - # - # obj = MyStruct.malloc(Fiddle::RUBY_FREE) - # begin - # ... - # ensure - # obj.call_free - # end - # - # obj = MyStruct.malloc - # begin - # ... - # ensure - # Fiddle.free obj.to_ptr - # end - # - def create(klass, types, members) - new_class = Class.new(klass){ - define_method(:initialize){|addr, func = nil| - if addr.is_a?(self.class.entity_class) - @entity = addr - else - @entity = self.class.entity_class.new(addr, types, func) - end - @entity.assign_names(members) - } - define_method(:[]) { |*args| @entity.send(:[], *args) } - define_method(:[]=) { |*args| @entity.send(:[]=, *args) } - define_method(:to_ptr){ @entity } - define_method(:to_i){ @entity.to_i } - define_singleton_method(:types) { types } - define_singleton_method(:members) { members } - - # Return the offset of a struct member given its name. - # For example: - # - # MyStruct = struct [ - # "int64_t i", - # "char c", - # ] - # - # MyStruct.offsetof("i") # => 0 - # MyStruct.offsetof("c") # => 8 - # - define_singleton_method(:offsetof) { |name| - klass.offsetof(name, members, types) - } - members.each{|name| - name = name[0] if name.is_a?(Array) # name is a nested struct - next if method_defined?(name) - define_method(name){ @entity[name] } - define_method(name + "="){|val| @entity[name] = val } - } - entity_class = klass.entity_class - alignment = entity_class.alignment(types) - size = entity_class.size(types) - define_singleton_method(:alignment) { alignment } - define_singleton_method(:size) { size } - define_singleton_method(:malloc) do |func=nil, &block| - if block - entity_class.malloc(types, func, size) do |entity| - block.call(new(entity)) - end - else - new(entity_class.malloc(types, func, size)) - end - end - } - return new_class - end - module_function :create - end - - # A pointer to a C structure - class CStructEntity < Fiddle::Pointer - include PackInfo - include ValueUtil - - def CStructEntity.alignment(types) - max = 1 - types.each do |type, count = 1| - if type.respond_to?(:entity_class) - n = type.alignment - else - n = ALIGN_MAP[type] - end - max = n if n > max - end - max - end - - # Allocates a C struct with the +types+ provided. - # - # See Fiddle::Pointer.malloc for memory management issues. - def CStructEntity.malloc(types, func = nil, size = size(types), &block) - if block_given? - super(size, func) do |struct| - struct.set_ctypes types - yield struct - end - else - struct = super(size, func) - struct.set_ctypes types - struct - end - end - - # Returns the offset for the packed sizes for the given +types+. - # - # Fiddle::CStructEntity.size( - # [ Fiddle::TYPE_DOUBLE, - # Fiddle::TYPE_INT, - # Fiddle::TYPE_CHAR, - # Fiddle::TYPE_VOIDP ]) #=> 24 - def CStructEntity.size(types) - offset = 0 - - max_align = types.map { |type, count = 1| - last_offset = offset - - if type.respond_to?(:entity_class) - align = type.alignment - type_size = type.size - else - align = PackInfo::ALIGN_MAP[type] - type_size = PackInfo::SIZE_MAP[type] - end - offset = PackInfo.align(last_offset, align) + - (type_size * count) - - align - }.max - - PackInfo.align(offset, max_align) - end - - # Wraps the C pointer +addr+ as a C struct with the given +types+. - # - # When the instance is garbage collected, the C function +func+ is called. - # - # See also Fiddle::Pointer.new - def initialize(addr, types, func = nil) - if func && addr.is_a?(Pointer) && addr.free - raise ArgumentError, 'free function specified on both underlying struct Pointer and when creating a CStructEntity - who do you want to free this?' - end - set_ctypes(types) - super(addr, @size, func) - end - - # Set the names of the +members+ in this C struct - def assign_names(members) - @members = [] - @nested_structs = {} - members.each_with_index do |member, index| - if member.is_a?(Array) # nested struct - member_name = member[0] - struct_type, struct_count = @ctypes[index] - if struct_count.nil? - struct = struct_type.new(to_i + @offset[index]) - else - structs = struct_count.times.map do |i| - struct_type.new(to_i + @offset[index] + i * struct_type.size) - end - struct = StructArray.new(to_i + @offset[index], - struct_type, - structs) - end - @nested_structs[member_name] = struct - else - member_name = member - end - @members << member_name - end - end - - # Calculates the offsets and sizes for the given +types+ in the struct. - def set_ctypes(types) - @ctypes = types - @offset = [] - offset = 0 - - max_align = types.map { |type, count = 1| - orig_offset = offset - if type.respond_to?(:entity_class) - align = type.alignment - type_size = type.size - else - align = ALIGN_MAP[type] - type_size = SIZE_MAP[type] - end - offset = PackInfo.align(orig_offset, align) - - @offset << offset - - offset += (type_size * count) - - align - }.max - - @size = PackInfo.align(offset, max_align) - end - - # Fetch struct member +name+ if only one argument is specified. If two - # arguments are specified, the first is an offset and the second is a - # length and this method returns the string of +length+ bytes beginning at - # +offset+. - # - # Examples: - # - # my_struct = struct(['int id']).malloc - # my_struct.id = 1 - # my_struct['id'] # => 1 - # my_struct[0, 4] # => "\x01\x00\x00\x00".b - # - def [](*args) - return super(*args) if args.size > 1 - name = args[0] - idx = @members.index(name) - if( idx.nil? ) - raise(ArgumentError, "no such member: #{name}") - end - ty = @ctypes[idx] - if( ty.is_a?(Array) ) - if ty.first.respond_to?(:entity_class) - return @nested_structs[name] - else - r = super(@offset[idx], SIZE_MAP[ty[0]] * ty[1]) - end - elsif ty.respond_to?(:entity_class) - return @nested_structs[name] - else - r = super(@offset[idx], SIZE_MAP[ty.abs]) - end - packer = Packer.new([ty]) - val = packer.unpack([r]) - case ty - when Array - case ty[0] - when TYPE_VOIDP - val = val.collect{|v| Pointer.new(v)} - end - when TYPE_VOIDP - val = Pointer.new(val[0]) - else - val = val[0] - end - if( ty.is_a?(Integer) && (ty < 0) ) - return unsigned_value(val, ty) - elsif( ty.is_a?(Array) && (ty[0] < 0) ) - return StructArray.new(self + @offset[idx], ty[0], val) - else - return val - end - end - - # Set struct member +name+, to value +val+. If more arguments are - # specified, writes the string of bytes to the memory at the given - # +offset+ and +length+. - # - # Examples: - # - # my_struct = struct(['int id']).malloc - # my_struct['id'] = 1 - # my_struct[0, 4] = "\x01\x00\x00\x00".b - # my_struct.id # => 1 - # - def []=(*args) - return super(*args) if args.size > 2 - name, val = *args - name = name.to_s if name.is_a?(Symbol) - nested_struct = @nested_structs[name] - if nested_struct - if nested_struct.is_a?(StructArray) - if val.nil? - nested_struct.each do |s| - s.replace(nil) - end - else - val.each_with_index do |v, i| - nested_struct[i] = v - end - end - else - nested_struct.replace(val) - end - return val - end - idx = @members.index(name) - if( idx.nil? ) - raise(ArgumentError, "no such member: #{name}") - end - ty = @ctypes[idx] - packer = Packer.new([ty]) - val = wrap_arg(val, ty, []) - buff = packer.pack([val].flatten()) - super(@offset[idx], buff.size, buff) - if( ty.is_a?(Integer) && (ty < 0) ) - return unsigned_value(val, ty) - elsif( ty.is_a?(Array) && (ty[0] < 0) ) - return val.collect{|v| unsigned_value(v,ty[0])} - else - return val - end - end - - undef_method :size= - def to_s() # :nodoc: - super(@size) - end - end - - # A pointer to a C union - class CUnionEntity < CStructEntity - include PackInfo - - # Returns the size needed for the union with the given +types+. - # - # Fiddle::CUnionEntity.size( - # [ Fiddle::TYPE_DOUBLE, - # Fiddle::TYPE_INT, - # Fiddle::TYPE_CHAR, - # Fiddle::TYPE_VOIDP ]) #=> 8 - def CUnionEntity.size(types) - types.map { |type, count = 1| - if type.respond_to?(:entity_class) - type.size * count - else - PackInfo::SIZE_MAP[type] * count - end - }.max - end - - # Calculate the necessary offset and for each union member with the given - # +types+ - def set_ctypes(types) - @ctypes = types - @offset = Array.new(types.length, 0) - @size = self.class.size types - end - end -end diff --git a/lib/ruby/stdlib/fiddle/types.rb b/lib/ruby/stdlib/fiddle/types.rb deleted file mode 100644 index 7baf31ec9ec..00000000000 --- a/lib/ruby/stdlib/fiddle/types.rb +++ /dev/null @@ -1,73 +0,0 @@ -# frozen_string_literal: true -module Fiddle - # Adds Windows type aliases to the including class for use with - # Fiddle::Importer. - # - # The aliases added are: - # * ATOM - # * BOOL - # * BYTE - # * DWORD - # * DWORD32 - # * DWORD64 - # * HANDLE - # * HDC - # * HINSTANCE - # * HWND - # * LPCSTR - # * LPSTR - # * PBYTE - # * PDWORD - # * PHANDLE - # * PVOID - # * PWORD - # * UCHAR - # * UINT - # * ULONG - # * WORD - module Win32Types - def included(m) # :nodoc: - # https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types - m.module_eval{ - typealias "ATOM", "WORD" - typealias "BOOL", "int" - typealias "BYTE", "unsigned char" - typealias "DWORD", "unsigned long" - typealias "DWORD32", "uint32_t" - typealias "DWORD64", "uint64_t" - typealias "HANDLE", "PVOID" - typealias "HDC", "HANDLE" - typealias "HINSTANCE", "HANDLE" - typealias "HWND", "HANDLE" - typealias "LPCSTR", "const char *" - typealias "LPSTR", "char *" - typealias "PBYTE", "BYTE *" - typealias "PDWORD", "DWORD *" - typealias "PHANDLE", "HANDLE *" - typealias "PVOID", "void *" - typealias "PWORD", "WORD *" - typealias "UCHAR", "unsigned char" - typealias "UINT", "unsigned int" - typealias "ULONG", "unsigned long" - typealias "WORD", "unsigned short" - } - end - module_function :included - end - - # Adds basic type aliases to the including class for use with Fiddle::Importer. - # - # The aliases added are +uint+ and +u_int+ (unsigned int) and - # +ulong+ and +u_long+ (unsigned long) - module BasicTypes - def included(m) # :nodoc: - m.module_eval{ - typealias "uint", "unsigned int" - typealias "u_int", "unsigned int" - typealias "ulong", "unsigned long" - typealias "u_long", "unsigned long" - } - end - module_function :included - end -end diff --git a/lib/ruby/stdlib/fiddle/value.rb b/lib/ruby/stdlib/fiddle/value.rb deleted file mode 100644 index 01fec1c206d..00000000000 --- a/lib/ruby/stdlib/fiddle/value.rb +++ /dev/null @@ -1,122 +0,0 @@ -# frozen_string_literal: true -require 'fiddle' - -module Fiddle - module ValueUtil #:nodoc: all - def unsigned_value(val, ty) - case ty.abs - when TYPE_CHAR - [val].pack("c").unpack("C")[0] - when TYPE_SHORT - [val].pack("s!").unpack("S!")[0] - when TYPE_INT - [val].pack("i!").unpack("I!")[0] - when TYPE_LONG - [val].pack("l!").unpack("L!")[0] - else - if defined?(TYPE_LONG_LONG) and - ty.abs == TYPE_LONG_LONG - [val].pack("q").unpack("Q")[0] - else - val - end - end - end - - def signed_value(val, ty) - case ty.abs - when TYPE_CHAR - [val].pack("C").unpack("c")[0] - when TYPE_SHORT - [val].pack("S!").unpack("s!")[0] - when TYPE_INT - [val].pack("I!").unpack("i!")[0] - when TYPE_LONG - [val].pack("L!").unpack("l!")[0] - else - if defined?(TYPE_LONG_LONG) and - ty.abs == TYPE_LONG_LONG - [val].pack("Q").unpack("q")[0] - else - val - end - end - end - - def wrap_args(args, tys, funcs, &block) - result = [] - tys ||= [] - args.each_with_index{|arg, idx| - result.push(wrap_arg(arg, tys[idx], funcs, &block)) - } - result - end - - def wrap_arg(arg, ty, funcs = [], &block) - funcs ||= [] - case arg - when nil - return 0 - when Pointer - return arg.to_i - when IO - case ty - when TYPE_VOIDP - return Pointer[arg].to_i - else - return arg.to_i - end - when Function - if( block ) - arg.bind_at_call(&block) - funcs.push(arg) - elsif !arg.bound? - raise(RuntimeError, "block must be given.") - end - return arg.to_i - when String - if( ty.is_a?(Array) ) - return arg.unpack('C*') - else - case SIZEOF_VOIDP - when SIZEOF_LONG - return [arg].pack("p").unpack("l!")[0] - else - if defined?(SIZEOF_LONG_LONG) and - SIZEOF_VOIDP == SIZEOF_LONG_LONG - return [arg].pack("p").unpack("q")[0] - else - raise(RuntimeError, "sizeof(void*)?") - end - end - end - when Float, Integer - return arg - when Array - if( ty.is_a?(Array) ) # used only by struct - case ty[0] - when TYPE_VOIDP - return arg.collect{|v| Integer(v)} - when TYPE_CHAR - if( arg.is_a?(String) ) - return val.unpack('C*') - end - end - return arg - else - return arg - end - else - if( arg.respond_to?(:to_ptr) ) - return arg.to_ptr.to_i - else - begin - return Integer(arg) - rescue - raise(ArgumentError, "unknown argument type: #{arg.class}") - end - end - end - end - end -end diff --git a/lib/ruby/stdlib/fiddle/version.rb b/lib/ruby/stdlib/fiddle/version.rb deleted file mode 100644 index db6504b6508..00000000000 --- a/lib/ruby/stdlib/fiddle/version.rb +++ /dev/null @@ -1,3 +0,0 @@ -module Fiddle - VERSION = "1.1.0" -end