1# coding: US-ASCII 2begin 3 require_relative 'helper' 4 require 'fiddle/import' 5rescue LoadError 6end 7 8module Fiddle 9 module LIBC 10 extend Importer 11 dlload LIBC_SO, LIBM_SO 12 13 typealias 'string', 'char*' 14 typealias 'FILE*', 'void*' 15 16 extern "void *strcpy(char*, char*)" 17 extern "int isdigit(int)" 18 extern "double atof(string)" 19 extern "unsigned long strtoul(char*, char **, int)" 20 extern "int qsort(void*, unsigned long, unsigned long, void*)" 21 extern "int fprintf(FILE*, char*)" 22 extern "int gettimeofday(timeval*, timezone*)" rescue nil 23 24 BoundQsortCallback = bind("void *bound_qsort_callback(void*, void*)"){|ptr1,ptr2| ptr1[0] <=> ptr2[0]} 25 Timeval = struct [ 26 "long tv_sec", 27 "long tv_usec", 28 ] 29 Timezone = struct [ 30 "int tz_minuteswest", 31 "int tz_dsttime", 32 ] 33 MyStruct = struct [ 34 "short num[5]", 35 "char c", 36 "unsigned char buff[7]", 37 ] 38 39 CallCallback = bind("void call_callback(void*, void*)"){ | ptr1, ptr2| 40 f = Function.new(ptr1.to_i, [TYPE_VOIDP], TYPE_VOID) 41 f.call(ptr2) 42 } 43 end 44 45 class TestImport < TestCase 46 def test_ensure_call_dlload 47 err = assert_raises(RuntimeError) do 48 Class.new do 49 extend Importer 50 extern "void *strcpy(char*, char*)" 51 end 52 end 53 assert_match(/call dlload before/, err.message) 54 end 55 56 def test_malloc() 57 s1 = LIBC::Timeval.malloc() 58 s2 = LIBC::Timeval.malloc() 59 refute_equal(s1.to_ptr.to_i, s2.to_ptr.to_i) 60 end 61 62 def test_sizeof() 63 assert_equal(SIZEOF_VOIDP, LIBC.sizeof("FILE*")) 64 assert_equal(LIBC::MyStruct.size(), LIBC.sizeof(LIBC::MyStruct)) 65 assert_equal(LIBC::MyStruct.size(), LIBC.sizeof(LIBC::MyStruct.malloc())) 66 end 67 68 def test_unsigned_result() 69 d = (2 ** 31) + 1 70 71 r = LIBC.strtoul(d.to_s, 0, 0) 72 assert_equal(d, r) 73 end 74 75 def test_io() 76 if( RUBY_PLATFORM != BUILD_RUBY_PLATFORM ) 77 return 78 end 79 io_in,io_out = IO.pipe() 80 LIBC.fprintf(io_out, "hello") 81 io_out.flush() 82 io_out.close() 83 str = io_in.read() 84 io_in.close() 85 assert_equal("hello", str) 86 end 87 88 def test_value() 89 i = LIBC.value('int', 2) 90 assert_equal(2, i.value) 91 92 d = LIBC.value('double', 2.0) 93 assert_equal(2.0, d.value) 94 95 ary = LIBC.value('int[3]', [0,1,2]) 96 assert_equal([0,1,2], ary.value) 97 end 98 99 def test_struct() 100 s = LIBC::MyStruct.malloc() 101 s.num = [0,1,2,3,4] 102 s.c = ?a.ord 103 s.buff = "012345\377" 104 assert_equal([0,1,2,3,4], s.num) 105 assert_equal(?a.ord, s.c) 106 assert_equal([?0.ord,?1.ord,?2.ord,?3.ord,?4.ord,?5.ord,?\377.ord], s.buff) 107 end 108 109 def test_gettimeofday() 110 if( defined?(LIBC.gettimeofday) ) 111 timeval = LIBC::Timeval.malloc() 112 timezone = LIBC::Timezone.malloc() 113 LIBC.gettimeofday(timeval, timezone) 114 cur = Time.now() 115 assert(cur.to_i - 2 <= timeval.tv_sec && timeval.tv_sec <= cur.to_i) 116 end 117 end 118 119 def test_strcpy() 120 buff = "000" 121 str = LIBC.strcpy(buff, "123") 122 assert_equal("123", buff) 123 assert_equal("123", str.to_s) 124 end 125 126 def test_isdigit 127 r1 = LIBC.isdigit(?1.ord) 128 r2 = LIBC.isdigit(?2.ord) 129 rr = LIBC.isdigit(?r.ord) 130 assert_operator(r1, :>, 0) 131 assert_operator(r2, :>, 0) 132 assert_equal(0, rr) 133 end 134 135 def test_atof 136 r = LIBC.atof("12.34") 137 assert_includes(12.00..13.00, r) 138 end 139 end 140end if defined?(Fiddle) 141