Improve CPP token pasting in <snarf.h>.
[bpt/guile.git] / libguile / snarf.h
1 /* classes: h_files */
2
3 #ifndef SCM_SNARF_H
4 #define SCM_SNARF_H
5
6 /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003, 2004, 2006, 2009 Free Software Foundation, Inc.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 \f
24
25 /* Macros for snarfing initialization actions from C source. */
26
27 #if defined(__cplusplus) || defined(GUILE_CPLUSPLUS_SNARF)
28
29 /* This used to be "SCM (*)(...)" but GCC on RedHat 7.1 doesn't seem
30 to like it.
31 */
32 #define SCM_FUNC_CAST_ARBITRARY_ARGS SCM (*)()
33
34 #else
35 #define SCM_FUNC_CAST_ARBITRARY_ARGS SCM (*)()
36 #endif
37
38 #if (defined SCM_ALIGNED) && (SCM_DEBUG_TYPING_STRICTNESS <= 1)
39 /* We support static allocation of some `SCM' objects. */
40 # define SCM_SUPPORT_STATIC_ALLOCATION
41 #endif
42
43 /* C preprocessor token concatenation. */
44 #define scm_i_paste(x, y) x ## y
45 #define scm_i_paste3(a, b, c) a ## b ## c
46
47
48 \f
49 /* Generic macros to be used in user macro definitions.
50 *
51 * For example, in order to define a macro which creates ints and
52 * initializes them to the result of foo (), do:
53 *
54 * #define SCM_FOO(NAME) \
55 * SCM_SNARF_HERE (int NAME) \
56 * SCM_SNARF_INIT (NAME = foo ())
57 *
58 * The SCM_SNARF_INIT text goes into the corresponding .x file
59 * up through the first occurrence of SCM_SNARF_DOC_START on that
60 * line, if any.
61 */
62
63 #ifdef SCM_MAGIC_SNARF_INITS
64 # define SCM_SNARF_HERE(X)
65 # define SCM_SNARF_INIT(X) ^^ X ^:^
66 # define SCM_SNARF_DOCS(TYPE, CNAME, FNAME, ARGLIST, REQ, OPT, VAR, DOCSTRING)
67 #else
68 # ifdef SCM_MAGIC_SNARF_DOCS
69 # define SCM_SNARF_HERE(X)
70 # define SCM_SNARF_INIT(X)
71 # define SCM_SNARF_DOCS(TYPE, CNAME, FNAME, ARGLIST, REQ, OPT, VAR, DOCSTRING) \
72 ^^ { \
73 cname CNAME ^^ \
74 fname FNAME ^^ \
75 type TYPE ^^ \
76 location __FILE__ __LINE__ ^^ \
77 arglist ARGLIST ^^ \
78 argsig REQ OPT VAR ^^ \
79 DOCSTRING ^^ }
80 # else
81 # define SCM_SNARF_HERE(X) X
82 # define SCM_SNARF_INIT(X)
83 # define SCM_SNARF_DOCS(TYPE, CNAME, FNAME, ARGLIST, REQ, OPT, VAR, DOCSTRING)
84 # endif
85 #endif
86
87 #define SCM_DEFINE(FNAME, PRIMNAME, REQ, OPT, VAR, ARGLIST, DOCSTRING) \
88 SCM_SNARF_HERE(\
89 static const char s_ ## FNAME [] = PRIMNAME; \
90 SCM FNAME ARGLIST\
91 )\
92 SCM_SNARF_INIT(\
93 scm_c_define_gsubr (s_ ## FNAME, REQ, OPT, VAR, \
94 (SCM_FUNC_CAST_ARBITRARY_ARGS) FNAME); \
95 )\
96 SCM_SNARF_DOCS(primitive, FNAME, PRIMNAME, ARGLIST, REQ, OPT, VAR, DOCSTRING)
97
98 #define SCM_PRIMITIVE_GENERIC(FNAME, PRIMNAME, REQ, OPT, VAR, ARGLIST, DOCSTRING) \
99 SCM_SNARF_HERE(\
100 static const char s_ ## FNAME [] = PRIMNAME; \
101 static SCM g_ ## FNAME; \
102 SCM FNAME ARGLIST\
103 )\
104 SCM_SNARF_INIT(\
105 g_ ## FNAME = SCM_PACK (0); \
106 scm_c_define_gsubr_with_generic (s_ ## FNAME, REQ, OPT, VAR, \
107 (SCM_FUNC_CAST_ARBITRARY_ARGS) FNAME, \
108 &g_ ## FNAME); \
109 )\
110 SCM_SNARF_DOCS(primitive, FNAME, PRIMNAME, ARGLIST, REQ, OPT, VAR, DOCSTRING)
111
112 #define SCM_DEFINE_PUBLIC(FNAME, PRIMNAME, REQ, OPT, VAR, ARGLIST, DOCSTRING) \
113 SCM_SNARF_HERE(\
114 static const char s_ ## FNAME [] = PRIMNAME; \
115 SCM FNAME ARGLIST\
116 )\
117 SCM_SNARF_INIT(\
118 scm_c_define_gsubr (s_ ## FNAME, REQ, OPT, VAR, \
119 (SCM_FUNC_CAST_ARBITRARY_ARGS) FNAME); \
120 scm_c_export (s_ ## FNAME, NULL); \
121 )\
122 SCM_SNARF_DOCS(primitive, FNAME, PRIMNAME, ARGLIST, REQ, OPT, VAR, DOCSTRING)
123
124 #define SCM_DEFINE1(FNAME, PRIMNAME, TYPE, ARGLIST, DOCSTRING) \
125 SCM_SNARF_HERE(\
126 static const char s_ ## FNAME [] = PRIMNAME; \
127 SCM FNAME ARGLIST\
128 )\
129 SCM_SNARF_INIT(scm_c_define_subr (s_ ## FNAME, TYPE, FNAME); ) \
130 SCM_SNARF_DOCS(1, FNAME, PRIMNAME, ARGLIST, 2, 0, 0, DOCSTRING)
131
132 #define SCM_PRIMITIVE_GENERIC_1(FNAME, PRIMNAME, TYPE, ARGLIST, DOCSTRING) \
133 SCM_SNARF_HERE(\
134 static const char s_ ## FNAME [] = PRIMNAME; \
135 static SCM g_ ## FNAME; \
136 SCM FNAME ARGLIST\
137 )\
138 SCM_SNARF_INIT(\
139 g_ ## FNAME = SCM_PACK (0); \
140 scm_c_define_subr_with_generic (s_ ## FNAME, TYPE, FNAME, &g_ ## FNAME); \
141 )\
142 SCM_SNARF_DOCS(1, FNAME, PRIMNAME, ARGLIST, 2, 0, 0, DOCSTRING)
143
144 #define SCM_PROC(RANAME, STR, REQ, OPT, VAR, CFN) \
145 SCM_SNARF_HERE(static const char RANAME[]=STR) \
146 SCM_SNARF_INIT(scm_c_define_gsubr (RANAME, REQ, OPT, VAR, \
147 (SCM_FUNC_CAST_ARBITRARY_ARGS) CFN))
148
149 #define SCM_REGISTER_PROC(RANAME, STR, REQ, OPT, VAR, CFN) \
150 SCM_SNARF_HERE(static const char RANAME[]=STR) \
151 SCM_SNARF_INIT(scm_c_define_gsubr (RANAME, REQ, OPT, VAR, \
152 (SCM_FUNC_CAST_ARBITRARY_ARGS) CFN);) \
153 SCM_SNARF_DOCS(register, CFN, STR, (), REQ, OPT, VAR, \
154 "implemented by the C function \"" #CFN "\"")
155
156 #define SCM_GPROC(RANAME, STR, REQ, OPT, VAR, CFN, GF) \
157 SCM_SNARF_HERE(\
158 static const char RANAME[]=STR;\
159 static SCM GF \
160 )SCM_SNARF_INIT(\
161 GF = SCM_PACK (0); /* Dirk:FIXME:: Can we safely use #f instead of 0? */ \
162 scm_c_define_gsubr_with_generic (RANAME, REQ, OPT, VAR, \
163 (SCM_FUNC_CAST_ARBITRARY_ARGS) CFN, &GF) \
164 )
165
166 #define SCM_PROC1(RANAME, STR, TYPE, CFN) \
167 SCM_SNARF_HERE(static const char RANAME[]=STR) \
168 SCM_SNARF_INIT(\
169 scm_c_define_subr (RANAME, TYPE, (SCM_FUNC_CAST_ARBITRARY_ARGS) CFN) \
170 )
171
172
173 #define SCM_GPROC1(RANAME, STR, TYPE, CFN, GF) \
174 SCM_SNARF_HERE(\
175 static const char RANAME[]=STR; \
176 static SCM GF \
177 )SCM_SNARF_INIT(\
178 GF = SCM_PACK (0); /* Dirk:FIXME:: Can we safely use #f instead of 0? */ \
179 scm_c_define_subr_with_generic (RANAME, TYPE, \
180 (SCM_FUNC_CAST_ARBITRARY_ARGS) CFN, &GF) \
181 )
182
183 #define SCM_SYNTAX(RANAME, STR, TYPE, CFN) \
184 SCM_SNARF_HERE(static const char RANAME[]=STR)\
185 SCM_SNARF_INIT(scm_make_synt (RANAME, TYPE, CFN))
186
187 #ifdef SCM_SUPPORT_STATIC_ALLOCATION
188
189 # define SCM_SYMBOL(c_name, scheme_name) \
190 SCM_SNARF_HERE( \
191 SCM_IMMUTABLE_STRING (scm_i_paste (c_name, _string), scheme_name); \
192 static SCM c_name) \
193 SCM_SNARF_INIT( \
194 c_name = scm_string_to_symbol (scm_i_paste (c_name, _string)) \
195 )
196
197 # define SCM_GLOBAL_SYMBOL(c_name, scheme_name) \
198 SCM_SNARF_HERE( \
199 SCM_IMMUTABLE_STRING (scm_i_paste (c_name, _string), scheme_name); \
200 SCM c_name) \
201 SCM_SNARF_INIT( \
202 c_name = scm_string_to_symbol (scm_i_paste (c_name, _string)) \
203 )
204
205 #else /* !SCM_SUPPORT_STATIC_ALLOCATION */
206
207 # define SCM_SYMBOL(c_name, scheme_name) \
208 SCM_SNARF_HERE(static SCM c_name) \
209 SCM_SNARF_INIT(c_name = scm_permanent_object (scm_from_locale_symbol (scheme_name)))
210
211 # define SCM_GLOBAL_SYMBOL(c_name, scheme_name) \
212 SCM_SNARF_HERE(SCM c_name) \
213 SCM_SNARF_INIT(c_name = scm_permanent_object (scm_from_locale_symbol (scheme_name)))
214
215 #endif /* !SCM_SUPPORT_STATIC_ALLOCATION */
216
217 #define SCM_KEYWORD(c_name, scheme_name) \
218 SCM_SNARF_HERE(static SCM c_name) \
219 SCM_SNARF_INIT(c_name = scm_permanent_object (scm_from_locale_keyword (scheme_name)))
220
221 #define SCM_GLOBAL_KEYWORD(c_name, scheme_name) \
222 SCM_SNARF_HERE(SCM c_name) \
223 SCM_SNARF_INIT(c_name = scm_permanent_object (scm_from_locale_keyword (scheme_name)))
224
225 #define SCM_VARIABLE(c_name, scheme_name) \
226 SCM_SNARF_HERE(static SCM c_name) \
227 SCM_SNARF_INIT(c_name = scm_permanent_object (scm_c_define (scheme_name, SCM_BOOL_F));)
228
229 #define SCM_GLOBAL_VARIABLE(c_name, scheme_name) \
230 SCM_SNARF_HERE(SCM c_name) \
231 SCM_SNARF_INIT(c_name = scm_permanent_object (scm_c_define (scheme_name, SCM_BOOL_F));)
232
233 #define SCM_VARIABLE_INIT(c_name, scheme_name, init_val) \
234 SCM_SNARF_HERE(static SCM c_name) \
235 SCM_SNARF_INIT(c_name = scm_permanent_object (scm_c_define (scheme_name, init_val));)
236
237 #define SCM_GLOBAL_VARIABLE_INIT(c_name, scheme_name, init_val) \
238 SCM_SNARF_HERE(SCM c_name) \
239 SCM_SNARF_INIT(c_name = scm_permanent_object (scm_c_define (scheme_name, init_val));)
240
241 #define SCM_MUTEX(c_name) \
242 SCM_SNARF_HERE(static scm_t_mutex c_name) \
243 SCM_SNARF_INIT(scm_i_plugin_mutex_init (&c_name, &scm_i_plugin_mutex))
244
245 #define SCM_GLOBAL_MUTEX(c_name) \
246 SCM_SNARF_HERE(scm_t_mutex c_name) \
247 SCM_SNARF_INIT(scm_i_plugin_mutex_init (&c_name, &scm_i_plugin_mutex))
248
249 #define SCM_REC_MUTEX(c_name) \
250 SCM_SNARF_HERE(static scm_t_rec_mutex c_name) \
251 SCM_SNARF_INIT(scm_i_plugin_rec_mutex_init (&c_name, &scm_i_plugin_rec_mutex))
252
253 #define SCM_GLOBAL_REC_MUTEX(c_name) \
254 SCM_SNARF_HERE(scm_t_rec_mutex c_name) \
255 SCM_SNARF_INIT(scm_i_plugin_rec_mutex_init (&c_name, &scm_i_plugin_rec_mutex))
256
257 #define SCM_SMOB(tag, scheme_name, size) \
258 SCM_SNARF_HERE(static scm_t_bits tag) \
259 SCM_SNARF_INIT((tag)=scm_make_smob_type((scheme_name), (size));)
260
261 #define SCM_GLOBAL_SMOB(tag, scheme_name, size) \
262 SCM_SNARF_HERE(scm_t_bits tag) \
263 SCM_SNARF_INIT((tag)=scm_make_smob_type((scheme_name), (size));)
264
265 #define SCM_SMOB_MARK(tag, c_name, arg) \
266 SCM_SNARF_HERE(static SCM c_name(SCM arg)) \
267 SCM_SNARF_INIT(scm_set_smob_mark((tag), (c_name));)
268
269 #define SCM_GLOBAL_SMOB_MARK(tag, c_name, arg) \
270 SCM_SNARF_HERE(SCM c_name(SCM arg)) \
271 SCM_SNARF_INIT(scm_set_smob_mark((tag), (c_name));)
272
273 #define SCM_SMOB_FREE(tag, c_name, arg) \
274 SCM_SNARF_HERE(static size_t c_name(SCM arg)) \
275 SCM_SNARF_INIT(scm_set_smob_free((tag), (c_name));)
276
277 #define SCM_GLOBAL_SMOB_FREE(tag, c_name, arg) \
278 SCM_SNARF_HERE(size_t c_name(SCM arg)) \
279 SCM_SNARF_INIT(scm_set_smob_free((tag), (c_name));)
280
281 #define SCM_SMOB_PRINT(tag, c_name, obj, port, pstate) \
282 SCM_SNARF_HERE(static int c_name(SCM obj, SCM port, scm_print_state* pstate)) \
283 SCM_SNARF_INIT(scm_set_smob_print((tag), (c_name));)
284
285 #define SCM_GLOBAL_SMOB_PRINT(tag, c_name, obj, port, pstate) \
286 SCM_SNARF_HERE(int c_name(SCM obj, SCM port, scm_print_state* pstate)) \
287 SCM_SNARF_INIT(scm_set_smob_print((tag), (c_name));)
288
289 #define SCM_SMOB_EQUALP(tag, c_name, obj1, obj2) \
290 SCM_SNARF_HERE(static SCM c_name(SCM obj1, SCM obj2)) \
291 SCM_SNARF_INIT(scm_set_smob_equalp((tag), (c_name));)
292
293 #define SCM_GLOBAL_SMOB_EQUALP(tag, c_name, obj1, obj2) \
294 SCM_SNARF_HERE(SCM c_name(SCM obj1, SCM obj2)) \
295 SCM_SNARF_INIT(scm_set_smob_equalp((tag), (c_name));)
296
297 #define SCM_SMOB_APPLY(tag, c_name, req, opt, rest, arglist) \
298 SCM_SNARF_HERE(static SCM c_name arglist) \
299 SCM_SNARF_INIT(scm_set_smob_apply((tag), (c_name), (req), (opt), (rest));)
300
301 #define SCM_GLOBAL_SMOB_APPLY(tag, c_name, req, opt, rest, arglist) \
302 SCM_SNARF_HERE(SCM c_name arglist) \
303 SCM_SNARF_INIT(scm_set_smob_apply((tag), (c_name), (req), (opt), (rest));)
304
305 \f
306 /* Low-level snarfing for static memory allocation. */
307
308 #ifdef SCM_SUPPORT_STATIC_ALLOCATION
309
310 #define SCM_IMMUTABLE_DOUBLE_CELL(c_name, car, cbr, ccr, cdr) \
311 static SCM_ALIGNED (8) SCM_UNUSED const scm_t_cell \
312 c_name ## _raw_cell [2] = \
313 { \
314 { SCM_PACK (car), SCM_PACK (cbr) }, \
315 { SCM_PACK (ccr), SCM_PACK (cdr) } \
316 }; \
317 static SCM_UNUSED const SCM c_name = SCM_PACK (& c_name ## _raw_cell)
318
319 #define SCM_IMMUTABLE_STRINGBUF(c_name, contents) \
320 SCM_IMMUTABLE_DOUBLE_CELL (c_name, \
321 scm_tc7_stringbuf | SCM_I_STRINGBUF_F_SHARED, \
322 (scm_t_bits) (contents), \
323 (scm_t_bits) sizeof (contents) - 1, \
324 (scm_t_bits) 0)
325
326 #define SCM_IMMUTABLE_STRING(c_name, contents) \
327 SCM_IMMUTABLE_STRINGBUF (scm_i_paste (c_name, _stringbuf), contents); \
328 SCM_IMMUTABLE_DOUBLE_CELL (c_name, \
329 scm_tc7_ro_string, \
330 (scm_t_bits) &scm_i_paste (c_name, \
331 _stringbuf_raw_cell), \
332 (scm_t_bits) 0, \
333 (scm_t_bits) sizeof (contents) - 1)
334
335 #endif /* SCM_SUPPORT_STATIC_ALLOCATION */
336
337 \f
338 /* Documentation. */
339
340 #ifdef SCM_MAGIC_SNARF_DOCS
341 #undef SCM_ASSERT
342 #define SCM_ASSERT(_cond, _arg, _pos, _subr) ^^ argpos _arg _pos __LINE__ ^^
343 #endif /* SCM_MAGIC_SNARF_DOCS */
344
345 #endif /* SCM_SNARF_H */
346
347 /*
348 Local Variables:
349 c-file-style: "gnu"
350 End:
351 */