Remove unused CPP defines naming <method> slots
[bpt/guile.git] / libguile / deprecated.c
CommitLineData
19e2247d
MV
1/* This file contains definitions for deprecated features. When you
2 deprecate something, move it here when that is feasible.
3*/
4
28b818d3 5/* Copyright (C) 2003, 2004, 2006, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Free Software Foundation, Inc.
19e2247d 6 *
73be1d9e 7 * This library is free software; you can redistribute it and/or
53befeb7
NJ
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 3 of
10 * the License, or (at your option) any later version.
19e2247d 11 *
53befeb7
NJ
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
73be1d9e
MV
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
19e2247d 16 *
73be1d9e
MV
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
53befeb7
NJ
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301 USA
73be1d9e 21 */
19e2247d 22
dbb605f5
LC
23#ifdef HAVE_CONFIG_H
24# include <config.h>
25#endif
26
0eb934f1
LC
27#define SCM_BUILDING_DEPRECATED_CODE
28
19e2247d 29#include "libguile/_scm.h"
55d30fac 30#include "libguile/deprecation.h"
3452e666 31
19e2247d
MV
32#if (SCM_ENABLE_DEPRECATED == 1)
33
f3c6a02c
AW
34\f
35
b2feee6b
AW
36SCM
37scm_internal_dynamic_wind (scm_t_guard before,
38 scm_t_inner inner,
39 scm_t_guard after,
40 void *inner_data,
41 void *guard_data)
42{
43 SCM ans;
44
45 scm_c_issue_deprecation_warning
46 ("`scm_internal_dynamic_wind' is deprecated. "
47 "Use the `scm_dynwind_begin' / `scm_dynwind_end' API instead.");
48
49 scm_dynwind_begin (SCM_F_DYNWIND_REWINDABLE);
50 scm_dynwind_rewind_handler (before, guard_data, SCM_F_WIND_EXPLICITLY);
51 scm_dynwind_unwind_handler (after, guard_data, SCM_F_WIND_EXPLICITLY);
52 ans = inner (inner_data);
53 scm_dynwind_end ();
54 return ans;
55}
56
57\f
58
65619ebe
AW
59SCM
60scm_immutable_cell (scm_t_bits car, scm_t_bits cdr)
61{
62 scm_c_issue_deprecation_warning
63 ("scm_immutable_cell is deprecated. Use scm_cell instead.");
64
65 return scm_cell (car, cdr);
66}
67
68SCM
69scm_immutable_double_cell (scm_t_bits car, scm_t_bits cbr,
70 scm_t_bits ccr, scm_t_bits cdr)
71{
72 scm_c_issue_deprecation_warning
73 ("scm_immutable_double_cell is deprecated. Use scm_double_cell instead.");
74
75 return scm_double_cell (car, cbr, ccr, cdr);
76}
77
78
79\f
80
c2247b78
AW
81SCM_GLOBAL_SYMBOL (scm_memory_alloc_key, "memory-allocation-error");
82void
83scm_memory_error (const char *subr)
84{
85 scm_c_issue_deprecation_warning
86 ("scm_memory_error is deprecated. Use scm_report_out_of_memory to raise "
87 "an exception, or abort() to cause the program to exit.");
88
89 fprintf (stderr, "FATAL: memory error in %s\n", subr);
90 abort ();
91}
92
93
94\f
95
623559f3
AW
96SCM scm_no_applicable_method = SCM_BOOL_F;
97
98void
99scm_init_deprecated_goops (void)
100{
101 scm_no_applicable_method =
102 scm_variable_ref (scm_c_lookup ("no-applicable-method"));
103}
104
e4aa440a 105#define BUFFSIZE 32 /* big enough for most uses */
9e2cd55e 106#define scm_si_specializers 1 /* offset of spec. slot in a <method> */
e4aa440a
AW
107#define SPEC_OF(x) SCM_SLOT (x, scm_si_specializers)
108
109static SCM
110scm_i_vector2list (SCM l, long len)
111{
112 long j;
113 SCM z = scm_c_make_vector (len, SCM_UNDEFINED);
114
115 for (j = 0; j < len; j++, l = SCM_CDR (l)) {
116 SCM_SIMPLE_VECTOR_SET (z, j, SCM_CAR (l));
117 }
118 return z;
119}
120
121static int
122applicablep (SCM actual, SCM formal)
123{
124 /* We already know that the cpl is well formed. */
125 return scm_is_true (scm_c_memq (formal, SCM_SLOT (actual, scm_si_cpl)));
126}
127
128static int
129more_specificp (SCM m1, SCM m2, SCM const *targs)
130{
131 register SCM s1, s2;
132 register long i;
133 /*
134 * Note:
135 * m1 and m2 can have != length (i.e. one can be one element longer than the
136 * other when we have a dotted parameter list). For instance, with the call
137 * (M 1)
138 * with
139 * (define-method M (a . l) ....)
140 * (define-method M (a) ....)
141 *
142 * we consider that the second method is more specific.
143 *
144 * BTW, targs is an array of types. We don't need it's size since
145 * we already know that m1 and m2 are applicable (no risk to go past
146 * the end of this array).
147 *
148 */
149 for (i=0, s1=SPEC_OF(m1), s2=SPEC_OF(m2); ; i++, s1=SCM_CDR(s1), s2=SCM_CDR(s2)) {
150 if (scm_is_null(s1)) return 1;
151 if (scm_is_null(s2)) return 0;
152 if (!scm_is_eq (SCM_CAR(s1), SCM_CAR(s2))) {
153 register SCM l, cs1 = SCM_CAR(s1), cs2 = SCM_CAR(s2);
154
155 for (l = SCM_SLOT (targs[i], scm_si_cpl); ; l = SCM_CDR(l)) {
156 if (scm_is_eq (cs1, SCM_CAR (l)))
157 return 1;
158 if (scm_is_eq (cs2, SCM_CAR (l)))
159 return 0;
160 }
161 return 0;/* should not occur! */
162 }
163 }
164 return 0; /* should not occur! */
165}
166
167static SCM
168sort_applicable_methods (SCM method_list, long size, SCM const *targs)
169{
170 long i, j, incr;
171 SCM *v, vector = SCM_EOL;
172 SCM buffer[BUFFSIZE];
173 SCM save = method_list;
174 scm_t_array_handle handle;
175
176 /* For reasonably sized method_lists we can try to avoid all the
177 * consing and reorder the list in place...
178 * This idea is due to David McClain <Dave_McClain@msn.com>
179 */
180 if (size <= BUFFSIZE)
181 {
182 for (i = 0; i < size; i++)
183 {
184 buffer[i] = SCM_CAR (method_list);
185 method_list = SCM_CDR (method_list);
186 }
187 v = buffer;
188 }
189 else
190 {
191 /* Too many elements in method_list to keep everything locally */
192 vector = scm_i_vector2list (save, size);
193 v = scm_vector_writable_elements (vector, &handle, NULL, NULL);
194 }
195
196 /* Use a simple shell sort since it is generally faster than qsort on
197 * small vectors (which is probably mostly the case when we have to
198 * sort a list of applicable methods).
199 */
200 for (incr = size / 2; incr; incr /= 2)
201 {
202 for (i = incr; i < size; i++)
203 {
204 for (j = i - incr; j >= 0; j -= incr)
205 {
206 if (more_specificp (v[j], v[j+incr], targs))
207 break;
208 else
209 {
210 SCM tmp = v[j + incr];
211 v[j + incr] = v[j];
212 v[j] = tmp;
213 }
214 }
215 }
216 }
217
218 if (size <= BUFFSIZE)
219 {
220 /* We did it in locally, so restore the original list (reordered) in-place */
221 for (i = 0, method_list = save; i < size; i++, v++)
222 {
223 SCM_SETCAR (method_list, *v);
224 method_list = SCM_CDR (method_list);
225 }
226 return save;
227 }
228
229 /* If we are here, that's that we did it the hard way... */
230 scm_array_handle_release (&handle);
231 return scm_vector_to_list (vector);
232}
233
234SCM
235scm_compute_applicable_methods (SCM gf, SCM args, long len, int find_method_p)
236{
237 register long i;
238 long count = 0;
239 SCM l, fl, applicable = SCM_EOL;
240 SCM save = args;
241 SCM buffer[BUFFSIZE];
242 SCM const *types;
243 SCM *p;
244 SCM tmp = SCM_EOL;
245 scm_t_array_handle handle;
246
247 scm_c_issue_deprecation_warning
248 ("scm_compute_applicable_methods is deprecated. Use "
249 "`compute-applicable-methods' from Scheme instead.");
250
251 /* Build the list of arguments types */
252 if (len >= BUFFSIZE)
253 {
254 tmp = scm_c_make_vector (len, SCM_UNDEFINED);
255 types = p = scm_vector_writable_elements (tmp, &handle, NULL, NULL);
256
257 /*
258 note that we don't have to work to reset the generation
259 count. TMP is a new vector anyway, and it is found
260 conservatively.
261 */
262 }
263 else
264 types = p = buffer;
265
266 for ( ; !scm_is_null (args); args = SCM_CDR (args))
267 *p++ = scm_class_of (SCM_CAR (args));
268
269 /* Build a list of all applicable methods */
270 for (l = scm_generic_function_methods (gf); !scm_is_null (l); l = SCM_CDR (l))
271 {
272 fl = SPEC_OF (SCM_CAR (l));
273 for (i = 0; ; i++, fl = SCM_CDR (fl))
274 {
275 if (SCM_INSTANCEP (fl)
276 /* We have a dotted argument list */
277 || (i >= len && scm_is_null (fl)))
278 { /* both list exhausted */
279 applicable = scm_cons (SCM_CAR (l), applicable);
280 count += 1;
281 break;
282 }
283 if (i >= len
284 || scm_is_null (fl)
285 || !applicablep (types[i], SCM_CAR (fl)))
286 break;
287 }
288 }
289
290 if (len >= BUFFSIZE)
291 scm_array_handle_release (&handle);
292
293 if (count == 0)
294 {
295 if (find_method_p)
296 return SCM_BOOL_F;
297 scm_call_2 (scm_no_applicable_method, gf, save);
298 /* if we are here, it's because no-applicable-method hasn't signaled an error */
299 return SCM_BOOL_F;
300 }
301
302 return (count == 1
303 ? applicable
304 : sort_applicable_methods (applicable, count, types));
305}
306
307SCM_SYMBOL (sym_compute_applicable_methods, "compute-applicable-methods");
308
309SCM
310scm_find_method (SCM l)
311#define FUNC_NAME "find-method"
312{
313 SCM gf;
314 long len = scm_ilength (l);
315
316 if (len == 0)
317 SCM_WRONG_NUM_ARGS ();
318
319 scm_c_issue_deprecation_warning
320 ("scm_find_method is deprecated. Use `compute-applicable-methods' "
321 "from Scheme instead.");
322
323 gf = SCM_CAR(l); l = SCM_CDR(l);
324 SCM_VALIDATE_GENERIC (1, gf);
325 if (scm_is_null (SCM_SLOT (gf, scm_si_methods)))
326 SCM_MISC_ERROR ("no methods for generic ~S", scm_list_1 (gf));
327
328 return scm_compute_applicable_methods (gf, l, len - 1, 1);
329}
330#undef FUNC_NAME
331
28b818d3
AW
332SCM
333scm_basic_make_class (SCM meta, SCM name, SCM dsupers, SCM dslots)
334{
335 scm_c_issue_deprecation_warning
336 ("scm_basic_make_class is deprecated. Use `define-class' in Scheme,"
337 "or use `(make META #:name NAME #:dsupers DSUPERS #:slots DSLOTS)' "
338 "in Scheme.");
339
340 return scm_make_standard_class (meta, name, dsupers, dslots);
341}
342
e4aa440a
AW
343
344\f
345
19e2247d
MV
346void
347scm_i_init_deprecated ()
348{
349#include "libguile/deprecated.x"
350}
351
352#endif