Introduction
Introduction Statistics Contact Development Disclaimer Help
tfuncall.lisp - clic - Clic is an command line interactive client for gopher wr…
git clone git://bitreich.org/clic/ git://hg6vgqziawt5s4dj.onion/clic/
Log
Files
Refs
Tags
LICENSE
---
tfuncall.lisp (8245B)
---
1 ;;;; -*- Mode: lisp; indent-tabs-mode: nil -*-
2 ;;;
3 ;;; funcall.lisp --- Tests function calling.
4 ;;;
5 ;;; Copyright (C) 2005-2006, James Bielman <[email protected]>
6 ;;; Copyright (C) 2005-2007, Luis Oliveira <[email protected]>
7 ;;;
8 ;;; Permission is hereby granted, free of charge, to any person
9 ;;; obtaining a copy of this software and associated documentation
10 ;;; files (the "Software"), to deal in the Software without
11 ;;; restriction, including without limitation the rights to use, copy,
12 ;;; modify, merge, publish, distribute, sublicense, and/or sell copies
13 ;;; of the Software, and to permit persons to whom the Software is
14 ;;; furnished to do so, subject to the following conditions:
15 ;;;
16 ;;; The above copyright notice and this permission notice shall be
17 ;;; included in all copies or substantial portions of the Software.
18 ;;;
19 ;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 ;;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 ;;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 ;;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23 ;;; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24 ;;; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 ;;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 ;;; DEALINGS IN THE SOFTWARE.
27 ;;;
28
29 (in-package #:cffi-tests)
30
31 ;;;# Calling with Built-In C Types
32 ;;;
33 ;;; Tests calling standard C library functions both passing and
34 ;;; returning each built-in type.
35
36 ;;; Don't run these tests if the implementation does not support
37 ;;; foreign-funcall.
38 #-cffi-sys::no-foreign-funcall
39 (progn
40
41 (deftest funcall.char
42 (foreign-funcall "toupper" :char (char-code #\a) :char)
43 #.(char-code #\A))
44
45 (deftest funcall.int.1
46 (foreign-funcall "abs" :int -100 :int)
47 100)
48
49 (defun funcall-abs (n)
50 (foreign-funcall "abs" :int n :int))
51
52 ;;; regression test: lispworks's %foreign-funcall based on creating
53 ;;; and caching foreign-funcallables at macro-expansion time.
54 (deftest funcall.int.2
55 (funcall-abs -42)
56 42)
57
58 (deftest funcall.long
59 (foreign-funcall "labs" :long -131072 :long)
60 131072)
61
62 #-cffi-sys::no-long-long
63 (deftest funcall.long-long
64 (foreign-funcall "my_llabs" :long-long -9223372036854775807 :long-lo…
65 9223372036854775807)
66
67 #-cffi-sys::no-long-long
68 (deftest funcall.unsigned-long-long
69 (let ((ullong-max (1- (expt 2 (* 8 (foreign-type-size :unsigned-long…
70 (eql ullong-max
71 (foreign-funcall "ullong" :unsigned-long-long ullong-max
72 :unsigned-long-long)))
73 t)
74
75 (deftest funcall.float
76 (foreign-funcall "my_sqrtf" :float 16.0 :float)
77 4.0)
78
79 (deftest funcall.double
80 (foreign-funcall "sqrt" :double 36.0d0 :double)
81 6.0d0)
82
83 #+(and scl long-float)
84 (deftest funcall.long-double
85 (foreign-funcall "sqrtl" :long-double 36.0l0 :long-double)
86 6.0l0)
87
88 (deftest funcall.string.1
89 (foreign-funcall "strlen" :string "Hello" :int)
90 5)
91
92 (deftest funcall.string.2
93 (with-foreign-pointer-as-string (s 100)
94 (setf (mem-ref s :char) 0)
95 (foreign-funcall "strcpy" :pointer s :string "Hello" :pointer)
96 (foreign-funcall "strcat" :pointer s :string ", world!" :pointer))
97 "Hello, world!")
98
99 (deftest funcall.string.3
100 (with-foreign-pointer (ptr 100)
101 (lisp-string-to-foreign "Hello, " ptr 8)
102 (foreign-funcall "strcat" :pointer ptr :string "world!" :string))
103 "Hello, world!")
104
105 ;;;# Calling Varargs Functions
106
107 (deftest funcall.varargs.nostdlib
108 (foreign-funcall-varargs
109 "sum_double_arbitrary" (:int 26)
110 :double 3.14d0 :double 3.14d0 :double 3.14d0 :double 3.14d0
111 :double 3.14d0 :double 3.14d0 :double 3.14d0 :double 3.14d0
112 :double 3.14d0 :double 3.14d0 :double 3.14d0 :double 3.14d0
113 :double 3.14d0 :double 3.14d0 :double 3.14d0 :double 3.14d0
114 :double 3.14d0 :double 3.14d0 :double 3.14d0 :double 3.14d0
115 :double 3.14d0 :double 3.14d0 :double 3.14d0 :double 3.14d0
116 :double 3.14d0 :double 3.14d0
117 :double)
118 81.64d0)
119
120 ;; The CHAR argument must be passed as :INT because chars are promoted
121 ;; to ints when passed as variable arguments.
122 (deftest funcall.varargs.char
123 (with-foreign-pointer-as-string (s 100)
124 (setf (mem-ref s :char) 0)
125 (foreign-funcall-varargs
126 "sprintf" (:pointer s :string "%c") :int 65 :int))
127 "A")
128
129 (deftest funcall.varargs.int
130 (with-foreign-pointer-as-string (s 100)
131 (setf (mem-ref s :char) 0)
132 (foreign-funcall-varargs
133 "sprintf" (:pointer s :string "%d") :int 1000 :int))
134 "1000")
135
136 (deftest funcall.varargs.long
137 (with-foreign-pointer-as-string (s 100)
138 (setf (mem-ref s :char) 0)
139 (foreign-funcall-varargs
140 "sprintf" (:pointer s :string "%ld")
141 :long 131072 :int))
142 "131072")
143
144 ;;; There is no FUNCALL.VARARGS.FLOAT as floats are promoted to double
145 ;;; when passed as variable arguments. Currently this fails in SBCL
146 ;;; and CMU CL on Darwin/ppc.
147 (deftest funcall.varargs.double
148 (with-foreign-pointer-as-string (s 100)
149 (setf (mem-ref s :char) 0)
150 (foreign-funcall-varargs
151 "sprintf" (:pointer s :string "%.2f") :double (coerce pi 'double-…
152 "3.14")
153
154 #+(and scl long-float)
155 (deftest funcall.varargs.long-double
156 (with-foreign-pointer-as-string (s 100)
157 (setf (mem-ref s :char) 0)
158 (foreign-funcall-varargs
159 "sprintf" :pointer s :string "%.2Lf" :long-double pi :int))
160 "3.14")
161
162 (deftest funcall.varargs.string
163 (with-foreign-pointer-as-string (s 100)
164 (setf (mem-ref s :char) 0)
165 (foreign-funcall-varargs
166 "sprintf" (:pointer s :string "%s, %s!") :string "Hello" :string …
167 "Hello, world!")
168
169 ;;; See DEFCFUN.DOUBLE26.
170 (deftest funcall.double26
171 (foreign-funcall "sum_double26"
172 :double 3.14d0 :double 3.14d0 :double 3.14d0
173 :double 3.14d0 :double 3.14d0 :double 3.14d0
174 :double 3.14d0 :double 3.14d0 :double 3.14d0
175 :double 3.14d0 :double 3.14d0 :double 3.14d0
176 :double 3.14d0 :double 3.14d0 :double 3.14d0
177 :double 3.14d0 :double 3.14d0 :double 3.14d0
178 :double 3.14d0 :double 3.14d0 :double 3.14d0
179 :double 3.14d0 :double 3.14d0 :double 3.14d0
180 :double 3.14d0 :double 3.14d0 :double)
181 81.64d0)
182
183 ;;; See DEFCFUN.FLOAT26.
184 (deftest funcall.float26
185 (foreign-funcall "sum_float26"
186 :float 5.0 :float 5.0 :float 5.0 :float 5.0 :float …
187 :float 5.0 :float 5.0 :float 5.0 :float 5.0 :float …
188 :float 5.0 :float 5.0 :float 5.0 :float 5.0 :float …
189 :float 5.0 :float 5.0 :float 5.0 :float 5.0 :float …
190 :float 5.0 :float 5.0 :float 5.0 :float 5.0 :float …
191 :float 5.0 :float)
192 130.0)
193
194 ;;; Funcalling a pointer.
195 (deftest funcall.f-s-p.1
196 (foreign-funcall-pointer (foreign-symbol-pointer "abs") nil :int -42…
197 42)
198
199 ;;;# Namespaces
200
201 #-cffi-sys::flat-namespace
202 (deftest funcall.namespace.1
203 (values (foreign-funcall ("ns_function" :library libtest) :boolean)
204 (foreign-funcall ("ns_function" :library libtest2) :boolean))
205 t nil)
206
207 ;;;# stdcall
208
209 #+(and x86 windows (not cffi-sys::no-stdcall))
210 (deftest funcall.stdcall.1
211 (flet ((fun ()
212 (foreign-funcall ("stdcall_fun@12" :convention :stdcall)
213 :int 1 :int 2 :int 3 :int)))
214 (loop repeat 100 do (fun)
215 finally (return (fun))))
216 6)
217
218 ;;; RT: NIL arguments are skipped
219
220 (defvar *nil-skipped*)
221
222 (define-foreign-type check-nil-skip-type ()
223 ()
224 (:actual-type :pointer)
225 (:simple-parser check-nil-skip-type))
226
227 (defmethod expand-to-foreign (val (type check-nil-skip-type))
228 (declare (ignore val))
229 (setf *nil-skipped* nil)
230 (null-pointer))
231
232 (deftest funcall.nil-skip
233 (let ((*nil-skipped* t))
234 (compile nil '(lambda ()
235 (foreign-funcall "abs" check-nil-skip-type nil)))
236 *nil-skipped*)
237 nil)
238
239 ;;; RT: CLISP returns NIL instead of a null-pointer
240
241 (deftest funcall.pointer-not-nil
242 (not (null (foreign-funcall "strchr" :string "" :int 1 :pointer)))
243 t)
244
245 ) ;; #-cffi-sys::no-foreign-funcall
You are viewing proxied material from bitreich.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.