/* Copyright 1989, 1990 by James Aspnes, David Applegate, and Bennet Yee */
/* See the file COPYING for distribution information */
#ifndef _ASSOC_H
#define _ASSOC_H
#include "config.h"
typedef datum *alist;
#define empty_alist() (0)
#define isempty(a) ((a) == 0)
#define free_alist(x) (free((void *) x))
#define NOTHING (0)
/* returns 1 if key is found, 0 otherwise */
/* If key is found, the value is stored in *value unless value = NULL */
extern int assoc (alist, datum key, datum * value /* RETVAL */ );
/* searches for particular key, value pair */
extern int alist_member (alist, datum key, datum value);
extern alist add_assoc (alist, datum key, datum value);
extern alist del_assoc (alist, datum key, datum value);
extern alist del_assocs (alist, datum key);
extern alist set_assoc (alist, datum key, datum value);
extern alist copy_alist (alist);
#define hash_range(range, key) ((unsigned long) 3 * (key) % (range))
#define next_probe(range, p) (((p) ? (p) : (range)) - 1)
/* these are not safe if the alist is empty */
#define alist_size(a) ((a)[0])
#define alist_count(a) ((a)[1])
#define alist_key(a, i) ((a)[((i) << 1) + 2])
#define alist_value(a, i) ((a)[((i) << 1) + 3])
#define FOREACH(alist, keyvar, valvar) \
{ \
unsigned long _FOREACH_p; \
if(alist) \
for(_FOREACH_p = 0; _FOREACH_p < alist_size(alist); _FOREACH_p++) { \
if((keyvar = alist_key(alist, _FOREACH_p)) != NOTHING) { \
valvar = alist_value(alist, _FOREACH_p);
#define FOREACH_MATCH(alist, key, valvar) \
{ \
unsigned long _FOREACH_p;\
if(alist) \
for(_FOREACH_p = hash_range(alist_size(alist), (key)); \
alist_key(alist, _FOREACH_p) != NOTHING; \
_FOREACH_p = next_probe(alist_size(alist), _FOREACH_p)) { \
if(alist_key(alist, _FOREACH_p) == (key)) { \
valvar = alist_value(alist, _FOREACH_p);
#define END_FOREACH }}}
/* "re-entrant FOREACH" */
typedef struct {
datum pos;
datum key;
} alist_iterator;
extern datum alist_first (alist a, alist_iterator * iter, datum * value);
extern datum alist_next (alist a, alist_iterator * iter, datum * value);
/* return 1 if another match exists */
extern int alist_first_match (alist a, alist_iterator * iter, datum * value,
datum key);
extern int alist_next_match (alist a, alist_iterator * iter, datum * value);
#endif /* _ASSOC_H */