Skip to content

Commit

Permalink
change first automatic defbitfield value to 1
Browse files Browse the repository at this point in the history
- make-foreign-bitfield now starts implicit bitfield values at 1.  No
  more special cases for zero.
- Document and update bf tests to match.
  • Loading branch information
S11001001 committed May 12, 2006
1 parent 3b33e99 commit 1e10150
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 26 deletions.
13 changes: 7 additions & 6 deletions doc/cffi-manual.texinfo
Original file line number Diff line number Diff line change
Expand Up @@ -2297,11 +2297,12 @@ An integer representing a bitmask.
The @code{defbitfield} macro is used to define foreign types that map
lists of symbols to integer values.

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.
If @var{value} is omitted, it will be computed as follows: find the
greatest @var{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 @var{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,
Expand All @@ -2314,7 +2315,7 @@ which is @code{:int} by default.
@subheading Examples
@lisp
(defbitfield open-flags
:rdonly ;@lispcmt{#x0000}
(:rdonly #x0000)
:wronly ;@lispcmt{#x0001}
:rdwr ;@lispcmt{@dots{}}
:nonblock
Expand Down
23 changes: 11 additions & 12 deletions src/enum.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -135,21 +135,20 @@
"Makes a new instance of the foreign-bitfield class."
(let ((type (make-instance 'foreign-bitfield :name type-name
:actual-type (parse-type base-type)))
(last-bit nil))
(bit-floor 1))
(dolist (pair values)
(destructuring-bind (symbol &optional (value nil value-p))
;; bit-floor rule: find the greatest single-bit int used so far,
;; and store its left-shift
(destructuring-bind (symbol &optional
(value (prog1 bit-floor
(setf bit-floor (ash bit-floor 1)))
value-p))
(mklist pair)
(check-type symbol symbol)
(if value-p
(check-type value integer)
(setf value (cond ((null 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 (or (null last-bit) (> value last-bit))
(or (zerop value) (single-bit-p value)))
(setf last-bit value))
(when value-p
(check-type value integer)
(when (and (>= value bit-floor) (single-bit-p value))
(setf bit-floor (ash value 1))))
(if (gethash symbol (symbol-values type))
(error "A foreign bitfield cannot contain duplicate symbols: ~S."
symbol)
Expand Down
16 changes: 8 additions & 8 deletions tests/enum.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -74,25 +74,25 @@
bf1)

(defbitfield bf2
zero
one
two
four
eight
sixteen
thirty-two)
thirty-two
sixty-four)

(deftest bitfield.2
(mapcar (lambda (symbol)
(foreign-bitfield-value 'bf2 (list symbol)))
'(zero one two four eight sixteen thirty-two))
(0 1 2 4 8 16 32))
'(one two four eight sixteen thirty-two sixty-four))
(1 2 4 8 16 32 64))

(defbitfield bf3
(three 3)
zero
(seven 7)
one
(seven 7)
two
(eight 8)
sixteen)

Expand All @@ -102,8 +102,8 @@
(deftest bitfield.3
(mapcar (lambda (symbol)
(foreign-bitfield-value 'bf3 (list symbol)))
'(zero one sixteen))
(0 1 16))
'(one two sixteen))
(1 2 16))

(defbitfield bf4
(zero 0)
Expand Down

0 comments on commit 1e10150

Please sign in to comment.