indentation changed
[libfirm] / ir / ident / ident.c
1 /*
2  * Project:     libFIRM
3  * File name:   ir/common/ident.c
4  * Purpose:     Hash table to store names.
5  * Author:      Goetz Lindenmaier
6  * Modified by:
7  * Created:
8  * CVS-ID:      $Id$
9  * Copyright:   (c) 1999-2003 Universität Karlsruhe
10  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
11  */
12
13 #ifdef HAVE_CONFIG_H
14 # include "config.h"
15 #endif
16
17 #include <assert.h>
18 #include <ctype.h>
19 #include <string.h>
20 #include <stddef.h>
21 #include <stdlib.h>
22
23 #ifdef FIRM_ENABLE_WCHAR
24 #include <wchar.h>
25 #endif
26
27 #include "ident_t.h"
28 #include "set.h"
29 #include "xmalloc.h"
30
31 /* for debugging only, not the real implementation */
32 struct _ident {
33   char reserved[sizeof(unsigned) + sizeof(size_t)];
34   char data[1];
35 };
36
37 /** The current ident module implementation. */
38 static ident_if_t impl;
39
40 /**
41  * Stores a string in the ident module and returns a handle for the string.
42  *
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
46  *
47  * @return id - a handle for the generated ident
48  *
49  * Default implementation using libfirm sets.
50  */
51 static ident *set_new_id_from_chars(void *handle, const char *str, int len)
52 {
53   set *id_set = handle;
54
55   /* GL: Who added this assert?  And why? */
56   //assert(len > 0);
57   return (ident *)set_hinsert0(id_set, str, len, ID_HASH(unsigned char, str, len));
58 }
59
60 /**
61  * Stores a string in the ident module and returns a handle for the string.
62  *
63  * @param handle   the handle for the set
64  * @param str      the string (or whatever) which shall be stored
65  *
66  * Default implementation using libfirm sets.
67  */
68 static ident *set_new_id_from_str(void *handle, const char *str)
69 {
70   assert(str);
71   return (ident *)set_new_id_from_chars(handle, str, strlen(str));
72 }
73
74 /**
75  * Returns a string represented by an ident.
76  *
77  * @param handle   the handle for the set
78  * @param id       the ident
79  *
80  * Default implementation using libfirm sets.
81  */
82 static const char *set_get_id_str(void *handle, ident *id)
83 {
84   struct set_entry *entry = (struct set_entry *)id;
85
86   return (const char *)entry->dptr;
87 }
88
89 /**
90  * Returns the length of the string represented by an ident.
91  *
92  * @param handle   the handle for the set
93  * @param id       the ident
94  *
95  * Default implementation using libfirm sets.
96  */
97 static int set_get_id_strlen(void *handle, ident *id)
98 {
99   struct set_entry *entry = (struct set_entry *)id;
100
101   return entry->size;
102 }
103
104 /**
105  * Default implementation using libfirm sets.
106  */
107 void set_finish_ident(void *handle) {
108   set *id_set = handle;
109
110   del_set(id_set);
111 }
112
113 /**
114  * Default implementation if no new_id_from_str() is provided.
115  */
116 static ident *def_new_id_from_str(void *handle, const char *str)
117 {
118   return impl.new_id_from_chars(handle, str, strlen(str));
119 }
120
121 /**
122  * Default implementation if no get_id_strlen() is provided.
123  */
124 static int def_get_id_strlen(void *handle, ident *id)
125 {
126   return strlen(impl.get_id_str(handle, id));
127 }
128
129 #ifdef FIRM_ENABLE_WCHAR
130 /**
131  * Stores a wide character string in the ident module and returns a
132  * handle for the string.
133  *
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
137  *
138  * @return id - a handle for the generated ident
139  *
140  * Default implementation using libfirm sets.
141  */
142 static ident *set_new_id_from_wchars(void *handle, const wchar_t *wstr, int len)
143 {
144   set *id_set = handle;
145   wchar_t *tmp;
146
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));
150   tmp[len] = L'\0';
151
152   return (ident *)set_hinsert(id_set, tmp, (len + 1) * sizeof(wchar_t), ID_HASH(wchar_t, tmp, len));
153 }
154
155 /**
156  * Stores a wide character string in the ident module and
157  * returns a handle for the string.
158  *
159  * @param handle   the handle for the set
160  * @param wstr     the wide character string which shall be stored
161  *
162  * Default implementation using libfirm sets.
163  */
164 static ident *set_new_id_from_wcs(void *handle, const wchar_t *wstr)
165 {
166   assert(wstr);
167   return (ident *)set_new_id_from_wchars(handle, wstr, wcslen(wstr));
168 }
169
170 /**
171  * Returns a wide character string represented by an ident.
172  *
173  * @param handle   the handle for the set
174  * @param id       the ident
175  *
176  * Default implementation using libfirm sets.
177  */
178 static const wchar_t *set_get_id_wcs(void *handle, ident *id)
179 {
180   struct set_entry *entry = (struct set_entry *)id;
181
182   return (const wchar_t *)entry->dptr;
183 }
184
185 /**
186  * Returns the length of the string represented by an ident.
187  *
188  * @param handle   the handle for the set
189  * @param id       the ident
190  *
191  * Default implementation using libfirm sets.
192  */
193 static int set_get_id_wcslen(void *handle, ident *id)
194 {
195   struct set_entry *entry = (struct set_entry *)id;
196
197   /* len + \0 is stored for wchar_t */
198   return entry->size / sizeof(wchar_t) - 1;
199 }
200
201 /**
202  * Default implementation if no new_id_from_wcs() is provided.
203  */
204 static ident *def_new_id_from_wcs(void *handle, const wchar_t *wstr)
205 {
206   return impl.new_id_from_wchars(handle, wstr, wcslen(wstr));
207 }
208
209 /**
210  * Default implementation if no new_id_from_wchars() is provided.
211  */
212 static ident *def_new_id_from_wchars(void *handle, const wchar_t *wstr, int len)
213 {
214   return impl.new_id_from_chars(handle, (const char *)wstr, (len + 1) * sizeof(wchar_t));
215 }
216
217 /**
218  * Default implementation if no get_id_wcs() is provided.
219  */
220 static const wchar_t *def_get_id_wcs(void *handle, ident *id)
221 {
222   return (const wchar_t *)impl.get_id_str(handle, id);
223 }
224
225 /**
226  * Default implementation if no get_id_wcslen() is provided.
227  */
228 static int def_get_id_wcslen(void *handle, ident *id)
229 {
230   return wcslen(impl.get_id_wcs(handle, id));
231 }
232 #endif /* FIRM_ENABLE_WCHAR */
233
234 /* Initialize the ident module. */
235 void init_ident(ident_if_t *id_if, int initial_n_idents)
236 {
237   if (id_if) {
238     memcpy(&impl, id_if, sizeof(impl));
239
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;
244
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 */
255   }
256   else {
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 */
268
269    impl.handle = new_set(memcmp, initial_n_idents);
270   }
271 }
272
273 ident *new_id_from_str(const char *str)
274 {
275   assert(str);
276   return impl.new_id_from_str(impl.handle, str);
277 }
278
279 ident *new_id_from_chars(const char *str, int len)
280 {
281   assert(len > 0);
282   return impl.new_id_from_chars(impl.handle, str, len);
283 }
284
285 const char *get_id_str(ident *id)
286 {
287   return impl.get_id_str(impl.handle, id);
288 }
289
290 int get_id_strlen(ident *id)
291 {
292   return impl.get_id_strlen(impl.handle, id);
293 }
294
295 void finish_ident(void) {
296   if (impl.finish_ident)
297     impl.finish_ident(impl.handle);
298 }
299
300 int id_is_prefix(ident *prefix, ident *id)
301 {
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));
304 }
305
306 int id_is_suffix(ident *suffix, ident *id)
307 {
308   int suflen = get_id_strlen(suffix);
309   int idlen  = get_id_strlen(id);
310   const char *part;
311
312   if (suflen > idlen) return 0;
313
314   part = get_id_str(id);
315   part = part + (idlen - suflen);
316
317   return 0 == memcmp(get_id_str(suffix), part, suflen);
318 }
319
320 int id_contains_char(ident *id, char c)
321 {
322   return strchr(get_id_str(id), c) != NULL;
323 }
324
325 #ifdef FIRM_ENABLE_WCHAR
326
327 ident *new_id_from_wcs (const wchar_t *str)
328 {
329   assert(str);
330   return impl.new_id_from_wcs(impl.handle, str);
331 }
332
333 ident *new_id_from_wchars (const wchar_t *str, int len)
334 {
335   assert(len > 0);
336   return impl.new_id_from_wchars(impl.handle, str, len);
337 }
338
339 const wchar_t *get_id_wcs(ident *id)
340 {
341   return impl.get_id_wcs(impl.handle, id);
342 }
343
344 int  get_id_wcslen(ident *id)
345 {
346   return impl.get_id_wcslen(impl.handle, id);
347 }
348
349 int id_contains_wchar (ident *id, wchar_t c)
350 {
351   return wcschr(get_id_wcs(id), c) != NULL;
352 }
353
354 #endif /* FIRM_ENABLE_WCHAR */