rubysl-dl 0.0.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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")