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 * @brief Hash table to store names.
23 * @author Goetz Lindenmaier
36 #ifdef FIRM_ENABLE_WCHAR
44 /* for debugging only, not the real implementation */
46 char reserved[sizeof(unsigned) + sizeof(size_t)];
50 /** The current ident module implementation. */
51 static ident_if_t impl;
54 * Stores a string in the ident module and returns a handle for the string.
56 * @param handle the handle for the set
57 * @param str the string which shall be stored
58 * @param len length of str in bytes
60 * @return id - a handle for the generated ident
62 * Default implementation using libfirm sets.
64 static ident *set_new_id_from_chars(void *handle, const char *str, int len)
68 /* GL: Who added this assert? And why? */
70 return (ident *)set_hinsert0(id_set, str, len, ID_HASH(unsigned char, str, len));
74 * Stores a string in the ident module and returns a handle for the string.
76 * @param handle the handle for the set
77 * @param str the string (or whatever) which shall be stored
79 * Default implementation using libfirm sets.
81 static ident *set_new_id_from_str(void *handle, const char *str)
84 return (ident *)set_new_id_from_chars(handle, str, strlen(str));
88 * Returns a string represented by an ident.
90 * @param handle the handle for the set
93 * Default implementation using libfirm sets.
95 static const char *set_get_id_str(void *handle, ident *id)
97 struct set_entry *entry = (struct set_entry *)id;
99 return (const char *)entry->dptr;
103 * Returns the length of the string represented by an ident.
105 * @param handle the handle for the set
106 * @param id the ident
108 * Default implementation using libfirm sets.
110 static int set_get_id_strlen(void *handle, ident *id)
112 struct set_entry *entry = (struct set_entry *)id;
118 * Default implementation using libfirm sets.
120 void set_finish_ident(void *handle) {
121 set *id_set = handle;
127 * Default implementation if no new_id_from_str() is provided.
129 static ident *def_new_id_from_str(void *handle, const char *str)
131 return impl.new_id_from_chars(handle, str, strlen(str));
135 * Default implementation if no get_id_strlen() is provided.
137 static int def_get_id_strlen(void *handle, ident *id)
139 return strlen(impl.get_id_str(handle, id));
142 #ifdef FIRM_ENABLE_WCHAR
144 * Stores a wide character string in the ident module and returns a
145 * handle for the string.
147 * @param handle the handle for the set
148 * @param wstr the wide character string which shall be stored
149 * @param len length of wstr
151 * @return id - a handle for the generated ident
153 * Default implementation using libfirm sets.
155 static ident *set_new_id_from_wchars(void *handle, const wchar_t *wstr, int len)
157 set *id_set = handle;
160 /* can't use hinsert0 here, so copy and add a 0 */
161 tmp = alloca((len + 1) * sizeof(*tmp));
162 memcpy(tmp, wstr, len * sizeof(*tmp));
165 return (ident *)set_hinsert(id_set, tmp, (len + 1) * sizeof(wchar_t), ID_HASH(wchar_t, tmp, len));
169 * Stores a wide character string in the ident module and
170 * returns a handle for the string.
172 * @param handle the handle for the set
173 * @param wstr the wide character string which shall be stored
175 * Default implementation using libfirm sets.
177 static ident *set_new_id_from_wcs(void *handle, const wchar_t *wstr)
180 return (ident *)set_new_id_from_wchars(handle, wstr, wcslen(wstr));
184 * Returns a wide character string represented by an ident.
186 * @param handle the handle for the set
187 * @param id the ident
189 * Default implementation using libfirm sets.
191 static const wchar_t *set_get_id_wcs(void *handle, ident *id)
193 struct set_entry *entry = (struct set_entry *)id;
195 return (const wchar_t *)entry->dptr;
199 * Returns the length of the string represented by an ident.
201 * @param handle the handle for the set
202 * @param id the ident
204 * Default implementation using libfirm sets.
206 static int set_get_id_wcslen(void *handle, ident *id)
208 struct set_entry *entry = (struct set_entry *)id;
210 /* len + \0 is stored for wchar_t */
211 return entry->size / sizeof(wchar_t) - 1;
215 * Default implementation if no new_id_from_wcs() is provided.
217 static ident *def_new_id_from_wcs(void *handle, const wchar_t *wstr)
219 return impl.new_id_from_wchars(handle, wstr, wcslen(wstr));
223 * Default implementation if no new_id_from_wchars() is provided.
225 static ident *def_new_id_from_wchars(void *handle, const wchar_t *wstr, int len)
227 return impl.new_id_from_chars(handle, (const char *)wstr, (len + 1) * sizeof(wchar_t));
231 * Default implementation if no get_id_wcs() is provided.
233 static const wchar_t *def_get_id_wcs(void *handle, ident *id)
235 return (const wchar_t *)impl.get_id_str(handle, id);
239 * Default implementation if no get_id_wcslen() is provided.
241 static int def_get_id_wcslen(void *handle, ident *id)
243 return wcslen(impl.get_id_wcs(handle, id));
245 #endif /* FIRM_ENABLE_WCHAR */
247 /* Initialize the ident module. */
248 void init_ident(ident_if_t *id_if, int initial_n_idents)
251 memcpy(&impl, id_if, sizeof(impl));
253 if (! impl.new_id_from_str)
254 impl.new_id_from_str = def_new_id_from_str;
255 if (! impl.get_id_strlen)
256 impl.get_id_strlen = def_get_id_strlen;
258 #ifdef FIRM_ENABLE_WCHAR
259 if (! impl.new_id_from_wcs)
260 impl.new_id_from_wcs = def_new_id_from_wcs;
261 if (! impl.new_id_from_wchars)
262 impl.new_id_from_wchars = def_new_id_from_wchars;
263 if (! impl.get_id_wcs)
264 impl.get_id_wcs = def_get_id_wcs;
265 if (! impl.get_id_wcslen)
266 impl.get_id_wcslen = def_get_id_wcslen;
267 #endif /* FIRM_ENABLE_WCHAR */
270 impl.new_id_from_str = set_new_id_from_str;
271 impl.new_id_from_chars = set_new_id_from_chars;
272 impl.get_id_str = set_get_id_str;
273 impl.get_id_strlen = set_get_id_strlen;
274 impl.finish_ident = set_finish_ident;
275 #ifdef FIRM_ENABLE_WCHAR
276 impl.new_id_from_wcs = set_new_id_from_wcs;
277 impl.new_id_from_wchars = set_new_id_from_wchars;
278 impl.get_id_wcs = set_get_id_wcs;
279 impl.get_id_wcslen = set_get_id_wcslen;
280 #endif /* FIRM_ENABLE_WCHAR */
282 impl.handle = new_set(memcmp, initial_n_idents);
286 ident *new_id_from_str(const char *str)
289 return impl.new_id_from_str(impl.handle, str);
292 ident *new_id_from_chars(const char *str, int len)
295 return impl.new_id_from_chars(impl.handle, str, len);
298 const char *get_id_str(ident *id)
300 return impl.get_id_str(impl.handle, id);
303 int get_id_strlen(ident *id)
305 return impl.get_id_strlen(impl.handle, id);
308 void finish_ident(void) {
309 if (impl.finish_ident)
310 impl.finish_ident(impl.handle);
313 int id_is_prefix(ident *prefix, ident *id)
315 if (get_id_strlen(prefix) > get_id_strlen(id)) return 0;
316 return 0 == memcmp(get_id_str(prefix), get_id_str(id), get_id_strlen(prefix));
319 int id_is_suffix(ident *suffix, ident *id)
321 int suflen = get_id_strlen(suffix);
322 int idlen = get_id_strlen(id);
325 if (suflen > idlen) return 0;
327 part = get_id_str(id);
328 part = part + (idlen - suflen);
330 return 0 == memcmp(get_id_str(suffix), part, suflen);
333 int id_contains_char(ident *id, char c)
335 return strchr(get_id_str(id), c) != NULL;
338 #ifdef FIRM_ENABLE_WCHAR
340 ident *new_id_from_wcs (const wchar_t *str)
343 return impl.new_id_from_wcs(impl.handle, str);
346 ident *new_id_from_wchars (const wchar_t *str, int len)
349 return impl.new_id_from_wchars(impl.handle, str, len);
352 const wchar_t *get_id_wcs(ident *id)
354 return impl.get_id_wcs(impl.handle, id);
357 int get_id_wcslen(ident *id)
359 return impl.get_id_wcslen(impl.handle, id);
362 int id_contains_wchar (ident *id, wchar_t c)
364 return wcschr(get_id_wcs(id), c) != NULL;
367 #endif /* FIRM_ENABLE_WCHAR */