>>>>> "Raymond" == Raymond Toy <[EMAIL PROTECTED]> writes:
>>>>> "Nicolas" == Nicolas Neuss <[EMAIL PROTECTED]> writes:
Raymond> FWIW, here is a simpler example that demonstrates the bug:
Raymond> (use-package "ALIEN")
Raymond> (use-package "C-CALL")
Raymond> (def-alien-type yes_no_t (enum yes_no_t :NO :YES))
Raymond> (def-alien-type nil
Raymond> (struct foo
Raymond> (arg1 yes_no_t)
Raymond> (arg2 yes_no_t)))
Raymond> (def-alien-routine "set_default_options" void
Raymond> (options (* (struct foo))))
I've finally gotten around to looking at this again. I confess that I
know very little about how alien stuff works, but the culprit appears
to be in the def-alien-type-translator for enum in
src/code/alieneval.lisp:
(def-alien-type-translator enum (&whole type name &rest mappings)
(cond (mappings
(let ((result (parse-enum name mappings)))
(when name
(multiple-value-bind
(old old-p)
(auxiliary-alien-type :enum name)
(when old-p
(unless (alien-type-= result old)
(warn "Redefining alien enum ~S" name))))
(setf (auxiliary-alien-type :enum name) result))
result))
...))
That (setf (auxiliary-alien-type ...)) is always done, whether the
type already exists or not. Compare this to parse-alien-record-type:
(defun parse-alien-record-type (kind name fields)
(if fields
(let* ((old (and name (auxiliary-alien-type kind name)))
(result (if (or (null old)
(alien-record-type-fields old))
(make-alien-record-type :name name :kind kind)
old)))
(when (and name (not (eq old result)))
(setf (auxiliary-alien-type kind name) result))
(parse-alien-record-fields result fields)
result)
...))
In this case, the setf auxiliary-alien-type is done only if the old
type and the result type are not eq.
I suspect we can should do the same for enum---if the old type is
equivalent to the result, we can skip the setf. This seems to work
with the sample (giving an error about set_default_options being an
undefined foreign symbol, of course). Something like:
(def-alien-type-translator enum (&whole type name &rest mappings)
(cond (mappings
(let ((result (parse-enum name mappings)))
(when name
(multiple-value-bind (old old-p)
(auxiliary-alien-type :enum name)
(when old-p
(unless (alien-type-= result old)
(warn "Redefining alien enum ~S" name)))
(when (or (not old-p)
(not (alien-type-= result old)))
(setf (auxiliary-alien-type :enum name) result))))
result))
...))
I know this is very likely too late to help, but if you have time, I'd
like to see if this solves the problem for you.
Ray