2012-11-06 04:49:57 +04:00
|
|
|
# coding: US-ASCII
|
2009-09-10 21:14:53 +04:00
|
|
|
require_relative 'test_base'
|
2005-02-04 16:35:37 +03:00
|
|
|
require 'dl/import'
|
|
|
|
|
|
|
|
module DL
|
|
|
|
module LIBC
|
|
|
|
extend Importer
|
|
|
|
dlload LIBC_SO, LIBM_SO
|
|
|
|
|
|
|
|
typealias 'string', 'char*'
|
|
|
|
typealias 'FILE*', 'void*'
|
|
|
|
|
|
|
|
extern "void *strcpy(char*, char*)"
|
|
|
|
extern "int isdigit(int)"
|
2008-12-29 17:54:24 +03:00
|
|
|
extern "double atof(string)"
|
2005-02-04 16:35:37 +03:00
|
|
|
extern "unsigned long strtoul(char*, char **, int)"
|
2008-12-30 11:05:06 +03:00
|
|
|
extern "int qsort(void*, unsigned long, unsigned long, void*)"
|
2008-12-29 17:54:24 +03:00
|
|
|
extern "int fprintf(FILE*, char*)"
|
2005-02-04 16:35:37 +03:00
|
|
|
extern "int gettimeofday(timeval*, timezone*)" rescue nil
|
|
|
|
|
|
|
|
QsortCallback = bind("void *qsort_callback(void*, void*)", :temp)
|
2010-02-16 13:03:02 +03:00
|
|
|
BoundQsortCallback = bind("void *bound_qsort_callback(void*, void*)"){|ptr1,ptr2| ptr1[0] <=> ptr2[0]}
|
2005-02-04 16:35:37 +03:00
|
|
|
Timeval = struct [
|
|
|
|
"long tv_sec",
|
|
|
|
"long tv_usec",
|
|
|
|
]
|
|
|
|
Timezone = struct [
|
|
|
|
"int tz_minuteswest",
|
|
|
|
"int tz_dsttime",
|
|
|
|
]
|
|
|
|
MyStruct = struct [
|
2006-06-30 22:05:40 +04:00
|
|
|
"short num[5]",
|
|
|
|
"char c",
|
|
|
|
"unsigned char buff[7]",
|
2005-02-04 16:35:37 +03:00
|
|
|
]
|
|
|
|
|
|
|
|
CallCallback = bind("void call_callback(void*, void*)"){|ptr1, ptr2|
|
2012-11-28 04:02:49 +04:00
|
|
|
f = Function.new(CFunc.new(ptr1.to_i, TYPE_VOID, "<anonymous>"), [TYPE_VOIDP])
|
2005-02-04 16:35:37 +03:00
|
|
|
f.call(ptr2)
|
|
|
|
}
|
|
|
|
CarriedFunction = bind("void callback_function(void*)", :carried, 0)
|
|
|
|
end
|
|
|
|
|
|
|
|
class TestImport < TestBase
|
2010-07-06 03:38:35 +04:00
|
|
|
def test_ensure_call_dlload
|
|
|
|
err = assert_raises(RuntimeError) do
|
|
|
|
Class.new do
|
2012-11-28 04:02:49 +04:00
|
|
|
extend Importer
|
2010-07-06 03:38:35 +04:00
|
|
|
extern "void *strcpy(char*, char*)"
|
|
|
|
end
|
|
|
|
end
|
2010-07-06 03:39:51 +04:00
|
|
|
assert_match(/call dlload before/, err.message)
|
2010-07-06 03:38:35 +04:00
|
|
|
end
|
|
|
|
|
2005-05-09 18:43:50 +04:00
|
|
|
def test_malloc()
|
|
|
|
s1 = LIBC::Timeval.malloc()
|
|
|
|
s2 = LIBC::Timeval.malloc()
|
|
|
|
assert_not_equal(s1.to_ptr.to_i, s2.to_ptr.to_i)
|
|
|
|
end
|
|
|
|
|
2005-02-06 09:54:12 +03:00
|
|
|
def test_sizeof()
|
2012-11-28 04:02:49 +04:00
|
|
|
assert_equal(SIZEOF_VOIDP, LIBC.sizeof("FILE*"))
|
2005-02-06 09:54:12 +03:00
|
|
|
assert_equal(LIBC::MyStruct.size(), LIBC.sizeof(LIBC::MyStruct))
|
|
|
|
end
|
|
|
|
|
2005-02-04 16:35:37 +03:00
|
|
|
def test_unsigned_result()
|
|
|
|
d = (2 ** 31) + 1
|
2009-03-06 06:56:38 +03:00
|
|
|
|
2005-02-04 16:35:37 +03:00
|
|
|
r = LIBC.strtoul(d.to_s, 0, 0)
|
|
|
|
assert_equal(d, r)
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_io()
|
2012-11-28 04:02:49 +04:00
|
|
|
if( RUBY_PLATFORM != BUILD_RUBY_PLATFORM )
|
2005-05-15 00:59:07 +04:00
|
|
|
return
|
|
|
|
end
|
2005-02-04 16:35:37 +03:00
|
|
|
io_in,io_out = IO.pipe()
|
2005-02-08 02:08:26 +03:00
|
|
|
LIBC.fprintf(io_out, "hello")
|
2005-02-04 16:35:37 +03:00
|
|
|
io_out.flush()
|
|
|
|
io_out.close()
|
|
|
|
str = io_in.read()
|
|
|
|
io_in.close()
|
|
|
|
assert_equal("hello", str)
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_value()
|
|
|
|
i = LIBC.value('int', 2)
|
|
|
|
assert_equal(2, i.value)
|
2009-03-06 06:56:38 +03:00
|
|
|
|
2005-02-04 16:35:37 +03:00
|
|
|
d = LIBC.value('double', 2.0)
|
|
|
|
assert_equal(2.0, d.value)
|
|
|
|
|
|
|
|
ary = LIBC.value('int[3]', [0,1,2])
|
|
|
|
assert_equal([0,1,2], ary.value)
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_carried_function()
|
|
|
|
data1 = "data"
|
|
|
|
data2 = nil
|
|
|
|
LIBC.call_callback(LIBC::CarriedFunction, LIBC::CarriedFunction.create_carrier(data1)){|d|
|
|
|
|
data2 = d
|
|
|
|
}
|
|
|
|
assert_equal(data1, data2)
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_struct()
|
|
|
|
s = LIBC::MyStruct.malloc()
|
2006-06-30 22:05:40 +04:00
|
|
|
s.num = [0,1,2,3,4]
|
2008-08-30 18:39:21 +04:00
|
|
|
s.c = ?a.ord
|
2006-06-30 22:05:40 +04:00
|
|
|
s.buff = "012345\377"
|
|
|
|
assert_equal([0,1,2,3,4], s.num)
|
2008-08-30 18:39:21 +04:00
|
|
|
assert_equal(?a.ord, s.c)
|
|
|
|
assert_equal([?0.ord,?1.ord,?2.ord,?3.ord,?4.ord,?5.ord,?\377.ord], s.buff)
|
2005-02-04 16:35:37 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
def test_gettimeofday()
|
|
|
|
if( defined?(LIBC.gettimeofday) )
|
|
|
|
timeval = LIBC::Timeval.malloc()
|
|
|
|
timezone = LIBC::Timezone.malloc()
|
|
|
|
LIBC.gettimeofday(timeval, timezone)
|
|
|
|
cur = Time.now()
|
|
|
|
assert(cur.to_i - 2 <= timeval.tv_sec && timeval.tv_sec <= cur.to_i)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_strcpy()
|
|
|
|
buff = "000"
|
|
|
|
str = LIBC.strcpy(buff, "123")
|
|
|
|
assert_equal("123", buff)
|
|
|
|
assert_equal("123", str.to_s)
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_isdigit()
|
2008-08-30 18:39:21 +04:00
|
|
|
r1 = LIBC.isdigit(?1.ord)
|
|
|
|
r2 = LIBC.isdigit(?2.ord)
|
|
|
|
rr = LIBC.isdigit(?r.ord)
|
2005-02-04 16:35:37 +03:00
|
|
|
assert_positive(r1)
|
|
|
|
assert_positive(r2)
|
|
|
|
assert_zero(rr)
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_atof()
|
|
|
|
r = LIBC.atof("12.34")
|
|
|
|
assert_match(12.00..13.00, r)
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_strtod()
|
|
|
|
f = Function.new(CFunc.new(@libc['strtod'], TYPE_DOUBLE, 'strtod'),
|
|
|
|
[TYPE_VOIDP, TYPE_VOIDP])
|
|
|
|
buff1 = "12.34"
|
|
|
|
buff2 = " "
|
|
|
|
r = f.call(buff1, buff2)
|
|
|
|
assert_match(12.00..13.00, r)
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_qsort()
|
|
|
|
buff = "9341"
|
|
|
|
LIBC.qsort(buff, buff.size, 1, LIBC::QsortCallback){|ptr1,ptr2| ptr1[0] <=> ptr2[0]}
|
|
|
|
assert_equal("1349", buff)
|
|
|
|
buff = "9341"
|
|
|
|
LIBC.qsort(buff, buff.size, 1, LIBC::BoundQsortCallback)
|
|
|
|
assert_equal("1349", buff)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|