2 * Copyright (C) 1995-2007 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 * File name: ir/common/ident.c
23 * Purpose: Hash table to store names.
24 * Author: Goetz Lindenmaier
28 * Copyright: (c) 1999-2003 Universität Karlsruhe
41 #ifdef FIRM_ENABLE_WCHAR
49 /* for debugging only, not the real implementation */
51 char reserved[sizeof(unsigned) + sizeof(size_t)];
55 /** The current ident module implementation. */
56 static ident_if_t impl;
59 * Stores a string in the ident module and returns a handle for the string.
61 * @param handle the handle for the set
62 * @param str the string which shall be stored
63 * @param len length of str in bytes
65 * @return id - a handle for the generated ident
67 * Default implementation using libfirm sets.
69 static ident *set_new_id_from_chars(void *handle, const char *str, int len)
73 /* GL: Who added this assert? And why? */
75 return (ident *)set_hinsert0(id_set, str, len, ID_HASH(unsigned char, str, len));
79 * Stores a string in the ident module and returns a handle for the string.
81 * @param handle the handle for the set
82 * @param str the string (or whatever) which shall be stored
84 * Default implementation using libfirm sets.
86 static ident *set_new_id_from_str(void *handle, const char *str)
89 return (ident *)set_new_id_from_chars(handle, str, strlen(str));
93 * Returns a string represented by an ident.
95 * @param handle the handle for the set
98 * Default implementation using libfirm sets.
100 static const char *set_get_id_str(void *handle, ident *id)
102 struct set_entry *entry = (struct set_entry *)id;
104 return (const char *)entry->dptr;
108 * Returns the length of the string represented by an ident.
110 * @param handle the handle for the set
111 * @param id the ident
113 * Default implementation using libfirm sets.
115 static int set_get_id_strlen(void *handle, ident *id)
117 struct set_entry *entry = (struct set_entry *)id;
123 * Default implementation using libfirm sets.
125 void set_finish_ident(void *handle) {
126 set *id_set = handle;
132 * Default implementation if no new_id_from_str() is provided.
134 static ident *def_new_id_from_str(void *handle, const char *str)
136 return impl.new_id_from_chars(handle, str, strlen(str));
140 * Default implementation if no get_id_strlen() is provided.
142 static int def_get_id_strlen(void *handle, ident *id)
144 return strlen(impl.get_id_str(handle, id));
147 #ifdef FIRM_ENABLE_WCHAR
149 * Stores a wide character string in the ident module and returns a
150 * handle for the string.
152 * @param handle the handle for the set
153 * @param wstr the wide character string which shall be stored
154 * @param len length of wstr
156 * @return id - a handle for the generated ident
158 * Default implementation using libfirm sets.
160 static ident *set_new_id_from_wchars(void *handle, const wchar_t *wstr, int len)
162 set *id_set = handle;
165 /* can't use hinsert0 here, so copy and add a 0 */
166 tmp = alloca((len + 1) * sizeof(*tmp));
167 memcpy(tmp, wstr, len * sizeof(*tmp));
170 return (ident *)set_hinsert(id_set, tmp, (len + 1) * sizeof(wchar_t), ID_HASH(wchar_t, tmp, len));
174 * Stores a wide character string in the ident module and
175 * returns a handle for the string.
177 * @param handle the handle for the set
178 * @param wstr the wide character string which shall be stored
180 * Default implementation using libfirm sets.
182 static ident *set_new_id_from_wcs(void *handle, const wchar_t *wstr)
185 return (ident *)set_new_id_from_wchars(handle, wstr, wcslen(wstr));
189 * Returns a wide character string represented by an ident.
191 * @param handle the handle for the set
192 * @param id the ident
194 * Default implementation using libfirm sets.
196 static const wchar_t *set_get_id_wcs(void *handle, ident *id)
198 struct set_entry *entry = (struct set_entry *)id;
200 return (const wchar_t *)entry->dptr;
204 * Returns the length of the string represented by an ident.
206 * @param handle the handle for the set
207 * @param id the ident
209 * Default implementation using libfirm sets.
211 static int set_get_id_wcslen(void *handle, ident *id)
213 struct set_entry *entry = (struct set_entry *)id;
215 /* len + \0 is stored for wchar_t */
216 return entry->size / sizeof(wchar_t) - 1;
220 * Default implementation if no new_id_from_wcs() is provided.
222 static ident *def_new_id_from_wcs(void *handle, const wchar_t *wstr)
224 return impl.new_id_from_wchars(handle, wstr, wcslen(wstr));
228 * Default implementation if no new_id_from_wchars() is provided.
230 static ident *def_new_id_from_wchars(void *handle, const wchar_t *wstr, int len)
232 return impl.new_id_from_chars(handle, (const char *)wstr, (len + 1) * sizeof(wchar_t));
236 * Default implementation if no get_id_wcs() is provided.
238 static const wchar_t *def_get_id_wcs(void *handle, ident *id)
240 return (const wchar_t *)impl.get_id_str(handle, id);
244 * Default implementation if no get_id_wcslen() is provided.
246 static int def_get_id_wcslen(void *handle, ident *id)
248 return wcslen(impl.get_id_wcs(handle, id));
250 #endif /* FIRM_ENABLE_WCHAR */
252 /* Initialize the ident module. */
253 void init_ident(ident_if_t *id_if, int initial_n_idents)
256 memcpy(&impl, id_if, sizeof(impl));
258 if (! impl.new_id_from_str)
259 impl.new_id_from_str = def_new_id_from_str;
260 if (! impl.get_id_strlen)
261 impl.get_id_strlen = def_get_id_strlen;
263 #ifdef FIRM_ENABLE_WCHAR
264 if (! impl.new_id_from_wcs)
265 impl.new_id_from_wcs = def_new_id_from_wcs;
266 if (! impl.new_id_from_wchars)
267 impl.new_id_from_wchars = def_new_id_from_wchars;
268 if (! impl.get_id_wcs)
269 impl.get_id_wcs = def_get_id_wcs;
270 if (! impl.get_id_wcslen)
271 impl.get_id_wcslen = def_get_id_wcslen;
272 #endif /* FIRM_ENABLE_WCHAR */
275 impl.new_id_from_str = set_new_id_from_str;
276 impl.new_id_from_chars = set_new_id_from_chars;
277 impl.get_id_str = set_get_id_str;
278 impl.get_id_strlen = set_get_id_strlen;
279 impl.finish_ident = set_finish_ident;
280 #ifdef FIRM_ENABLE_WCHAR
281 impl.new_id_from_wcs = set_new_id_from_wcs;
282 impl.new_id_from_wchars = set_new_id_from_wchars;
283 impl.get_id_wcs = set_get_id_wcs;
284 impl.get_id_wcslen = set_get_id_wcslen;
285 #endif /* FIRM_ENABLE_WCHAR */
287 impl.handle = new_set(memcmp, initial_n_idents);
291 ident *new_id_from_str(const char *str)
294 return impl.new_id_from_str(impl.handle, str);
297 ident *new_id_from_chars(const char *str, int len)
300 return impl.new_id_from_chars(impl.handle, str, len);
303 const char *get_id_str(ident *id)
305 return impl.get_id_str(impl.handle, id);
308 int get_id_strlen(ident *id)
310 return impl.get_id_strlen(impl.handle, id);
313 void finish_ident(void) {
314 if (impl.finish_ident)
315 impl.finish_ident(impl.handle);
318 int id_is_prefix(ident *prefix, ident *id)
320 if (get_id_strlen(prefix) > get_id_strlen(id)) return 0;
321 return 0 == memcmp(get_id_str(prefix), get_id_str(id), get_id_strlen(prefix));
324 int id_is_suffix(ident *suffix, ident *id)
326 int suflen = get_id_strlen(suffix);
327 int idlen = get_id_strlen(id);
330 if (suflen > idlen) return 0;
332 part = get_id_str(id);
333 part = part + (idlen - suflen);
335 return 0 == memcmp(get_id_str(suffix), part, suflen);
338 int id_contains_char(ident *id, char c)
340 return strchr(get_id_str(id), c) != NULL;
343 #ifdef FIRM_ENABLE_WCHAR
345 ident *new_id_from_wcs (const wchar_t *str)
348 return impl.new_id_from_wcs(impl.handle, str);
351 ident *new_id_from_wchars (const wchar_t *str, int len)
354 return impl.new_id_from_wchars(impl.handle, str, len);
357 const wchar_t *get_id_wcs(ident *id)
359 return impl.get_id_wcs(impl.handle, id);
362 int get_id_wcslen(ident *id)
364 return impl.get_id_wcslen(impl.handle, id);
367 int id_contains_wchar (ident *id, wchar_t c)
369 return wcschr(get_id_wcs(id), c) != NULL;
372 #endif /* FIRM_ENABLE_WCHAR */