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