@c -*-texinfo-*- @c This is part of the GNU Guile Reference Manual. @c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2012, 2014 @c Free Software Foundation, Inc. @c See the file guile.texi for copying conditions. @node Function Snarfing @section Function Snarfing 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 @code{scm_c_define_gsubr} or related functions. If you have many functions to publish, it can sometimes be annoying to keep the list of calls to @code{scm_c_define_gsubr} in sync with the list of function definitions. Guile provides the @code{guile-snarf} program to manage this problem. Using this tool, you can keep all the information needed to define the function alongside the function definition itself; @code{guile-snarf} will extract this information from your source code, and automatically generate a file of calls to @code{scm_c_define_gsubr} which you can @code{#include} into an initialization function. The snarfing mechanism works for many kind of initialization actions, not just for collecting calls to @code{scm_c_define_gsubr}. For a full list of what can be done, @xref{Snarfing Macros}. @cindex guile-snarf invocation @cindex guile-snarf example The @code{guile-snarf} program is invoked like this: @smallexample guile-snarf [-o @var{outfile}] [@var{cpp-args} ...] @end smallexample This command will extract initialization actions to @var{outfile}. When no @var{outfile} has been specified or when @var{outfile} is @code{-}, standard output will be used. The C preprocessor is called with @var{cpp-args} (which usually include an input file) and the output is filtered to extract the initialization actions. If there are errors during processing, @var{outfile} is deleted and the program exits with non-zero status. During snarfing, the pre-processor macro @code{SCM_MAGIC_SNARFER} is defined. You could use this to avoid including snarfer output files that don't yet exist by writing code like this: @smallexample #ifndef SCM_MAGIC_SNARFER #include "foo.x" #endif @end smallexample Here is how you might define the Scheme function @code{clear-image}, implemented by the C function @code{clear_image}: @example @group #include SCM_DEFINE (clear_image, "clear-image", 1, 0, 0, (SCM image), "Clear the image.") @{ /* C code to clear the image in @code{image}... */ @} void init_image_type () @{ #include "image-type.x" @} @end group @end example The @code{SCM_DEFINE} declaration says that the C function @code{clear_image} implements a Scheme function called @code{clear-image}, which takes one required argument (of type @code{SCM} and named @code{image}), no optional arguments, and no rest argument. The string @code{"Clear the image."} provides a short help text for the function, it is called a @dfn{docstring}. @code{SCM_DEFINE} macro also defines a static array of characters initialized to the Scheme name of the function. In this case, @code{s_clear_image} is set to the C string, "clear-image". You might want to use this symbol when generating error messages. Assuming the text above lives in a file named @file{image-type.c}, you will need to execute the following command to prepare this file for compilation: @example guile-snarf -o image-type.x image-type.c @end example This scans @file{image-type.c} for @code{SCM_DEFINE} declarations, and writes to @file{image-type.x} the output: @example scm_c_define_gsubr ("clear-image", 1, 0, 0, (SCM (*)() ) clear_image); @end example When compiled normally, @code{SCM_DEFINE} is a macro which expands to the function header for @code{clear_image}. Note that the output file name matches the @code{#include} from the input file. Also, you still need to provide all the same information you would if you were using @code{scm_c_define_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 @code{guile-snarf} must process, you should consider using a fragment like the following in your Makefile: @example snarfcppopts = $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) .SUFFIXES: .x .c.x: guile-snarf -o $@@ $< $(snarfcppopts) @end example This tells make to run @code{guile-snarf} to produce each needed @file{.x} file from the corresponding @file{.c} file. The program @code{guile-snarf} passes 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 @code{guile-snarf} to define preprocessor symbols, add header file directories, and so on.