From c1fb6a82dcfbd308390d380d62c7127635fc66db Mon Sep 17 00:00:00 2001 From: tenderlove Date: Tue, 27 Nov 2012 19:54:50 +0000 Subject: * ext/fiddle/handle.c: Make Fiddle independent of DL, copy DL::Handle to Fiddle::Handle. * ext/fiddle/pointer.c: Make Fiddle independent of DL, copy DL::Pointer to Fiddle::Pointer. * test/fiddle/test_func.rb: relevent tests * test/fiddle/test_handle.rb: ditto * test/fiddle/test_pointer.rb: ditto * ext/dl/lib/dl/struct.rb: use Fiddle::Pointer if available * ext/fiddle/extconf.rb: check for dlfcn.h * ext/fiddle/fiddle.c: add constants for sizeof() things * ext/fiddle/fiddle.h: include dlfcn.h * ext/fiddle/function.c: expose a C function for creating new Fiddle::Function objects. * ext/fiddle/lib/fiddle.rb: include constants for dl backwards compat * ext/fiddle/lib/fiddle/function.rb: read the pointer from the function for dl backwards compat. * test/dl/test_callback.rb: check the addresses of the pointers rather than their types. * test/fiddle/helper.rb: remove dependency on dl * test/fiddle/test_closure.rb: ditto * test/fiddle/test_fiddle.rb: ditto git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37907 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- test/fiddle/test_pointer.rb | 231 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 test/fiddle/test_pointer.rb (limited to 'test/fiddle/test_pointer.rb') diff --git a/test/fiddle/test_pointer.rb b/test/fiddle/test_pointer.rb new file mode 100644 index 0000000000..ef33b91062 --- /dev/null +++ b/test/fiddle/test_pointer.rb @@ -0,0 +1,231 @@ +require_relative 'helper' +require_relative '../ruby/envutil' + +module Fiddle + class TestPointer < TestCase + def dlwrap arg + Fiddle.dlwrap arg + end + + include Test::Unit::Assertions + + def test_cptr_to_int + null = Fiddle::NULL + assert_equal(null.to_i, null.to_int) + end + + def test_malloc_free_func_int + free = Fiddle::Function.new(Fiddle::RUBY_FREE, [TYPE_VOIDP], TYPE_VOID) + assert_equal free.to_i, Fiddle::RUBY_FREE.to_i + + ptr = Pointer.malloc(10, free.to_i) + assert_equal 10, ptr.size + assert_equal free.to_i, ptr.free.to_i + end + + def test_malloc_free_func + free = Fiddle::Function.new(Fiddle::RUBY_FREE, [TYPE_VOIDP], TYPE_VOID) + + ptr = Pointer.malloc(10, free) + assert_equal 10, ptr.size + assert_equal free.to_i, ptr.free.to_i + end + + def test_to_str + str = "hello world" + ptr = Pointer[str] + + assert_equal 3, ptr.to_str(3).length + assert_equal str, ptr.to_str + + ptr[5] = 0 + assert_equal "hello\0world", ptr.to_str + end + + def test_to_s + str = "hello world" + ptr = Pointer[str] + + assert_equal 3, ptr.to_s(3).length + assert_equal str, ptr.to_s + + ptr[5] = 0 + assert_equal 'hello', ptr.to_s + end + + def test_minus + str = "hello world" + ptr = Pointer[str] + assert_equal ptr.to_s, (ptr + 3 - 3).to_s + end + + # TODO: what if the pointer size is 0? raise an exception? do we care? + def test_plus + str = "hello world" + ptr = Pointer[str] + new_str = ptr + 3 + assert_equal 'lo world', new_str.to_s + end + + def test_inspect + ptr = Pointer.new(0) + inspect = ptr.inspect + assert_match(/size=#{ptr.size}/, inspect) + assert_match(/free=#{sprintf("%#x", ptr.free.to_i)}/, inspect) + assert_match(/ptr=#{sprintf("%#x", ptr.to_i)}/, inspect) + end + + def test_to_ptr_string + str = "hello world" + ptr = Pointer[str] + assert ptr.tainted?, 'pointer should be tainted' + assert_equal str.length, ptr.size + assert_equal 'hello', ptr[0,5] + end + + def test_to_ptr_io + buf = Pointer.malloc(10) + File.open(__FILE__, 'r') do |f| + ptr = Pointer.to_ptr f + fread = Function.new(@libc['fread'], + [TYPE_VOIDP, TYPE_INT, TYPE_INT, TYPE_VOIDP], + TYPE_INT) + fread.call(buf.to_i, Fiddle::SIZEOF_CHAR, buf.size - 1, ptr.to_i) + end + + File.open(__FILE__, 'r') do |f| + assert_equal f.read(9), buf.to_s + end + end + + def test_to_ptr_with_ptr + ptr = Pointer.new 0 + ptr2 = Pointer.to_ptr Struct.new(:to_ptr).new(ptr) + assert_equal ptr, ptr2 + + assert_raises(Fiddle::DLError) do + Pointer.to_ptr Struct.new(:to_ptr).new(nil) + end + end + + def test_to_ptr_with_num + ptr = Pointer.new 0 + assert_equal ptr, Pointer[0] + end + + def test_equals + ptr = Pointer.new 0 + ptr2 = Pointer.new 0 + assert_equal ptr2, ptr + end + + def test_not_equals + ptr = Pointer.new 0 + refute_equal 10, ptr, '10 should not equal the pointer' + end + + def test_cmp + ptr = Pointer.new 0 + assert_nil(ptr <=> 10, '10 should not be comparable') + end + + def test_ref_ptr + ary = [0,1,2,4,5] + addr = Pointer.new(dlwrap(ary)) + assert_equal addr.to_i, addr.ref.ptr.to_i + + assert_equal addr.to_i, (+ (- addr)).to_i + end + + def test_to_value + ary = [0,1,2,4,5] + addr = Pointer.new(dlwrap(ary)) + assert_equal ary, addr.to_value + end + + def test_free + ptr = Pointer.malloc(4) + assert_nil ptr.free + end + + def test_free= + assert_normal_exit(<<-"End", '[ruby-dev:39269]') + require 'fiddle' + Fiddle::LIBC_SO = #{Fiddle::LIBC_SO.dump} + Fiddle::LIBM_SO = #{Fiddle::LIBM_SO.dump} + include Fiddle + @libc = dlopen(LIBC_SO) + @libm = dlopen(LIBM_SO) + free = Fiddle::Function.new(Fiddle::RUBY_FREE, [TYPE_VOIDP], TYPE_VOID) + ptr = Fiddle::Pointer.malloc(4) + ptr.free = free + free.ptr + ptr.free.ptr + End + + free = Function.new(Fiddle::RUBY_FREE, [TYPE_VOIDP], TYPE_VOID) + ptr = Pointer.malloc(4) + ptr.free = free + + assert_equal free.ptr, ptr.free.ptr + end + + def test_null? + ptr = Pointer.new(0) + assert ptr.null? + end + + def test_size + ptr = Pointer.malloc(4) + assert_equal 4, ptr.size + Fiddle.free ptr.to_i + end + + def test_size= + ptr = Pointer.malloc(4) + ptr.size = 10 + assert_equal 10, ptr.size + Fiddle.free ptr.to_i + end + + def test_aref_aset + check = Proc.new{|str,ptr| + assert_equal(str.size(), ptr.size()) + assert_equal(str, ptr.to_s()) + assert_equal(str[0,2], ptr.to_s(2)) + assert_equal(str[0,2], ptr[0,2]) + assert_equal(str[1,2], ptr[1,2]) + assert_equal(str[1,0], ptr[1,0]) + assert_equal(str[0].ord, ptr[0]) + assert_equal(str[1].ord, ptr[1]) + } + str = 'abc' + ptr = Pointer[str] + check.call(str, ptr) + + str[0] = "c" + assert_equal 'c'.ord, ptr[0] = "c".ord + check.call(str, ptr) + + str[0,2] = "aa" + assert_equal 'aa', ptr[0,2] = "aa" + check.call(str, ptr) + + ptr2 = Pointer['cdeeee'] + str[0,2] = "cd" + assert_equal ptr2, ptr[0,2] = ptr2 + check.call(str, ptr) + + ptr3 = Pointer['vvvv'] + str[0,2] = "vv" + assert_equal ptr3.to_i, ptr[0,2] = ptr3.to_i + check.call(str, ptr) + end + + def test_null_pointer + nullpo = Pointer.new(0) + assert_raise(DLError) {nullpo[0]} + assert_raise(DLError) {nullpo[0] = 1} + end + end +end -- cgit v1.2.3