Next: , Previous: The Groveller, Up: The Groveller


13.2 Specification File Syntax

The specification files are read by the normal Lisp reader, so they have syntax very similar to normal Lisp code. In particular, semicolon-comments and reader-macros will work as expected.

There are several forms recognized by CFFI-Grovel:

— Grovel Form: progn &rest forms

Processes a list of forms. Useful for conditionalizing several forms. For example:

  #+freebsd
  (progn
    (constant (ev-enable "EV_ENABLE"))
    (constant (ev-disable "EV_DISABLE")))
— Grovel Form: include &rest files

Include the specified files (specified as strings) in the generated C source code.

— Grovel Form: in-package symbol

Set the package to be used for the final Lisp output.

— Grovel Form: ctype lisp-name size-designator

Define a CFFI foreign type for the string in size-designator, e.g. (ctype :pid "pid_t").

— Grovel Form: constant (lisp-name &rest c-names) &key type documentation optional

Search for the constant named by the first c-name string found to be known to the C preprocessor and define it as lisp-name.

The type keyword argument specifies how to grovel the constant: either integer (the default) or double-float. If optional is true, no error will be raised if all the c-names are unknown. If lisp-name is a keyword, the actual constant will be a symbol of the same name interned in the current package.

— Grovel Form: define name &optional value

Defines an additional C preprocessor symbol, which is useful for altering the behavior of included system headers.

— Grovel Form: cc-flags &rest flags

Adds cc-flags to the command line arguments used for the C compiler invocation.

— Grovel Form: cstruct lisp-name c-name slots

Define a CFFI foreign struct with the slot data specfied. Slots are of the form (lisp-name c-name &key type count (signed t)).

— Grovel Form: cunion lisp-name c-name slots

Identical to cstruct, but defines a CFFI foreign union.

— Grovel Form: cstruct-and-class c-name slots

Defines a CFFI foreign struct, as with cstruct and defines a CLOS class to be used with it. This is useful for mapping foreign structures to application-layer code that shouldn't need to worry about memory allocation issues.

— Grovel Form: cvar namespec type &key read-only

Defines a foreign variable of the specified type, even if that variable is potentially a C preprocessor pseudo-variable. e.g. (cvar ("errno" errno) errno-values), assuming that errno-values is an enum or equivalent to type :int.

The namespec is similar to the one used in defcvar.

— Grovel Form: cenum name-and-opts &rest elements

Defines a true C enum, with elements specified as ((lisp-name &rest c-names) &key optional documentation). name-and-opts can be either a symbol as name, or a list (name &key base-type define-constants). If define-constants is non-null, a Lisp constant will be defined for each enum member.

— Grovel Form: constantenum name-and-opts &rest elements

Defines an enumeration of pre-processor constants, with elements specified as ((lisp-name &rest c-names) &key optional documentation). name-and-opts can be either a symbol as name, or a list (name &key base-type define-constants). If define-constants is non-null, a Lisp constant will be defined for each enum member.

This example defines :af-inet to represent the value held by AF_INET or PF_INET, whichever the pre-processor finds first. Similarly for :af-packet, but no error will be signalled if the platform supports neither AF_PACKET nor PF_PACKET.

  (constantenum address-family
    ((:af-inet "AF_INET" "PF_INET")
     :documentation "IPv4 Protocol family")
    ((:af-local "AF_UNIX" "AF_LOCAL" "PF_UNIX" "PF_LOCAL")
     :documentation "File domain sockets")
    ((:af-inet6 "AF_INET6" "PF_INET6")
     :documentation "IPv6 Protocol family")
    ((:af-packet "AF_PACKET" "PF_PACKET")
     :documentation "Raw packet access"
     :optional t))
— Grovel Form: bitfield name-and-opts &rest elements

Defines a bitfield, with elements specified as ((lisp-name &rest c-names) &key optional documentation). name-and-opts can be either a symbol as name, or a list (name &key base-type). For example:

  (bitfield flags-ctype
    ((:flag-a "FLAG_A")
      :documentation "DOCU_A")
    ((:flag-b "FLAG_B" "FLAG_B_ALT")
      :documentation "DOCU_B")
    ((:flag-c "FLAG_C")
      :documentation "DOCU_C"
      :optional t))