Merge pull request #457 from vivien/text-variable
[tig.git] / src / map.c
blob710083dfb95a28f0ae7fb6ba47a8b2344b2c4016
1 /* Copyright (c) 2006-2015 Jonas Fonseca <jonas.fonseca@gmail.com>
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU General Public License as
5 * published by the Free Software Foundation; either version 2 of
6 * the License, or (at your option) any later version.
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.
14 #include "tig/tig.h"
15 #include "tig/map.h"
17 #include "compat/hashtab.h"
20 string_map_hash_fn string_map_hash_helper = htab_hash_string;
22 static int
23 string_map_equal(const void *element, const void *map_)
25 struct string_map *map = (struct string_map *) map_;
26 const char *key = map->key_fn(element);
28 return !strcmp(key, map->key);
31 void *
32 string_map_get(struct string_map *map, const char *key)
34 if (map->htab) {
35 map->key = key;
36 return htab_find_with_hash(map->htab, map, htab_hash_string(key));
39 return NULL;
42 void **
43 string_map_get_at(struct string_map *map, const char *key)
45 if (map->htab) {
46 map->key = key;
47 return htab_find_slot_with_hash(map->htab, map, htab_hash_string(key), NO_INSERT);
50 return NULL;
53 void **
54 string_map_put_to(struct string_map *map, const char *key)
56 if (!map->htab) {
57 map->htab = htab_create_alloc(16, map->hash_fn, string_map_equal, NULL, calloc, free);
58 if (!map->htab)
59 return NULL;
62 map->key = key;
63 return htab_find_slot_with_hash(map->htab, map, htab_hash_string(key), INSERT);
66 void *
67 string_map_put(struct string_map *map, const char *key, void *value)
69 void **slot = string_map_put_to(map, key);
71 if (!slot)
72 return NULL;
74 *slot = value;
75 return value;
78 void *
79 string_map_remove(struct string_map *map, const char *key)
81 void *value = NULL;
82 void **slot = string_map_get_at(map, key);
84 if (slot) {
85 value = *slot;
86 htab_clear_slot(map->htab, slot);
89 return value;
92 void
93 string_map_clear(struct string_map *map)
95 if (map->htab)
96 htab_empty(map->htab);
99 struct string_map_iterator {
100 string_map_iterator_fn fn;
101 void *data;
104 static int
105 string_map_iterate(void **slot, void *data)
107 struct string_map_iterator *iterator = data;
109 return iterator->fn(iterator->data, *slot);
112 void
113 string_map_foreach(struct string_map *map, string_map_iterator_fn fn, void *data)
115 if (map->htab) {
116 struct string_map_iterator iterator = { fn, data };
118 htab_traverse_noresize(map->htab, string_map_iterate, &iterator);
122 /* vim: set ts=8 sw=8 noexpandtab: */