Merge remote-tracking branch 'origin/stable-2.0'
[bpt/guile.git] / libguile / procprop.c
CommitLineData
80be163f 1/* Copyright (C) 1995,1996,1998,2000,2001,2003,2004, 2006, 2008, 2009, 2010, 2011, 2012 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"
a0599745
MD
36
37#include "libguile/validate.h"
38#include "libguile/procprop.h"
0f2d19dd
JB
39\f
40
c083a529 41SCM_GLOBAL_SYMBOL (scm_sym_system_procedure, "system-procedure");
fd12a19a 42SCM_GLOBAL_SYMBOL (scm_sym_name, "name");
67e60655 43
e1bdf9e2 44static SCM overrides;
56164a5a 45
f3cf9421
AW
46static SCM arity_overrides;
47
314b8716
AW
48int
49scm_i_procedure_arity (SCM proc, int *req, int *opt, int *rest)
67e60655 50{
f3cf9421
AW
51 SCM o;
52
b2208d2e 53 o = scm_weak_table_refq (arity_overrides, proc, SCM_BOOL_F);
f3cf9421
AW
54
55 if (scm_is_true (o))
56 {
57 *req = scm_to_int (scm_car (o));
58 *opt = scm_to_int (scm_cadr (o));
59 *rest = scm_is_true (scm_caddr (o));
60 return 1;
61 }
62
75c3ed28 63 while (!SCM_PROGRAM_P (proc))
67e60655 64 {
8b33752b 65 if (SCM_STRUCTP (proc))
75c3ed28 66 {
75c3ed28
AW
67 if (!SCM_STRUCT_APPLICABLE_P (proc))
68 return 0;
69 proc = SCM_STRUCT_PROCEDURE (proc);
75c3ed28 70 }
8b33752b
AW
71 else if (SCM_HAS_TYP7 (proc, scm_tc7_smob))
72 {
73 if (!SCM_SMOB_APPLICABLE_P (proc))
74 return 0;
01e909d9
AW
75 if (!scm_i_program_arity (SCM_SMOB_DESCRIPTOR (proc).apply_trampoline,
76 req, opt, rest))
77 return 0;
78
79 /* The trampoline gets the smob too, which users don't
80 see. */
81 *req -= 1;
82
83 return 1;
8b33752b
AW
84 }
85 else
86 return 0;
67e60655 87 }
f3cf9421 88
75c3ed28 89 return scm_i_program_arity (proc, req, opt, rest);
67e60655
MD
90}
91
f3cf9421
AW
92SCM_DEFINE (scm_set_procedure_minimum_arity_x, "set-procedure-minimum-arity!",
93 4, 0, 0, (SCM proc, SCM req, SCM opt, SCM rest),
94 "")
95#define FUNC_NAME s_scm_set_procedure_minimum_arity_x
96{
97 int t SCM_UNUSED;
98
99 SCM_VALIDATE_PROC (1, proc);
100 SCM_VALIDATE_INT_COPY (2, req, t);
101 SCM_VALIDATE_INT_COPY (3, opt, t);
102 SCM_VALIDATE_BOOL (4, rest);
103
b2208d2e 104 scm_weak_table_putq_x (arity_overrides, proc, scm_list_3 (req, opt, rest));
f3cf9421
AW
105 return SCM_UNDEFINED;
106}
107#undef FUNC_NAME
108
cb2ce548
AW
109SCM_DEFINE (scm_procedure_minimum_arity, "procedure-minimum-arity", 1, 0, 0,
110 (SCM proc),
111 "Return the \"minimum arity\" of a procedure.\n\n"
112 "If the procedure has only one arity, that arity is returned\n"
113 "as a list of three values: the number of required arguments,\n"
114 "the number of optional arguments, and a boolean indicating\n"
115 "whether or not the procedure takes rest arguments.\n\n"
116 "For a case-lambda procedure, the arity returned is the one\n"
117 "with the lowest minimum number of arguments, and the highest\n"
118 "maximum number of arguments.\n\n"
119 "If it was not possible to determine the arity of the procedure,\n"
120 "@code{#f} is returned.")
121#define FUNC_NAME s_scm_procedure_minimum_arity
122{
123 int req, opt, rest;
124
125 if (scm_i_procedure_arity (proc, &req, &opt, &rest))
126 return scm_list_3 (scm_from_int (req),
127 scm_from_int (opt),
128 scm_from_bool (rest));
129 else
130 return SCM_BOOL_F;
131}
132#undef FUNC_NAME
133
3b3b36dd 134SCM_DEFINE (scm_procedure_properties, "procedure-properties", 1, 0, 0,
1bbd0b84 135 (SCM proc),
b7e64f8b 136 "Return @var{proc}'s property list.")
1bbd0b84 137#define FUNC_NAME s_scm_procedure_properties
0f2d19dd 138{
314b8716 139 SCM ret;
56164a5a 140
34d19ef6 141 SCM_VALIDATE_PROC (1, proc);
314b8716 142
203a92b6 143 ret = scm_weak_table_refq (overrides, proc, SCM_BOOL_F);
314b8716 144
e1bdf9e2
AW
145 if (scm_is_false (ret))
146 {
147 if (SCM_PROGRAM_P (proc))
07e424b7 148 ret = scm_i_program_properties (proc);
e1bdf9e2
AW
149 else
150 ret = SCM_EOL;
151 }
152
3fc7e2c1 153 return ret;
0f2d19dd 154}
1bbd0b84 155#undef FUNC_NAME
0f2d19dd 156
3b3b36dd 157SCM_DEFINE (scm_set_procedure_properties_x, "set-procedure-properties!", 2, 0, 0,
56164a5a
AW
158 (SCM proc, SCM alist),
159 "Set @var{proc}'s property list to @var{alist}.")
1bbd0b84 160#define FUNC_NAME s_scm_set_procedure_properties_x
0f2d19dd 161{
56164a5a
AW
162 SCM_VALIDATE_PROC (1, proc);
163
203a92b6 164 scm_weak_table_putq_x (overrides, proc, alist);
314b8716 165
0f2d19dd
JB
166 return SCM_UNSPECIFIED;
167}
1bbd0b84 168#undef FUNC_NAME
0f2d19dd 169
3b3b36dd 170SCM_DEFINE (scm_procedure_property, "procedure-property", 2, 0, 0,
56164a5a
AW
171 (SCM proc, SCM key),
172 "Return the property of @var{proc} with name @var{key}.")
1bbd0b84 173#define FUNC_NAME s_scm_procedure_property
0f2d19dd 174{
56164a5a
AW
175 SCM_VALIDATE_PROC (1, proc);
176
3fc7e2c1 177 return scm_assq_ref (scm_procedure_properties (proc), key);
0f2d19dd 178}
1bbd0b84 179#undef FUNC_NAME
0f2d19dd 180
3b3b36dd 181SCM_DEFINE (scm_set_procedure_property_x, "set-procedure-property!", 3, 0, 0,
56164a5a
AW
182 (SCM proc, SCM key, SCM val),
183 "In @var{proc}'s property list, set the property named @var{key} to\n"
184 "@var{val}.")
1bbd0b84 185#define FUNC_NAME s_scm_set_procedure_property_x
0f2d19dd 186{
90fa152c 187 SCM props;
56164a5a 188
e1bdf9e2 189 SCM_VALIDATE_PROC (1, proc);
3fc7e2c1 190
203a92b6
AW
191 scm_i_pthread_mutex_lock (&scm_i_misc_mutex);
192 props = scm_weak_table_refq (overrides, proc, SCM_BOOL_F);
f2ed4473
AW
193 if (scm_is_false (props))
194 {
195 if (SCM_PROGRAM_P (proc))
196 props = scm_i_program_properties (proc);
197 else
198 props = SCM_EOL;
199 }
203a92b6
AW
200 scm_weak_table_putq_x (overrides, proc, scm_assq_set_x (props, key, val));
201 scm_i_pthread_mutex_unlock (&scm_i_misc_mutex);
c783b082 202
0f2d19dd
JB
203 return SCM_UNSPECIFIED;
204}
1bbd0b84 205#undef FUNC_NAME
0f2d19dd
JB
206
207\f
208
1cc91f1b 209
0f2d19dd
JB
210void
211scm_init_procprop ()
0f2d19dd 212{
203a92b6 213 overrides = scm_c_make_weak_table (0, SCM_WEAK_TABLE_KIND_KEY);
b2208d2e 214 arity_overrides = scm_c_make_weak_table (0, SCM_WEAK_TABLE_KIND_KEY);
a0599745 215#include "libguile/procprop.x"
0f2d19dd
JB
216}
217
89e00824
ML
218
219/*
220 Local Variables:
221 c-file-style: "gnu"
222 End:
223*/