Recently Written · git

clic

MIRROR ONLY Gopher client with pretty colours in Common Lisp

git clone https://github.com/equwal/clic

Log | Files | Refs


3rdparties/software/cffi_0.21.0/tests/memory.lisp (19020 bytes)

1 ;;;; -*- Mode: lisp; indent-tabs-mode: nil -*-
2 ;;;
3 ;;; memory.lisp --- Tests for memory referencing.
4 ;;;
5 ;;; Copyright (C) 2005-2006, James Bielman  <jamesjb@jamesjb.com>
6 ;;;
7 ;;; Permission is hereby granted, free of charge, to any person
8 ;;; obtaining a copy of this software and associated documentation
9 ;;; files (the "Software"), to deal in the Software without
10 ;;; restriction, including without limitation the rights to use, copy,
11 ;;; modify, merge, publish, distribute, sublicense, and/or sell copies
12 ;;; of the Software, and to permit persons to whom the Software is
13 ;;; furnished to do so, subject to the following conditions:
14 ;;;
15 ;;; The above copyright notice and this permission notice shall be
16 ;;; included in all copies or substantial portions of the Software.
17 ;;;
18 ;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 ;;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 ;;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 ;;; NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22 ;;; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 ;;; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 ;;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 ;;; DEALINGS IN THE SOFTWARE.
26 ;;;
27 
28 (in-package #:cffi-tests)
29 
30 (deftest deref.char
31     (with-foreign-object (p :char)
32       (setf (mem-ref p :char) -127)
33       (mem-ref p :char))
34   -127)
35 
36 (deftest deref.unsigned-char
37     (with-foreign-object (p :unsigned-char)
38       (setf (mem-ref p :unsigned-char) 255)
39       (mem-ref p :unsigned-char))
40   255)
41 
42 (deftest deref.short
43     (with-foreign-object (p :short)
44       (setf (mem-ref p :short) -32767)
45       (mem-ref p :short))
46   -32767)
47 
48 (deftest deref.unsigned-short
49     (with-foreign-object (p :unsigned-short)
50       (setf (mem-ref p :unsigned-short) 65535)
51       (mem-ref p :unsigned-short))
52   65535)
53 
54 (deftest deref.int
55     (with-foreign-object (p :int)
56       (setf (mem-ref p :int) -131072)
57       (mem-ref p :int))
58   -131072)
59 
60 (deftest deref.unsigned-int
61     (with-foreign-object (p :unsigned-int)
62       (setf (mem-ref p :unsigned-int) 262144)
63       (mem-ref p :unsigned-int))
64   262144)
65 
66 (deftest deref.long
67     (with-foreign-object (p :long)
68       (setf (mem-ref p :long) -536870911)
69       (mem-ref p :long))
70   -536870911)
71 
72 (deftest deref.unsigned-long
73     (with-foreign-object (p :unsigned-long)
74       (setf (mem-ref p :unsigned-long) 536870912)
75       (mem-ref p :unsigned-long))
76   536870912)
77 
78 #+(and darwin openmcl)
79 (pushnew 'deref.long-long rt::*expected-failures*)
80 
81 (deftest deref.long-long
82     (with-foreign-object (p :long-long)
83       (setf (mem-ref p :long-long) -9223372036854775807)
84       (mem-ref p :long-long))
85   -9223372036854775807)
86 
87 (deftest deref.unsigned-long-long
88     (with-foreign-object (p :unsigned-long-long)
89       (setf (mem-ref p :unsigned-long-long) 18446744073709551615)
90       (mem-ref p :unsigned-long-long))
91   18446744073709551615)
92 
93 (deftest deref.float.1
94     (with-foreign-object (p :float)
95       (setf (mem-ref p :float) 0.0)
96       (mem-ref p :float))
97   0.0)
98 
99 (deftest deref.float.2
100     (with-foreign-object (p :float)
101       (setf (mem-ref p :float) *float-max*)
102       (mem-ref p :float))
103   #.*float-max*)
104 
105 (deftest deref.float.3
106     (with-foreign-object (p :float)
107       (setf (mem-ref p :float) *float-min*)
108       (mem-ref p :float))
109   #.*float-min*)
110 
111 (deftest deref.double.1
112     (with-foreign-object (p :double)
113       (setf (mem-ref p :double) 0.0d0)
114       (mem-ref p :double))
115   0.0d0)
116 
117 (deftest deref.double.2
118     (with-foreign-object (p :double)
119       (setf (mem-ref p :double) *double-max*)
120       (mem-ref p :double))
121   #.*double-max*)
122 
123 (deftest deref.double.3
124     (with-foreign-object (p :double)
125       (setf (mem-ref p :double) *double-min*)
126       (mem-ref p :double))
127   #.*double-min*)
128 
129 ;;; TODO: use something like *DOUBLE-MIN/MAX* above once we actually
130 ;;; have an available lisp that supports long double.
131 ;#-cffi-sys::no-long-float
132 #+(and scl long-double)
133 (progn
134   (deftest deref.long-double.1
135       (with-foreign-object (p :long-double)
136         (setf (mem-ref p :long-double) 0.0l0)
137         (mem-ref p :long-double))
138     0.0l0)
139 
140   (deftest deref.long-double.2
141       (with-foreign-object (p :long-double)
142         (setf (mem-ref p :long-double) most-positive-long-float)
143         (mem-ref p :long-double))
144     #.most-positive-long-float)
145 
146   (deftest deref.long-double.3
147       (with-foreign-object (p :long-double)
148         (setf (mem-ref p :long-double) least-positive-long-float)
149         (mem-ref p :long-double))
150     #.least-positive-long-float))
151 
152 ;;; make sure the lisp doesn't convert NULL to NIL
153 (deftest deref.pointer.null
154     (with-foreign-object (p :pointer)
155       (setf (mem-ref p :pointer) (null-pointer))
156       (null-pointer-p (mem-ref p :pointer)))
157   t)
158 
159 ;;; regression test. lisp-string-to-foreign should handle empty strings
160 (deftest lisp-string-to-foreign.empty
161     (with-foreign-pointer (str 2)
162       (setf (mem-ref str :unsigned-char) 42)
163       (lisp-string-to-foreign "" str 1)
164       (mem-ref str :unsigned-char))
165   0)
166 
167 ;;; regression test. with-foreign-pointer shouldn't evaluate
168 ;;; the size argument twice.
169 (deftest with-foreign-pointer.evalx2
170     (let ((count 0))
171       (with-foreign-pointer (x (incf count) size-var)
172         (values count size-var)))
173   1 1)
174 
175 (defconstant +two+ 2)
176 
177 ;;; regression test. cffi-allegro's with-foreign-pointer wasn't
178 ;;; handling constants properly.
179 (deftest with-foreign-pointer.constant-size
180     (with-foreign-pointer (p +two+ size)
181       size)
182   2)
183 
184 (deftest mem-ref.left-to-right
185     (let ((i 0))
186       (with-foreign-object (p :char 3)
187         (setf (mem-ref p :char 0) 66 (mem-ref p :char 1) 92)
188         (setf (mem-ref p :char (incf i)) (incf i))
189         (values (mem-ref p :char 0) (mem-ref p :char 1) i)))
190   66 2 2)
191 
192 ;;; This needs to be in a real function for at least Allegro CL or the
193 ;;; compiler macro on %MEM-REF is not expanded and the test doesn't
194 ;;; actually test anything!
195 (defun %mem-ref-left-to-right ()
196   (let ((result nil))
197     (with-foreign-object (p :char)
198       (%mem-set 42 p :char)
199       (%mem-ref (progn (push 1 result) p) :char (progn (push 2 result) 0))
200       (nreverse result))))
201 
202 ;;; Test left-to-right evaluation of the arguments to %MEM-REF when
203 ;;; optimized by the compiler macro.
204 (deftest %mem-ref.left-to-right
205     (%mem-ref-left-to-right)
206   (1 2))
207 
208 ;;; This needs to be in a top-level function for at least Allegro CL
209 ;;; or the compiler macro on %MEM-SET is not expanded and the test
210 ;;; doesn't actually test anything!
211 (defun %mem-set-left-to-right ()
212   (let ((result nil))
213     (with-foreign-object (p :char)
214       (%mem-set (progn (push 1 result) 0)
215                 (progn (push 2 result) p)
216                 :char
217                 (progn (push 3 result) 0))
218       (nreverse result))))
219 
220 ;;; Test left-to-right evaluation of the arguments to %MEM-SET when
221 ;;; optimized by the compiler macro.
222 (deftest %mem-set.left-to-right
223     (%mem-set-left-to-right)
224   (1 2 3))
225 
226 ;; regression test. mem-aref's setf expansion evaluated its type argument twice.
227 (deftest mem-aref.eval-type-x2
228     (let ((count 0))
229       (with-foreign-pointer (p 1)
230         (setf (mem-aref p (progn (incf count) :char) 0) 127))
231       count)
232   1)
233 
234 (deftest mem-aref.left-to-right
235     (let ((count -1))
236       (with-foreign-pointer (p 2)
237         (values
238          (setf (mem-aref p (progn (incf count) :char) (incf count)) (incf count))
239          (setq count -1)
240          (mem-aref (progn (incf count) p) :char (incf count))
241          count)))
242   2 -1 2 1)
243 
244 ;; regression tests. nested mem-ref's and mem-aref's had bogus getters
245 (deftest mem-ref.nested
246     (with-foreign-object (p :pointer)
247       (with-foreign-object (i :int)
248         (setf (mem-ref p :pointer) i)
249         (setf (mem-ref i :int) 42)
250         (setf (mem-ref (mem-ref p :pointer) :int) 1984)
251         (mem-ref i :int)))
252   1984)
253 
254 (deftest mem-aref.nested
255     (with-foreign-object (p :pointer)
256       (with-foreign-object (i :int 2)
257         (setf (mem-aref p :pointer 0) i)
258         (setf (mem-aref i :int 1) 42)
259         (setf (mem-aref (mem-ref p :pointer 0) :int 1) 1984)
260         (mem-aref i :int 1)))
261   1984)
262 
263 (cffi:defcstruct mem-aref.bare-struct
264   (a :uint8))
265 
266 ;;; regression test: although mem-aref was dealing with bare struct
267 ;;; types as though they were pointers, it wasn't calculating the
268 ;;; proper offsets. The offsets for bare structs types should be
269 ;;; calculated as aggregate types.
270 (deftest mem-aref.bare-struct
271     (with-foreign-object (a 'mem-aref.bare-struct 2)
272       (eql (- (pointer-address (cffi:mem-aref a 'mem-aref.bare-struct 1))
273               (pointer-address (cffi:mem-aref a 'mem-aref.bare-struct 0)))
274            (foreign-type-size '(:struct mem-aref.bare-struct))))
275   t)
276 
277 ;;; regression tests. dereferencing an aggregate type. dereferencing a
278 ;;; struct should return a pointer to the struct itself, not return the
279 ;;; first 4 bytes (or whatever the size of :pointer is) as a pointer.
280 ;;;
281 ;;; This important for accessing an array of structs, which is
282 ;;; what the deref.array-of-aggregates test does.
283 (defcstruct some-struct (x :int))
284 
285 (deftest deref.aggregate
286     (with-foreign-object (s 'some-struct)
287       (pointer-eq s (mem-ref s 'some-struct)))
288   t)
289 
290 (deftest deref.array-of-aggregates
291     (with-foreign-object (arr 'some-struct 3)
292       (loop for i below 3
293             do (setf (foreign-slot-value (mem-aref arr 'some-struct i)
294                                          'some-struct 'x)
295                      112))
296       (loop for i below 3
297             collect (foreign-slot-value (mem-aref arr 'some-struct i)
298                                         'some-struct 'x)))
299   (112 112 112))
300 
301 ;;; pointer operations
302 (deftest pointer.1
303     (pointer-address (make-pointer 42))
304   42)
305 
306 ;;; I suppose this test is not very good. --luis
307 (deftest pointer.2
308     (pointer-address (null-pointer))
309   0)
310 
311 (deftest pointer.null
312     (nth-value 0 (ignore-errors (null-pointer-p nil)))
313   nil)
314 
315 (deftest foreign-pointer-type.nil
316     (typep nil 'foreign-pointer)
317   nil)
318 
319 ;;; Ensure that a pointer to the highest possible address can be
320 ;;; created using MAKE-POINTER.  Regression test for CLISP/X86-64.
321 (deftest make-pointer.high
322     (let* ((pointer-length (foreign-type-size :pointer))
323            (high-address (1- (expt 2 (* pointer-length 8))))
324            (pointer (make-pointer high-address)))
325       (- high-address (pointer-address pointer)))
326   0)
327 
328 ;;; Ensure that incrementing a pointer by zero bytes returns an
329 ;;; equivalent pointer.
330 (deftest inc-pointer.zero
331     (with-foreign-object (x :int)
332       (pointer-eq x (inc-pointer x 0)))
333   t)
334 
335 ;;; Test the INITIAL-ELEMENT keyword argument to FOREIGN-ALLOC.
336 (deftest foreign-alloc.1
337     (let ((ptr (foreign-alloc :int :initial-element 42)))
338       (unwind-protect
339            (mem-ref ptr :int)
340         (foreign-free ptr)))
341   42)
342 
343 ;;; Test the INITIAL-ELEMENT and COUNT arguments to FOREIGN-ALLOC.
344 (deftest foreign-alloc.2
345     (let ((ptr (foreign-alloc :int :count 4 :initial-element 100)))
346       (unwind-protect
347            (loop for i from 0 below 4
348                  collect (mem-aref ptr :int i))
349         (foreign-free ptr)))
350   (100 100 100 100))
351 
352 ;;; Test the INITIAL-CONTENTS and COUNT arguments to FOREIGN-ALLOC,
353 ;;; passing a list of initial values.
354 (deftest foreign-alloc.3
355     (let ((ptr (foreign-alloc :int :count 4 :initial-contents '(4 3 2 1))))
356       (unwind-protect
357            (loop for i from 0 below 4
358                  collect (mem-aref ptr :int i))
359         (foreign-free ptr)))
360   (4 3 2 1))
361 
362 ;;; Test INITIAL-CONTENTS and COUNT with FOREIGN-ALLOC passing a
363 ;;; vector of initial values.
364 (deftest foreign-alloc.4
365     (let ((ptr (foreign-alloc :int :count 4 :initial-contents #(10 20 30 40))))
366       (unwind-protect
367            (loop for i from 0 below 4
368                  collect (mem-aref ptr :int i))
369         (foreign-free ptr)))
370   (10 20 30 40))
371 
372 ;;; Ensure calling FOREIGN-ALLOC with both INITIAL-ELEMENT and
373 ;;; INITIAL-CONTENTS signals an error.
374 (deftest foreign-alloc.5
375     (values
376      (ignore-errors
377        (let ((ptr (foreign-alloc :int :initial-element 1
378                                  :initial-contents '(1))))
379          (foreign-free ptr))
380        t))
381   nil)
382 
383 ;;; Regression test: FOREIGN-ALLOC shouldn't actually perform translation
384 ;;; on initial-element/initial-contents since MEM-AREF will do that already.
385 (define-foreign-type not-an-int ()
386   ()
387   (:actual-type :int)
388   (:simple-parser not-an-int))
389 
390 (defmethod translate-to-foreign (value (type not-an-int))
391   (assert (not (integerp value)))
392   0)
393 
394 (deftest foreign-alloc.6
395     (let ((ptr (foreign-alloc 'not-an-int :initial-element 'foooo)))
396       (foreign-free ptr)
397       t)
398   t)
399 
400 ;;; Ensure calling FOREIGN-ALLOC with NULL-TERMINATED-P and a non-pointer
401 ;;; type signals an error.
402 (deftest foreign-alloc.7
403     (values
404      (ignore-errors
405        (let ((ptr (foreign-alloc :int :null-terminated-p t)))
406          (foreign-free ptr))
407        t))
408   nil)
409 
410 ;;; The opposite of the above test.
411 (defctype pointer-alias :pointer)
412 
413 (deftest foreign-alloc.8
414     (progn
415       (foreign-free (foreign-alloc 'pointer-alias :count 0 :null-terminated-p t))
416       t)
417   t)
418 
419 ;;; Ensure calling FOREIGN-ALLOC with NULL-TERMINATED-P actually places
420 ;;; a null pointer at the end. Not a very reliable test apparently.
421 (deftest foreign-alloc.9
422     (let ((ptr (foreign-alloc :pointer :count 0 :null-terminated-p t)))
423       (unwind-protect
424            (null-pointer-p (mem-ref ptr :pointer))
425         (foreign-free ptr)))
426   t)
427 
428 ;;; RT: FOREIGN-ALLOC with :COUNT 0 on CLISP signalled an error.
429 (deftest foreign-alloc.10
430     (null (foreign-free (foreign-alloc :char :count 0)))
431   t)
432 
433 ;;; Tests for mem-ref with a non-constant type. This is a way to test
434 ;;; the functional interface (without compiler macros).
435 
436 (deftest deref.nonconst.char
437     (let ((type :char))
438       (with-foreign-object (p type)
439         (setf (mem-ref p type) -127)
440         (mem-ref p type)))
441   -127)
442 
443 (deftest deref.nonconst.unsigned-char
444     (let ((type :unsigned-char))
445       (with-foreign-object (p type)
446         (setf (mem-ref p type) 255)
447         (mem-ref p type)))
448   255)
449 
450 (deftest deref.nonconst.short
451     (let ((type :short))
452       (with-foreign-object (p type)
453         (setf (mem-ref p type) -32767)
454         (mem-ref p type)))
455   -32767)
456 
457 (deftest deref.nonconst.unsigned-short
458     (let ((type :unsigned-short))
459       (with-foreign-object (p type)
460         (setf (mem-ref p type) 65535)
461         (mem-ref p type)))
462   65535)
463 
464 (deftest deref.nonconst.int
465     (let ((type :int))
466       (with-foreign-object (p type)
467         (setf (mem-ref p type) -131072)
468         (mem-ref p type)))
469   -131072)
470 
471 (deftest deref.nonconst.unsigned-int
472     (let ((type :unsigned-int))
473       (with-foreign-object (p type)
474         (setf (mem-ref p type) 262144)
475         (mem-ref p type)))
476   262144)
477 
478 (deftest deref.nonconst.long
479     (let ((type :long))
480       (with-foreign-object (p type)
481         (setf (mem-ref p type) -536870911)
482         (mem-ref p type)))
483   -536870911)
484 
485 (deftest deref.nonconst.unsigned-long
486     (let ((type :unsigned-long))
487       (with-foreign-object (p type)
488         (setf (mem-ref p type) 536870912)
489         (mem-ref p type)))
490   536870912)
491 
492 #+(and darwin openmcl)
493 (pushnew 'deref.nonconst.long-long rt::*expected-failures*)
494 
495 (deftest deref.nonconst.long-long
496     (let ((type :long-long))
497       (with-foreign-object (p type)
498         (setf (mem-ref p type) -9223372036854775807)
499         (mem-ref p type)))
500   -9223372036854775807)
501 
502 (deftest deref.nonconst.unsigned-long-long
503     (let ((type :unsigned-long-long))
504       (with-foreign-object (p type)
505         (setf (mem-ref p type) 18446744073709551615)
506         (mem-ref p type)))
507   18446744073709551615)
508 
509 (deftest deref.nonconst.float.1
510     (let ((type :float))
511       (with-foreign-object (p type)
512         (setf (mem-ref p type) 0.0)
513         (mem-ref p type)))
514   0.0)
515 
516 (deftest deref.nonconst.float.2
517     (let ((type :float))
518       (with-foreign-object (p type)
519         (setf (mem-ref p type) *float-max*)
520         (mem-ref p type)))
521   #.*float-max*)
522 
523 (deftest deref.nonconst.float.3
524     (let ((type :float))
525       (with-foreign-object (p type)
526         (setf (mem-ref p type) *float-min*)
527         (mem-ref p type)))
528   #.*float-min*)
529 
530 (deftest deref.nonconst.double.1
531     (let ((type :double))
532       (with-foreign-object (p type)
533         (setf (mem-ref p type) 0.0d0)
534         (mem-ref p type)))
535   0.0d0)
536 
537 (deftest deref.nonconst.double.2
538     (let ((type :double))
539       (with-foreign-object (p type)
540         (setf (mem-ref p type) *double-max*)
541         (mem-ref p type)))
542   #.*double-max*)
543 
544 (deftest deref.nonconst.double.3
545     (let ((type :double))
546       (with-foreign-object (p type)
547         (setf (mem-ref p type) *double-min*)
548         (mem-ref p type)))
549   #.*double-min*)
550 
551 ;;; regression tests: lispworks's %mem-ref and %mem-set compiler
552 ;;; macros were misbehaving.
553 
554 (defun mem-ref-rt-1 ()
555   (with-foreign-object (a :int 2)
556     (setf (mem-aref a :int 0) 123
557           (mem-aref a :int 1) 456)
558     (values (mem-aref a :int 0) (mem-aref a :int 1))))
559 
560 (deftest mem-ref.rt.1
561     (mem-ref-rt-1)
562   123 456)
563 
564 (defun mem-ref-rt-2 ()
565   (with-foreign-object (a :double 2)
566     (setf (mem-aref a :double 0) 123.0d0
567           (mem-aref a :double 1) 456.0d0)
568     (values (mem-aref a :double 0) (mem-aref a :double 1))))
569 
570 (deftest mem-ref.rt.2
571     (mem-ref-rt-2)
572   123.0d0 456.0d0)
573 
574 (deftest incf-pointer.1
575     (let ((ptr (null-pointer)))
576       (incf-pointer ptr)
577       (pointer-address ptr))
578   1)
579 
580 (deftest incf-pointer.2
581     (let ((ptr (null-pointer)))
582       (incf-pointer ptr 42)
583       (pointer-address ptr))
584   42)
585 
586 (deftest pointerp.1
587     (values
588      (pointerp (null-pointer))
589      (null-pointer-p (null-pointer))
590      (typep (null-pointer) 'foreign-pointer))
591   t t t)
592 
593 (deftest pointerp.2
594     (let ((p (make-pointer #xFEFF)))
595       (values
596        (pointerp p)
597        (typep p 'foreign-pointer)))
598   t t)
599 
600 (deftest pointerp.3
601     (pointerp 'not-a-pointer)
602   nil)
603 
604 (deftest pointerp.4
605     (pointerp 42)
606   nil)
607 
608 (deftest pointerp.5
609     (pointerp 0)
610   nil)
611 
612 (deftest pointerp.6
613     (pointerp nil)
614   nil)
615 
616 (deftest mem-ref.setf.1
617     (with-foreign-object (p :char)
618       (setf (mem-ref p :char) 42))
619   42)
620 
621 (define-foreign-type int+1 ()
622   ()
623   (:actual-type :int)
624   (:simple-parser int+1))
625 
626 (defmethod translate-to-foreign (value (type int+1))
627   (1+ value))
628 
629 (defmethod translate-from-foreign (value (type int+1))
630   (1+ value))
631 
632 (deftest mem-ref.setf.2
633     (with-foreign-object (p 'int+1)
634       (values (setf (mem-ref p 'int+1) 42)
635               (mem-ref p 'int+1)))
636   42 ; should this be 43?
637   44)
638 
639 (deftest pointer-eq.non-pointers.1
640     (expecting-error (pointer-eq 1 2))
641   :error)
642 
643 (deftest pointer-eq.non-pointers.2
644     (expecting-error (pointer-eq 'a 'b))
645   :error)
646 
647 (deftest null-pointer-p.non-pointer.1
648     (expecting-error (null-pointer-p 'not-a-pointer))
649   :error)
650 
651 (deftest null-pointer-p.non-pointer.2
652     (expecting-error (null-pointer-p 0))
653   :error)
654 
655 (deftest null-pointer-p.non-pointer.3
656     (expecting-error (null-pointer-p nil))
657   :error)