[Ecls-list] (and defconstant ffi:c-inline)

Matthew Mondor mm_lists at pulsar-zone.net
Fri Apr 2 09:25:12 UTC 2010

On Fri, 2 Apr 2010 01:40:18 -0400
Matthew Mondor <mm_lists at pulsar-zone.net> wrote:

> And optionally provide a macro like WITH-FCNTL-CONSTANTS and other
> categories using predefined lists, although unfortunately this would
> introduce some extra redundancy...

Sorry for yet again replying to my own questions :)
I could resume some testing and the following works fine while also
being decent API-wise:

(eval-when (:execute :load-toplevel :compile-toplevel)
  (defvar *c-headers* (make-hash-table :test 'eq)))

(defmacro define-c-constants (header-name c-header-name &rest constants)
  `(eval-when (:execute :load-toplevel :compile-toplevel)
     (setf (gethash ',header-name *c-headers*)
           '(,header-name ,c-header-name , at constants))))

(defmacro with-c-constants (header &body body)
        (header-name c-header-name &rest constants)
      (gethash header *c-headers*)
    (declare (ignore header-name))
       (ffi:clines ,(format nil "~%#include <~A>~%" c-header-name))
             #'(lambda (c)
                 (destructuring-bind (symbol constant) c
                     (ffi:c-inline () () :int ,constant :one-liner t))))
         , at body))))

;;; Define all fcntl.h constants we want to export
(define-c-constants :fcntl "fcntl.h"
  (o-rdonly "O_RDONLY")
  (o-creat "O_CREAT"))

;;; This function imports all fcntl.h exported symbols
(defun foo ()
  (with-c-constants :fcntl
    (format t "~A ~A~%" o-rdonly o-creat)))

An additional advantage is that it's possibe to C-c C-c individual
functions using this method, since the #include directive is still
there.  Still, if others have suggestions, I'm still interested in
further ideas.


More information about the ecl-devel mailing list