comparison go/godc/godc_test.go @ 0:0cfcc391201f

initial from svn dyncall-1745
author Daniel Adler
date Thu, 19 Mar 2015 22:26:28 +0100
parents
children 9943c30ee2aa
comparison
equal deleted inserted replaced
-1:000000000000 0:0cfcc391201f
1 /*
2
3 godc_test.go
4 Copyright (c) 2014 Tassilo Philipp <tphilipp@potion-studios.com>
5
6 Permission to use, copy, modify, and distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18 */
19
20
21 package godc
22
23 import (
24 "testing"
25 "fmt"
26 "unsafe"
27 "math"
28 )
29
30 func TestGoDC(t *testing.T) {
31 lm := new(ExtLib)
32 if err := lm.Load("/usr/lib/libm.so"); err != nil {
33 t.FailNow()
34 }
35 defer lm.Free()
36
37 if err := lm.SymsInit("/usr/lib/libm.so"); err != nil {
38 t.FailNow()
39 }
40 defer lm.SymsCleanup()
41
42 fmt.Printf("Testing dl:\n")
43 fmt.Printf("-----------\n")
44 fmt.Printf("Loaded library at address: %p\n", lm.lib)
45 fmt.Printf("C sqrt function at address: %p\n", lm.FindSymbol("sqrt"))
46 fmt.Printf("C pow function at address: %p\n\n", lm.FindSymbol("pow"))
47
48 fmt.Printf("Testing dlSyms:\n")
49 fmt.Printf("---------------\n")
50 fmt.Printf("Symbols in libm: %d\n", lm.SymsCount())
51 fmt.Printf("Symbol name for address %p: %s\n", lm.FindSymbol("pow"), lm.SymsNameFromValue(lm.FindSymbol("pow")))
52 fmt.Printf("All symbol names in libm:\n")
53 for i, n := 0, lm.SymsCount(); i<n; i++ {
54 fmt.Printf(" %s\n", lm.SymsName(i))
55 }
56 fmt.Printf("\n")
57
58
59
60 // Another lib
61 lc := new(ExtLib)
62 if err := lc.Load("/usr/lib/libc.so"); err != nil {
63 t.FailNow()
64 }
65 defer lc.Free()
66
67 if err := lc.SymsInit("/usr/lib/libc.so"); err != nil {
68 t.FailNow()
69 }
70 defer lc.SymsCleanup()
71
72 fmt.Printf("Symbols in libc: %d (not listing them here, too many)\n\n", lc.SymsCount())
73
74
75
76 // Call some functions
77 fmt.Printf("Testing dc:\n")
78 fmt.Printf("-----------\n")
79 vm := new(CallVM)
80 if err := vm.InitCallVM(); err != nil {
81 t.FailNow()
82 }
83 defer vm.Free()
84
85 vm.Mode(DC_CALL_C_DEFAULT)
86
87
88 // Float
89 vm.Reset()
90 vm.ArgFloat(36)
91 rf := vm.CallFloat(lm.FindSymbol("sqrtf"))
92 fmt.Printf("sqrtf(36) = %f\n", rf)
93 if(rf != 6.0) { t.FailNow() }
94
95 vm.Reset() // Test reset, reusing VM
96 vm.ArgDouble(3.6)
97 rd := vm.CallDouble(lm.FindSymbol("floor"))
98 fmt.Printf("floor(3.6) = %f\n", rd)
99 if(rd != 3.0) { t.FailNow() }
100
101
102 // Double
103 vm.Reset()
104 vm.ArgDouble(4.2373)
105 rd = vm.CallDouble(lm.FindSymbol("sqrt"))
106 fmt.Printf("sqrt(4.2373) = %f\n", rd)
107 if(math.Abs(rd - 2.05847) > 0.00001) { t.FailNow() }
108
109 vm.Reset()
110 vm.ArgDouble(2.373)
111 vm.ArgDouble(-1000) // 2 args
112 rd = vm.CallDouble(lm.FindSymbol("copysign"))
113 fmt.Printf("copysign(2.373, -1000) = %f\n", rd)
114 if(rd != -2.373) { t.FailNow() }
115
116
117 // Strings
118 vm.Reset()
119 cs1 := vm.AllocCString("/return/only/this_here")
120 defer vm.FreeCString(cs1)
121
122 vm.ArgPointer(cs1)
123 rs := vm.CallPointerToStr(lc.FindSymbol("basename"))
124 fmt.Printf("basename(\"/return/only/this_here\") = %s\n", rs)
125 if(rs != "this_here") { t.FailNow() }
126 // Reuse path
127 rs = vm.CallPointerToStr(lc.FindSymbol("dirname"))
128 fmt.Printf("dirname(\"/return/only/this_here\") = %s\n", rs)
129 if(rs != "/return/only") { t.FailNow() }
130
131
132 // Integer
133 vm.Reset()
134 vm.ArgInt('a')
135 ri := vm.CallInt(lc.FindSymbol("toupper"))
136 fmt.Printf("toupper('a') = %c\n", ri)
137 if(ri != 'A') { t.FailNow() }
138
139 vm.Reset()
140 vm.ArgInt('a')
141 ri = vm.CallInt(lc.FindSymbol("tolower"))
142 fmt.Printf("tolower('a') = %c\n", ri)
143 if(ri != 'a') { t.FailNow() }
144
145 vm.Reset()
146 vm.ArgInt('R')
147 ri = vm.CallInt(lc.FindSymbol("toupper"))
148 fmt.Printf("toupper('R') = %c\n", vm.CallInt(lc.FindSymbol("toupper")))
149 if(ri != 'R') { t.FailNow() }
150
151 vm.Reset()
152 vm.ArgInt('R')
153 ri = vm.CallInt(lc.FindSymbol("tolower"))
154 fmt.Printf("tolower('R') = %c\n", vm.CallInt(lc.FindSymbol("tolower")))
155 if(ri != 'r') { t.FailNow() }
156
157
158 // Integer return
159 vm.Reset()
160 cs2 := vm.AllocCString("Tassilo")
161 defer vm.FreeCString(cs2)
162
163 fmt.Printf("rand() = %d\n", vm.CallInt(lc.FindSymbol("rand")))
164 fmt.Printf("rand() = %d\n", vm.CallInt(lc.FindSymbol("rand")))
165 fmt.Printf("rand() = %d\n", vm.CallInt(lc.FindSymbol("rand")))
166 fmt.Printf("rand() = %d\n", vm.CallInt(lc.FindSymbol("rand")))
167 fmt.Printf("rand() = %d\n", vm.CallInt(lc.FindSymbol("rand")))
168 vm.ArgPointer(cs2)
169 ri = vm.CallInt(lc.FindSymbol("strlen"))
170 fmt.Printf("strlen(\"Tassilo\") = %d\n", ri)
171 if(ri != 7) { t.FailNow() }
172
173
174 // Formatted - with signature/conversion
175 vm.Reset()
176 vm.ArgF("dd)d", 3.14, -2000) // 2 args, second passed as int, but ArgF will convert
177 rd = vm.CallDouble(lm.FindSymbol("copysign"))
178 fmt.Printf("dd)d: copysign(3.14, -2000) = %f\n", rd)
179 if(rd != -3.14) { t.FailNow() }
180
181 // Formatted - without signature/conversion
182 vm.Reset()
183 vm.ArgF("dd)d", -31.4, 42.4) // 2 args, second passed as int, but ArgF will convert
184 rd = vm.CallDouble(lm.FindSymbol("copysign"))
185 fmt.Printf("dd)d: copysign(-31.4, 42.4) = %f\n", rd)
186 if(rd != 31.4) { t.FailNow() }
187
188 // Formatted - use Go's types, pass unsupported type, should return an error
189 vm.Reset()
190 err := vm.ArgF_Go(6.14, vm)
191 fmt.Printf("ArgF_Go: copysign(6.14, <unsupported type>) should return error: %t\n", err != nil)
192 if(err == nil) { t.FailNow() }
193
194 // Formatted - use Go's types
195 vm.Reset()
196 vm.ArgF_Go(-61.4, 42.4) // 2 args, both need to be correct or undefined behaviour
197 rd = vm.CallDouble(lm.FindSymbol("copysign"))
198 fmt.Printf("copysign(-61.4, 42.4) = %f\n", rd)
199 if(rd != 61.4) { t.FailNow() }
200
201
202 // Ellipse
203 vm.Mode(DC_CALL_C_ELLIPSIS)
204 vm.Reset()
205 buf := make([]byte, 1000)
206 bufPtr := unsafe.Pointer(&buf[0])
207 cs3 := vm.AllocCString("Four:%d | \"Hello\":%s | Pi:%f")
208 cs4 := vm.AllocCString("Hello")
209 defer vm.FreeCString(cs4)
210 defer vm.FreeCString(cs3)
211
212 vm.ArgPointer(bufPtr)
213 vm.ArgPointer(cs3)
214 vm.Mode(DC_CALL_C_ELLIPSIS_VARARGS)
215 vm.ArgInt(4)
216 vm.ArgPointer(cs4)
217 vm.ArgDouble(3.14) // Double, b/c of ... promotion rules
218 ri = vm.CallInt(lc.FindSymbol("sprintf"))
219 fmt.Printf("sprintf(bufPtr, \"Four:%%d | \\\"Hello\\\":%%s | Pi:%%f\", 4, \"Hello\", 3.14) = %d:\n", ri)
220 fmt.Printf(" bufPtr: %s\n", string(buf[/*slice printed bytes*/:ri]))
221 if(ri != 36) { t.FailNow() }
222
223
224 //@@@ untested:
225 // - ArgF and ArgF_Go with strings
226 // - ArgF and ArgF_Go with bools
227 // - ...
228 }
229