2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief Hash table to store names.
23 * @author Goetz Lindenmaier
37 #ifdef FIRM_ENABLE_WCHAR
45 /* for debugging only, not the real implementation */
47 char reserved[sizeof(unsigned) + sizeof(size_t)];
51 /** The current ident module implementation. */
52 static ident_if_t impl;
55 * Stores a string in the ident module and returns a handle for the string.
57 * @param handle the handle for the set
58 * @param str the string which shall be stored
59 * @param len length of str in bytes
61 * @return id - a handle for the generated ident
63 * Default implementation using libfirm sets.
65 static ident *set_new_id_from_chars(void *handle, const char *str, int len)
69 /* GL: Who added this assert? And why? */
71 return (ident *)set_hinsert0(id_set, str, len, ID_HASH(unsigned char, str, len));
75 * Stores a string in the ident module and returns a handle for the string.
77 * @param handle the handle for the set
78 * @param str the string (or whatever) which shall be stored
80 * Default implementation using libfirm sets.
82 static ident *set_new_id_from_str(void *handle, const char *str)
85 return (ident *)set_new_id_from_chars(handle, str, strlen(str));
89 * Returns a string represented by an ident.
91 * @param handle the handle for the set
94 * Default implementation using libfirm sets.
96 static const char *set_get_id_str(void *handle, ident *id)
98 struct set_entry *entry = (struct set_entry *)id;
101 return (const char *)entry->dptr;
105 * Returns the length of the string represented by an ident.
107 * @param handle the handle for the set
108 * @param id the ident
110 * Default implementation using libfirm sets.
112 static int set_get_id_strlen(void *handle, ident *id)
114 struct set_entry *entry = (struct set_entry *)id;
121 * Default implementation using libfirm sets.
123 void set_finish_ident(void *handle) {
124 set *id_set = handle;
130 * Default implementation if no new_id_from_str() is provided.
132 static ident *def_new_id_from_str(void *handle, const char *str)
134 return impl.new_id_from_chars(handle, str, strlen(str));
138 * Default implementation if no get_id_strlen() is provided.
140 static int def_get_id_strlen(void *handle, ident *id)
142 return strlen(impl.get_id_str(handle, id));
145 #ifdef FIRM_ENABLE_WCHAR
147 * Stores a wide character string in the ident module and returns a
148 * handle for the string.
150 * @param handle the handle for the set
151 * @param wstr the wide character string which shall be stored
152 * @param len length of wstr
154 * @return id - a handle for the generated ident
156 * Default implementation using libfirm sets.
158 static ident *set_new_id_from_wchars(void *handle, const wchar_t *wstr, int len)
160 set *id_set = handle;
163 /* can't use hinsert0 here, so copy and add a 0 */
164 tmp = alloca((len + 1) * sizeof(*tmp));
165 memcpy(tmp, wstr, len * sizeof(*tmp));
168 return (ident *)set_hinsert(id_set, tmp, (len + 1) * sizeof(wchar_t), ID_HASH(wchar_t, tmp, len));
172 * Stores a wide character string in the ident module and
173 * returns a handle for the string.
175 * @param handle the handle for the set
176 * @param wstr the wide character string which shall be stored
178 * Default implementation using libfirm sets.
180 static ident *set_new_id_from_wcs(void *handle, const wchar_t *wstr)
183 return (ident *)set_new_id_from_wchars(handle, wstr, wcslen(wstr));
187 * Returns a wide character string represented by an ident.
189 * @param handle the handle for the set
190 * @param id the ident
192 * Default implementation using libfirm sets.
194 static const wchar_t *set_get_id_wcs(void *handle, ident *id)
196 struct set_entry *entry = (struct set_entry *)id;
198 return (const wchar_t *)entry->dptr;
202 * Returns the length of the string represented by an ident.
204 * @param handle the handle for the set
205 * @param id the ident
207 * Default implementation using libfirm sets.
209 static int set_get_id_wcslen(void *handle, ident *id)
211 struct set_entry *entry = (struct set_entry *)id;
213 /* len + \0 is stored for wchar_t */
214 return entry->size / sizeof(wchar_t) - 1;
218 * Default implementation if no new_id_from_wcs() is provided.
220 static ident *def_new_id_from_wcs(void *handle, const wchar_t *wstr)
222 return impl.new_id_from_wchars(handle, wstr, wcslen(wstr));
226 * Default implementation if no new_id_from_wchars() is provided.
228 static ident *def_new_id_from_wchars(void *handle, const wchar_t *wstr, int len)
230 return impl.new_id_from_chars(handle, (const char *)wstr, (len + 1) * sizeof(wchar_t));
234 * Default implementation if no get_id_wcs() is provided.
236 static const wchar_t *def_get_id_wcs(void *handle, ident *id)
238 return (const wchar_t *)impl.get_id_str(handle, id);
242 * Default implementation if no get_id_wcslen() is provided.
244 static int def_get_id_wcslen(void *handle, ident *id)
246 return wcslen(impl.get_id_wcs(handle, id));
248 #endif /* FIRM_ENABLE_WCHAR */
250 /* Initialize the ident module. */
251 void init_ident(ident_if_t *id_if, int initial_n_idents)
254 memcpy(&impl, id_if, sizeof(impl));
256 if (! impl.new_id_from_str)
257 impl.new_id_from_str = def_new_id_from_str;
258 if (! impl.get_id_strlen)
259 impl.get_id_strlen = def_get_id_strlen;
261 #ifdef FIRM_ENABLE_WCHAR
262 if (! impl.new_id_from_wcs)
263 impl.new_id_from_wcs = def_new_id_from_wcs;
264 if (! impl.new_id_from_wchars)
265 impl.new_id_from_wchars = def_new_id_from_wchars;
266 if (! impl.get_id_wcs)
267 impl.get_id_wcs = def_get_id_wcs;
268 if (! impl.get_id_wcslen)
269 impl.get_id_wcslen = def_get_id_wcslen;
270 #endif /* FIRM_ENABLE_WCHAR */
273 impl.new_id_from_str = set_new_id_from_str;
274 impl.new_id_from_chars = set_new_id_from_chars;
275 impl.get_id_str = set_get_id_str;
276 impl.get_id_strlen = set_get_id_strlen;
277 impl.finish_ident = set_finish_ident;
278 #ifdef FIRM_ENABLE_WCHAR
279 impl.new_id_from_wcs = set_new_id_from_wcs;
280 impl.new_id_from_wchars = set_new_id_from_wchars;
281 impl.get_id_wcs = set_get_id_wcs;
282 impl.get_id_wcslen = set_get_id_wcslen;
283 #endif /* FIRM_ENABLE_WCHAR */
285 /* it's ok to use memcmp here, we check only strings */
286 impl.handle = new_set(memcmp, initial_n_idents);
290 ident *new_id_from_str(const char *str)
293 return impl.new_id_from_str(impl.handle, str);
296 ident *new_id_from_chars(const char *str, int len)
299 return impl.new_id_from_chars(impl.handle, str, len);
302 const char *get_id_str(ident *id)
304 return impl.get_id_str(impl.handle, id);
307 int get_id_strlen(ident *id)
309 return impl.get_id_strlen(impl.handle, id);
312 void finish_ident(void) {
313 if (impl.finish_ident)
314 impl.finish_ident(impl.handle);
317 int id_is_prefix(ident *prefix, ident *id)
319 if (get_id_strlen(prefix) > get_id_strlen(id)) return 0;
320 return 0 == memcmp(get_id_str(prefix), get_id_str(id), get_id_strlen(prefix));
323 int id_is_suffix(ident *suffix, ident *id)
325 int suflen = get_id_strlen(suffix);
326 int idlen = get_id_strlen(id);
329 if (suflen > idlen) return 0;
331 part = get_id_str(id);
332 part = part + (idlen - suflen);
334 return 0 == memcmp(get_id_str(suffix), part, suflen);
337 int id_contains_char(ident *id, char c)
339 return strchr(get_id_str(id), c) != NULL;
342 ident *id_unique(const char *tag)
344 static unsigned unique_id = 0;
347 snprintf(buf, sizeof(buf), tag, unique_id);
349 return new_id_from_str(buf);
352 #ifdef FIRM_ENABLE_WCHAR
354 ident *new_id_from_wcs (const wchar_t *str)
357 return impl.new_id_from_wcs(impl.handle, str);
360 ident *new_id_from_wchars (const wchar_t *str, int len)
363 return impl.new_id_from_wchars(impl.handle, str, len);
366 const wchar_t *get_id_wcs(ident *id)
368 return impl.get_id_wcs(impl.handle, id);
371 int get_id_wcslen(ident *id)
373 return impl.get_id_wcslen(impl.handle, id);
376 int id_contains_wchar (ident *id, wchar_t c)
378 return wcschr(get_id_wcs(id), c) != NULL;
381 #endif /* FIRM_ENABLE_WCHAR */