masks ::= [docstring] { (symbol value) }*
name-and-options ::= name | (name &optional (base-type :int))
The defbitfield
macro is used to define foreign types that map
lists of symbols to integer values.
If value is omitted, it will be computed as follows: find the greatest value previously used, including those so computed, with only a single 1-bit in its binary representation (that is, powers of two), and left-shift it by one. This rule guarantees that a computed value cannot clash with previous values, but may clash with future explicitly specified values.
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.
Types defined with defbitfield
canonicalize to base-type
which is :int
by default.
(defbitfield open-flags (:rdonly #x0000) :wronly ;#x0001 :rdwr ;... :nonblock :append (:creat #x0200)) ;; etc... CFFI> (foreign-bitfield-symbols 'open-flags #b1101) => (:RDONLY :WRONLY :NONBLOCK :APPEND) CFFI> (foreign-bitfield-value 'open-flags '(:rdwr :creat)) => 514 ; #x0202 (defcfun ("open" unix-open) :int (path :string) (flags open-flags) (mode :uint16)) ; unportable CFFI> (unix-open "/tmp/foo" '(:wronly :creat) #o644) => #<an fd> ;;; Consider also the following lispier wrapper around open() (defun lispier-open (path mode &rest flags) (unix-open path flags mode))