guile-devel
[Top][All Lists]
Advanced

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

ffi helper: enums


From: Matt Wette
Subject: ffi helper: enums
Date: Sat, 17 Jun 2017 11:53:19 -0700

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)





reply via email to

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