summaryrefslogtreecommitdiff
path: root/doc/ref/libguile-snarf.texi
blob: 9b0e42fa33fb31bf5efc12a976738adee02eec0b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
@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 <libguile.h>

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.