libguile/Makefile.am (snarfcppopts): Remove CFLAGS
[bpt/guile.git] / libguile / procprop.c
CommitLineData
e2cbf527 1/* Copyright (C) 1995,1996,1998,2000,2001,2003,2004, 2006, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
0f2d19dd 2 *
73be1d9e 3 * This library is free software; you can redistribute it and/or
53befeb7
NJ
4 * modify it under the terms of the GNU Lesser General Public License
5 * as published by the Free Software Foundation; either version 3 of
6 * the License, or (at your option) any later version.
0f2d19dd 7 *
53befeb7
NJ
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
73be1d9e
MV
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
0f2d19dd 12 *
73be1d9e
MV
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
53befeb7
NJ
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 * 02110-1301 USA
73be1d9e 17 */
1bbd0b84 18
1bbd0b84 19
0f2d19dd 20\f
dbb605f5
LC
21#ifdef HAVE_CONFIG_H
22# include <config.h>
23#endif
0f2d19dd 24
a0599745
MD
25#include "libguile/_scm.h"
26
27#include "libguile/alist.h"
28#include "libguile/eval.h"
29#include "libguile/procs.h"
30#include "libguile/gsubr.h"
5540e847 31#include "libguile/smob.h"
a0599745
MD
32#include "libguile/root.h"
33#include "libguile/vectors.h"
203a92b6 34#include "libguile/weak-table.h"
2fb924f6 35#include "libguile/programs.h"
9f309e2c 36#include "libguile/vm-builtins.h"
a0599745
MD
37
38#include "libguile/validate.h"
39#include "libguile/procprop.h"
0f2d19dd
JB
40\f
41
c083a529 42SCM_GLOBAL_SYMBOL (scm_sym_system_procedure, "system-procedure");
fd12a19a 43SCM_GLOBAL_SYMBOL (scm_sym_name, "name");
67e60655 44
e1bdf9e2 45static SCM overrides;
56164a5a 46
f3cf9421
AW
47static SCM arity_overrides;
48
314b8716
AW
49int
50scm_i_procedure_arity (SCM proc, int *req, int *opt, int *rest)
67e60655 51{
f3cf9421
AW
52 SCM o;
53
b2208d2e 54 o = scm_weak_table_refq (arity_overrides, proc, SCM_BOOL_F);
f3cf9421
AW
55
56 if (scm_is_true (o))
57 {
58 *req = scm_to_int (scm_car (o));
59 *opt = scm_to_int (scm_cadr (o));
60 *rest = scm_is_true (scm_caddr (o));
61 return 1;
62 }
63
d798a895 64 while (!SCM_PROGRAM_P (proc))
67e60655 65 {
8b33752b 66 if (SCM_STRUCTP (proc))
75c3ed28 67 {
75c3ed28
AW
68 if (!SCM_STRUCT_APPLICABLE_P (proc))
69 return 0;
70 proc = SCM_STRUCT_PROCEDURE (proc);
75c3ed28 71 }
8b33752b
AW
72 else if (SCM_HAS_TYP7 (proc, scm_tc7_smob))
73 {
74 if (!SCM_SMOB_APPLICABLE_P (proc))
75 return 0;
01e909d9
AW
76 if (!scm_i_program_arity (SCM_SMOB_DESCRIPTOR (proc).apply_trampoline,
77 req, opt, rest))
78 return 0;
79
80 /* The trampoline gets the smob too, which users don't
81 see. */
82 *req -= 1;
83
84 return 1;
8b33752b
AW
85 }
86 else
87 return 0;
67e60655 88 }
f3cf9421 89
75c3ed28 90 return scm_i_program_arity (proc, req, opt, rest);
67e60655
MD
91}
92
f3cf9421
AW
93SCM_DEFINE (scm_set_procedure_minimum_arity_x, "set-procedure-minimum-arity!",
94 4, 0, 0, (SCM proc, SCM req, SCM opt, SCM rest),
95 "")
96#define FUNC_NAME s_scm_set_procedure_minimum_arity_x
97{
98 int t SCM_UNUSED;
99
100 SCM_VALIDATE_PROC (1, proc);
101 SCM_VALIDATE_INT_COPY (2, req, t);
102 SCM_VALIDATE_INT_COPY (3, opt, t);
103 SCM_VALIDATE_BOOL (4, rest);
104
b2208d2e 105 scm_weak_table_putq_x (arity_overrides, proc, scm_list_3 (req, opt, rest));
f3cf9421
AW
106 return SCM_UNDEFINED;
107}
108#undef FUNC_NAME
109
cb2ce548
AW
110SCM_DEFINE (scm_procedure_minimum_arity, "procedure-minimum-arity", 1, 0, 0,
111 (SCM proc),
112 "Return the \"minimum arity\" of a procedure.\n\n"
113 "If the procedure has only one arity, that arity is returned\n"
114 "as a list of three values: the number of required arguments,\n"
115 "the number of optional arguments, and a boolean indicating\n"
116 "whether or not the procedure takes rest arguments.\n\n"
117 "For a case-lambda procedure, the arity returned is the one\n"
118 "with the lowest minimum number of arguments, and the highest\n"
119 "maximum number of arguments.\n\n"
120 "If it was not possible to determine the arity of the procedure,\n"
121 "@code{#f} is returned.")
122#define FUNC_NAME s_scm_procedure_minimum_arity
123{
124 int req, opt, rest;
125
126 if (scm_i_procedure_arity (proc, &req, &opt, &rest))
127 return scm_list_3 (scm_from_int (req),
128 scm_from_int (opt),
129 scm_from_bool (rest));
130 else
131 return SCM_BOOL_F;
132}
133#undef FUNC_NAME
134
3b3b36dd 135SCM_DEFINE (scm_procedure_properties, "procedure-properties", 1, 0, 0,
1bbd0b84 136 (SCM proc),
b7e64f8b 137 "Return @var{proc}'s property list.")
1bbd0b84 138#define FUNC_NAME s_scm_procedure_properties
0f2d19dd 139{
40553c20 140 SCM ret, user_props;
56164a5a 141
34d19ef6 142 SCM_VALIDATE_PROC (1, proc);
314b8716 143
40553c20
AW
144 user_props = scm_weak_table_refq (overrides, proc, SCM_BOOL_F);
145
146 if (scm_is_pair (user_props) && scm_is_true (scm_car (user_props)))
147 return scm_cdr (user_props);
148
d798a895 149 if (SCM_PROGRAM_P (proc))
80797145 150 ret = scm_i_program_properties (proc);
40553c20
AW
151 else
152 ret = SCM_EOL;
153
154 if (scm_is_pair (user_props))
155 for (user_props = scm_cdr (user_props);
156 scm_is_pair (user_props);
157 user_props = scm_cdr (user_props))
158 ret = scm_assq_set_x (ret, scm_caar (user_props), scm_cdar (user_props));
314b8716 159
3fc7e2c1 160 return ret;
0f2d19dd 161}
1bbd0b84 162#undef FUNC_NAME
0f2d19dd 163
3b3b36dd 164SCM_DEFINE (scm_set_procedure_properties_x, "set-procedure-properties!", 2, 0, 0,
56164a5a
AW
165 (SCM proc, SCM alist),
166 "Set @var{proc}'s property list to @var{alist}.")
1bbd0b84 167#define FUNC_NAME s_scm_set_procedure_properties_x
0f2d19dd 168{
56164a5a
AW
169 SCM_VALIDATE_PROC (1, proc);
170
40553c20 171 scm_weak_table_putq_x (overrides, proc, scm_cons (SCM_BOOL_T, alist));
314b8716 172
0f2d19dd
JB
173 return SCM_UNSPECIFIED;
174}
1bbd0b84 175#undef FUNC_NAME
0f2d19dd 176
3b3b36dd 177SCM_DEFINE (scm_procedure_property, "procedure-property", 2, 0, 0,
56164a5a
AW
178 (SCM proc, SCM key),
179 "Return the property of @var{proc} with name @var{key}.")
1bbd0b84 180#define FUNC_NAME s_scm_procedure_property
0f2d19dd 181{
40553c20
AW
182 SCM user_props;
183
56164a5a
AW
184 SCM_VALIDATE_PROC (1, proc);
185
40553c20
AW
186 if (scm_is_eq (key, scm_sym_name))
187 return scm_procedure_name (proc);
188 if (scm_is_eq (key, scm_sym_documentation))
189 return scm_procedure_documentation (proc);
190
191 user_props = scm_weak_table_refq (overrides, proc, SCM_BOOL_F);
192 if (scm_is_true (user_props))
193 {
194 SCM pair = scm_assq (key, scm_cdr (user_props));
195 if (scm_is_pair (pair))
196 return scm_cdr (pair);
197 if (scm_is_true (scm_car (user_props)))
198 return SCM_BOOL_F;
199 }
200
3fc7e2c1 201 return scm_assq_ref (scm_procedure_properties (proc), key);
0f2d19dd 202}
1bbd0b84 203#undef FUNC_NAME
0f2d19dd 204
3b3b36dd 205SCM_DEFINE (scm_set_procedure_property_x, "set-procedure-property!", 3, 0, 0,
56164a5a
AW
206 (SCM proc, SCM key, SCM val),
207 "In @var{proc}'s property list, set the property named @var{key} to\n"
208 "@var{val}.")
1bbd0b84 209#define FUNC_NAME s_scm_set_procedure_property_x
0f2d19dd 210{
40553c20 211 SCM user_props, override_p;
56164a5a 212
e1bdf9e2 213 SCM_VALIDATE_PROC (1, proc);
3fc7e2c1 214
203a92b6 215 scm_i_pthread_mutex_lock (&scm_i_misc_mutex);
40553c20
AW
216 user_props = scm_weak_table_refq (overrides, proc, SCM_BOOL_F);
217 if (scm_is_false (user_props))
f2ed4473 218 {
40553c20
AW
219 override_p = SCM_BOOL_F;
220 user_props = SCM_EOL;
f2ed4473 221 }
40553c20
AW
222 else
223 {
224 override_p = scm_car (user_props);
225 user_props = scm_cdr (user_props);
226 }
227 scm_weak_table_putq_x (overrides, proc,
228 scm_cons (override_p,
229 scm_assq_set_x (user_props, key, val)));
203a92b6 230 scm_i_pthread_mutex_unlock (&scm_i_misc_mutex);
c783b082 231
0f2d19dd
JB
232 return SCM_UNSPECIFIED;
233}
1bbd0b84 234#undef FUNC_NAME
0f2d19dd 235
e2cbf527 236
0f2d19dd
JB
237\f
238
e2cbf527
AW
239SCM_SYMBOL (scm_sym_source, "source");
240
241
242SCM_DEFINE (scm_procedure_name, "procedure-name", 1, 0, 0,
243 (SCM proc),
244 "Return the name of the procedure @var{proc}")
245#define FUNC_NAME s_scm_procedure_name
246{
40553c20 247 SCM user_props;
e65f80af 248
e2cbf527 249 SCM_VALIDATE_PROC (1, proc);
e65f80af 250
40553c20
AW
251 user_props = scm_weak_table_refq (overrides, proc, SCM_BOOL_F);
252 if (scm_is_true (user_props))
253 {
254 SCM pair = scm_assq (scm_sym_name, scm_cdr (user_props));
255 if (scm_is_pair (pair))
256 return scm_cdr (pair);
257 if (scm_is_true (scm_car (user_props)))
258 return SCM_BOOL_F;
259 }
e65f80af 260
d798a895 261 if (SCM_PROGRAM_P (proc))
80797145 262 return scm_i_program_name (proc);
30b7cf9d
AW
263 else if (SCM_STRUCTP (proc) && SCM_STRUCT_APPLICABLE_P (proc))
264 return scm_procedure_name (SCM_STRUCT_PROCEDURE (proc));
e65f80af 265 else
40553c20 266 return SCM_BOOL_F;
e2cbf527
AW
267}
268#undef FUNC_NAME
269
270
bf8328ec
AW
271SCM_GLOBAL_SYMBOL (scm_sym_documentation, "documentation");
272
273SCM_DEFINE (scm_procedure_documentation, "procedure-documentation", 1, 0, 0,
274 (SCM proc),
275 "Return the documentation string associated with @code{proc}. By\n"
276 "convention, if a procedure contains more than one expression and the\n"
277 "first expression is a string constant, that string is assumed to contain\n"
278 "documentation for that procedure.")
279#define FUNC_NAME s_scm_procedure_documentation
280{
40553c20 281 SCM user_props;
bf8328ec
AW
282
283 SCM_VALIDATE_PROC (1, proc);
284
285 while (SCM_STRUCTP (proc) && SCM_STRUCT_APPLICABLE_P (proc))
286 proc = SCM_STRUCT_PROCEDURE (proc);
287
40553c20
AW
288 user_props = scm_weak_table_refq (overrides, proc, SCM_BOOL_F);
289 if (scm_is_true (user_props))
290 {
291 SCM pair = scm_assq (scm_sym_documentation, scm_cdr (user_props));
292 if (scm_is_pair (pair))
293 return scm_cdr (pair);
294 if (scm_is_true (scm_car (user_props)))
295 return SCM_BOOL_F;
296 }
bf8328ec 297
d798a895 298 if (SCM_PROGRAM_P (proc))
80797145 299 return scm_i_program_documentation (proc);
bf8328ec 300 else
40553c20 301 return SCM_BOOL_F;
bf8328ec
AW
302}
303#undef FUNC_NAME
304
305
e2cbf527
AW
306SCM_DEFINE (scm_procedure_source, "procedure-source", 1, 0, 0,
307 (SCM proc),
308 "Return the source of the procedure @var{proc}.")
309#define FUNC_NAME s_scm_procedure_source
310{
311 SCM src;
312 SCM_VALIDATE_PROC (1, proc);
313
314 do
315 {
316 src = scm_procedure_property (proc, scm_sym_source);
317 if (scm_is_true (src))
318 return src;
319
320 if (SCM_STRUCTP (proc) && SCM_STRUCT_APPLICABLE_P (proc)
321 && SCM_HEAP_OBJECT_P ((proc = SCM_STRUCT_PROCEDURE (proc))))
322 continue;
323 }
324 while (0);
325
326 return SCM_BOOL_F;
327}
328#undef FUNC_NAME
329
330
331\f
1cc91f1b 332
0f2d19dd
JB
333void
334scm_init_procprop ()
0f2d19dd 335{
203a92b6 336 overrides = scm_c_make_weak_table (0, SCM_WEAK_TABLE_KIND_KEY);
b2208d2e 337 arity_overrides = scm_c_make_weak_table (0, SCM_WEAK_TABLE_KIND_KEY);
a0599745 338#include "libguile/procprop.x"
9f309e2c 339 scm_init_vm_builtin_properties ();
0f2d19dd
JB
340}
341
89e00824
ML
342
343/*
344 Local Variables:
345 c-file-style: "gnu"
346 End:
347*/