foreign-globals.lisp - clic - Clic is an command line interactive client for gopher written in Common LISP (HTM) git clone git://bitreich.org/clic/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/clic/ (DIR) Log (DIR) Files (DIR) Refs (DIR) Tags (DIR) README (DIR) LICENSE --- foreign-globals.lisp (9271B) --- 1 ;;;; -*- Mode: lisp; indent-tabs-mode: nil -*- 2 ;;; 3 ;;; foreign-globals.lisp --- Tests on foreign globals. 4 ;;; 5 ;;; Copyright (C) 2005-2007, Luis Oliveira <loliveira(@)common-lisp.net> 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 (defcvar ("var_char" *char-var*) :char) 31 (defcvar "var_unsigned_char" :unsigned-char) 32 (defcvar "var_short" :short) 33 (defcvar "var_unsigned_short" :unsigned-short) 34 (defcvar "var_int" :int) 35 (defcvar "var_unsigned_int" :unsigned-int) 36 (defcvar "var_long" :long) 37 (defcvar "var_unsigned_long" :unsigned-long) 38 (defcvar "var_float" :float) 39 (defcvar "var_double" :double) 40 (defcvar "var_pointer" :pointer) 41 (defcvar "var_string" :string) 42 (defcvar "var_long_long" :long-long) 43 (defcvar "var_unsigned_long_long" :unsigned-long-long) 44 45 ;;; The expected failures marked below result from this odd behaviour: 46 ;;; 47 ;;; (foreign-symbol-pointer "var_char") => NIL 48 ;;; 49 ;;; (foreign-symbol-pointer "var_char" :library 'libtest) 50 ;;; => #<Pointer to type :VOID = #xF7F50740> 51 ;;; 52 ;;; Why is this happening? --luis 53 #+lispworks 54 (mapc (lambda (x) (pushnew x rtest::*expected-failures*)) 55 '(foreign-globals.ref.char foreign-globals.get-var-pointer.1 56 foreign-globals.get-var-pointer.2 foreign-globals.symbol-name 57 foreign-globals.read-only.1 )) 58 59 (deftest foreign-globals.ref.char 60 *char-var* 61 -127) 62 63 (deftest foreign-globals.ref.unsigned-char 64 *var-unsigned-char* 65 255) 66 67 (deftest foreign-globals.ref.short 68 *var-short* 69 -32767) 70 71 (deftest foreign-globals.ref.unsigned-short 72 *var-unsigned-short* 73 65535) 74 75 (deftest foreign-globals.ref.int 76 *var-int* 77 -32767) 78 79 (deftest foreign-globals.ref.unsigned-int 80 *var-unsigned-int* 81 65535) 82 83 (deftest foreign-globals.ref.long 84 *var-long* 85 -2147483647) 86 87 (deftest foreign-globals.ref.unsigned-long 88 *var-unsigned-long* 89 4294967295) 90 91 (deftest foreign-globals.ref.float 92 *var-float* 93 42.0) 94 95 (deftest foreign-globals.ref.double 96 *var-double* 97 42.0d0) 98 99 (deftest foreign-globals.ref.pointer 100 (null-pointer-p *var-pointer*) 101 t) 102 103 (deftest foreign-globals.ref.string 104 *var-string* 105 "Hello, foreign world!") 106 107 #+openmcl (push 'foreign-globals.set.long-long rt::*expected-failures*) 108 109 (deftest foreign-globals.ref.long-long 110 *var-long-long* 111 -9223372036854775807) 112 113 (deftest foreign-globals.ref.unsigned-long-long 114 *var-unsigned-long-long* 115 18446744073709551615) 116 117 ;; The *.set.* tests restore the old values so that the *.ref.* 118 ;; don't fail when re-run. 119 (defmacro with-old-value-restored ((place) &body body) 120 (let ((old (gensym))) 121 `(let ((,old ,place)) 122 (prog1 123 (progn ,@body) 124 (setq ,place ,old))))) 125 126 (deftest foreign-globals.set.int 127 (with-old-value-restored (*var-int*) 128 (setq *var-int* 42) 129 *var-int*) 130 42) 131 132 (deftest foreign-globals.set.string 133 (with-old-value-restored (*var-string*) 134 (setq *var-string* "Ehxosxangxo") 135 (prog1 136 *var-string* 137 ;; free the string we just allocated 138 (foreign-free (mem-ref (get-var-pointer '*var-string*) :pointer)))) 139 "Ehxosxangxo") 140 141 (deftest foreign-globals.set.long-long 142 (with-old-value-restored (*var-long-long*) 143 (setq *var-long-long* -9223000000000005808) 144 *var-long-long*) 145 -9223000000000005808) 146 147 (deftest foreign-globals.get-var-pointer.1 148 (pointerp (get-var-pointer '*char-var*)) 149 t) 150 151 (deftest foreign-globals.get-var-pointer.2 152 (mem-ref (get-var-pointer '*char-var*) :char) 153 -127) 154 155 ;;; Symbol case. 156 157 (defcvar "UPPERCASEINT1" :int) 158 (defcvar "UPPER_CASE_INT1" :int) 159 (defcvar "MiXeDCaSeInT1" :int) 160 (defcvar "MiXeD_CaSe_InT1" :int) 161 162 (deftest foreign-globals.ref.uppercaseint1 163 *uppercaseint1* 164 12345) 165 166 (deftest foreign-globals.ref.upper-case-int1 167 *upper-case-int1* 168 23456) 169 170 (deftest foreign-globals.ref.mixedcaseint1 171 *mixedcaseint1* 172 34567) 173 174 (deftest foreign-globals.ref.mixed-case-int1 175 *mixed-case-int1* 176 45678) 177 178 (when (string= (symbol-name 'nil) "NIL") 179 (let ((*readtable* (copy-readtable))) 180 (setf (readtable-case *readtable*) :invert) 181 (eval (read-from-string "(defcvar \"UPPERCASEINT2\" :int)")) 182 (eval (read-from-string "(defcvar \"UPPER_CASE_INT2\" :int)")) 183 (eval (read-from-string "(defcvar \"MiXeDCaSeInT2\" :int)")) 184 (eval (read-from-string "(defcvar \"MiXeD_CaSe_InT2\" :int)")) 185 (setf (readtable-case *readtable*) :preserve) 186 (eval (read-from-string "(DEFCVAR \"UPPERCASEINT3\" :INT)")) 187 (eval (read-from-string "(DEFCVAR \"UPPER_CASE_INT3\" :INT)")) 188 (eval (read-from-string "(DEFCVAR \"MiXeDCaSeInT3\" :INT)")) 189 (eval (read-from-string "(DEFCVAR \"MiXeD_CaSe_InT3\" :INT)")))) 190 191 192 ;;; EVAL gets rid of SBCL's unreachable code warnings. 193 (when (string= (symbol-name (eval nil)) "nil") 194 (let ((*readtable* (copy-readtable))) 195 (setf (readtable-case *readtable*) :invert) 196 (eval (read-from-string "(DEFCVAR \"UPPERCASEINT2\" :INT)")) 197 (eval (read-from-string "(DEFCVAR \"UPPER_CASE_INT2\" :INT)")) 198 (eval (read-from-string "(DEFCVAR \"MiXeDCaSeInT2\" :INT)")) 199 (eval (read-from-string "(DEFCVAR \"MiXeD_CaSe_InT2\" :INT)")) 200 (setf (readtable-case *readtable*) :downcase) 201 (eval (read-from-string "(defcvar \"UPPERCASEINT3\" :int)")) 202 (eval (read-from-string "(defcvar \"UPPER_CASE_INT3\" :int)")) 203 (eval (read-from-string "(defcvar \"MiXeDCaSeInT3\" :int)")) 204 (eval (read-from-string "(defcvar \"MiXeD_CaSe_InT3\" :int)")))) 205 206 (deftest foreign-globals.ref.uppercaseint2 207 *uppercaseint2* 208 12345) 209 210 (deftest foreign-globals.ref.upper-case-int2 211 *upper-case-int2* 212 23456) 213 214 (deftest foreign-globals.ref.mixedcaseint2 215 *mixedcaseint2* 216 34567) 217 218 (deftest foreign-globals.ref.mixed-case-int2 219 *mixed-case-int2* 220 45678) 221 222 (deftest foreign-globals.ref.uppercaseint3 223 *uppercaseint3* 224 12345) 225 226 (deftest foreign-globals.ref.upper-case-int3 227 *upper-case-int3* 228 23456) 229 230 (deftest foreign-globals.ref.mixedcaseint3 231 *mixedcaseint3* 232 34567) 233 234 (deftest foreign-globals.ref.mixed-case-int3 235 *mixed-case-int3* 236 45678) 237 238 ;;; regression test: 239 ;;; gracefully accept symbols in defcvar 240 241 (defcvar *var-char* :char) 242 (defcvar var-char :char) 243 244 (deftest foreign-globals.symbol-name 245 (values *var-char* var-char) 246 -127 -127) 247 248 ;;;# Namespace 249 250 #-cffi-sys::flat-namespace 251 (progn 252 (deftest foreign-globals.namespace.1 253 (values 254 (mem-ref (foreign-symbol-pointer "var_char" :library 'libtest) :char) 255 (foreign-symbol-pointer "var_char" :library 'libtest2)) 256 -127 nil) 257 258 (deftest foreign-globals.namespace.2 259 (values 260 (mem-ref (foreign-symbol-pointer "ns_var" :library 'libtest) :boolean) 261 (mem-ref (foreign-symbol-pointer "ns_var" :library 'libtest2) :boolean)) 262 t nil) 263 264 ;; For its "default" module, Lispworks seems to cache lookups from 265 ;; the newest module tried. If a lookup happens to have failed 266 ;; subsequent lookups will fail even the symbol exists in other 267 ;; modules. So this test fails. 268 #+lispworks 269 (pushnew 'foreign-globals.namespace.3 regression-test::*expected-failures*) 270 271 (deftest foreign-globals.namespace.3 272 (values 273 (foreign-symbol-pointer "var_char" :library 'libtest2) 274 (mem-ref (foreign-symbol-pointer "var_char") :char)) 275 nil -127) 276 277 (defcvar ("ns_var" *ns-var1* :library libtest) :boolean) 278 (defcvar ("ns_var" *ns-var2* :library libtest2) :boolean) 279 280 (deftest foreign-globals.namespace.4 281 (values *ns-var1* *ns-var2*) 282 t nil)) 283 284 ;;;# Read-only 285 286 (defcvar ("var_char" *var-char-ro* :read-only t) :char 287 "docstring") 288 289 (deftest foreign-globals.read-only.1 290 (values *var-char-ro* 291 (ignore-errors (setf *var-char-ro* 12))) 292 -127 nil) 293 294 (deftest defcvar.docstring 295 (documentation '*var-char-ro* 'variable) 296 "docstring") 297 298 ;;;# Other tests 299 300 ;;; RT: FOREIGN-SYMBOL-POINTER shouldn't signal an error when passed 301 ;;; an undefined variable. 302 (deftest foreign-globals.undefined.1 303 (foreign-symbol-pointer "surely-undefined?") 304 nil) 305 306 (deftest foreign-globals.error.1 307 (handler-case (foreign-symbol-pointer 'not-a-string) 308 (type-error () t)) 309 t)