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;
100 return (const char *)entry->dptr;
104 * Returns the length of the string represented by an ident.
106 * @param handle the handle for the set
107 * @param id the ident
109 * Default implementation using libfirm sets.
111 static int set_get_id_strlen(void *handle, ident *id)
113 struct set_entry *entry = (struct set_entry *)id;
120 * Default implementation using libfirm sets.
122 void set_finish_ident(void *handle) {
123 set *id_set = handle;
129 * Default implementation if no new_id_from_str() is provided.
131 static ident *def_new_id_from_str(void *handle, const char *str)
133 return impl.new_id_from_chars(handle, str, strlen(str));
137 * Default implementation if no get_id_strlen() is provided.
139 static int def_get_id_strlen(void *handle, ident *id)
141 return strlen(impl.get_id_str(handle, id));
144 #ifdef FIRM_ENABLE_WCHAR
146 * Stores a wide character string in the ident module and returns a
147 * handle for the string.
149 * @param handle the handle for the set
150 * @param wstr the wide character string which shall be stored
151 * @param len length of wstr
153 * @return id - a handle for the generated ident
155 * Default implementation using libfirm sets.
157 static ident *set_new_id_from_wchars(void *handle, const wchar_t *wstr, int len)
159 set *id_set = handle;
162 /* can't use hinsert0 here, so copy and add a 0 */
163 tmp = alloca((len + 1) * sizeof(*tmp));
164 memcpy(tmp, wstr, len * sizeof(*tmp));
167 return (ident *)set_hinsert(id_set, tmp, (len + 1) * sizeof(wchar_t), ID_HASH(wchar_t, tmp, len));
171 * Stores a wide character string in the ident module and
172 * returns a handle for the string.
174 * @param handle the handle for the set
175 * @param wstr the wide character string which shall be stored
177 * Default implementation using libfirm sets.
179 static ident *set_new_id_from_wcs(void *handle, const wchar_t *wstr)
182 return (ident *)set_new_id_from_wchars(handle, wstr, wcslen(wstr));
186 * Returns a wide character string represented by an ident.
188 * @param handle the handle for the set
189 * @param id the ident
191 * Default implementation using libfirm sets.
193 static const wchar_t *set_get_id_wcs(void *handle, ident *id)
195 struct set_entry *entry = (struct set_entry *)id;
197 return (const wchar_t *)entry->dptr;
201 * Returns the length of the string represented by an ident.
203 * @param handle the handle for the set
204 * @param id the ident
206 * Default implementation using libfirm sets.
208 static int set_get_id_wcslen(void *handle, ident *id)
210 struct set_entry *entry = (struct set_entry *)id;
212 /* len + \0 is stored for wchar_t */
213 return entry->size / sizeof(wchar_t) - 1;
217 * Default implementation if no new_id_from_wcs() is provided.
219 static ident *def_new_id_from_wcs(void *handle, const wchar_t *wstr)
221 return impl.new_id_from_wchars(handle, wstr, wcslen(wstr));
225 * Default implementation if no new_id_from_wchars() is provided.
227 static ident *def_new_id_from_wchars(void *handle, const wchar_t *wstr, int len)
229 return impl.new_id_from_chars(handle, (const char *)wstr, (len + 1) * sizeof(wchar_t));
233 * Default implementation if no get_id_wcs() is provided.
235 static const wchar_t *def_get_id_wcs(void *handle, ident *id)
237 return (const wchar_t *)impl.get_id_str(handle, id);
241 * Default implementation if no get_id_wcslen() is provided.
243 static int def_get_id_wcslen(void *handle, ident *id)
245 return wcslen(impl.get_id_wcs(handle, id));
247 #endif /* FIRM_ENABLE_WCHAR */
249 /* Initialize the ident module. */
250 void init_ident(ident_if_t *id_if, int initial_n_idents)
253 memcpy(&impl, id_if, sizeof(impl));
255 if (! impl.new_id_from_str)
256 impl.new_id_from_str = def_new_id_from_str;
257 if (! impl.get_id_strlen)
258 impl.get_id_strlen = def_get_id_strlen;
260 #ifdef FIRM_ENABLE_WCHAR
261 if (! impl.new_id_from_wcs)
262 impl.new_id_from_wcs = def_new_id_from_wcs;
263 if (! impl.new_id_from_wchars)
264 impl.new_id_from_wchars = def_new_id_from_wchars;
265 if (! impl.get_id_wcs)
266 impl.get_id_wcs = def_get_id_wcs;
267 if (! impl.get_id_wcslen)
268 impl.get_id_wcslen = def_get_id_wcslen;
269 #endif /* FIRM_ENABLE_WCHAR */
272 impl.new_id_from_str = set_new_id_from_str;
273 impl.new_id_from_chars = set_new_id_from_chars;
274 impl.get_id_str = set_get_id_str;
275 impl.get_id_strlen = set_get_id_strlen;
276 impl.finish_ident = set_finish_ident;
277 #ifdef FIRM_ENABLE_WCHAR
278 impl.new_id_from_wcs = set_new_id_from_wcs;
279 impl.new_id_from_wchars = set_new_id_from_wchars;
280 impl.get_id_wcs = set_get_id_wcs;
281 impl.get_id_wcslen = set_get_id_wcslen;
282 #endif /* FIRM_ENABLE_WCHAR */
284 impl.handle = new_set(memcmp, initial_n_idents);
288 ident *new_id_from_str(const char *str)
291 return impl.new_id_from_str(impl.handle, str);
294 ident *new_id_from_chars(const char *str, int len)
297 return impl.new_id_from_chars(impl.handle, str, len);
300 const char *get_id_str(ident *id)
302 return impl.get_id_str(impl.handle, id);
305 int get_id_strlen(ident *id)
307 return impl.get_id_strlen(impl.handle, id);
310 void finish_ident(void) {
311 if (impl.finish_ident)
312 impl.finish_ident(impl.handle);
315 int id_is_prefix(ident *prefix, ident *id)
317 if (get_id_strlen(prefix) > get_id_strlen(id)) return 0;
318 return 0 == memcmp(get_id_str(prefix), get_id_str(id), get_id_strlen(prefix));
321 int id_is_suffix(ident *suffix, ident *id)
323 int suflen = get_id_strlen(suffix);
324 int idlen = get_id_strlen(id);
327 if (suflen > idlen) return 0;
329 part = get_id_str(id);
330 part = part + (idlen - suflen);
332 return 0 == memcmp(get_id_str(suffix), part, suflen);
335 int id_contains_char(ident *id, char c)
337 return strchr(get_id_str(id), c) != NULL;
340 #ifdef FIRM_ENABLE_WCHAR
342 ident *new_id_from_wcs (const wchar_t *str)
345 return impl.new_id_from_wcs(impl.handle, str);
348 ident *new_id_from_wchars (const wchar_t *str, int len)
351 return impl.new_id_from_wchars(impl.handle, str, len);
354 const wchar_t *get_id_wcs(ident *id)
356 return impl.get_id_wcs(impl.handle, id);
359 int get_id_wcslen(ident *id)
361 return impl.get_id_wcslen(impl.handle, id);
364 int id_contains_wchar (ident *id, wchar_t c)
366 return wcschr(get_id_wcs(id), c) != NULL;
369 #endif /* FIRM_ENABLE_WCHAR */