mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* ext/fiddle/*: Adding fiddle library to wrap libffi
* test/fiddle/*: testing fiddle extension * ext/dl/lib/dl.rb: Requiring fiddle if it is available * ext/dl/lib/dl/callback.rb: using Fiddle if it is available * ext/dl/lib/dl/func.rb: ditto git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27640 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
ca3c007f05
commit
4bada8b864
22 changed files with 1084 additions and 71 deletions
71
test/fiddle/helper.rb
Normal file
71
test/fiddle/helper.rb
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
require 'minitest/autorun'
|
||||
require 'dl'
|
||||
require 'fiddle'
|
||||
|
||||
# FIXME: this is stolen from DL and needs to be refactored.
|
||||
require_relative '../ruby/envutil'
|
||||
|
||||
libc_so = libm_so = nil
|
||||
|
||||
case RUBY_PLATFORM
|
||||
when /cygwin/
|
||||
libc_so = "cygwin1.dll"
|
||||
libm_so = "cygwin1.dll"
|
||||
when /x86_64-linux/
|
||||
libc_so = "/lib64/libc.so.6"
|
||||
libm_so = "/lib64/libm.so.6"
|
||||
when /linux/
|
||||
libdir = '/lib'
|
||||
case [0].pack('L!').size
|
||||
when 4
|
||||
# 32-bit ruby
|
||||
libdir = '/lib32' if File.directory? '/lib32'
|
||||
when 8
|
||||
# 64-bit ruby
|
||||
libdir = '/lib64' if File.directory? '/lib64'
|
||||
end
|
||||
libc_so = File.join(libdir, "libc.so.6")
|
||||
libm_so = File.join(libdir, "libm.so.6")
|
||||
when /mingw/, /mswin/
|
||||
require "rbconfig"
|
||||
libc_so = libm_so = RbConfig::CONFIG["RUBY_SO_NAME"].split(/-/, 2)[0] + ".dll"
|
||||
when /darwin/
|
||||
libc_so = "/usr/lib/libc.dylib"
|
||||
libm_so = "/usr/lib/libm.dylib"
|
||||
when /kfreebsd/
|
||||
libc_so = "/lib/libc.so.0.1"
|
||||
libm_so = "/lib/libm.so.1"
|
||||
when /bsd|dragonfly/
|
||||
libc_so = "/usr/lib/libc.so"
|
||||
libm_so = "/usr/lib/libm.so"
|
||||
else
|
||||
libc_so = ARGV[0] if ARGV[0] && ARGV[0][0] == ?/
|
||||
libm_so = ARGV[1] if ARGV[1] && ARGV[1][0] == ?/
|
||||
if( !(libc_so && libm_so) )
|
||||
$stderr.puts("libc and libm not found: #{$0} <libc> <libm>")
|
||||
end
|
||||
end
|
||||
|
||||
libc_so = nil if !libc_so || (libc_so[0] == ?/ && !File.file?(libc_so))
|
||||
libm_so = nil if !libm_so || (libm_so[0] == ?/ && !File.file?(libm_so))
|
||||
|
||||
if !libc_so || !libm_so
|
||||
ruby = EnvUtil.rubybin
|
||||
ldd = `ldd #{ruby}`
|
||||
#puts ldd
|
||||
libc_so = $& if !libc_so && %r{/\S*/libc\.so\S*} =~ ldd
|
||||
libm_so = $& if !libm_so && %r{/\S*/libm\.so\S*} =~ ldd
|
||||
#p [libc_so, libm_so]
|
||||
end
|
||||
|
||||
Fiddle::LIBC_SO = libc_so
|
||||
Fiddle::LIBM_SO = libm_so
|
||||
|
||||
module Fiddle
|
||||
class TestCase < MiniTest::Unit::TestCase
|
||||
def setup
|
||||
@libc = DL.dlopen(LIBC_SO)
|
||||
@libm = DL.dlopen(LIBM_SO)
|
||||
end
|
||||
end
|
||||
end
|
||||
49
test/fiddle/test_closure.rb
Normal file
49
test/fiddle/test_closure.rb
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
require_relative 'helper'
|
||||
|
||||
module Fiddle
|
||||
class TestClosure < Fiddle::TestCase
|
||||
def test_argument_errors
|
||||
assert_raises(TypeError) do
|
||||
Closure.new(TYPE_INT, TYPE_INT)
|
||||
end
|
||||
|
||||
assert_raises(TypeError) do
|
||||
Closure.new('foo', [TYPE_INT])
|
||||
end
|
||||
|
||||
assert_raises(TypeError) do
|
||||
Closure.new(TYPE_INT, ['meow!'])
|
||||
end
|
||||
end
|
||||
|
||||
def test_call
|
||||
closure = Class.new(Closure) {
|
||||
def call
|
||||
10
|
||||
end
|
||||
}.new(TYPE_INT, [])
|
||||
|
||||
func = Function.new(closure, [], TYPE_INT)
|
||||
assert_equal 10, func.call
|
||||
end
|
||||
|
||||
def test_returner
|
||||
closure = Class.new(Closure) {
|
||||
def call thing
|
||||
thing
|
||||
end
|
||||
}.new(TYPE_INT, [TYPE_INT])
|
||||
|
||||
func = Function.new(closure, [TYPE_INT], TYPE_INT)
|
||||
assert_equal 10, func.call(10)
|
||||
end
|
||||
|
||||
def test_block_caller
|
||||
cb = Closure::BlockCaller.new(TYPE_INT, [TYPE_INT]) do |one|
|
||||
one
|
||||
end
|
||||
func = Function.new(cb, [TYPE_INT], TYPE_INT)
|
||||
assert_equal 11, func.call(11)
|
||||
end
|
||||
end
|
||||
end
|
||||
19
test/fiddle/test_fiddle.rb
Normal file
19
test/fiddle/test_fiddle.rb
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
require_relative 'helper'
|
||||
|
||||
class TestFiddle < Fiddle::TestCase
|
||||
def test_constants_match
|
||||
[
|
||||
:TYPE_VOID,
|
||||
:TYPE_VOIDP,
|
||||
:TYPE_CHAR,
|
||||
:TYPE_SHORT,
|
||||
:TYPE_INT,
|
||||
:TYPE_LONG,
|
||||
:TYPE_LONG_LONG,
|
||||
:TYPE_FLOAT,
|
||||
:TYPE_DOUBLE,
|
||||
].each do |name|
|
||||
assert_equal(DL.const_get(name), Fiddle.const_get(name))
|
||||
end
|
||||
end
|
||||
end
|
||||
66
test/fiddle/test_function.rb
Normal file
66
test/fiddle/test_function.rb
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
require_relative 'helper'
|
||||
|
||||
module Fiddle
|
||||
class TestFunction < Fiddle::TestCase
|
||||
def setup
|
||||
super
|
||||
Fiddle.last_error = nil
|
||||
end
|
||||
|
||||
def test_default_abi
|
||||
func = Function.new(@libm['sin'], [TYPE_DOUBLE], TYPE_DOUBLE)
|
||||
assert_equal Function::DEFAULT, func.abi
|
||||
end
|
||||
|
||||
def test_argument_errors
|
||||
assert_raises(TypeError) do
|
||||
Function.new(@libm['sin'], TYPE_DOUBLE, TYPE_DOUBLE)
|
||||
end
|
||||
|
||||
assert_raises(TypeError) do
|
||||
Function.new(@libm['sin'], ['foo'], TYPE_DOUBLE)
|
||||
end
|
||||
|
||||
assert_raises(TypeError) do
|
||||
Function.new(@libm['sin'], [TYPE_DOUBLE], 'foo')
|
||||
end
|
||||
end
|
||||
|
||||
def test_call
|
||||
func = Function.new(@libm['sin'], [TYPE_DOUBLE], TYPE_DOUBLE)
|
||||
assert_in_delta 1.0, func.call(90 * Math::PI / 180), 0.0001
|
||||
end
|
||||
|
||||
def test_argument_count
|
||||
closure = Class.new(Closure) {
|
||||
def call one
|
||||
10 + one
|
||||
end
|
||||
}.new(TYPE_INT, [TYPE_INT])
|
||||
func = Function.new(closure, [TYPE_INT], TYPE_INT)
|
||||
|
||||
assert_raises(ArgumentError) do
|
||||
func.call(1,2,3)
|
||||
end
|
||||
assert_raises(ArgumentError) do
|
||||
func.call
|
||||
end
|
||||
end
|
||||
|
||||
def test_last_error
|
||||
func = Function.new(@libc['strcpy'], [TYPE_VOIDP, TYPE_VOIDP], TYPE_VOIDP)
|
||||
|
||||
assert_nil Fiddle.last_error
|
||||
str = func.call("000", "123")
|
||||
refute_nil Fiddle.last_error
|
||||
end
|
||||
|
||||
def test_strcpy
|
||||
f = Function.new(@libc['strcpy'], [TYPE_VOIDP, TYPE_VOIDP], TYPE_VOIDP)
|
||||
buff = "000"
|
||||
str = f.call(buff, "123")
|
||||
assert_equal("123", buff)
|
||||
assert_equal("123", str.to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue