Remove "face-lift" comment.
[bpt/guile.git] / libguile / alist.c
CommitLineData
e282f286 1/* Copyright (C) 1995, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
0f2d19dd
JB
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
82892bed
JB
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
0f2d19dd
JB
17 *
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
20 *
21 * The exception is that, if you link the GUILE library with other files
22 * to produce an executable, this does not by itself cause the
23 * resulting executable to be covered by the GNU General Public License.
24 * Your use of that executable is in no way restricted on account of
25 * linking the GUILE library code into it.
26 *
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
29 *
30 * This exception applies only to the code released by the
31 * Free Software Foundation under the name GUILE. If you copy
32 * code from other Free Software Foundation releases into a copy of
33 * GUILE, as the General Public License permits, the exception does
34 * not apply to the code that you add in this way. To avoid misleading
35 * anyone as to the status of such modified files, you must delete
36 * this exception notice from them.
37 *
38 * If you write modifications of your own for GUILE, it is your choice
39 * whether to permit this exception to apply to your modifications.
82892bed 40 * If you do not wish that, delete this exception notice. */
1bbd0b84 41
1bbd0b84 42
0f2d19dd 43\f
a0599745
MD
44#include "libguile/_scm.h"
45#include "libguile/eq.h"
46#include "libguile/list.h"
20e6290e 47
a0599745
MD
48#include "libguile/validate.h"
49#include "libguile/alist.h"
0f2d19dd
JB
50
51\f
52
3b3b36dd 53SCM_DEFINE (scm_acons, "acons", 3, 0, 0,
0b5f3f34 54 (SCM key, SCM value, SCM alist),
b380b885
MD
55 "Adds a new key-value pair to @var{alist}. A new pair is\n"
56 "created whose car is @var{key} and whose cdr is @var{value}, and the\n"
57 "pair is consed onto @var{alist}, and the new list is returned. This\n"
58 "function is @emph{not} destructive; @var{alist} is not modified.")
1bbd0b84 59#define FUNC_NAME s_scm_acons
0f2d19dd 60{
0b5f3f34
GB
61 SCM pair;
62 SCM head;
63
64 SCM_NEWCELL (pair);
665aeda3
DH
65 SCM_SET_CELL_OBJECT_0 (pair, key);
66 SCM_SET_CELL_OBJECT_1 (pair, value);
0b5f3f34
GB
67
68 SCM_NEWCELL (head);
665aeda3
DH
69 SCM_SET_CELL_OBJECT_0 (head, pair);
70 SCM_SET_CELL_OBJECT_1 (head, alist);
0b5f3f34
GB
71
72 return head;
0f2d19dd 73}
1bbd0b84 74#undef FUNC_NAME
0f2d19dd
JB
75
76\f
77
a1ec6916 78SCM_DEFINE (scm_sloppy_assq, "sloppy-assq", 2, 0, 0,
0b5f3f34 79 (SCM key, SCM alist),
b380b885
MD
80 "Behaves like @code{assq} but does not do any error checking.\n"
81 "Recommended only for use in Guile internals.")
1bbd0b84 82#define FUNC_NAME s_scm_sloppy_assq
0f2d19dd 83{
0c95b57d 84 for (; SCM_CONSP (alist); alist = SCM_CDR (alist))
0f2d19dd 85 {
2de257bd 86 SCM tmp = SCM_CAR (alist);
fbd485ba 87 if (SCM_CONSP (tmp) && SCM_EQ_P (SCM_CAR (tmp), key))
cf18adf0 88 return tmp;
0f2d19dd
JB
89 }
90 return SCM_BOOL_F;
91}
1bbd0b84 92#undef FUNC_NAME
0f2d19dd
JB
93
94
95
a1ec6916 96SCM_DEFINE (scm_sloppy_assv, "sloppy-assv", 2, 0, 0,
0b5f3f34 97 (SCM key, SCM alist),
b380b885
MD
98 "Behaves like @code{assv} but does not do any error checking.\n"
99 "Recommended only for use in Guile internals.")
1bbd0b84 100#define FUNC_NAME s_scm_sloppy_assv
0f2d19dd 101{
0c95b57d 102 for (; SCM_CONSP (alist); alist = SCM_CDR (alist))
0f2d19dd 103 {
2de257bd 104 SCM tmp = SCM_CAR (alist);
0b5f3f34
GB
105 if (SCM_CONSP (tmp)
106 && SCM_NFALSEP (scm_eqv_p (SCM_CAR (tmp), key)))
cf18adf0 107 return tmp;
0f2d19dd
JB
108 }
109 return SCM_BOOL_F;
110}
1bbd0b84 111#undef FUNC_NAME
0f2d19dd
JB
112
113
a1ec6916 114SCM_DEFINE (scm_sloppy_assoc, "sloppy-assoc", 2, 0, 0,
0b5f3f34 115 (SCM key, SCM alist),
b380b885
MD
116 "Behaves like @code{assoc} but does not do any error checking.\n"
117 "Recommended only for use in Guile internals.")
1bbd0b84 118#define FUNC_NAME s_scm_sloppy_assoc
0f2d19dd 119{
0c95b57d 120 for (; SCM_CONSP (alist); alist = SCM_CDR (alist))
0f2d19dd 121 {
2de257bd 122 SCM tmp = SCM_CAR (alist);
0b5f3f34
GB
123 if (SCM_CONSP (tmp)
124 && SCM_NFALSEP (scm_equal_p (SCM_CAR (tmp), key)))
cf18adf0 125 return tmp;
0f2d19dd
JB
126 }
127 return SCM_BOOL_F;
128}
1bbd0b84 129#undef FUNC_NAME
0f2d19dd
JB
130
131
132\f
133
3b3b36dd 134SCM_DEFINE (scm_assq, "assq", 2, 0, 0,
0b5f3f34 135 (SCM key, SCM alist),
b380b885
MD
136 "@deffnx primitive assv key alist\n"
137 "@deffnx primitive assoc key alist\n"
138 "Fetches the entry in @var{alist} that is associated with @var{key}. To\n"
139 "decide whether the argument @var{key} matches a particular entry in\n"
140 "@var{alist}, @code{assq} compares keys with @code{eq?}, @code{assv}\n"
141 "uses @code{eqv?} and @code{assoc} uses @code{equal?}. If @var{key}\n"
142 "cannot be found in @var{alist} (according to whichever equality\n"
143 "predicate is in use), then @code{#f} is returned. These functions\n"
144 "return the entire alist entry found (i.e. both the key and the value).")
1bbd0b84 145#define FUNC_NAME s_scm_assq
0f2d19dd 146{
1aa621a3
MD
147 SCM ls = alist;
148 for (; SCM_CONSP (ls); ls = SCM_CDR (ls))
e1385ffc 149 {
1aa621a3
MD
150 SCM tmp = SCM_CAR (ls);
151 SCM_ASSERT_TYPE (SCM_CONSP (tmp), alist, SCM_ARG2, FUNC_NAME,
152 "association list");
fbd485ba 153 if (SCM_EQ_P (SCM_CAR (tmp), key))
2de257bd 154 return tmp;
e1385ffc 155 }
1aa621a3
MD
156 SCM_ASSERT_TYPE (SCM_NULLP (ls), alist, SCM_ARG2, FUNC_NAME,
157 "association list");
1bbd0b84 158 return SCM_BOOL_F;
0f2d19dd 159}
1bbd0b84 160#undef FUNC_NAME
0f2d19dd
JB
161
162
3b3b36dd 163SCM_DEFINE (scm_assv, "assv", 2, 0, 0,
0b5f3f34 164 (SCM key, SCM alist),
b380b885 165 "Behaves like @code{assq} but uses @code{eqv?} for key comparison.")
1bbd0b84 166#define FUNC_NAME s_scm_assv
0f2d19dd 167{
1aa621a3
MD
168 SCM ls = alist;
169 for(; SCM_CONSP (ls); ls = SCM_CDR (ls))
e1385ffc 170 {
1aa621a3
MD
171 SCM tmp = SCM_CAR (ls);
172 SCM_ASSERT_TYPE (SCM_CONSP (tmp), alist, SCM_ARG2, FUNC_NAME,
173 "association list");
2de257bd
MD
174 if (SCM_NFALSEP (scm_eqv_p (SCM_CAR (tmp), key)))
175 return tmp;
e1385ffc 176 }
1aa621a3
MD
177 SCM_ASSERT_TYPE (SCM_NULLP (ls), alist, SCM_ARG2, FUNC_NAME,
178 "association list");
0f2d19dd
JB
179 return SCM_BOOL_F;
180}
1bbd0b84 181#undef FUNC_NAME
0f2d19dd
JB
182
183
3b3b36dd 184SCM_DEFINE (scm_assoc, "assoc", 2, 0, 0,
0b5f3f34 185 (SCM key, SCM alist),
b380b885 186 "Behaves like @code{assq} but uses @code{equal?} for key comparison.")
1bbd0b84 187#define FUNC_NAME s_scm_assoc
0f2d19dd 188{
1aa621a3
MD
189 SCM ls = alist;
190 for(; SCM_CONSP (ls); ls = SCM_CDR (ls))
e1385ffc 191 {
1aa621a3
MD
192 SCM tmp = SCM_CAR (ls);
193 SCM_ASSERT_TYPE (SCM_CONSP (tmp), alist, SCM_ARG2, FUNC_NAME,
194 "association list");
2de257bd
MD
195 if (SCM_NFALSEP (scm_equal_p (SCM_CAR (tmp), key)))
196 return tmp;
e1385ffc 197 }
1aa621a3
MD
198 SCM_ASSERT_TYPE (SCM_NULLP (ls), alist, SCM_ARG2, FUNC_NAME,
199 "association list");
1bbd0b84 200 return SCM_BOOL_F;
0f2d19dd 201}
1bbd0b84 202#undef FUNC_NAME
0f2d19dd
JB
203
204
205\f
206
d1ca2c64
DH
207/* Dirk:API2.0:: We should not return #f if the key was not found. In the
208 * current solution we can not distinguish between finding a (key . #f) pair
209 * and not finding the key at all.
210 *
211 * Possible alternative solutions:
212 * 1) Remove assq-ref from the API: assq is sufficient.
213 * 2) Signal an error (what error type?) if the key is not found.
214 * 3) provide an additional 'default' parameter.
215 * 3.1) The default parameter is mandatory.
216 * 3.2) The default parameter is optional, but if no default is given and
217 * the key is not found, signal an error (what error type?).
218 */
a1ec6916 219SCM_DEFINE (scm_assq_ref, "assq-ref", 2, 0, 0,
1bbd0b84 220 (SCM alist, SCM key),
b380b885
MD
221 "@deffnx primitive assv-ref alist key\n"
222 "@deffnx primitive assoc-ref alist key\n"
223 "Like @code{assq}, @code{assv} and @code{assoc}, except that only the\n"
224 "value associated with @var{key} in @var{alist} is returned. These\n"
225 "functions are equivalent to\n\n"
226 "@lisp\n"
227 "(let ((ent (@var{associator} @var{key} @var{alist})))\n"
228 " (and ent (cdr ent)))\n"
229 "@end lisp\n\n"
230 "where @var{associator} is one of @code{assq}, @code{assv} or @code{assoc}.")
1bbd0b84 231#define FUNC_NAME s_scm_assq_ref
0f2d19dd
JB
232{
233 SCM handle;
234
235 handle = scm_sloppy_assq (key, alist);
0c95b57d 236 if (SCM_CONSP (handle))
0f2d19dd
JB
237 {
238 return SCM_CDR (handle);
239 }
240 return SCM_BOOL_F;
241}
1bbd0b84 242#undef FUNC_NAME
0f2d19dd
JB
243
244
a1ec6916 245SCM_DEFINE (scm_assv_ref, "assv-ref", 2, 0, 0,
1bbd0b84 246 (SCM alist, SCM key),
b380b885 247 "Behaves like @code{assq-ref} but uses @code{eqv?} for key comparison.")
1bbd0b84 248#define FUNC_NAME s_scm_assv_ref
0f2d19dd
JB
249{
250 SCM handle;
251
252 handle = scm_sloppy_assv (key, alist);
0c95b57d 253 if (SCM_CONSP (handle))
0f2d19dd
JB
254 {
255 return SCM_CDR (handle);
256 }
257 return SCM_BOOL_F;
258}
1bbd0b84 259#undef FUNC_NAME
0f2d19dd
JB
260
261
a1ec6916 262SCM_DEFINE (scm_assoc_ref, "assoc-ref", 2, 0, 0,
1bbd0b84 263 (SCM alist, SCM key),
b380b885 264 "Behaves like @code{assq-ref} but uses @code{equal?} for key comparison.")
1bbd0b84 265#define FUNC_NAME s_scm_assoc_ref
0f2d19dd
JB
266{
267 SCM handle;
268
269 handle = scm_sloppy_assoc (key, alist);
0c95b57d 270 if (SCM_CONSP (handle))
0f2d19dd
JB
271 {
272 return SCM_CDR (handle);
273 }
274 return SCM_BOOL_F;
275}
1bbd0b84 276#undef FUNC_NAME
0f2d19dd
JB
277
278
279
280\f
281
282
a1ec6916 283SCM_DEFINE (scm_assq_set_x, "assq-set!", 3, 0, 0,
1bbd0b84 284 (SCM alist, SCM key, SCM val),
b380b885
MD
285 "@deffnx primitive assv-set! alist key value\n"
286 "@deffnx primitive assoc-set! alist key value\n"
287 "Reassociate @var{key} in @var{alist} with @var{value}: find any existing\n"
288 "@var{alist} entry for @var{key} and associate it with the new\n"
289 "@var{value}. If @var{alist} does not contain an entry for @var{key},\n"
290 "add a new one. Return the (possibly new) alist.\n\n"
291 "These functions do not attempt to verify the structure of @var{alist},\n"
292 "and so may cause unusual results if passed an object that is not an\n"
293 "association list.")
1bbd0b84 294#define FUNC_NAME s_scm_assq_set_x
0f2d19dd
JB
295{
296 SCM handle;
297
298 handle = scm_sloppy_assq (key, alist);
0c95b57d 299 if (SCM_CONSP (handle))
0f2d19dd
JB
300 {
301 SCM_SETCDR (handle, val);
302 return alist;
303 }
304 else
305 return scm_acons (key, val, alist);
306}
1bbd0b84 307#undef FUNC_NAME
0f2d19dd 308
a1ec6916 309SCM_DEFINE (scm_assv_set_x, "assv-set!", 3, 0, 0,
1bbd0b84 310 (SCM alist, SCM key, SCM val),
b380b885 311 "Behaves like @code{assq-set!} but uses @code{eqv?} for key comparison.")
1bbd0b84 312#define FUNC_NAME s_scm_assv_set_x
0f2d19dd
JB
313{
314 SCM handle;
315
316 handle = scm_sloppy_assv (key, alist);
0c95b57d 317 if (SCM_CONSP (handle))
0f2d19dd
JB
318 {
319 SCM_SETCDR (handle, val);
320 return alist;
321 }
322 else
323 return scm_acons (key, val, alist);
324}
1bbd0b84 325#undef FUNC_NAME
0f2d19dd 326
a1ec6916 327SCM_DEFINE (scm_assoc_set_x, "assoc-set!", 3, 0, 0,
1bbd0b84 328 (SCM alist, SCM key, SCM val),
b380b885 329 "Behaves like @code{assq-set!} but uses @code{equal?} for key comparison.")
1bbd0b84 330#define FUNC_NAME s_scm_assoc_set_x
0f2d19dd
JB
331{
332 SCM handle;
333
334 handle = scm_sloppy_assoc (key, alist);
0c95b57d 335 if (SCM_CONSP (handle))
0f2d19dd
JB
336 {
337 SCM_SETCDR (handle, val);
338 return alist;
339 }
340 else
341 return scm_acons (key, val, alist);
342}
1bbd0b84 343#undef FUNC_NAME
0f2d19dd
JB
344
345
346\f
347
a1ec6916 348SCM_DEFINE (scm_assq_remove_x, "assq-remove!", 2, 0, 0,
1bbd0b84 349 (SCM alist, SCM key),
b380b885
MD
350 "@deffnx primitive assv-remove! alist key\n"
351 "@deffnx primitive assoc-remove! alist key\n"
623ada63 352 "Delete the first entry in @var{alist} associated with @var{key}, and return\n"
b380b885 353 "the resulting alist.")
1bbd0b84 354#define FUNC_NAME s_scm_assq_remove_x
0f2d19dd
JB
355{
356 SCM handle;
357
358 handle = scm_sloppy_assq (key, alist);
623ada63 359 if (SCM_CONSP (handle))
60e61f0a 360 alist = scm_delq1_x (handle, alist);
623ada63 361
5d253852 362 return alist;
0f2d19dd 363}
1bbd0b84 364#undef FUNC_NAME
0f2d19dd
JB
365
366
a1ec6916 367SCM_DEFINE (scm_assv_remove_x, "assv-remove!", 2, 0, 0,
1bbd0b84 368 (SCM alist, SCM key),
b380b885 369 "Behaves like @code{assq-remove!} but uses @code{eqv?} for key comparison.")
1bbd0b84 370#define FUNC_NAME s_scm_assv_remove_x
0f2d19dd
JB
371{
372 SCM handle;
373
374 handle = scm_sloppy_assv (key, alist);
623ada63 375 if (SCM_CONSP (handle))
60e61f0a 376 alist = scm_delq1_x (handle, alist);
623ada63 377
5d253852 378 return alist;
0f2d19dd 379}
1bbd0b84 380#undef FUNC_NAME
0f2d19dd
JB
381
382
a1ec6916 383SCM_DEFINE (scm_assoc_remove_x, "assoc-remove!", 2, 0, 0,
1bbd0b84 384 (SCM alist, SCM key),
b380b885 385 "Behaves like @code{assq-remove!} but uses @code{equal?} for key comparison.")
1bbd0b84 386#define FUNC_NAME s_scm_assoc_remove_x
0f2d19dd
JB
387{
388 SCM handle;
389
390 handle = scm_sloppy_assoc (key, alist);
623ada63 391 if (SCM_CONSP (handle))
60e61f0a 392 alist = scm_delq1_x (handle, alist);
623ada63 393
5d253852 394 return alist;
0f2d19dd 395}
1bbd0b84 396#undef FUNC_NAME
0f2d19dd
JB
397
398
399\f
400
401
1cc91f1b 402
0f2d19dd
JB
403void
404scm_init_alist ()
0f2d19dd 405{
8dc9439f 406#ifndef SCM_MAGIC_SNARFER
a0599745 407#include "libguile/alist.x"
8dc9439f 408#endif
0f2d19dd
JB
409}
410
89e00824
ML
411
412/*
413 Local Variables:
414 c-file-style: "gnu"
415 End:
416*/