require 'test_base' 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)" extern "float atof(string)" extern "unsigned long strtoul(char*, char **, int)" extern "int qsort(void*, int, int, void*)" extern "void fprintf(FILE*, char*)" extern "int gettimeofday(timeval*, timezone*)" rescue nil QsortCallback = bind("void *qsort_callback(void*, void*)", :temp) BoundQsortCallback = bind("void *qsort_callback(void*, void*)"){|ptr1,ptr2| ptr1[0] <=> ptr2[0]} Timeval = struct [ "long tv_sec", "long tv_usec", ] Timezone = struct [ "int tz_minuteswest", "int tz_dsttime", ] MyStruct = struct [ "int num[10]", "unsigned char buff[8]", ] CallCallback = bind("void call_callback(void*, void*)"){|ptr1, ptr2| f = Function.new(CFunc.new(ptr1.to_i, DL::TYPE_VOID, ""), [TYPE_VOIDP]) f.call(ptr2) } CarriedFunction = bind("void callback_function(void*)", :carried, 0) end class TestImport < TestBase def test_sizeof() assert_equal(DL::SIZEOF_VOIDP, LIBC.sizeof("FILE*")) assert_equal(LIBC::MyStruct.size(), LIBC.sizeof(LIBC::MyStruct)) end def test_unsigned_result() d = (2 ** 31) + 1 r = LIBC.strtoul(d.to_s, 0, 0) assert_equal(d, r) end def test_io() io_in,io_out = IO.pipe() LIBC.fprintf(io_out, "hello") 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) 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() s.num = [0,1,2,3,4,5,6,7,8,9] s.buff = "0123456\377" assert_equal([0,1,2,3,4,5,6,7,8,9], s.num) assert_equal([?0,?1,?2,?3,?4,?5,?6,?\377], s.buff) 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() r1 = LIBC.isdigit(?1) r2 = LIBC.isdigit(?2) rr = LIBC.isdigit(?r) 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