Managing Subr Definitions
=========================

When writing C code for use with Guile, you typically define a set of C functions, and then make some of them visible to the Scheme world by calling the scm_make_gsubr function; a C functions published in this way is called a subr.  If you have many subrs to publish, it can sometimes be annoying to keep the list of calls to scm_make_gsubr in sync with the list of function definitions. Frequently, a programmer will define a new subr in C, recompile his application, and then discover that the Scheme interpreter cannot see the subr, because he forgot to call scm_make_gsubr.

Guile provides the guile-snarf command to manage this problem. Using this tool, you can keep all the information needed to define the subr alongside the function definition itself; guile-snarf will extract this information from your source code, and automatically generate a file of calls to scm_make_gsubr which you can #include into an initialization function.  (The command name comes from the verb ``to snarf'', here meaning ``to unceremoniously extract information from a somewhat unwilling source.'')

How guile-snarf works
---------------------

For example, here is how you might define a new subr called clear-image, implemented by the C function clear_image:

     #include <libguile.h>

     ...

     SCM_PROC (s_clear_image, "clear-image", 1, 0, 0, clear_image);

     SCM
     clear_image (SCM image_smob)
     {
       ...
     }

     ...

     void
     init_image_type ()
     {
     #include "image-type.x"
     }

The SCM_PROC declaration says that the C function clear_image implements a Scheme subr called clear-image, which takes one required argument, no optional arguments, and no tail argument.  SCM_PROC also declares a static array of characters named s_clear_image, initialized to the string "clear-image".  The body of clear_image may use the array in error messages, instead of writing out the literal string; this may save string space on some systems.

Assuming the text above lives in a file named image-type.c, you will need to execute the following command to compile this file:

     guile-snarf image-type.c > image-type.x

This scans image-type.c for SCM_PROC declarations, and sends the following output to the file image-type.x:

     scm_make_gsubr (s_clear_image, 1, 0, 0, clear_image);

When compiled normally, SCM_PROC is a macro which expands to a declaration of the s_clear_image string.

In other words, guile-snarf scans source code looking for uses of the SCM_PROC macro, and generates C code to define the appropriate subrs.  You need to provide all the same information you would if you were using scm_make_gsubr yourself, but you can place the information near the function definition itself, so it is less likely to become incorrect or out-of-date.

If you have many files that guile-snarf must process, you should consider using a rule like the following in your Makefile:

     .SUFFIXES: .x
     .c.x:
     	./guile-snarf $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $< > $

This tells make to run guile-snarf to produce each needed .x file from the corresponding .c file.

guile-snarf passes all its command-line arguments directly to the C preprocessor, which it uses to extract the information it needs from the source code. this means you can pass normal compilation flags to guile-snarf to define preprocessor symbols, add header file directories, and so on.

Macros guile-snarf recognizes
-----------------------------

Here are the macros you can use in your source code from which guile-snarf can construct initialization code:

 -- Macro: SCM_PROC (NAMESTR, NAME, REQ, OPT, TAIL, C_FUNC)
     Declare a new Scheme primitive function, or subr.  The new subr will be named NAME in Scheme code, and be implemented by the C function C_FUNC.  The subr will take REQ required arguments and OPT optional arguments.  If TAIL is non-zero, the function will accept any remaining arguments as a list.

     Use this macro outside all function bodies, preferably above the definition of C_FUNC itself.  When compiled, the SCM_PROC declaration will expand to a definition for the NAMESTR array, initialized to NAME.  The guile-snarf command uses this declaration to automatically generate initialization code to create the subr and bind it in the top-level environment.  See How guile-snarf works, for more info.

     See Subrs, for details on argument passing and how to write C_FUNC.

 -- Macro: SCM_GLOBAL (VAR, SCHEME_NAME)
     Declare a global Scheme variable named SCHEME_NAME, and a static C variable named VAR to point to it.  The value of the Scheme variable lives in the CDR of the cell VAR points to. Initialize the variable to #f.

     Use this macro outside all function bodies.  When compiled, the SCM_GLOBAL macro will expand to a definition for the variable VAR, initialized to an innocuous value.  The guile-snarf command will use this declaration to automatically generate code to create a global variable named SCHEME_NAME, and store a pointer to its cell in VAR.

 -- Macro: SCM_CONST_LONG (VAR, SCHEME_NAME, VALUE)
     Like SCM_GLOBAL, but initialize the variable to VALUE, which must be an integer.

 -- Macro: SCM_SYMBOL (VAR, NAME)
     Declare a C variable of type SCM named VAR, and initialize it to the Scheme symbol object whose name is NAME.

     Use this macro outside all function bodies.  When compiled, the SCM_SYMBOL macro will expand to a definition for the variable VAR, initialized to an innocuous value.  The guile-snarf command will use this declaration to automatically generate code to create a symbol named NAME, and store it in VAR.