New patches: [implicit defbitfield symbol values Stephen Compall **20060511072106 - Foreign Type Translators: defctype does not create Lisp types; you have to use eql specializers. - enum.lisp: Use reduce in %foreign-bitfield-value. Code a default rule for bitfield symbol values. ] < > { hunk ./doc/cffi-manual.texinfo 1853 The @code{:string} type performs automatic conversion between Lisp and C strings. Note that, in the case of functions the converted C string -will have dynamic extent (ie. it will be automatically freed after the -foreign function returns). +will have dynamic extent (i.e.@: it will be automatically freed after +the foreign function returns). @lisp hunk ./doc/cffi-manual.texinfo 1857 -;;; :STRING example +;;; @lispcmt{:STRING example} CFFI> (foreign-funcall "getenv" :string "SHELL" :string) hunk ./doc/cffi-manual.texinfo 1859 -"/bin/bash" +@result{} "/bin/bash" @end lisp @ForeignType{:boolean &optional (base-type :int)} hunk ./doc/cffi-manual.texinfo 1934 We created the @code{my-boolean} type in the previous section. To tell @cffi{} how to automatically convert Lisp values to @code{my-boolean} values, specialize the generic function -@code{translate-to-foreign} on the @code{my-boolean} type: +@code{translate-to-foreign} using an @sc{eql}-specializer with the +name of your type, in this case the symbol @code{my-boolean}: @lisp ;;; @lispcmt{Define a method that converts Lisp booleans to C booleans.} hunk ./doc/cffi-manual.texinfo 1947 function, this method will be invoked to convert the Lisp value to an integer. To perform the inverse operation, which is needed for functions that return a @code{my-boolean}, specialize the -@code{translate-from-foreign} generic function: +@code{translate-from-foreign} generic function in the same manner as +above: @lisp ;;; @lispcmt{Define a method that converts C booleans to Lisp booleans.} hunk ./doc/cffi-manual.texinfo 1957 @end lisp When a @code{translate-to-foreign} method requires allocation of -foreign memory, the @code{free-translated-object} method can be -specialized to free the memory once the foreign object is no longer -needed. This is called automatically by @cffi{} when passing objects to +foreign memory, you may specialize the @code{free-translated-object} +method to free the memory once the foreign object is no longer needed. +This is called automatically by @cffi{} when passing objects to foreign functions. A type translator does not necessarily need to convert the value. For hunk ./doc/cffi-manual.texinfo 2038 @noindent Much better. +The expansion interface has no equivalent of +@code{free-translated-object}; you must instead define a method on @code{expand-to-foreign-dyn}, the third generic function in this hunk ./doc/cffi-manual.texinfo 2041 -interface, is especially useful when you can allocate something much -more efficiently if you know the object has dynamic extent. Consider -the following example: +interface. This is especially useful when you can allocate something +much more efficiently if you know the object has dynamic extent, as is +the case with function calls that don't save the relevant allocated +arguments. Consider the following example: @lisp ;;; This type inherits :string's translators. hunk ./doc/cffi-manual.texinfo 2298 @subheading Description The @code{defbitfield} macro is used to define foreign types that map -lists of lisp symbols to integer values. +lists of symbols to integer values. hunk ./doc/cffi-manual.texinfo 2300 -If @var{value} is omitted its value will either be 0, if it's the -first entry, or it it will continue the progression from the last -specified value. +If @var{value} is omitted its value will either be @code{0}, if it is +the first entry, or it will be the result of left-shifting the largest +@var{value} so far, specified or omitted, with a single 1-bit in its +binary representation, by one; if there is no such value so far, +@code{1} is used. hunk ./doc/cffi-manual.texinfo 2306 -Symbol lists will be automatically converted to values and vice-versa +Symbol lists will be automatically converted to values and vice versa when being passed as arguments to or returned from foreign functions, respectively. The same applies to any other situations where an object of a bitfield type is expected. hunk ./doc/cffi-manual.texinfo 2317 @subheading Examples @lisp (defbitfield open-flags - (:rdonly #x0000) - (:wronly #x0001) - (:rdwr #x0002) - (:nonblock #x0004) - (:append #x0008) + :rdonly ;@lispcmt{#x0000} + :wronly ;@lispcmt{#x0001} + :rdwr ;@lispcmt{@dots{}} + :nonblock + :append (:creat #x0200)) hunk ./doc/cffi-manual.texinfo 2323 - ;; etc.. + ;; @lispcmt{etc@dots{}} CFFI> (foreign-bitfield-symbols 'open-flags #b1101) @result{} (:RDONLY :WRONLY :NONBLOCK :APPEND) hunk ./doc/cffi-manual.texinfo 2337 (mode :uint16)) ; unportable CFFI> (unix-open "/tmp/foo" '(:wronly :creat) #o644) -@result{} +@result{} # hunk ./doc/cffi-manual.texinfo 2339 -;;; Consider also the following lispier wrapper around open() +;;; @lispcmt{Consider also the following lispier wrapper around open()} (defun lispier-open (path mode &rest flags) (unix-open path flags mode)) @end lisp hunk ./src/enum.lisp 137 (defun make-foreign-bitfield (type-name base-type values) "Makes a new instance of the foreign-bitfield class." (let ((type (make-instance 'foreign-bitfield :name type-name - :actual-type (parse-type base-type)))) + :actual-type (parse-type base-type))) + (last-bit nil)) (dolist (pair values) hunk ./src/enum.lisp 140 - (destructuring-bind (symbol value) pair - (check-type value integer) + (destructuring-bind (symbol &optional (value nil value-p)) + (mklist pair) (check-type symbol symbol) hunk ./src/enum.lisp 143 + (if value-p + (check-type value integer) + (setf value (cond ((null last-bit) (setf last-bit 0)) + ((zerop last-bit) 1) + (t (ash last-bit 1))))) + ;; find the greatest single-bit int used so far, and use its + ;; left-shift + (when (and (> value last-bit) (single-bit-p value)) + (setf last-bit value)) (if (gethash symbol (symbol-values type)) (error "A foreign bitfield cannot contain duplicate symbols: ~S." symbol) hunk ./src/enum.lisp 169 (make-foreign-bitfield ',name ',base-type ',masks))))) (defun %foreign-bitfield-value (type symbols) - (let ((bitfield 0)) - (dolist (symbol symbols) - (check-type symbol symbol) - (let ((value (or (gethash symbol (symbol-values type)) - (error "~S is not a valid symbol for bitfield type ~S." - symbol type)))) - (setq bitfield (logior bitfield value)))) - bitfield)) + (reduce #'logior symbols + :key (lambda (symbol) + (check-type symbol symbol) + (or (gethash symbol (symbol-values type)) + (error "~S is not a valid symbol for bitfield type ~S." + symbol type))))) (defun foreign-bitfield-value (type symbols) "Convert a list of symbols into an integer according to the TYPE bitfield." hunk ./src/enum.lisp 205 (defmethod translate-type-from-foreign (value (type foreign-bitfield)) (%foreign-bitfield-symbols type value)) + hunk ./src/utils.lisp 41 #:symbolicate #:let-when #:bif - #:post-incf)) + #:post-incf + #:single-bit-p)) (in-package #:cffi-utils) hunk ./src/utils.lisp 159 (len (length x))) (replace name x :start1 index) (incf index len)))))) + +(defun single-bit-p (integer) + "Answer whether INTEGER, which must be an integer, is a single +set twos-complement bit." + (if (<= integer 0) + nil ;infinite set bits for negatives + (loop until (logbitp 0 integer) + do (setf integer (ash integer -1)) + finally (return (zerop (ash integer -1)))))) ;(defun deprecation-warning (bad-name &optional good-name) ; (warn "using deprecated ~S~@[, should use ~S instead~]" } Context: [Make :POINTER a parameterized foreign type. James Bielman **20060507003511 - :POINTER without arguments is a void pointer. - (:POINTER :INT) is a pointer to an :INT. - These nest properly: (:POINTER (:POINTER :INT)). - Pointers are not type checked yet---an optional pointer type checker will be added someday. ] [Bugfix: Quote type arguments to %DEFCFUN-VARARGS. James Bielman **20060507002829] [Recognize OpenMCL/X86-64 and set CFFI features accordingly. James Bielman **20060504173940] [Conditionalize against non-CPU specific word-size features in OpenMCL. James Bielman **20060504021623] [Bugfix: Specialize UNPARSE for UFFI-CHAR in CFFI-UFFI-COMPAT. James Bielman **20060504015421 - Fixes an error when loading FASL files that dumped UFFI-CHAR instead of (UFFI-CHAR :CHAR) using MAKE-LOAD-FORM. - Reported by Ricardo Boccato. ] [More copyright header year updates. James Bielman **20060503064225] [Update copyright year in file headers. James Bielman **20060503063944] [Conditionally set variables for implementations in Makefile. James Bielman **20060503063241 - Allow overriding from the environment as suggest in the comment, which didn't actually work. (eg.: OPENMCL=openmcl64 make test) ] [Add OpenMCL/X86-64 fasl files to 'make clean'. James Bielman **20060503061637] [Make corman's finalizers thread-safe (hopefully) Luis Oliveira **20060424173620] [Add support for finalizers Luis Oliveira **20060424025357 - New functions: finalize and cancel-finalization. - New cffi-"feature": no-finalizers. Only ECL pushes this. - Document new functions. ] [Include stdint.h in libtest.c Luis Oliveira **20060424025320] [Oops, forgot to bump the version number. Luis Oliveira **20060424025119] [TAG 0.9.1 Luis Oliveira **20060418011351] Patch bundle hash: 5816af08accd180a1e4b598d597a0e1e0fe071d3