1c072babb850b21adc78957cdc91324d81c7dced
[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,
7 * 2004, 2006, 2009, 2010, 2011 Free Software Foundation, Inc.
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 3 of
12 * the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 */
24
25 \f
26
27 /* Macros for snarfing initialization actions from C source. */
28
29 /* Casting to a function that can take any number of arguments. */
30 #define SCM_FUNC_CAST_ARBITRARY_ARGS scm_t_subr
31
32
33 #ifdef SCM_ALIGNED
34 /* We support static allocation of some `SCM' objects. */
35 # define SCM_SUPPORT_STATIC_ALLOCATION
36 #endif
37
38 /* C preprocessor token concatenation. */
39 #define scm_i_paste(x, y) x ## y
40 #define scm_i_paste3(a, b, c) a ## b ## c
41
42
43 \f
44 /* Generic macros to be used in user macro definitions.
45 *
46 * For example, in order to define a macro which creates ints and
47 * initializes them to the result of foo (), do:
48 *
49 * #define SCM_FOO(NAME) \
50 * SCM_SNARF_HERE (int NAME) \
51 * SCM_SNARF_INIT (NAME = foo ())
52 *
53 * The SCM_SNARF_INIT text goes into the corresponding .x file
54 * up through the first occurrence of SCM_SNARF_DOC_START on that
55 * line, if any.
56 *
57 * Some debugging options can cause the preprocessor to echo #define
58 * directives to its output. Keeping the snarfing markers on separate
59 * lines prevents guile-snarf from inadvertently snarfing the definition
60 * of SCM_SNARF_INIT if those options are in effect.
61 */
62
63 #ifdef SCM_MAGIC_SNARF_INITS
64 # define SCM_SNARF_HERE(X)
65 # define SCM_SNARF_INIT_PREFIX ^^
66 # define SCM_SNARF_INIT(X) SCM_SNARF_INIT_PREFIX X ^:^
67 # define SCM_SNARF_DOCS(TYPE, CNAME, FNAME, ARGLIST, REQ, OPT, VAR, DOCSTRING)
68 #else
69 # ifdef SCM_MAGIC_SNARF_DOCS
70 # define SCM_SNARF_HERE(X)
71 # define SCM_SNARF_INIT(X)
72 # define SCM_SNARF_DOCS(TYPE, CNAME, FNAME, ARGLIST, REQ, OPT, VAR, DOCSTRING) \
73 ^^ { \
74 cname CNAME ^^ \
75 fname FNAME ^^ \
76 type TYPE ^^ \
77 location __FILE__ __LINE__ ^^ \
78 arglist ARGLIST ^^ \
79 argsig REQ OPT VAR ^^ \
80 DOCSTRING ^^ }
81 # else
82 # define SCM_SNARF_HERE(X) X
83 # define SCM_SNARF_INIT(X)
84 # define SCM_SNARF_DOCS(TYPE, CNAME, FNAME, ARGLIST, REQ, OPT, VAR, DOCSTRING)
85 # endif
86 #endif
87
88 #define SCM_DEFINE_GSUBR(FNAME, PRIMNAME, REQ, OPT, VAR, ARGLIST, DOCSTRING) \
89 SCM_SNARF_HERE(\
90 static const char s_ ## FNAME [] = PRIMNAME; \
91 SCM FNAME ARGLIST\
92 )\
93 SCM_SNARF_INIT(\
94 scm_c_define_gsubr (s_ ## FNAME, REQ, OPT, VAR, \
95 (SCM_FUNC_CAST_ARBITRARY_ARGS) FNAME); \
96 )\
97 SCM_SNARF_DOCS(primitive, FNAME, PRIMNAME, ARGLIST, REQ, OPT, VAR, DOCSTRING)
98
99 #ifdef SCM_SUPPORT_STATIC_ALLOCATION
100
101 /* Static subr allocation. */
102 /* FIXME: how to verify that req + opt + rest < 11, all are positive, etc? */
103 #define SCM_DEFINE(FNAME, PRIMNAME, REQ, OPT, VAR, ARGLIST, DOCSTRING) \
104 SCM_SYMBOL (scm_i_paste (FNAME, __name), PRIMNAME); \
105 SCM_SNARF_HERE( \
106 static const char scm_i_paste (s_, FNAME) [] = PRIMNAME; \
107 SCM_API SCM FNAME ARGLIST; \
108 SCM_IMMUTABLE_POINTER (scm_i_paste (FNAME, __subr_foreign), \
109 (scm_t_bits) &FNAME); /* the subr */ \
110 SCM_STATIC_SUBR_OBJVECT (scm_i_paste (FNAME, __raw_objtable), \
111 /* FIXME: directly be the foreign */ \
112 SCM_BOOL_F); \
113 /* FIXME: be immutable. grr */ \
114 SCM_STATIC_PROGRAM (scm_i_paste (FNAME, __subr), \
115 SCM_BOOL_F, \
116 SCM_PACK (&scm_i_paste (FNAME, __raw_objtable)), \
117 SCM_BOOL_F); \
118 SCM FNAME ARGLIST \
119 ) \
120 SCM_SNARF_INIT( \
121 /* Initialize the foreign. */ \
122 scm_i_paste (FNAME, __raw_objtable)[2] = scm_i_paste (FNAME, __subr_foreign); \
123 /* Initialize the procedure name (an interned symbol). */ \
124 scm_i_paste (FNAME, __raw_objtable)[3] = scm_i_paste (FNAME, __name); \
125 /* Initialize the objcode trampoline. */ \
126 SCM_SET_CELL_OBJECT (scm_i_paste (FNAME, __subr), 1, \
127 scm_subr_objcode_trampoline (REQ, OPT, VAR)); \
128 \
129 /* Define the subr. */ \
130 scm_define (scm_i_paste (FNAME, __name), scm_i_paste (FNAME, __subr)); \
131 ) \
132 SCM_SNARF_DOCS(primitive, FNAME, PRIMNAME, ARGLIST, REQ, OPT, VAR, DOCSTRING)
133
134 #else /* !SCM_SUPPORT_STATIC_ALLOCATION */
135
136 /* Always use the generic subr case. */
137 #define SCM_DEFINE SCM_DEFINE_GSUBR
138
139 #endif /* !SCM_SUPPORT_STATIC_ALLOCATION */
140
141
142 #define SCM_PRIMITIVE_GENERIC(FNAME, PRIMNAME, REQ, OPT, VAR, ARGLIST, DOCSTRING) \
143 SCM_SNARF_HERE(\
144 static const char s_ ## FNAME [] = PRIMNAME; \
145 static SCM g_ ## FNAME; \
146 SCM FNAME ARGLIST\
147 )\
148 SCM_SNARF_INIT(\
149 g_ ## FNAME = SCM_PACK (0); \
150 scm_c_define_gsubr_with_generic (s_ ## FNAME, REQ, OPT, VAR, \
151 (SCM_FUNC_CAST_ARBITRARY_ARGS) FNAME, \
152 &g_ ## FNAME); \
153 )\
154 SCM_SNARF_DOCS(primitive, FNAME, PRIMNAME, ARGLIST, REQ, OPT, VAR, DOCSTRING)
155
156 #define SCM_DEFINE_PUBLIC(FNAME, PRIMNAME, REQ, OPT, VAR, ARGLIST, DOCSTRING) \
157 SCM_SNARF_HERE(\
158 static const char s_ ## FNAME [] = PRIMNAME; \
159 SCM FNAME ARGLIST\
160 )\
161 SCM_SNARF_INIT(\
162 scm_c_define_gsubr (s_ ## FNAME, REQ, OPT, VAR, \
163 (SCM_FUNC_CAST_ARBITRARY_ARGS) FNAME); \
164 scm_c_export (s_ ## FNAME, NULL); \
165 )\
166 SCM_SNARF_DOCS(primitive, FNAME, PRIMNAME, ARGLIST, REQ, OPT, VAR, DOCSTRING)
167
168 #define SCM_PROC(RANAME, STR, REQ, OPT, VAR, CFN) \
169 SCM_SNARF_HERE(static const char RANAME[]=STR) \
170 SCM_SNARF_INIT(scm_c_define_gsubr (RANAME, REQ, OPT, VAR, \
171 (SCM_FUNC_CAST_ARBITRARY_ARGS) CFN))
172
173 #define SCM_REGISTER_PROC(RANAME, STR, REQ, OPT, VAR, CFN) \
174 SCM_SNARF_HERE(static const char RANAME[]=STR) \
175 SCM_SNARF_INIT(scm_c_define_gsubr (RANAME, REQ, OPT, VAR, \
176 (SCM_FUNC_CAST_ARBITRARY_ARGS) CFN);) \
177 SCM_SNARF_DOCS(register, CFN, STR, (), REQ, OPT, VAR, \
178 "implemented by the C function \"" #CFN "\"")
179
180 #define SCM_GPROC(RANAME, STR, REQ, OPT, VAR, CFN, GF) \
181 SCM_SNARF_HERE(\
182 static const char RANAME[]=STR;\
183 static SCM GF \
184 )SCM_SNARF_INIT(\
185 GF = SCM_PACK (0); /* Dirk:FIXME:: Can we safely use #f instead of 0? */ \
186 scm_c_define_gsubr_with_generic (RANAME, REQ, OPT, VAR, \
187 (SCM_FUNC_CAST_ARBITRARY_ARGS) CFN, &GF) \
188 )
189
190 #ifdef SCM_SUPPORT_STATIC_ALLOCATION
191
192 # define SCM_SYMBOL(c_name, scheme_name) \
193 SCM_SNARF_HERE( \
194 SCM_IMMUTABLE_STRING (scm_i_paste (c_name, _string), scheme_name); \
195 static SCM c_name) \
196 SCM_SNARF_INIT( \
197 c_name = scm_string_to_symbol (scm_i_paste (c_name, _string)) \
198 )
199
200 # define SCM_GLOBAL_SYMBOL(c_name, scheme_name) \
201 SCM_SNARF_HERE( \
202 SCM_IMMUTABLE_STRING (scm_i_paste (c_name, _string), scheme_name); \
203 SCM c_name) \
204 SCM_SNARF_INIT( \
205 c_name = scm_string_to_symbol (scm_i_paste (c_name, _string)) \
206 )
207
208 #else /* !SCM_SUPPORT_STATIC_ALLOCATION */
209
210 # define SCM_SYMBOL(c_name, scheme_name) \
211 SCM_SNARF_HERE(static SCM c_name) \
212 SCM_SNARF_INIT(c_name = scm_from_locale_symbol (scheme_name))
213
214 # define SCM_GLOBAL_SYMBOL(c_name, scheme_name) \
215 SCM_SNARF_HERE(SCM c_name) \
216 SCM_SNARF_INIT(c_name = scm_from_locale_symbol (scheme_name))
217
218 #endif /* !SCM_SUPPORT_STATIC_ALLOCATION */
219
220 #define SCM_KEYWORD(c_name, scheme_name) \
221 SCM_SNARF_HERE(static SCM c_name) \
222 SCM_SNARF_INIT(c_name = scm_from_locale_keyword (scheme_name))
223
224 #define SCM_GLOBAL_KEYWORD(c_name, scheme_name) \
225 SCM_SNARF_HERE(SCM c_name) \
226 SCM_SNARF_INIT(c_name = scm_from_locale_keyword (scheme_name))
227
228 #define SCM_VARIABLE(c_name, scheme_name) \
229 SCM_SNARF_HERE(static SCM c_name) \
230 SCM_SNARF_INIT(c_name = scm_c_define (scheme_name, SCM_BOOL_F);)
231
232 #define SCM_GLOBAL_VARIABLE(c_name, scheme_name) \
233 SCM_SNARF_HERE(SCM c_name) \
234 SCM_SNARF_INIT(c_name = scm_c_define (scheme_name, SCM_BOOL_F);)
235
236 #define SCM_VARIABLE_INIT(c_name, scheme_name, init_val) \
237 SCM_SNARF_HERE(static SCM c_name) \
238 SCM_SNARF_INIT(c_name = scm_c_define (scheme_name, init_val);)
239
240 #define SCM_GLOBAL_VARIABLE_INIT(c_name, scheme_name, init_val) \
241 SCM_SNARF_HERE(SCM c_name) \
242 SCM_SNARF_INIT(c_name = scm_c_define (scheme_name, init_val);)
243
244 #define SCM_MUTEX(c_name) \
245 SCM_SNARF_HERE(static scm_t_mutex c_name) \
246 SCM_SNARF_INIT(scm_i_plugin_mutex_init (&c_name, &scm_i_plugin_mutex))
247
248 #define SCM_GLOBAL_MUTEX(c_name) \
249 SCM_SNARF_HERE(scm_t_mutex c_name) \
250 SCM_SNARF_INIT(scm_i_plugin_mutex_init (&c_name, &scm_i_plugin_mutex))
251
252 #define SCM_REC_MUTEX(c_name) \
253 SCM_SNARF_HERE(static scm_t_rec_mutex c_name) \
254 SCM_SNARF_INIT(scm_i_plugin_rec_mutex_init (&c_name, &scm_i_plugin_rec_mutex))
255
256 #define SCM_GLOBAL_REC_MUTEX(c_name) \
257 SCM_SNARF_HERE(scm_t_rec_mutex c_name) \
258 SCM_SNARF_INIT(scm_i_plugin_rec_mutex_init (&c_name, &scm_i_plugin_rec_mutex))
259
260 #define SCM_SMOB(tag, scheme_name, size) \
261 SCM_SNARF_HERE(static scm_t_bits tag) \
262 SCM_SNARF_INIT((tag)=scm_make_smob_type((scheme_name), (size));)
263
264 #define SCM_GLOBAL_SMOB(tag, scheme_name, size) \
265 SCM_SNARF_HERE(scm_t_bits tag) \
266 SCM_SNARF_INIT((tag)=scm_make_smob_type((scheme_name), (size));)
267
268 #define SCM_SMOB_MARK(tag, c_name, arg) \
269 SCM_SNARF_HERE(static SCM c_name(SCM arg)) \
270 SCM_SNARF_INIT(scm_set_smob_mark((tag), (c_name));)
271
272 #define SCM_GLOBAL_SMOB_MARK(tag, c_name, arg) \
273 SCM_SNARF_HERE(SCM c_name(SCM arg)) \
274 SCM_SNARF_INIT(scm_set_smob_mark((tag), (c_name));)
275
276 #define SCM_SMOB_FREE(tag, c_name, arg) \
277 SCM_SNARF_HERE(static size_t c_name(SCM arg)) \
278 SCM_SNARF_INIT(scm_set_smob_free((tag), (c_name));)
279
280 #define SCM_GLOBAL_SMOB_FREE(tag, c_name, arg) \
281 SCM_SNARF_HERE(size_t c_name(SCM arg)) \
282 SCM_SNARF_INIT(scm_set_smob_free((tag), (c_name));)
283
284 #define SCM_SMOB_PRINT(tag, c_name, obj, port, pstate) \
285 SCM_SNARF_HERE(static int c_name(SCM obj, SCM port, scm_print_state* pstate)) \
286 SCM_SNARF_INIT(scm_set_smob_print((tag), (c_name));)
287
288 #define SCM_GLOBAL_SMOB_PRINT(tag, c_name, obj, port, pstate) \
289 SCM_SNARF_HERE(int c_name(SCM obj, SCM port, scm_print_state* pstate)) \
290 SCM_SNARF_INIT(scm_set_smob_print((tag), (c_name));)
291
292 #define SCM_SMOB_EQUALP(tag, c_name, obj1, obj2) \
293 SCM_SNARF_HERE(static SCM c_name(SCM obj1, SCM obj2)) \
294 SCM_SNARF_INIT(scm_set_smob_equalp((tag), (c_name));)
295
296 #define SCM_GLOBAL_SMOB_EQUALP(tag, c_name, obj1, obj2) \
297 SCM_SNARF_HERE(SCM c_name(SCM obj1, SCM obj2)) \
298 SCM_SNARF_INIT(scm_set_smob_equalp((tag), (c_name));)
299
300 #define SCM_SMOB_APPLY(tag, c_name, req, opt, rest, arglist) \
301 SCM_SNARF_HERE(static SCM c_name arglist) \
302 SCM_SNARF_INIT(scm_set_smob_apply((tag), (c_name), (req), (opt), (rest));)
303
304 #define SCM_GLOBAL_SMOB_APPLY(tag, c_name, req, opt, rest, arglist) \
305 SCM_SNARF_HERE(SCM c_name arglist) \
306 SCM_SNARF_INIT(scm_set_smob_apply((tag), (c_name), (req), (opt), (rest));)
307
308 \f
309 /* Low-level snarfing for static memory allocation. */
310
311 #ifdef SCM_SUPPORT_STATIC_ALLOCATION
312
313 #define SCM_IMMUTABLE_CELL(c_name, car, cdr) \
314 static SCM_ALIGNED (8) SCM_UNUSED const scm_t_cell \
315 c_name ## _raw_scell = \
316 { \
317 SCM_PACK (car), \
318 SCM_PACK (cdr) \
319 }; \
320 static SCM_UNUSED const SCM c_name = SCM_PACK (& c_name ## _raw_scell)
321
322 #define SCM_IMMUTABLE_DOUBLE_CELL(c_name, car, cbr, ccr, cdr) \
323 static SCM_ALIGNED (8) SCM_UNUSED const scm_t_cell \
324 c_name ## _raw_cell [2] = \
325 { \
326 { SCM_PACK (car), SCM_PACK (cbr) }, \
327 { SCM_PACK (ccr), SCM_PACK (cdr) } \
328 }; \
329 static SCM_UNUSED const SCM c_name = SCM_PACK (& c_name ## _raw_cell)
330
331 #define SCM_STATIC_DOUBLE_CELL(c_name, car, cbr, ccr, cdr) \
332 static SCM_ALIGNED (8) SCM_UNUSED scm_t_cell \
333 c_name ## _raw_cell [2] = \
334 { \
335 { SCM_PACK (car), SCM_PACK (cbr) }, \
336 { SCM_PACK (ccr), SCM_PACK (cdr) } \
337 }; \
338 static SCM_UNUSED SCM c_name = SCM_PACK (& c_name ## _raw_cell)
339
340 #define SCM_IMMUTABLE_STRINGBUF(c_name, contents) \
341 static SCM_UNUSED const \
342 struct \
343 { \
344 scm_t_bits word_0; \
345 scm_t_bits word_1; \
346 const char buffer[sizeof (contents)]; \
347 } \
348 c_name = \
349 { \
350 scm_tc7_stringbuf | SCM_I_STRINGBUF_F_SHARED, \
351 sizeof (contents) - 1, \
352 contents \
353 }
354
355 #define SCM_IMMUTABLE_STRING(c_name, contents) \
356 SCM_IMMUTABLE_STRINGBUF (scm_i_paste (c_name, _stringbuf), contents); \
357 SCM_IMMUTABLE_DOUBLE_CELL (c_name, \
358 scm_tc7_ro_string, \
359 (scm_t_bits) &scm_i_paste (c_name, \
360 _stringbuf), \
361 (scm_t_bits) 0, \
362 (scm_t_bits) (sizeof (contents) - 1))
363
364 #define SCM_IMMUTABLE_POINTER(c_name, ptr) \
365 SCM_IMMUTABLE_CELL (c_name, scm_tc7_pointer, ptr)
366
367 /* for primitive-generics, add a foreign to the end */
368 #define SCM_STATIC_SUBR_OBJVECT(c_name, foreign) \
369 static SCM_ALIGNED (8) SCM c_name[4] = \
370 { \
371 SCM_PACK (scm_tc7_vector | (2 << 8)), \
372 SCM_PACK (0), \
373 foreign, \
374 SCM_BOOL_F, /* the name */ \
375 }
376
377 #define SCM_STATIC_PROGRAM(c_name, objcode, objtable, freevars) \
378 static SCM_ALIGNED (8) SCM_UNUSED SCM \
379 scm_i_paste (c_name, _raw_cell)[] = \
380 { \
381 SCM_PACK (scm_tc7_program | SCM_F_PROGRAM_IS_PRIMITIVE), \
382 objcode, \
383 objtable, \
384 freevars \
385 }; \
386 static SCM_UNUSED const SCM c_name = \
387 SCM_PACK (& scm_i_paste (c_name, _raw_cell))
388
389 #endif /* SCM_SUPPORT_STATIC_ALLOCATION */
390
391 \f
392 /* Documentation. */
393
394 #ifdef SCM_MAGIC_SNARF_DOCS
395 #undef SCM_ASSERT
396 #define SCM_ASSERT(_cond, _arg, _pos, _subr) ^^ argpos _arg _pos __LINE__ ^^
397 #endif /* SCM_MAGIC_SNARF_DOCS */
398
399 #endif /* SCM_SNARF_H */
400
401 /*
402 Local Variables:
403 c-file-style: "gnu"
404 End:
405 */