/* Copyright (c) 1993 Stephen F. White */ #include "cool.h" #include "proto.h" /* * map.c - functions for manipulating mappings (associative arrays) * * All functions except map_copy() "eat" their arguments. That is, the * caller should bump the refcount if necessary. */ void map_free (Map * map) { MapPair *pair, *pnext; int i; if (!map) return; if (!--map->ref) { for (i = 0; i < map->size; i++) { for (pair = map->table[i]; pair; pair = pnext) { var_free (pair->from); var_free (pair->to); pnext = pair->next; FREE (pair); } } FREE (map); } } Map *map_copy (Map * map) { Map *new = map_new (map->num); int i; MapPair *pair; for (i = 0; i < map->size; i++) { for (pair = map->table[i]; pair; pair = pair->next) { map_add (new, var_dup (pair->from), var_dup (pair->to)); } } return new; } int map_find (Map * map, Var key, Var * returnval) { int hval = hash_var (key) % map->size; MapPair *pair; if (!map || !returnval) { return -1; } for (pair = map->table[hval]; pair; pair = pair->next) { if (var_eq (key, pair->from)) { *returnval = pair->to; return 0; } } return -1; } Map *map_add (Map * map, Var key, Var value) { int hval = hash_var (key) % map->size; MapPair *pair, *prev; Map *new; if (map->ref > 1) { /* copy old map to new map */ new = map_copy (map); map->ref--; map = new; } for (prev = pair = map->table[hval]; pair; prev = pair, pair = pair->next) { if (var_eq (key, pair->from)) { var_free (pair->to); pair->to = value; var_free (key); return map; } } pair = MALLOC (MapPair, 1); pair->from = key; pair->to = value; pair->next = 0; if (prev) { prev->next = pair; } else { map->table[hval] = pair; } map->num++; return map; } /*********** * map_keys * By Robin Powell * * Return a list of all the keys used by a mapping, used in op_for. ***********/ List * map_keys(Map *map) { List *new = list_new(0); int i; MapPair *pair; for (i = 0; i < map->size; i++) { for (pair = map->table[i]; pair; pair = pair->next) { new = list_append(new, var_dup(pair->from), 0 ); } } return new; }