guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: ffi helper: enums


From: Amirouche
Subject: Re: ffi helper: enums
Date: Sun, 18 Jun 2017 02:19:15 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.1.1



Le 17/06/2017 à 20:53, Matt Wette a écrit :
The following seems to be a Guile architecture wrt how FFI-based interfaces 
should be implemented.

I am working on a ffi-helper: a program that will read in a C dot-h file and 
generate a Guile dot-scm file which defines a module to provide hooks into the 
associated C library.  I am looking for concurrence on the following:

Enums and #defines:
Here is how I plan to handle enums and #defines
1) visibility to values is provided through an access function
    e.g., (get-foo-val ‘ABC)
    not ABC via (define ABC 1)
2) only #defined symbols that evaluate to constants (e.g., 123, “ABC”, etc) 
will be visible
3) all enum-defined symbols will be visible
4) for enum typedefs and enum def's I will provide (but not export) wrappers so 
that functions that
    take an enum type as argument will require the symbolic form
    e.g., if signature is
        typedef enum { ABC = 1 } foo_enum_t;
        typedef enum { OK = 0, ERROR = 1 } foo_status_t;
        foo_status_t bar(foo_enum_t flag)
    then the guile un-wrapper/wrapper will convert symbols<=>ints to allow 
users code to look like
        (bar ‘ABC) => ‘OK
    Optionally, the un-wrappers could be coded tolerate integers.

OK?

Matt

P.S. auto-generated and hand-clean-up (i.e., not fully working yet)

;; access to #define constants:
(define cairo-svg-def-val
   (let ((deftab
           '((CAIRO_VERSION_MAJOR . 1)
             (CAIRO_VERSION_MINOR . 14)
             ...
             (CAIRO_SVG_VERSION_1_1 . 1)
             (CAIRO_SVG_VERSION_1_2 . 2))))
     (lambda (k) (assq-ref deftab k))))
(export cairo-svg-def-val)

;; typedef struct _cairo_font_options cairo_font_options_t;
(define-std-pointer-wrapper cairo_font_options_t*)

;; typedef enum _cairo_status cairo_status_t;
(define wrap-cairo_status_t
   (let ((vnl '((0 . CAIRO_STATUS_SUCCESS)
                (1 . CAIRO_STATUS_NO_MEMORY)
                ...
                (38 . CAIRO_STATUS_JBIG2_GLOBAL_MISSING)
                (39 . CAIRO_STATUS_LAST_STATUS))))
     (lambda (code) (assq-ref vnl code))))
(define unwrap-cairo_status_t
   (let ((nvl '((CAIRO_STATUS_SUCCESS . 0)
                (CAIRO_STATUS_NO_MEMORY . 1)
                ...
                (CAIRO_STATUS_JBIG2_GLOBAL_MISSING . 38)
                (CAIRO_STATUS_LAST_STATUS . 39))))
     (lambda (name) (assq-ref nvl name))))
(define wrap-enum-_cairo_status
   (let ((vnl '((0 . CAIRO_STATUS_SUCCESS)
                (1 . CAIRO_STATUS_NO_MEMORY)
                (2 . CAIRO_STATUS_INVALID_RESTORE)
                ...
                (38 . CAIRO_STATUS_JBIG2_GLOBAL_MISSING)
                (39 . CAIRO_STATUS_LAST_STATUS))))
     (lambda (code) (assq-ref vnl code))))
(define unwrap-enum-_cairo_status
   (let ((nvl '((CAIRO_STATUS_SUCCESS . 0)
                (CAIRO_STATUS_NO_MEMORY . 1)
                ...
                (CAIRO_STATUS_JBIG2_GLOBAL_MISSING . 38)
                (CAIRO_STATUS_LAST_STATUS . 39))))
     (lambda (name) (assq-ref nvl name))))

;; cairo_status_t cairo_font_options_status(cairo_font_options_t *options);
(define cairo_font_options_status
   (let ((f (ffi:pointer->procedure
              ffi:int
              (lib-func "cairo_font_options_status")
              (list '*))))
     (lambda (options)
       (let ((~options (unwrap-cairo_font_options_t* options)))
         (wrap-cairo_status_t (f ~options))))))
(export cairo_font_options_status)




It makes sens to me.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]