/* 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 */