rubysl-dl 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,28 @@
1
+ EXPORTS
2
+ test_alloc_test_struct
3
+ test_append
4
+ test_arylen
5
+ test_c2i
6
+ test_call_func1
7
+ test_callback1
8
+ test_close
9
+ test_d2f
10
+ test_f2d
11
+ test_fill_test_struct
12
+ test_fill_test_union
13
+ test_gets
14
+ test_i2c
15
+ test_init
16
+ test_isucc
17
+ test_lcc
18
+ test_lsucc
19
+ test_open
20
+ test_strcat
21
+ test_strlen
22
+ test_succ
23
+ test_data_init
24
+ test_data_add
25
+ test_data_aref
26
+ test_set_long_value
27
+ test_get_long_value
28
+ internal_long_value
@@ -0,0 +1,247 @@
1
+ #include <stdio.h>
2
+ #include <string.h>
3
+
4
+ static char internal_string[] = "internal_string";
5
+ long internal_long_value = 100;
6
+
7
+ struct test_struct {
8
+ char c;
9
+ long l;
10
+ };
11
+
12
+ union test_union {
13
+ char c;
14
+ int i;
15
+ long l;
16
+ void *p;
17
+ };
18
+
19
+ struct test_data {
20
+ char name[1024];
21
+ struct test_data *next;
22
+ };
23
+
24
+ long
25
+ test_get_long_value()
26
+ {
27
+ return internal_long_value;
28
+ };
29
+
30
+ void
31
+ test_set_long_value(long l)
32
+ {
33
+ internal_long_value = l;
34
+ };
35
+
36
+ void
37
+ test_fill_test_struct(struct test_struct *ptr, char c, long l)
38
+ {
39
+ ptr->c = c;
40
+ ptr->l = l;
41
+ };
42
+
43
+ void
44
+ test_fill_test_union(union test_union *ptr, long l)
45
+ {
46
+ ptr->l = l;
47
+ };
48
+
49
+ struct test_struct *
50
+ test_alloc_test_struct(char c, long l)
51
+ {
52
+ struct test_struct *data;
53
+
54
+ data = (struct test_struct *)malloc(sizeof(struct test_struct));
55
+ data->c = c;
56
+ data->l = l;
57
+
58
+ return data;
59
+ };
60
+
61
+ int
62
+ test_c2i(char c)
63
+ {
64
+ return (int)c;
65
+ };
66
+
67
+ char
68
+ test_i2c(int i)
69
+ {
70
+ return (char)i;
71
+ };
72
+
73
+ long
74
+ test_lcc(char c1, char c2)
75
+ {
76
+ return (long)(c1 + c2);
77
+ };
78
+
79
+ double
80
+ test_f2d(float f)
81
+ {
82
+ double d;
83
+ d = f;
84
+ return d;
85
+ };
86
+
87
+ float
88
+ test_d2f(double d)
89
+ {
90
+ float f;
91
+ f = d;
92
+ return f;
93
+ };
94
+
95
+ int
96
+ test_strlen(const char *str)
97
+ {
98
+ return strlen(str);
99
+ };
100
+
101
+ int
102
+ test_isucc(int i)
103
+ {
104
+ return (i+1);
105
+ };
106
+
107
+ long
108
+ test_lsucc(long l)
109
+ {
110
+ return (l+1);
111
+ };
112
+
113
+ void
114
+ test_succ(long *l)
115
+ {
116
+ (*l)++;
117
+ };
118
+
119
+ char *
120
+ test_strcat(char *str1, const char *str2)
121
+ {
122
+ return strcat(str1, str2);
123
+ };
124
+
125
+ int
126
+ test_arylen(char *ary[])
127
+ {
128
+ int i;
129
+ for( i=0; ary[i]; i++ ){};
130
+ return i;
131
+ };
132
+
133
+ void
134
+ test_append(char *ary[], int len, char *astr)
135
+ {
136
+ int i;
137
+ int size1,size2;
138
+ char *str;
139
+
140
+ size2 = strlen(astr);
141
+
142
+ for( i=0; i <= len - 1; i++ ){
143
+ size1 = strlen(ary[i]);
144
+ str = (char*)malloc(size1 + size2 + 1);
145
+ strcpy(str, ary[i]);
146
+ strcat(str, astr);
147
+ ary[i] = str;
148
+ };
149
+ };
150
+
151
+ int
152
+ test_init(int *argc, char **argv[])
153
+ {
154
+ int i;
155
+ char s[256];
156
+
157
+ for( i=0; i < (*argc); i++ ){
158
+ sprintf(s, "arg%d", i);
159
+ if( strcmp((*argv)[i], s) != 0 ){
160
+ return 1;
161
+ }
162
+ }
163
+ return 0;
164
+ }
165
+
166
+ FILE *
167
+ test_open(const char *filename, const char *mode)
168
+ {
169
+ FILE *file;
170
+ file = fopen(filename,mode);
171
+ return file;
172
+ };
173
+
174
+ void
175
+ test_close(FILE *file)
176
+ {
177
+ fclose(file);
178
+ };
179
+
180
+ char *
181
+ test_gets(char *s, int size, FILE *f)
182
+ {
183
+ return fgets(s,size,f);
184
+ };
185
+
186
+ typedef int callback1_t(int, char *);
187
+ #define CALLBACK_MSG "callback message"
188
+
189
+ int
190
+ test_callback1(int err, const char *msg)
191
+ {
192
+ if( strcmp(msg, CALLBACK_MSG) == 0 ){
193
+ return 1;
194
+ }
195
+ else{
196
+ return 0;
197
+ }
198
+ }
199
+
200
+ int
201
+ test_call_func1(callback1_t *func)
202
+ {
203
+ if( func ){
204
+ return (*func)(0, CALLBACK_MSG);
205
+ }
206
+ else{
207
+ return 0;
208
+ }
209
+ }
210
+
211
+ struct test_data *
212
+ test_data_init()
213
+ {
214
+ struct test_data *data;
215
+
216
+ data = (struct test_data *)malloc(sizeof(struct test_data));
217
+ data->next = NULL;
218
+ memset(data->name, 0, 1024);
219
+
220
+ return data;
221
+ };
222
+
223
+ void
224
+ test_data_add(struct test_data *list, const char *name)
225
+ {
226
+ struct test_data *data;
227
+
228
+ data = (struct test_data *)malloc(sizeof(struct test_data));
229
+ memset(data->name, 0, 1024);
230
+ strncpy(data->name, name, 1024);
231
+ data->next = list->next;
232
+ list->next = data;
233
+ };
234
+
235
+ struct test_data *
236
+ test_data_aref(struct test_data *list, int i)
237
+ {
238
+ struct test_data *data;
239
+ int j;
240
+
241
+ for( data = list->next, j=0; data; data = data->next, j++ ){
242
+ if( i == j ){
243
+ return data;
244
+ };
245
+ };
246
+ return NULL;
247
+ };
@@ -0,0 +1,306 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'dl'
4
+ require 'dl/import'
5
+
6
+ $FAIL = 0
7
+ $TOTAL = 0
8
+
9
+ def assert(label, ty, *conds)
10
+ $TOTAL += 1
11
+ cond = !conds.include?(false)
12
+ if( cond )
13
+ printf("succeed in `#{label}'\n")
14
+ else
15
+ $FAIL += 1
16
+ case ty
17
+ when :may
18
+ printf("fail in `#{label}' ... expected\n")
19
+ when :must
20
+ printf("fail in `#{label}' ... unexpected\n")
21
+ when :raise
22
+ raise(RuntimeError, "fail in `#{label}'")
23
+ end
24
+ end
25
+ end
26
+
27
+ def debug(*xs)
28
+ if( $DEBUG )
29
+ xs.each{|x|
30
+ p x
31
+ }
32
+ end
33
+ end
34
+
35
+ print("DLSTACK = #{DL::DLSTACK}\n")
36
+ print("MAX_ARG = #{DL::MAX_ARG}\n")
37
+ print("\n")
38
+ print("DL::FREE = #{DL::FREE.inspect}\n")
39
+ print("\n")
40
+
41
+ $LIB = nil
42
+ if( !$LIB && File.exist?("libtest.so") )
43
+ $LIB = "./libtest.so"
44
+ end
45
+ if( !$LIB && File.exist?("test/libtest.so") )
46
+ $LIB = "./test/libtest.so"
47
+ end
48
+
49
+ module LIBTest
50
+ extend DL::Importable
51
+
52
+ dlload($LIB)
53
+ extern "int test_c2i(char)"
54
+ extern "char test_i2c(int)"
55
+ extern "long test_lcc(char, char)"
56
+ extern "double test_f2d(float)"
57
+ extern "float test_d2f(double)"
58
+ extern "int test_strlen(char*)"
59
+ extern "int test_isucc(int)"
60
+ extern "long test_lsucc(long)"
61
+ extern "void test_succ(long *)"
62
+ extern "int test_arylen(int [])"
63
+ extern "void test_append(char*[], int, char *)"
64
+ end
65
+
66
+ DL.dlopen($LIB){|h|
67
+ c2i = h["test_c2i","IC"]
68
+ debug c2i
69
+ r,rs = c2i[?a]
70
+ debug r,rs
71
+ assert("c2i", :may, r == ?a)
72
+ assert("extern c2i", :must, r == LIBTest.test_c2i(?a))
73
+
74
+ i2c = h["test_i2c","CI"]
75
+ debug i2c
76
+ r,rs = i2c[?a]
77
+ debug r,rs
78
+ assert("i2c", :may, r == ?a)
79
+ assert("exern i2c", :must, r == LIBTest.test_i2c(?a))
80
+
81
+ lcc = h["test_lcc","LCC"]
82
+ debug lcc
83
+ r,rs = lcc[1,2]
84
+ assert("lcc", :may, r == 3)
85
+ assert("extern lcc", :must, r == LIBTest.test_lcc(1,2))
86
+
87
+ f2d = h["test_f2d","DF"]
88
+ debug f2d
89
+ r,rs = f2d[20.001]
90
+ debug r,rs
91
+ assert("f2d", :may, r.to_i == 20)
92
+ assert("extern f2d", :must, r = LIBTest.test_f2d(20.001))
93
+
94
+ d2f = h["test_d2f","FD"]
95
+ debug d2f
96
+ r,rs = d2f[20.001]
97
+ debug r,rs
98
+ assert("d2f", :may, r.to_i == 20)
99
+ assert("extern d2f", :must, r == LIBTest.test_d2f(20.001))
100
+
101
+ strlen = h["test_strlen","IS"]
102
+ debug strlen
103
+ r,rs = strlen["0123456789"]
104
+ debug r,rs
105
+ assert("strlen", :must, r == 10)
106
+ assert("extern strlen", :must, r == LIBTest.test_strlen("0123456789"))
107
+
108
+ isucc = h["test_isucc","II"]
109
+ debug isucc
110
+ r,rs = isucc[2]
111
+ debug r,rs
112
+ assert("isucc", :must, r == 3)
113
+ assert("extern isucc", :must, r == LIBTest.test_isucc(2))
114
+
115
+ lsucc = h["test_lsucc","LL"]
116
+ debug lsucc
117
+ r,rs = lsucc[10000000]
118
+ debug r,rs
119
+ assert("lsucc", :must, r == 10000001)
120
+ assert("extern lsucc", :must, r == LIBTest.test_lsucc(10000000))
121
+
122
+ succ = h["test_succ","0l"]
123
+ debug succ
124
+ r,rs = succ[0]
125
+ debug r,rs
126
+ assert("succ", :must, rs[0] == 1)
127
+ l = DL.malloc(DL.sizeof("L"))
128
+ l.struct!("L",:lval)
129
+ LIBTest.test_succ(l)
130
+ assert("extern succ", :must, rs[0] == l[:lval])
131
+
132
+ arylen = h["test_arylen","IA"]
133
+ debug arylen
134
+ r,rs = arylen[["a","b","c","d",nil]]
135
+ debug r,rs
136
+ assert("arylen", :must, r == 4)
137
+
138
+ arylen = h["test_arylen","IP"]
139
+ debug arylen
140
+ r,rs = arylen[["a","b","c","d",nil]]
141
+ debug r,rs
142
+ assert("arylen", :must, r == 4)
143
+ assert("extern arylen", :must, r == LIBTest.test_arylen(["a","b","c","d",nil]))
144
+
145
+ append = h["test_append","0aIS"]
146
+ debug append
147
+ r,rs = append[["a","b","c"],3,"x"]
148
+ debug r,rs
149
+ assert("append", :must, rs[0].to_a('S',3) == ["ax","bx","cx"])
150
+
151
+ LIBTest.test_append(["a","b","c"],3,"x")
152
+ assert("extern append", :must, rs[0].to_a('S',3) == LIBTest._args_[0].to_a('S',3))
153
+
154
+ strcat = h["test_strcat","SsS"]
155
+ debug strcat
156
+ r,rs = strcat["abc\0","x"]
157
+ debug r,rs
158
+ assert("strcat", :must, rs[0].to_s == "abcx")
159
+
160
+ init = h["test_init","IiP"]
161
+ debug init
162
+ argc = 3
163
+ argv = ["arg0","arg1","arg2"].to_ptr
164
+ r,rs = init[argc, argv.ref]
165
+ assert("init", :must, r == 0)
166
+ }
167
+
168
+
169
+ h = DL.dlopen($LIB)
170
+
171
+ sym_open = h["test_open", "PSS"]
172
+ sym_gets = h["test_gets", "SsIP"]
173
+ sym_close = h["test_close", "0P"]
174
+ debug sym_open,sym_gets,sym_close
175
+
176
+ line = "Hello world!\n"
177
+ File.open("tmp.txt", "w"){|f|
178
+ f.print(line)
179
+ }
180
+
181
+ fp,rs = sym_open["tmp.txt", "r"]
182
+ if( fp )
183
+ fp.free = sym_close
184
+ r,rs = sym_gets[" " * 256, 256, fp]
185
+ debug r,rs
186
+ assert("open,gets", :must, rs[0] == line)
187
+ ObjectSpace.define_finalizer(fp) {File.unlink("tmp.txt")}
188
+ fp = nil
189
+ else
190
+ assert("open,gets", :must, line == nil)
191
+ File.unlink("tmp.txt")
192
+ end
193
+
194
+
195
+ callback1 = h["test_callback1"]
196
+ debug callback1
197
+ r,rs = h["test_call_func1", "IP"][callback1]
198
+ debug r,rs
199
+ assert("callback1", :must, r == 1)
200
+
201
+
202
+ callback2 = DL.callback("LLP"){|num,ptr|
203
+ msg = ptr.to_s
204
+ if( msg == "callback message" )
205
+ 2
206
+ else
207
+ 0
208
+ end
209
+ }
210
+ debug callback2
211
+ r,rs = h["test_call_func1", "IP"][callback2]
212
+ debug r,rs
213
+ assert("callback2", :must, r == 2)
214
+ DL.remove_callback(callback2)
215
+
216
+ ptr = DL.malloc(DL.sizeof('CL'))
217
+ ptr.struct!("CL", :c, :l)
218
+ ptr["c"] = 0
219
+ ptr["l"] = 0
220
+ r,rs = h["test_fill_test_struct","0PIL"][ptr,100,1000]
221
+ debug r,rs
222
+ assert("fill_test_struct", :must, ptr["c"] == 100, ptr["l"] == 1000)
223
+ assert("fill_test_struct", :must, ptr[:c] == 100, ptr[:l] == 1000) unless (Fixnum === :-)
224
+
225
+
226
+ r,rs = h["test_alloc_test_struct", "PIL"][100,200]
227
+ r.free = DL::FREE
228
+ r.struct!("CL", :c, :l)
229
+ assert("alloc_test_struct", :must, r["c"] == 100, r["l"] == 200)
230
+ assert("alloc_test_struct", :must, r[:c] == 100, r[:l] == 200) unless (Fixnum === :-)
231
+
232
+ ptr = h["test_strlen"]
233
+ sym1 = DL::Symbol.new(ptr,"foo","0")
234
+ sym2 = h["test_strlen","LS"]
235
+ assert("Symbol.new", :must, ptr == sym1.to_ptr, sym1.to_ptr == sym2.to_ptr)
236
+
237
+ set_val = h["test_set_long_value","0"]
238
+ get_val = h["test_get_long_value","L"]
239
+ lval = get_val[][0]
240
+ ptr = h["internal_long_value"]
241
+ ptr.struct!("L", :l)
242
+ assert("get value", :must, ptr["l"] == lval)
243
+ assert("get value", :must, ptr[:l] == lval) unless (Fixnum === :-)
244
+ ptr["l"] = 200
245
+ lval = get_val[][0]
246
+ assert("set value", :must, ptr["l"] == lval)
247
+ assert("set value", :must, ptr[:l] == lval) unless (Fixnum === :-)
248
+
249
+
250
+ data_init = h["test_data_init", "P"]
251
+ data_add = h["test_data_add", "0PS"]
252
+ data_aref = h["test_data_aref", "PPI"]
253
+ r,rs = data_init[]
254
+ ptr = r
255
+ data_add[ptr, "name1"]
256
+ data_add[ptr, "name2"]
257
+ data_add[ptr, "name3"]
258
+
259
+ r,rs = data_aref[ptr, 1]
260
+ ptr = r
261
+ ptr.struct!("C1024P", :name, :next)
262
+ assert("data_aref", :must,
263
+ ptr["name"].collect{|c| c.chr}.join.split("\0")[0] == "name2")
264
+ assert("data_aref", :must,
265
+ ptr["name"].collect{|c| c.chr}.join.split("\0")[0] == "name2") unless (Fixnum === :-)
266
+
267
+ ptr = ptr["next"]
268
+ ptr.struct!("C1024P", :name, :next)
269
+ assert("data_aref", :must,
270
+ ptr["name"].collect{|c| c.chr}.join.split("\0")[0] == "name1")
271
+ assert("data_aref", :must,
272
+ ptr["name"].collect{|c| c.chr}.join.split("\0")[0] == "name1") unless (Fixnum === :-)
273
+
274
+ GC.start
275
+
276
+ ptr = DL::malloc(32)
277
+ ptr.struct!("CHIL", "c", "h", "i", "l")
278
+ ptr["c"] = 1
279
+ ptr["h"] = 2
280
+ ptr["i"] = 3
281
+ ptr["l"] = 4
282
+ assert("struct!", :must,
283
+ ptr["c"] == 1 &&
284
+ ptr["h"] == 2 &&
285
+ ptr["i"] == 3 &&
286
+ ptr["l"] == 4)
287
+
288
+ ptr = DL::malloc(DL::sizeof("IP"))
289
+ ptr.struct!("IP", "n", "ptr")
290
+ ptr["n"] = 10
291
+ ptr["ptr"] = nil
292
+ assert("struct!", :must, ptr["n"] == 10 && ptr["ptr"] == nil)
293
+
294
+ ptr = DL::malloc(16)
295
+ ptr.struct!("CICI", "c1", "i1", "c2", "i2")
296
+ ptr["c1"] = 0xf1
297
+ ptr["c2"] = 0xf2
298
+ c1 = [ptr["c1"]].pack("c").unpack("C")[0]
299
+ c2 = [ptr["c2"]].pack("c").unpack("C")[0]
300
+ assert("struct!", :must,
301
+ c1 == 0xf1 &&
302
+ c2 == 0xf2)
303
+
304
+
305
+ GC.start
306
+ printf("fail/total = #{$FAIL}/#{$TOTAL}\n")