3 * File name: ir/common/ident.c
4 * Purpose: Hash table to store names.
5 * Author: Goetz Lindenmaier
9 * Copyright: (c) 1999-2003 Universität Karlsruhe
10 * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
23 #ifdef FIRM_ENABLE_WCHAR
31 /* for debugging only, not the real implementation */
33 char reserved[sizeof(unsigned) + sizeof(size_t)];
37 /** The current ident module implementation. */
38 static ident_if_t impl;
41 * Stores a string in the ident module and returns a handle for the string.
43 * @param handle the handle for the set
44 * @param str the string which shall be stored
45 * @param len length of str in bytes
47 * @return id - a handle for the generated ident
49 * Default implementation using libfirm sets.
51 static ident *set_new_id_from_chars(void *handle, const char *str, int len)
55 /* GL: Who added this assert? And why? */
57 return (ident *)set_hinsert0(id_set, str, len, ID_HASH(unsigned char, str, len));
61 * Stores a string in the ident module and returns a handle for the string.
63 * @param handle the handle for the set
64 * @param str the string (or whatever) which shall be stored
66 * Default implementation using libfirm sets.
68 static ident *set_new_id_from_str(void *handle, const char *str)
71 return (ident *)set_new_id_from_chars(handle, str, strlen(str));
75 * Returns a string represented by an ident.
77 * @param handle the handle for the set
80 * Default implementation using libfirm sets.
82 static const char *set_get_id_str(void *handle, ident *id)
84 struct set_entry *entry = (struct set_entry *)id;
86 return (const char *)entry->dptr;
90 * Returns the length of the string represented by an ident.
92 * @param handle the handle for the set
95 * Default implementation using libfirm sets.
97 static int set_get_id_strlen(void *handle, ident *id)
99 struct set_entry *entry = (struct set_entry *)id;
105 * Default implementation using libfirm sets.
107 void set_finish_ident(void *handle) {
108 set *id_set = handle;
114 * Default implementation if no new_id_from_str() is provided.
116 static ident *def_new_id_from_str(void *handle, const char *str)
118 return impl.new_id_from_chars(handle, str, strlen(str));
122 * Default implementation if no get_id_strlen() is provided.
124 static int def_get_id_strlen(void *handle, ident *id)
126 return strlen(impl.get_id_str(handle, id));
129 #ifdef FIRM_ENABLE_WCHAR
131 * Stores a wide character string in the ident module and returns a
132 * handle for the string.
134 * @param handle the handle for the set
135 * @param wstr the wide character string which shall be stored
136 * @param len length of wstr
138 * @return id - a handle for the generated ident
140 * Default implementation using libfirm sets.
142 static ident *set_new_id_from_wchars(void *handle, const wchar_t *wstr, int len)
144 set *id_set = handle;
147 /* can't use hinsert0 here, so copy and add a 0 */
148 tmp = alloca((len + 1) * sizeof(*tmp));
149 memcpy(tmp, wstr, len * sizeof(*tmp));
152 return (ident *)set_hinsert(id_set, tmp, (len + 1) * sizeof(wchar_t), ID_HASH(wchar_t, tmp, len));
156 * Stores a wide character string in the ident module and
157 * returns a handle for the string.
159 * @param handle the handle for the set
160 * @param wstr the wide character string which shall be stored
162 * Default implementation using libfirm sets.
164 static ident *set_new_id_from_wcs(void *handle, const wchar_t *wstr)
167 return (ident *)set_new_id_from_wchars(handle, wstr, wcslen(wstr));
171 * Returns a wide character string represented by an ident.
173 * @param handle the handle for the set
174 * @param id the ident
176 * Default implementation using libfirm sets.
178 static const wchar_t *set_get_id_wcs(void *handle, ident *id)
180 struct set_entry *entry = (struct set_entry *)id;
182 return (const wchar_t *)entry->dptr;
186 * Returns the length of the 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 int set_get_id_wcslen(void *handle, ident *id)
195 struct set_entry *entry = (struct set_entry *)id;
197 /* len + \0 is stored for wchar_t */
198 return entry->size / sizeof(wchar_t) - 1;
202 * Default implementation if no new_id_from_wcs() is provided.
204 static ident *def_new_id_from_wcs(void *handle, const wchar_t *wstr)
206 return impl.new_id_from_wchars(handle, wstr, wcslen(wstr));
210 * Default implementation if no new_id_from_wchars() is provided.
212 static ident *def_new_id_from_wchars(void *handle, const wchar_t *wstr, int len)
214 return impl.new_id_from_chars(handle, (const char *)wstr, (len + 1) * sizeof(wchar_t));
218 * Default implementation if no get_id_wcs() is provided.
220 static const wchar_t *def_get_id_wcs(void *handle, ident *id)
222 return (const wchar_t *)impl.get_id_str(handle, id);
226 * Default implementation if no get_id_wcslen() is provided.
228 static int def_get_id_wcslen(void *handle, ident *id)
230 return wcslen(impl.get_id_wcs(handle, id));
232 #endif /* FIRM_ENABLE_WCHAR */
234 /* Initialize the ident module. */
235 void init_ident(ident_if_t *id_if, int initial_n_idents)
238 memcpy(&impl, id_if, sizeof(impl));
240 if (! impl.new_id_from_str)
241 impl.new_id_from_str = def_new_id_from_str;
242 if (! impl.get_id_strlen)
243 impl.get_id_strlen = def_get_id_strlen;
245 #ifdef FIRM_ENABLE_WCHAR
246 if (! impl.new_id_from_wcs)
247 impl.new_id_from_wcs = def_new_id_from_wcs;
248 if (! impl.new_id_from_wchars)
249 impl.new_id_from_wchars = def_new_id_from_wchars;
250 if (! impl.get_id_wcs)
251 impl.get_id_wcs = def_get_id_wcs;
252 if (! impl.get_id_wcslen)
253 impl.get_id_wcslen = def_get_id_wcslen;
254 #endif /* FIRM_ENABLE_WCHAR */
257 impl.new_id_from_str = set_new_id_from_str;
258 impl.new_id_from_chars = set_new_id_from_chars;
259 impl.get_id_str = set_get_id_str;
260 impl.get_id_strlen = set_get_id_strlen;
261 impl.finish_ident = set_finish_ident;
262 #ifdef FIRM_ENABLE_WCHAR
263 impl.new_id_from_wcs = set_new_id_from_wcs;
264 impl.new_id_from_wchars = set_new_id_from_wchars;
265 impl.get_id_wcs = set_get_id_wcs;
266 impl.get_id_wcslen = set_get_id_wcslen;
267 #endif /* FIRM_ENABLE_WCHAR */
269 impl.handle = new_set(memcmp, initial_n_idents);
273 ident *new_id_from_str(const char *str)
276 return impl.new_id_from_str(impl.handle, str);
279 ident *new_id_from_chars(const char *str, int len)
282 return impl.new_id_from_chars(impl.handle, str, len);
285 const char *get_id_str(ident *id)
287 return impl.get_id_str(impl.handle, id);
290 int get_id_strlen(ident *id)
292 return impl.get_id_strlen(impl.handle, id);
295 void finish_ident(void) {
296 if (impl.finish_ident)
297 impl.finish_ident(impl.handle);
300 int id_is_prefix(ident *prefix, ident *id)
302 if (get_id_strlen(prefix) > get_id_strlen(id)) return 0;
303 return 0 == memcmp(get_id_str(prefix), get_id_str(id), get_id_strlen(prefix));
306 int id_is_suffix(ident *suffix, ident *id)
308 int suflen = get_id_strlen(suffix);
309 int idlen = get_id_strlen(id);
312 if (suflen > idlen) return 0;
314 part = get_id_str(id);
315 part = part + (idlen - suflen);
317 return 0 == memcmp(get_id_str(suffix), part, suflen);
320 int id_contains_char(ident *id, char c)
322 return strchr(get_id_str(id), c) != NULL;
325 #ifdef FIRM_ENABLE_WCHAR
327 ident *new_id_from_wcs (const wchar_t *str)
330 return impl.new_id_from_wcs(impl.handle, str);
333 ident *new_id_from_wchars (const wchar_t *str, int len)
336 return impl.new_id_from_wchars(impl.handle, str, len);
339 const wchar_t *get_id_wcs(ident *id)
341 return impl.get_id_wcs(impl.handle, id);
344 int get_id_wcslen(ident *id)
346 return impl.get_id_wcslen(impl.handle, id);
349 int id_contains_wchar (ident *id, wchar_t c)
351 return wcschr(get_id_wcs(id), c) != NULL;
354 #endif /* FIRM_ENABLE_WCHAR */