maintainer changed: was lord, now jimb; first import
[bpt/guile.git] / libguile / hashtab.c
CommitLineData
0f2d19dd
JB
1/* Copyright (C) 1995,1996 Free Software Foundation, Inc.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
6 * any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
15 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
16 *
17 * As a special exception, the Free Software Foundation gives permission
18 * for additional uses of the text contained in its release of GUILE.
19 *
20 * The exception is that, if you link the GUILE library with other files
21 * to produce an executable, this does not by itself cause the
22 * resulting executable to be covered by the GNU General Public License.
23 * Your use of that executable is in no way restricted on account of
24 * linking the GUILE library code into it.
25 *
26 * This exception does not however invalidate any other reasons why
27 * the executable file might be covered by the GNU General Public License.
28 *
29 * This exception applies only to the code released by the
30 * Free Software Foundation under the name GUILE. If you copy
31 * code from other Free Software Foundation releases into a copy of
32 * GUILE, as the General Public License permits, the exception does
33 * not apply to the code that you add in this way. To avoid misleading
34 * anyone as to the status of such modified files, you must delete
35 * this exception notice from them.
36 *
37 * If you write modifications of your own for GUILE, it is your choice
38 * whether to permit this exception to apply to your modifications.
39 * If you do not wish that, delete this exception notice.
40 */
41\f
42
43#include <stdio.h>
44#include "_scm.h"
45
46\f
47
48#ifdef __STDC__
49SCM
50scm_hash_fn_get_handle (SCM table, SCM obj, unsigned int (*hash_fn)(), SCM (*assoc_fn)(), void * closure)
51#else
52SCM
53scm_hash_fn_get_handle (table, obj, hash_fn, assoc_fn, closure)
54 SCM table;
55 SCM obj;
56 unsigned int (*hash_fn)();
57 SCM (*assoc_fn)();
58 void * closure;
59#endif
60{
61 int k;
62 SCM h;
63
64 SCM_ASSERT (SCM_NIMP (table) && SCM_VECTORP (table), table, SCM_ARG1, "hash_fn_get_handle");
65 if (SCM_LENGTH (table) == 0)
66 return SCM_EOL;
67 k = hash_fn (obj, SCM_LENGTH (table), closure);
68 SCM_ASSERT ((0 <= k) && (k < SCM_LENGTH (table)),
69 SCM_MAKINUM (k),
70 SCM_OUTOFRANGE,
71 "hash_fn_get_handle");
72 h = assoc_fn (obj, SCM_VELTS (table)[k], closure);
73 return h;
74}
75
76
77#ifdef __STDC__
78SCM
79scm_hash_fn_create_handle_x (SCM table, SCM obj, SCM init, unsigned int (*hash_fn)(), SCM (*assoc_fn)(), void * closure)
80#else
81SCM
82scm_hash_fn_create_handle_x (table, obj, init, hash_fn, assoc_fn, closure)
83 SCM table;
84 SCM obj;
85 SCM init;
86 unsigned int (*hash_fn)();
87 SCM (*assoc_fn)();
88 void * closure;
89#endif
90{
91 int k;
92 SCM it;
93
94 SCM_ASSERT (SCM_NIMP (table) && SCM_VECTORP (table), table, SCM_ARG1, "hash_fn_create_handle_x");
95 if (SCM_LENGTH (table) == 0)
96 return SCM_EOL;
97 k = hash_fn (obj, SCM_LENGTH (table), closure);
98 SCM_ASSERT ((0 <= k) && (k < SCM_LENGTH (table)),
99 SCM_MAKINUM (k),
100 SCM_OUTOFRANGE,
101 "hash_fn_create_handle_x");
102 SCM_REDEFER_INTS;
103 it = assoc_fn (obj, SCM_VELTS (table)[k], closure);
104 if (SCM_NIMP (it))
105 {
106 return it;
107 }
108 {
109 SCM new_bucket;
110 SCM old_bucket;
111 old_bucket = SCM_VELTS (table)[k];
112 new_bucket = scm_acons (obj, init, old_bucket);
113 SCM_VELTS(table)[k] = new_bucket;
114 SCM_REALLOW_INTS;
115 return SCM_CAR (new_bucket);
116 }
117}
118
119
120
121#ifdef __STDC__
122SCM
123scm_hash_fn_ref (SCM table, SCM obj, SCM dflt, unsigned int (*hash_fn)(), SCM (*assoc_fn)(), void * closure)
124#else
125SCM
126scm_hash_fn_ref (table, obj, dflt, hash_fn, assoc_fn, closure)
127 SCM table;
128 SCM obj;
129 SCM dflt;
130 unsigned int (*hash_fn)();
131 SCM (*assoc_fn)();
132 void * closure;
133#endif
134{
135 SCM it;
136
137 it = scm_hash_fn_get_handle (table, obj, hash_fn, assoc_fn, closure);
138 if (SCM_IMP (it))
139 return dflt;
140 else
141 return SCM_CDR (it);
142}
143
144
145
146#ifdef __STDC__
147SCM
148scm_hash_fn_set_x (SCM table, SCM obj, SCM val, unsigned int (*hash_fn)(), SCM (*assoc_fn)(), void * closure)
149#else
150SCM
151scm_hash_fn_set_x (table, obj, val, hash_fn, assoc_fn, closure)
152 SCM table;
153 SCM obj;
154 SCM val;
155 unsigned int (*hash_fn)();
156 SCM (*assoc_fn)();
157 void * closure;
158#endif
159{
160 SCM it;
161
162 it = scm_hash_fn_create_handle_x (table, obj, SCM_BOOL_F, hash_fn, assoc_fn, closure);
163 SCM_SETCDR (it, val);
164 return val;
165}
166
167
168
169
170#ifdef __STDC__
171SCM
172scm_hash_fn_remove_x (SCM table,
173 SCM obj,
174 unsigned int (*hash_fn)(),
175 SCM (*assoc_fn)(),
176 SCM (*delete_fn)(),
177 void * closure)
178#else
179SCM
180scm_hash_fn_remove_x (table, obj, hash_fn, assoc_fn, delete_fn, closure)
181 SCM table;
182 SCM obj;
183 unsigned int (*hash_fn)();
184 SCM (*assoc_fn)();
185 SCM (*delete_fn)();
186 void * closure;
187#endif
188{
189 int k;
190 SCM h;
191
192 SCM_ASSERT (SCM_NIMP (table) && SCM_VECTORP (table), table, SCM_ARG1, "hash_fn_remove_x");
193 if (SCM_LENGTH (table) == 0)
194 return SCM_EOL;
195 k = hash_fn (obj, SCM_LENGTH (table), closure);
196 SCM_ASSERT ((0 <= k) && (k < SCM_LENGTH (table)),
197 SCM_MAKINUM (k),
198 SCM_OUTOFRANGE,
199 "hash_fn_remove_x");
200 h = assoc_fn (obj, SCM_VELTS (table)[k], closure);
201 SCM_VELTS(table)[k] = delete_fn (h, SCM_VELTS(table)[k]);
202 return h;
203}
204
205
206\f
207
208SCM_PROC (s_hashq_get_handle, "hashq-get-handle", 2, 0, 0, scm_hashq_get_handle);
209#ifdef __STDC__
210SCM
211scm_hashq_get_handle (SCM table, SCM obj)
212#else
213SCM
214scm_hashq_get_handle (table, obj)
215 SCM table;
216 SCM obj;
217#endif
218{
219 return scm_hash_fn_get_handle (table, obj, scm_ihashq, scm_sloppy_assq, 0);
220}
221
222
223SCM_PROC (s_hashq_create_handle_x, "hashq-create-handle!", 3, 0, 0, scm_hashq_create_handle_x);
224#ifdef __STDC__
225SCM
226scm_hashq_create_handle_x (SCM table, SCM obj, SCM init)
227#else
228SCM
229scm_hashq_create_handle_x (table, obj, init)
230 SCM table;
231 SCM obj;
232 SCM init;
233#endif
234{
235 return scm_hash_fn_create_handle_x (table, obj, init, scm_ihashq, scm_sloppy_assq, 0);
236}
237
238
239SCM_PROC (s_hashq_ref, "hashq-ref", 2, 1, 0, scm_hashq_ref);
240#ifdef __STDC__
241SCM
242scm_hashq_ref (SCM table, SCM obj, SCM dflt)
243#else
244SCM
245scm_hashq_ref (table, obj, dflt)
246 SCM table;
247 SCM obj;
248 SCM dflt;
249#endif
250{
251 if (dflt == SCM_UNDEFINED)
252 dflt = SCM_BOOL_F;
253 return scm_hash_fn_ref (table, obj, dflt, scm_ihashq, scm_sloppy_assq, 0);
254}
255
256
257
258SCM_PROC (s_hashq_set_x, "hashq-set!", 3, 0, 0, scm_hashq_set_x);
259#ifdef __STDC__
260SCM
261scm_hashq_set_x (SCM table, SCM obj, SCM val)
262#else
263SCM
264scm_hashq_set_x (table, obj, val)
265 SCM table;
266 SCM obj;
267 SCM val;
268#endif
269{
270 return scm_hash_fn_set_x (table, obj, val, scm_ihashq, scm_sloppy_assq, 0);
271}
272
273
274
275SCM_PROC (s_hashq_remove_x, "hashq-remove!", 2, 0, 0, scm_hashq_remove_x);
276#ifdef __STDC__
277SCM
278scm_hashq_remove_x (SCM table, SCM obj)
279#else
280SCM
281scm_hashq_remove_x (table, obj)
282 SCM table;
283 SCM obj;
284#endif
285{
286 return scm_hash_fn_remove_x (table, obj, scm_ihashq, scm_sloppy_assq, scm_delq_x, 0);
287}
288
289
290\f
291
292SCM_PROC (s_hashv_get_handle, "hashv-get-handle", 2, 0, 0, scm_hashv_get_handle);
293#ifdef __STDC__
294SCM
295scm_hashv_get_handle (SCM table, SCM obj)
296#else
297SCM
298scm_hashv_get_handle (table, obj)
299 SCM table;
300 SCM obj;
301#endif
302{
303 return scm_hash_fn_get_handle (table, obj, scm_ihashv, scm_sloppy_assv, 0);
304}
305
306
307SCM_PROC (s_hashv_create_handle_x, "hashv-create-handle!", 3, 0, 0, scm_hashv_create_handle_x);
308#ifdef __STDC__
309SCM
310scm_hashv_create_handle_x (SCM table, SCM obj, SCM init)
311#else
312SCM
313scm_hashv_create_handle_x (table, obj, init)
314 SCM table;
315 SCM obj;
316 SCM init;
317#endif
318{
319 return scm_hash_fn_create_handle_x (table, obj, init, scm_ihashv, scm_sloppy_assv, 0);
320}
321
322
323SCM_PROC (s_hashv_ref, "hashv-ref", 2, 1, 0, scm_hashv_ref);
324#ifdef __STDC__
325SCM
326scm_hashv_ref (SCM table, SCM obj, SCM dflt)
327#else
328SCM
329scm_hashv_ref (table, obj, dflt)
330 SCM table;
331 SCM obj;
332 SCM dflt;
333#endif
334{
335 if (dflt == SCM_UNDEFINED)
336 dflt = SCM_BOOL_F;
337 return scm_hash_fn_ref (table, obj, dflt, scm_ihashv, scm_sloppy_assv, 0);
338}
339
340
341
342SCM_PROC (s_hashv_set_x, "hashv-set!", 3, 0, 0, scm_hashv_set_x);
343#ifdef __STDC__
344SCM
345scm_hashv_set_x (SCM table, SCM obj, SCM val)
346#else
347SCM
348scm_hashv_set_x (table, obj, val)
349 SCM table;
350 SCM obj;
351 SCM val;
352#endif
353{
354 return scm_hash_fn_set_x (table, obj, val, scm_ihashv, scm_sloppy_assv, 0);
355}
356
357
358SCM_PROC (s_hashv_remove_x, "hashv-remove!", 2, 0, 0, scm_hashv_remove_x);
359#ifdef __STDC__
360SCM
361scm_hashv_remove_x (SCM table, SCM obj)
362#else
363SCM
364scm_hashv_remove_x (table, obj)
365 SCM table;
366 SCM obj;
367#endif
368{
369 return scm_hash_fn_remove_x (table, obj, scm_ihashv, scm_sloppy_assv, scm_delv_x, 0);
370}
371
372\f
373
374SCM_PROC (s_hash_get_handle, "hash-get-handle", 2, 0, 0, scm_hash_get_handle);
375#ifdef __STDC__
376SCM
377scm_hash_get_handle (SCM table, SCM obj)
378#else
379SCM
380scm_hash_get_handle (table, obj)
381 SCM table;
382 SCM obj;
383#endif
384{
385 return scm_hash_fn_get_handle (table, obj, scm_ihash, scm_sloppy_assoc, 0);
386}
387
388
389SCM_PROC (s_hash_create_handle_x, "hash-create-handle!", 3, 0, 0, scm_hash_create_handle_x);
390#ifdef __STDC__
391SCM
392scm_hash_create_handle_x (SCM table, SCM obj, SCM init)
393#else
394SCM
395scm_hash_create_handle_x (table, obj, init)
396 SCM table;
397 SCM obj;
398 SCM init;
399#endif
400{
401 return scm_hash_fn_create_handle_x (table, obj, init, scm_ihash, scm_sloppy_assoc, 0);
402}
403
404
405SCM_PROC (s_hash_ref, "hash-ref", 2, 1, 0, scm_hash_ref);
406#ifdef __STDC__
407SCM
408scm_hash_ref (SCM table, SCM obj, SCM dflt)
409#else
410SCM
411scm_hash_ref (table, obj, dflt)
412 SCM table;
413 SCM obj;
414 SCM dflt;
415#endif
416{
417 if (dflt == SCM_UNDEFINED)
418 dflt = SCM_BOOL_F;
419 return scm_hash_fn_ref (table, obj, dflt, scm_ihash, scm_sloppy_assoc, 0);
420}
421
422
423
424SCM_PROC (s_hash_set_x, "hash-set!", 3, 0, 0, scm_hash_set_x);
425#ifdef __STDC__
426SCM
427scm_hash_set_x (SCM table, SCM obj, SCM val)
428#else
429SCM
430scm_hash_set_x (table, obj, val)
431 SCM table;
432 SCM obj;
433 SCM val;
434#endif
435{
436 return scm_hash_fn_set_x (table, obj, val, scm_ihash, scm_sloppy_assoc, 0);
437}
438
439
440
441SCM_PROC (s_hash_remove_x, "hash-remove!", 2, 0, 0, scm_hash_remove_x);
442#ifdef __STDC__
443SCM
444scm_hash_remove_x (SCM table, SCM obj)
445#else
446SCM
447scm_hash_remove_x (table, obj)
448 SCM table;
449 SCM obj;
450#endif
451{
452 return scm_hash_fn_remove_x (table, obj, scm_ihash, scm_sloppy_assoc, scm_delete_x, 0);
453}
454
455\f
456
457
458struct scm_ihashx_closure
459{
460 SCM hash;
461 SCM assoc;
462 SCM delete;
463};
464
465
466#ifdef __STDC__
467static unsigned int
468scm_ihashx (SCM obj, unsigned int n, struct scm_ihashx_closure * closure)
469#else
470static unsigned int
471scm_ihashx (obj, n, closure)
472 SCM obj;
473 unsigned int n;
474 struct scm_ihashx_closure * closure;
475#endif
476{
477 SCM answer;
478 SCM_ALLOW_INTS;
479 answer = scm_apply (closure->hash,
480 scm_listify (obj, scm_ulong2num ((unsigned long)n), SCM_UNDEFINED),
481 SCM_EOL);
482 SCM_DEFER_INTS;
483 return SCM_INUM (answer);
484}
485
486
487#ifdef __STDC__
488static SCM
489scm_sloppy_assx (SCM obj, SCM alist, struct scm_ihashx_closure * closure)
490#else
491static SCM
492scm_sloppy_assx (obj, alist, closure)
493 SCM obj;
494 SCM alist;
495 struct scm_ihashx_closure * closure;
496#endif
497{
498 SCM answer;
499 SCM_ALLOW_INTS;
500 answer = scm_apply (closure->assoc,
501 scm_listify (obj, alist, SCM_UNDEFINED),
502 SCM_EOL);
503 SCM_DEFER_INTS;
504 return answer;
505}
506
507
508
509#ifdef __STDC__
510static SCM
511scm_delx_x (SCM obj, SCM alist, struct scm_ihashx_closure * closure)
512#else
513static SCM
514scm_delx_x (obj, alist, closure)
515 SCM obj;
516 SCM alist;
517 struct scm_ihashx_closure * closure;
518#endif
519{
520 SCM answer;
521 SCM_ALLOW_INTS;
522 answer = scm_apply (closure->delete,
523 scm_listify (obj, alist, SCM_UNDEFINED),
524 SCM_EOL);
525 SCM_DEFER_INTS;
526 return answer;
527}
528
529
530
531SCM_PROC (s_hashx_get_handle, "hashx-get-handle", 4, 0, 0, scm_hashx_get_handle);
532#ifdef __STDC__
533SCM
534scm_hashx_get_handle (SCM hash, SCM assoc, SCM table, SCM obj)
535#else
536SCM
537scm_hashx_get_handle (hash, assoc, table, obj)
538 SCM hash;
539 SCM assoc;
540 SCM table;
541 SCM obj;
542#endif
543{
544 struct scm_ihashx_closure closure;
545 closure.hash = hash;
546 closure.assoc = assoc;
547 return scm_hash_fn_get_handle (table, obj, scm_ihashx, scm_sloppy_assx, (void *)&closure);
548}
549
550
551SCM_PROC (s_hashx_create_handle_x, "hashx-create-handle!", 5, 0, 0, scm_hashx_create_handle_x);
552#ifdef __STDC__
553SCM
554scm_hashx_create_handle_x (SCM hash, SCM assoc, SCM table, SCM obj, SCM init)
555#else
556SCM
557scm_hashx_create_handle_x (hash, assoc, table, obj, init)
558 SCM hash;
559 SCM assoc;
560 SCM table;
561 SCM obj;
562 SCM init;
563#endif
564{
565 struct scm_ihashx_closure closure;
566 closure.hash = hash;
567 closure.assoc = assoc;
568 return scm_hash_fn_create_handle_x (table, obj, init, scm_ihashx, scm_sloppy_assx, (void *)&closure);
569}
570
571
572
573SCM_PROC (s_hashx_ref, "hashx-ref", 4, 1, 0, scm_hashx_ref);
574#ifdef __STDC__
575SCM
576scm_hashx_ref (SCM hash, SCM assoc, SCM table, SCM obj, SCM dflt)
577#else
578SCM
579scm_hashx_ref (hash, assoc, table, obj, dflt)
580 SCM hash;
581 SCM assoc;
582 SCM table;
583 SCM obj;
584 SCM dflt;
585#endif
586{
587 struct scm_ihashx_closure closure;
588 if (dflt == SCM_UNDEFINED)
589 dflt = SCM_BOOL_F;
590 closure.hash = hash;
591 closure.assoc = assoc;
592 return scm_hash_fn_ref (table, obj, dflt, scm_ihashx, scm_sloppy_assx, (void *)&closure);
593}
594
595
596
597
598SCM_PROC (s_hashx_set_x, "hashx-set!", 5, 0, 0, scm_hashx_set_x);
599#ifdef __STDC__
600SCM
601scm_hashx_set_x (SCM hash, SCM assoc, SCM table, SCM obj, SCM val)
602#else
603SCM
604scm_hashx_set_x (hash, assoc, table, obj, val)
605 SCM hash;
606 SCM assoc;
607 SCM table;
608 SCM obj;
609 SCM val;
610#endif
611{
612 struct scm_ihashx_closure closure;
613 closure.hash = hash;
614 closure.assoc = assoc;
615 return scm_hash_fn_set_x (table, obj, val, scm_ihashx, scm_sloppy_assx, (void *)&closure);
616}
617
618
619#ifdef __STDC__
620SCM
621scm_hashx_remove_x (SCM hash, SCM assoc, SCM delete, SCM table, SCM obj)
622#else
623SCM
624scm_hashx_remove_x (hash, assoc, delete, table, obj)
625 SCM hash;
626 SCM assoc;
627 SCM delete;
628 SCM table;
629 SCM obj;
630#endif
631{
632 struct scm_ihashx_closure closure;
633 closure.hash = hash;
634 closure.assoc = assoc;
635 closure.delete = delete;
636 return scm_hash_fn_remove_x (table, obj, scm_ihashx, scm_sloppy_assx, scm_delx_x, 0);
637}
638
639\f
640
641#ifdef __STDC__
642void
643scm_init_hashtab (void)
644#else
645void
646scm_init_hashtab ()
647#endif
648{
649#include "hashtab.x"
650}
651