2011-04-12 Diego Novillo <dnovillo@google.com>
[official-gcc.git] / gcc / strstrmap.c
blobab2b48d9a9e20cebc701ac8c0107e1e9a3c9074d
1 /* A string to string mapping.
3 Copyright (C) 2011 Free Software Foundation, Inc.
4 Contributed by Lawrence Crowl <crowl@google.com>.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
13 GCC is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
26 #include "libiberty.h"
27 #include "hashtab.h"
29 #include "strstrmap.h"
31 /* The hash table slot type. */
33 typedef struct strstrhashslot_d
35 const char *key;
36 const char *val;
37 } strstrhashslot_t;
39 /* Returns a hash code for the slot v.
40 Function type is typedef hashval_t (*htab_hash) (const void *); */
42 static hashval_t
43 strstrhashslot_hash (const void *v)
45 const strstrhashslot_t *s = (const strstrhashslot_t *) v;
46 return htab_hash_string (s->key);
49 /* Compares two slots, V1 and V2, for equality.
50 Function type is typedef int (*htab_eq) (const void *, const void *); */
52 static int
53 strstrhashslot_eq (const void *v1, const void *v2)
55 const strstrhashslot_t *s1 = (const strstrhashslot_t *) v1;
56 const strstrhashslot_t *s2 = (const strstrhashslot_t *) v2;
57 return strcmp (s1->key, s2->key) == 0;
60 /* Free the slot V. */
62 static void
63 strstrhashslot_free (void *v)
65 strstrhashslot_t *s = (strstrhashslot_t *) v;
66 free (CONST_CAST (void *, (const void *) s->key));
67 free (CONST_CAST (void *, (const void *) s->val));
68 free (v);
71 /* The type for the hash table itself. */
73 struct strstrmap_d
75 htab_t tab;
78 /* Create a hash table. */
80 strstrmap_t*
81 strstrmap_create (void)
83 strstrmap_t *tbl;
84 htab_t tab;
85 tbl = XCNEW (strstrmap_t);
86 gcc_assert (tbl != NULL);
87 tab = htab_create (37, strstrhashslot_hash,
88 strstrhashslot_eq, strstrhashslot_free);
89 gcc_assert (tab != NULL);
90 tbl->tab = tab;
91 return tbl;
94 /* Destroy the hash table TBL. */
96 void
97 strstrmap_destroy (strstrmap_t *tbl)
99 htab_delete (tbl->tab);
100 free (tbl);
103 /* Insert a mapping from KEY to VAL into hash table TBL.
104 All parameters must not be NULL.
105 If the KEY is new, the insert returns NULL.
106 If the KEY is not new, the insert returns the old VAL,
107 which has been replaced.
108 The caller owns any storage that the return value points to. */
110 const char*
111 strstrmap_insert (strstrmap_t *tbl, const char *key, const char *val)
113 strstrhashslot_t query;
114 strstrhashslot_t **spot;
115 const char* result;
117 gcc_assert (tbl != NULL);
118 gcc_assert (key != NULL);
119 gcc_assert (val != NULL);
121 query.key = key;
122 query.val = val;
123 spot = (strstrhashslot_t **) htab_find_slot (tbl->tab, &query, INSERT);
125 if (*spot == NULL)
127 /* We found no instance of key in the table. */
128 strstrhashslot_t *entry
129 = (strstrhashslot_t *) xmalloc (sizeof (strstrhashslot_t));
130 entry->key = xstrdup (key);
131 entry->val = xstrdup (val);
132 *spot = entry;
133 result = NULL;
135 else
137 /* We found an instance of key already in the table. */
138 strstrhashslot_t *entry = (strstrhashslot_t *)*spot;
139 result = entry->val;
140 entry->val = xstrdup (val);
143 return result;
146 /* Lookup a mapping for KEY in hash table TBL.
147 All parameters must not be NULL.
148 If the KEY is new, the insert returns NULL.
149 If the KEY is not new, the insert returns the old VAL,
150 which has been replaced.
151 The caller does NOT owns any storage that the return value points to. */
153 const char*
154 strstrmap_lookup (strstrmap_t* tbl, const char* key)
156 strstrhashslot_t query;
157 strstrhashslot_t **spot;
158 const char* result;
160 gcc_assert (tbl != NULL);
161 gcc_assert (key != NULL);
163 query.key = key;
164 spot = (strstrhashslot_t **) htab_find_slot (tbl->tab, &query, NO_INSERT);
166 if (spot == NULL)
168 /* We found no instance of key in the table. */
169 result = NULL;
171 else
173 /* We found an instance of key in the table. */
174 strstrhashslot_t *entry = (strstrhashslot_t *)*spot;
175 gcc_assert (entry != NULL);
176 result = entry->val;
179 return result;