[Add unit testing framework using RT. jbielman**20050611052654 Add unit testing framework using RT. Lots of manual and CFFI-SYS updates. Add passing a double float to sprintf in examples.lisp. Update the syntax of the nested structure example. Add the INC-PTR function to the CFFI-SYS backends. Add the shareable byte vector interface to the CFFI-SYS backends. Started writing support for aggregate structure slots. Not used yet. ] { hunk ./Makefile 35 -test: - test -x `which openmcl` && openmcl --load examples/run-examples.lisp - test -x `which sbcl` && sbcl --noinform --load examples/run-examples.lisp - test -x `which lisp` && lisp -load examples/run-examples.lisp - test -x `which clisp` && clisp examples/run-examples.lisp +test: shlibs + @test -x `which openmcl` && echo "-------- Running unit tests in OpenMCL: --------" && openmcl --load tests/run-tests.lisp + @test -x `which sbcl` && echo "-------- Running unit tests in SBCL: --------" && sbcl --noinform --load tests/run-tests.lisp + @test -x `which lisp` && echo "-------- Running unit tests in CMU CL: --------" && lisp -load tests/run-tests.lisp + @test -x `which clisp` && echo "-------- Running unit tests in CLISP: --------" && clisp tests/run-tests.lisp hunk ./cffi-tests.asd 41 - (:file "memory") - (:file "struct") - (:file "union"))))) + (:file "memory"))))) hunk ./doc/cffi-sys-specification.html 3 - CFFI-SYS Specification + CFFI-SYS Specification + hunk ./doc/cffi-sys-specification.html 18 - CFFI, the Common Foreign Function Interface, purports to be a portable - foreign function interface for Common Lisp. + CFFI, the Common Foreign Function Interface, purports to be a + portable foreign function interface for Common Lisp. hunk ./doc/cffi-sys-specification.html 23 - This specification defines a set of low-level primitives that must - be defined for each Lisp implementation supported by CFFI. These - operators are defined in the CFFI-SYS package. + This specification defines a set of low-level primitives that + must be defined for each Lisp implementation supported by CFFI. + These operators are defined in the CFFI-SYS package. hunk ./doc/cffi-sys-specification.html 29 - The CFFI package uses the CFFI-SYS interface to - implement an extensible foreign type system with support for typedefs, - structures, and unions, a declarative interface for defining foreign - function calls, and automatic conversion of foreign function arguments - to/from Lisp types. + The CFFI package uses the CFFI-SYS interface + to implement an extensible foreign type system with support for + typedefs, structures, and unions, a declarative interface for + defining foreign function calls, and automatic conversion of + foreign function arguments to/from Lisp types. hunk ./doc/cffi-sys-specification.html 39 - Functions in CFFI-SYS that are low-level versions of functions - exported from the CFFI package begin with a leading - percent-sign (eg. %mem-ref). + Functions in CFFI-SYS that are low-level versions of + functions exported from the CFFI package begin with a + leading percent-sign (eg. %mem-ref). hunk ./doc/cffi-sys-specification.html 47 - Foreign Type: :char
- Foreign Type: :unsigned-char
- Foreign Type: :short
- Foreign Type: :unsigned-short
- Foreign Type: :int
- Foreign Type: :unsigned-int
- Foreign Type: :long
- Foreign Type: :unsigned-long
- Foreign Type: :long-long
- Foreign Type: :unsigned-long-long
+ Foreign Type: :char
+ Foreign Type: :unsigned-char
+ Foreign Type: :short
+ Foreign Type: :unsigned-short
+ Foreign Type: :int
+ Foreign Type: :unsigned-int
+ Foreign Type: :long
+ Foreign Type: :unsigned-long
+ Foreign Type: :long-long
+ Foreign Type: :unsigned-long-long
hunk ./doc/cffi-sys-specification.html 60 - These types correspond to the native C integer types according to - the ABI of the system the Lisp implementation is compiled against. + These types correspond to the native C integer types according + to the ABI of the system the Lisp implementation is compiled + against. hunk ./doc/cffi-sys-specification.html 66 - Foreign Type: :int8
- Foreign Type: :uint8
- Foreign Type: :int16
- Foreign Type: :uint16
- Foreign Type: :int32
- Foreign Type: :uint32
- Foreign Type: :int64
- Foreign Type: :uint64
+ Foreign Type: :int8
+ Foreign Type: :uint8
+ Foreign Type: :int16
+ Foreign Type: :uint16
+ Foreign Type: :int32
+ Foreign Type: :uint32
+ Foreign Type: :int64
+ Foreign Type: :uint64
hunk ./doc/cffi-sys-specification.html 77 - Foreign integer types of specific sizes, corresponding to the - C types defined in stdint.h. + Foreign integer types of specific sizes, corresponding to the C + types defined in stdint.h. hunk ./doc/cffi-sys-specification.html 82 - Foreign Type: :size
- Foreign Type: :ssize
- Foreign Type: :ptrdiff
- Foreign Type: :time
+ Foreign Type: :size
+ Foreign Type: :ssize
+ Foreign Type: :ptrdiff
+ Foreign Type: :time
hunk ./doc/cffi-sys-specification.html 89 - Foreign integer types corresponding to the standard C types (without - the _t suffix). + Foreign integer types corresponding to the standard C types + (without the _t suffix). hunk ./doc/cffi-sys-specification.html 94 - - I'm sure there are more of these that could be useful, let's add - any types that can't be defined portably to this list as necessary. - + + I'm sure there are more of these that could be useful, let's + add any types that can't be defined portably to this list as + necessary. + hunk ./doc/cffi-sys-specification.html 102 - Foreign Type: :float
- Foreign Type: :double
+ Foreign Type: :float
+ Foreign Type: :double
hunk ./doc/cffi-sys-specification.html 107 - The :float type represents a C float and a Lisp - single-float. :double represents a C double - and a Lisp double-float. + The :float type represents a C float and a Lisp + single-float. :double represents a + C double and a Lisp double-float. hunk ./doc/cffi-sys-specification.html 115 - A foreign pointer to an object of any type, corresponding to - void *. + A foreign pointer to an object of any type, corresponding to + void *. hunk ./doc/cffi-sys-specification.html 122 - No type at all. Only valid as the return type of a function. + No type at all. Only valid as the return type of a function. hunk ./doc/cffi-sys-specification.html 126 + hunk ./doc/cffi-sys-specification.html 128 - Return the size, in bytes, of objects having foreign type type. - An error is signalled if type is not a known built-in foreign - type. + Return the size, in bytes, of objects having foreign type type. + An error is signalled if type is not a known built-in foreign + type. hunk ./doc/cffi-sys-specification.html 136 - Return the default alignment in bytes for structure members of foreign - type type. - An error is signalled if type is not a known built-in foreign - type. + Return the default alignment in bytes for structure members of + foreign type type. An error is signalled if type + is not a known built-in foreign type. hunk ./doc/cffi-sys-specification.html 142 - - Maybe this should take an optional keyword argument specifying - an alternate alignment system, eg. :mac68k for 68000-compatible - alignment on Darwin. - + + Maybe this should take an optional keyword argument specifying + an alternate alignment system, eg. :mac68k for 68000-compatible + alignment on Darwin. + hunk ./doc/cffi-sys-specification.html 152 + hunk ./doc/cffi-sys-specification.html 154 - Return true if ptr is a foreign pointer. + Return true if ptr is a foreign pointer. hunk ./doc/cffi-sys-specification.html 158 + hunk ./doc/cffi-sys-specification.html 162 - + hunk ./doc/cffi-sys-specification.html 165 - Return true if ptr is a null foreign pointer. + Return true if ptr is a null foreign pointer. hunk ./doc/cffi-sys-specification.html 173 - Allocate size bytes of foreign-addressable memory and return - a pointer to the allocated block. An implementation-specific - error is signalled if the memory cannot be allocated. + Allocate size bytes of foreign-addressable memory and + return a pointer to the allocated block. An + implementation-specific error is signalled if the memory cannot + be allocated. hunk ./doc/cffi-sys-specification.html 182 - Free a pointer ptr allocated by foreign-alloc. - The results are undefined if ptr is used after being freed. + Free a pointer ptr allocated by foreign-alloc. + The results are undefined if ptr is used after being + freed. hunk ./doc/cffi-sys-specification.html 187 -

Macro: with-foreign-ptr (var size &optional size-var) &body body

+

Macro: with-foreign-ptr (var size + &optional size-var) &body body

hunk ./doc/cffi-sys-specification.html 191 - Bind var to a pointer to size bytes of foreign-accessible - memory during body. Both ptr and the memory block it - points to have dynamic extent and may be stack allocated if supported - by the implementation. If size-var is supplied, it will be bound - to size during body. + Bind var to a pointer to size bytes of + foreign-accessible memory during body. Both ptr + and the memory block it points to have dynamic extent and may be + stack allocated if supported by the implementation. + If size-var is supplied, it will be bound to size + during body. hunk ./doc/cffi-sys-specification.html 204 - Dereference a pointer offset bytes from ptr to an object - for reading (or writing when used with setf) of built-in type - type. + Dereference a pointer offset bytes from ptr to an + object for reading (or writing when used with setf) of + built-in type type. hunk ./doc/cffi-sys-specification.html 211 -
+
hunk ./doc/cffi-sys-specification.html 221
-    

Macro: %foreign-funcall name {arg-type arg}* &optional result-type => object

+

Macro: %foreign-funcall name + {arg-type arg}* &optional result-type + => object

hunk ./doc/cffi-sys-specification.html 226 - Invoke a foreign function called name, which may be mangled - depending on the ABI of the system (eg. adding leading underscore for - Darwin). + Invoke a foreign function called name, which may be + mangled depending on the ABI of the system (eg. adding leading + underscore for Darwin). hunk ./doc/cffi-sys-specification.html 232 - The remaining arguments are pairs of foreign types and their values, - followed by the return type of the function, assumed to be :void - if not supplied. + The remaining arguments are pairs of foreign types and their + values, followed by the return type of the function, assumed to + be :void if not supplied. hunk ./doc/cffi-sys-specification.html 238 - - This wording is pretty awkward, rewrite this description. - + + This wording is pretty awkward, rewrite this description. + hunk ./doc/cffi-sys-specification.html 245 -
+
hunk ./doc/cffi-sys-specification.html 262
-    Loads the foreign shared library name.
+      Loads the foreign shared library name.
hunk ./doc/cffi-sys-specification.html 266
-    
-    There is a lot of behavior to decide here.  Currently I lean toward
-    not requiring NAME to be a full path to the library so we can search
-    the system library directories (maybe even get LD_LIBRARY_PATH from
-    the environment) as necessary.
-    
+      
+        There is a lot of behavior to decide here.  Currently I lean
+        toward not requiring NAME to be a full path to the library so
+        we can search the system library directories (maybe even get
+        LD_LIBRARY_PATH from the environment) as necessary.
+      
hunk ./doc/cffi-sys-specification.html 275
-    
-    6 June 2005 / James Bielman / jamesjb at jamesjb dot com
-    
+      
+        6 June 2005 / James Bielman / jamesjb at jamesjb dot com
+      
hunk ./doc/cffi-sys-specification.html 282
-
hunk ./doc/manual.html 3
-  CFFI User Manual
+    CFFI User Manual
+    
hunk ./doc/manual.html 14
-
+    
hunk ./doc/manual.html 24
-      
  • A type safe pointer interface can be developed on top of n +
  • A type safe pointer interface can be developed on top of an hunk ./doc/manual.html 35 - Foreign Type: :char
    - Foreign Type: :unsigned-char
    - Foreign Type: :short
    - Foreign Type: :unsigned-short
    - Foreign Type: :int
    - Foreign Type: :unsigned-int
    - Foreign Type: :long
    - Foreign Type: :unsigned-long
    - Foreign Type: :long-long
    - Foreign Type: :unsigned-long-long
    + Foreign Type: :char
    + Foreign Type: :unsigned-char
    + Foreign Type: :short
    + Foreign Type: :unsigned-short
    + Foreign Type: :int
    + Foreign Type: :unsigned-int
    + Foreign Type: :long
    + Foreign Type: :unsigned-long
    + Foreign Type: :long-long
    + Foreign Type: :unsigned-long-long
    hunk ./doc/manual.html 53 - Foreign Type: :int8
    - Foreign Type: :uint8
    - Foreign Type: :int16
    - Foreign Type: :uint16
    - Foreign Type: :int32
    - Foreign Type: :uint32
    - Foreign Type: :int64
    - Foreign Type: :uint64
    + Foreign Type: :int8
    + Foreign Type: :uint8
    + Foreign Type: :int16
    + Foreign Type: :uint16
    + Foreign Type: :int32
    + Foreign Type: :uint32
    + Foreign Type: :int64
    + Foreign Type: :uint64
    hunk ./doc/manual.html 64 - Foreign integer types of specific sizes, corresponding to the - C types defined in stdint.h. + Foreign integer types of specific sizes, corresponding to the C + types defined in stdint.h. hunk ./doc/manual.html 69 - Foreign Type: :size
    - Foreign Type: :ssize
    - Foreign Type: :ptrdiff
    - Foreign Type: :time
    + Foreign Type: :size
    + Foreign Type: :ssize
    + Foreign Type: :ptrdiff
    + Foreign Type: :time
    hunk ./doc/manual.html 74 - + hunk ./doc/manual.html 76 - Foreign integer types corresponding to the standard C types (without - the _t suffix). + Foreign integer types corresponding to the standard C types + (without the _t suffix). hunk ./doc/manual.html 79 - + hunk ./doc/manual.html 81 - - I'm sure there are more of these that could be useful, let's add - any types that can't be defined portably to this list as necessary. - + + I'm sure there are more of these that could be useful, let's + add any types that can't be defined portably to this list as + necessary. + hunk ./doc/manual.html 87 - + hunk ./doc/manual.html 89 - Foreign Type: :float
    - Foreign Type: :double
    + Foreign Type: :float
    + Foreign Type: :double
    hunk ./doc/manual.html 92 - + hunk ./doc/manual.html 94 - The :float type represents a C float and a Lisp - single-float. :double represents a C double - and a Lisp double-float. + The :float type represents a C float and a Lisp + single-float. :double represents a + C double and a Lisp double-float. hunk ./doc/manual.html 102 - A foreign pointer to an object of any type, corresponding to - void *. + A foreign pointer to an object of any type, corresponding to + void *. hunk ./doc/manual.html 109 - No type at all. Only valid as the return type of a function. + No type at all. Only valid as the return type of a function. hunk ./doc/manual.html 115 - Macro: defctype name type - &optional documentation + Macro: defctype name type + &optional documentation hunk ./doc/manual.html 118 - + hunk ./doc/manual.html 120 - + hunk ./doc/manual.html 122 - Macro: defcstruct name &body - doc-options-and-slots + Macro: defcstruct name &body + doc-options-and-slots hunk ./doc/manual.html 125 - + hunk ./doc/manual.html 127 - A structure slot is either simple, or aggregate. + A structure slot is either simple, or aggregate. hunk ./doc/manual.html 131 - Simple structure slots contain a single instance of a type that - canonicalizes to a built-in type, such as :long or - :pointer. + Simple structure slots contain a single instance of a type that + canonicalizes to a built-in type, such as :long or + :pointer. hunk ./doc/manual.html 135 - + hunk ./doc/manual.html 137 - Aggregate slots contain an embedded structure or union, or an array - of objects. + Aggregate slots contain an embedded structure or union, or an array + of objects. hunk ./doc/manual.html 141 +

    Example:

    + +
    +(defcstruct timeval
    +  (tv-sec  :long)
    +  (tv-usec :long))
    +
    + hunk ./doc/manual.html 150 - Accessor: foreign-slot-value ptr type - &rest slot-names => object + Accessor: foreign-slot-value ptr type + &rest slot-names => object hunk ./doc/manual.html 153 - + hunk ./doc/manual.html 155 - For simple slots, foreign-slot-value returns the value of - the object, such as a Lisp integer or pointer. In C, this would be - expressed as ptr->slot. + For simple slots, foreign-slot-value returns the value + of the object, such as a Lisp integer or pointer. In C, this + would be expressed as ptr->slot. hunk ./doc/manual.html 161 - For aggregate slots, a pointer inside the structure to the beginning - of the slot's data is returned. In C, this would be expressed as - &ptr->slot. This pointer and the memory it points to - have the same extent as ptr. + For aggregate slots, a pointer inside the structure to the + beginning of the slot's data is returned. In C, this would be + expressed as + &ptr->slot. This pointer and the memory it points to + have the same extent as ptr. hunk ./doc/manual.html 167 - + hunk ./doc/manual.html 169 - There are compiler macros for foreign-slot-value and its - setf expansion that open code the memory access when - type and slot-names are constant at compile-time. + There are compiler macros for foreign-slot-value and its + setf expansion that open code the memory access when + type and slot-names are constant at compile-time. hunk ./doc/manual.html 175 - Macro: explain-foreign-slot-value ptr type - &rest slot-names + Macro: explain-foreign-slot-value ptr type + &rest slot-names hunk ./doc/manual.html 178 - + hunk ./doc/manual.html 180 - This macro translates the slot access that would occur by calling - FOREIGN-SLOT-VALUE with the same arguments into an equivalent - expression in C and prints it to *STANDARD-OUTPUT*. + This macro translates the slot access that would occur by calling + FOREIGN-SLOT-VALUE with the same arguments into an + equivalent expression in C and prints it + to *STANDARD-OUTPUT*. hunk ./doc/manual.html 188 -
    +
    hunk ./doc/manual.html 198
    -                     &rest slot-names => ptr
    +    &rest slot-names => ptr
    hunk ./doc/manual.html 215
    -
    -(defcstruct timeval
    -  (tv-sec  :long)
    -  (tv-usec :long))
    -
    +
    hunk ./doc/manual.html 232
    +
    hunk ./doc/manual.html 285
    -                     &optional (count 0) => ptr
    +                     &optional (count 1) => ptr
    hunk ./doc/manual.html 288
    +
    +(let ((ptr (foreign-object-alloc <type> <count>)))
    +  ...)
    +
    +==>
    +
    +{
    +   void *ptr = malloc (sizeof (<type>) * <count>);
    +
    +   if (ptr == NULL)
    +      raise_storage_condition ();
    +
    +   ...
    +}
    +
    + hunk ./doc/manual.html 309 +
    +(foreign-object-free ptr)
    +
    +==>
    +
    +free (ptr);
    +
    + hunk ./doc/manual.html 318 - Macro: with-foreign-object (var type - &optional (count 1)) &body body + Macro: with-foreign-object (var type + &optional (count 1)) &body body hunk ./doc/manual.html 322 -

    Foreign Pointers

    +
    +(with-foreign-object (ptr <type> <count>)
    +  ...)
    hunk ./doc/manual.html 326
    +==>
    +
    +{
    +   void *ptr = alloca (sizeof (<type>) * <count>);
    +   ...
    +}
    +
    + +

    Foreign Pointers

    + hunk ./doc/manual.html 337 - Describe the theory of how foreign variables work---they are always - pointers, even when accessing integer types or embedded structures. - You cannot represent a structure by value. + Describe the theory of how foreign variables work---they are always + pointers, even when accessing integer types or embedded structures. + You cannot represent a structure by value. hunk ./doc/manual.html 362 -
    +
    hunk ./examples/examples.lisp 88
    -     string "%d #x%x!" :int 666 :unsigned-int #xcafebabe
    +     string "%d %f #x%x!" :int 666 
    +     :double (coerce pi 'double-float)
    +     :unsigned-int #xcafebabe
    hunk ./examples/examples.lisp 103
    -;; Proposed syntax for nested structures:
    -#+nil
    +;; Nested structure example:
    hunk ./examples/examples.lisp 105
    -  (name    :pointer)
    -  (timeval :struct timeval))
    +  (name    :char 100)
    +  (timeval timeval))
    hunk ./src/cffi-clisp.lisp 43
    +   #:inc-ptr
    hunk ./src/cffi-clisp.lisp 105
    +(defun inc-ptr (ptr offset)
    +  "Return a pointer pointing OFFSET bytes past PTR."
    +  (ffi:unsigned-foreign-address
    +   (+ offset (ffi:foreign-address-unsigned ptr))))
    +
    hunk ./src/cffi-clisp.lisp 139
    -
    -(defun %inc-ptr (ptr offset)
    -  "Return a new pointer OFFSET bytes past PTR."
    -  (ffi:unsigned-foreign-address
    -   (+ offset (ffi:foreign-address-unsigned ptr))))
    hunk ./src/cffi-cmucl.lisp 36
    +   #:inc-ptr
    hunk ./src/cffi-cmucl.lisp 44
    -   #:%mem-ref))
    +   #:%mem-ref
    +   #:make-shareable-byte-vector
    +   #:with-pointer-to-vector-data))
    hunk ./src/cffi-cmucl.lisp 67
    +(declaim (inline inc-ptr))
    +(defun inc-ptr (ptr offset)
    +  "Return a pointer pointing OFFSET bytes past PTR."
    +  (sys:sap+ ptr offset))
    +
    hunk ./src/cffi-cmucl.lisp 118
    +
    +;;;# Shareable Vectors
    +;;;
    +;;; This interface is very experimental.  WITH-POINTER-TO-VECTOR-DATA
    +;;; should be defined to perform a copy-in/copy-out if the Lisp
    +;;; implementation can't do this.
    +
    +(defun make-shareable-byte-vector (size)
    +  "Create a Lisp vector of SIZE bytes that can passed to
    +WITH-POINTER-TO-VECTOR-DATA."
    +  (make-array size :element-type '(unsigned-byte 8)))
    +
    +(defmacro with-pointer-to-vector-data ((ptr-var vector) &body body)
    +  "Bind PTR-VAR to a foreign pointer to the data in VECTOR."
    +  `(sys:without-gcing
    +     (let ((,ptr-var (sys:vector-sap ,vector)))
    +       ,@body)))
    hunk ./src/cffi-openmcl.lisp 38
    +   #:inc-ptr
    hunk ./src/cffi-openmcl.lisp 43
    -   #:%load-foreign-library))
    +   #:%load-foreign-library
    +   #:make-shareable-byte-vector
    +   #:with-pointer-to-vector-data))
    hunk ./src/cffi-openmcl.lisp 85
    +
    +(defun inc-ptr (ptr offset)
    +  "Return a pointer OFFSET bytes past PTR."
    +  (ccl:%inc-ptr ptr offset))
    +
    +;;;# Shareable Vectors
    +;;;
    +;;; This interface is very experimental.  WITH-POINTER-TO-VECTOR-DATA
    +;;; should be defined to perform a copy-in/copy-out if the Lisp
    +;;; implementation can't do this.
    +
    +(defun make-shareable-byte-vector (size)
    +  "Create a Lisp vector of SIZE bytes that can passed to
    +WITH-POINTER-TO-VECTOR-DATA."
    +  (make-array size :element-type '(unsigned-byte 8)))
    +
    +(defmacro with-pointer-to-vector-data ((ptr-var vector) &body body)
    +  "Bind PTR-VAR to a foreign pointer to the data in VECTOR."
    +  `(ccl:with-pointer-to-ivector (,ptr-var ,vector)
    +     ,@body))
    hunk ./src/cffi-sbcl.lisp 36
    +   #:inc-ptr
    hunk ./src/cffi-sbcl.lisp 44
    -   #:%mem-ref))
    +   #:%mem-ref
    +   #:make-shareable-byte-vector
    +   #:with-pointer-to-vector-data))
    hunk ./src/cffi-sbcl.lisp 64
    +(defun inc-ptr (ptr offset)
    +  "Return a pointer pointing OFFSET bytes past PTR."
    +  (sb-sys:sap+ ptr offset))
    hunk ./src/cffi-sbcl.lisp 104
    +
    +;;;# Shareable Vectors
    +;;;
    +;;; This interface is very experimental.  WITH-POINTER-TO-VECTOR-DATA
    +;;; should be defined to perform a copy-in/copy-out if the Lisp
    +;;; implementation can't do this.
    +
    +(defun make-shareable-byte-vector (size)
    +  "Create a Lisp vector of SIZE bytes can passed to
    +WITH-POINTER-TO-VECTOR-DATA."
    +  (make-array size :element-type '(unsigned-byte 8)))
    +
    +(defmacro with-pointer-to-vector-data ((ptr-var vector) &body body)
    +  "Bind PTR-VAR to a foreign pointer to the data in VECTOR."
    +  `(sb-sys:without-gcing
    +     (let ((,ptr-var (sb-sys:vector-sap ,vector)))
    +       ,@body)))
    hunk ./src/early-types.lisp 59
    -  (gethash name *foreign-types*))
    +  (or (gethash name *foreign-types*)
    +      (error "Undefined foreign type: ~S" name)))
    hunk ./src/package.lisp 36
    +   #:pointerp
    hunk ./src/package.lisp 39
    +   #:inc-ptr
    hunk ./src/package.lisp 42
    +   ;; Shareable vectors.
    +   #:make-shareable-vector
    +   #:with-pointer-to-vector-data
    +
    hunk ./src/package.lisp 64
    +   #:foreign-enum-keyword
    +   #:foreign-enum-value
    hunk ./src/types.lisp 30
    -;;;# Foreign Type Deferencing
    +;;;# Dereferencing Foreign Pointers
    hunk ./src/types.lisp 39
    -      (progn
    -        #-(and) (format t "~&;; Open-coding MEM-REF form: ~S~%" form)
    -        `(%mem-ref ,ptr ,(canonicalize-foreign-type (eval type)) ,offset))
    +      `(%mem-ref ,ptr ,(canonicalize-foreign-type (eval type)) ,offset)
    hunk ./src/types.lisp 67
    -      (progn
    -        #-(and) (format t "~&;; Open-coding (SETF MEM-REF) form: ~S~%" form)
    -        `(setf (%mem-ref ,ptr ,(canonicalize-foreign-type (eval type))
    -                         ,offset) ,value))
    +      `(setf (%mem-ref ,ptr ,(canonicalize-foreign-type (eval type))
    +                       ,offset) ,value)
    hunk ./src/types.lisp 71
    +;;;# Dereferencing Foreign Arrays
    +
    +;;; TODO: FOREIGN-AREF needs its own SETF expander and a compiler
    +;;; macro to optimize array references when TYPE is constant.
    hunk ./src/types.lisp 85
    +;;;## Foreign Structure Slots
    +
    +(defgeneric foreign-struct-slot-address (ptr slot)
    +  (:documentation "Get the address of SLOT relative to PTR."))
    +
    +(defgeneric foreign-struct-slot-value (ptr slot)
    +  (:documentation "Return the value of SLOT in structure PTR."))
    +
    +(defclass foreign-struct-slot ()
    +  ((offset :initarg :offset :accessor slot-offset)
    +   (type   :initarg :type   :accessor slot-type))
    +  (:documentation "Base class for simple and aggregate slots."))
    +
    +(defmethod foreign-struct-slot-address (ptr (slot foreign-struct-slot))
    +  "Return the address of SLOT relative to PTR."
    +  (inc-ptr ptr (slot-offset slot)))
    +
    +;;;### Simple Slots
    +
    +(defclass simple-struct-slot (foreign-struct-slot)
    +  ()
    +  (:documentation "Non-aggregate structure slots."))
    +
    +(defmethod foreign-struct-slot-value (ptr (slot simple-struct-slot))
    +  "Return the value of a simple SLOT from a struct at PTR."
    +  (mem-ref ptr (slot-type slot) (slot-offset slot)))
    +
    +;;;### Aggregate Slots
    +
    +(defclass aggregate-struct-slot (foreign-struct-slot)
    +  ((count :initarg count :accessor slot-count))
    +  (:documentation "Aggregate structure slots."))
    +
    +(defmethod foreign-struct-slot-value (ptr (slot aggregate-struct-slot))
    +  "Return a pointer to SLOT relative to PTR."
    +  (foreign-struct-slot-address ptr slot))
    +
    +;;;## Defining Foreign Structures
    +
    +(defun new-notice-foreign-struct-definition (name slots)
    +  "Parse and install a foreign structure definition."
    +  (let ((struct (make-instance 'foreign-struct-type :name name))
    +        (offset 0))
    +    (declare (ignore struct))
    +    (dolist (slotdef slots)
    +      (destructuring-bind (slotname type &optional (count 1)) slotdef
    +        (declare (ignore slotname))
    +        (setf offset (adjust-for-alignment type offset))
    +        ;; If TYPE is an aggregate type or COUNT is non-nil, create an
    +        ;; AGGREGATE-STRUCT-SLOT, otherwise create a SIMPLE-STRUCT
    +        ;; slot.  Add the slot to STRUCT's hash of slot objects.
    +        (incf offset (* count (foreign-type-size type)))))))
    +
    hunk ./src/types.lisp 140
    +  (new-notice-foreign-struct-definition name slots)
    hunk ./src/types.lisp 143
    -    (loop for (slot type) in slots
    +    (loop for (slot type . nil) in slots
    hunk ./src/types.lisp 151
    +(defmacro defcstruct (name &body fields)
    +  "Define the layout of a foreign structure."
    +  `(eval-when (:compile-toplevel :load-toplevel :execute)
    +     (notice-foreign-struct-definition ',name ',fields)))
    +
    +;;;## Accessing Foreign Structure Slots
    +
    hunk ./src/types.lisp 180
    -      (progn
    -        #-(and) (format t "~&;; Open-coding FOREIGN-SLOT-VALUE form: ~S~%" form)
    -        (destructuring-bind (&key offset type)
    -            (get-slot-info (eval type) (eval slot-name))
    -          `(mem-ref ,ptr ,type ,offset)))
    +      (destructuring-bind (&key offset type)
    +          (get-slot-info (eval type) (eval slot-name))
    +        `(mem-ref ,ptr ',type ,offset))
    hunk ./src/types.lisp 210
    -  "Optimizer for FOREIGN-SLOT-VALUE when TYPE is constant."
    +  "Optimizer when TYPE and SLOT-NAME are constant."
    hunk ./src/types.lisp 212
    -      (progn
    -        #-(and) (format t "~&;; Open-coding (SETF FOREIGN-SLOT-VALUE) form: ~S~%" form)
    -        (destructuring-bind (&key offset type)
    -            (get-slot-info (eval type) (eval slot-name))
    -          `(setf (mem-ref ,ptr ,type ,offset) ,value)))
    +      (destructuring-bind (&key offset type)
    +          (get-slot-info (eval type) (eval slot-name))
    +        `(setf (mem-ref ,ptr ,type ,offset) ,value))
    hunk ./src/types.lisp 226
    -
    -(defmacro defcstruct (name &body fields)
    -  "Define the layout of a foreign structure."
    -  `(eval-when (:compile-toplevel :load-toplevel :execute)
    -     (notice-foreign-struct-definition ',name ',fields)))
    hunk ./tests/funcall.lisp 61
    -      (setf (mem-ref s :char) 0)
    hunk ./tests/funcall.lisp 71
    -      (setf (mem-ref s :char) 0)
    hunk ./tests/funcall.lisp 76
    -      (setf (mem-ref s :char) 0)
    hunk ./tests/funcall.lisp 81
    -      (setf (mem-ref s :char) 0)
    hunk ./tests/funcall.lisp 89
    -      (setf (mem-ref s :char) 0)
    hunk ./tests/funcall.lisp 95
    -      (setf (mem-ref s :char) 0)
    hunk ./tests/memory.lisp 32
    -      (setf (mem-ref p :char) -127)
    +      (setf (mem-ref p :char) 127)
    hunk ./tests/memory.lisp 34
    -  -127)
    -
    -(deftest deref.unsigned-char
    -    (with-foreign-object (p :unsigned-char)
    -      (setf (mem-ref p :unsigned-char) 255)
    -      (mem-ref p :unsigned-char))
    -  255)
    +  127)
    hunk ./tests/memory.lisp 38
    -      (setf (mem-ref p :short) -32767)
    +      (setf (mem-ref p :short) 32767)
    hunk ./tests/memory.lisp 40
    -  -32767)
    -
    -(deftest deref.unsigned-short
    -    (with-foreign-object (p :unsigned-short)
    -      (setf (mem-ref p :unsigned-short) 65535)
    -      (mem-ref p :unsigned-short))
    -  65535)
    +  32767)
    hunk ./tests/memory.lisp 44
    -      (setf (mem-ref p :int) -131072)
    +      (setf (mem-ref p :int) 131072)
    hunk ./tests/memory.lisp 46
    -  -131072)
    -
    -(deftest deref.unsigned-int
    -    (with-foreign-object (p :unsigned-int)
    -      (setf (mem-ref p :unsigned-int) 262144)
    -      (mem-ref p :unsigned-int))
    -  262144)
    +  131072)
    hunk ./tests/memory.lisp 50
    -      (setf (mem-ref p :long) -536870911)
    +      (setf (mem-ref p :long) 536870912)
    hunk ./tests/memory.lisp 52
    -  -536870911)
    -
    -(deftest deref.unsigned-long
    -    (with-foreign-object (p :unsigned-long)
    -      (setf (mem-ref p :unsigned-long) 536870912)
    -      (mem-ref p :unsigned-long))
    hunk ./tests/memory.lisp 53
    -
    -(deftest deref.float.1
    -    (with-foreign-object (p :float)
    -      (setf (mem-ref p :float) 0.0)
    -      (mem-ref p :float))
    -  0.0)
    -
    -(deftest deref.float.2
    -    (with-foreign-object (p :float)
    -      (setf (mem-ref p :float) most-positive-single-float)
    -      (mem-ref p :float))
    -  #.most-positive-single-float)
    -
    -(deftest deref.float.3
    -    (with-foreign-object (p :float)
    -      (setf (mem-ref p :float) least-positive-single-float)
    -      (mem-ref p :float))
    -  #.least-positive-single-float)
    -
    -(deftest deref.double.1
    -    (with-foreign-object (p :double)
    -      (setf (mem-ref p :double) 0.0d0)
    -      (mem-ref p :double))
    -  0.0d0)
    -
    -(deftest deref.double.2
    -    (with-foreign-object (p :double)
    -      (setf (mem-ref p :double) most-positive-double-float)
    -      (mem-ref p :double))
    -  #.most-positive-double-float)
    -
    -(deftest deref.double.3
    -    (with-foreign-object (p :double)
    -      (setf (mem-ref p :double) least-positive-double-float)
    -      (mem-ref p :double))
    -  #.least-positive-double-float)
    -
    hunk ./tests/package.lisp 29
    -  (:use #:cl #:cffi #+lispworks #:regression-test #-lispworks #:rt)
    +  (:use #:cl #:cffi #:rt)
    hunk ./tests/run-tests.lisp 28
    -(format t "~&-------- Running tests in ~A --------~%"
    -        (lisp-implementation-type))
    -
    hunk ./tests/run-tests.lisp 33
    +#+clisp
    +(load "~/Downloads/asdf")
    +#+clisp
    +(push "~/.asdf-install-dir/systems/" asdf:*central-registry*)
    hunk ./tests/struct-tests.lisp 28
    -;; TODO: Make a separate CFFI-TESTS package for this later.
    -(in-package #:cffi)
    +(asdf:operate 'asdf:load-op 'cffi :verbose nil)
    +
    +(defpackage #:cffi-tests
    +  (:use #:cl #:cffi))
    +(in-package #:cffi-tests)
    hunk ./tests/struct-tests.lisp 51
    -  (with-foreign-struct (a align-test)
    +  (with-foreign-object (a align-test)
    hunk ./tests/struct-tests.lisp 58
    +
    }