remove #ifdef HAVE_CONFIG_Hs
[libfirm] / ir / ident / ident.c
1 /*
2  * Copyright (C) 1995-2008 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 #include "config.h"
27
28 #include <assert.h>
29 #include <ctype.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <stddef.h>
33 #include <stdlib.h>
34
35 #include "ident_t.h"
36 #include "set.h"
37 #include "xmalloc.h"
38
39 /* for debugging only, not the real implementation */
40 struct _ident {
41   char reserved[sizeof(unsigned) + sizeof(size_t)];
42   char data[1];
43 };
44
45 /** The current ident module implementation. */
46 static ident_if_t impl;
47
48 /**
49  * Stores a string in the ident module and returns a handle for the string.
50  *
51  * @param handle   the handle for the set
52  * @param str      the string which shall be stored
53  * @param len      length of str in bytes
54  *
55  * @return id - a handle for the generated ident
56  *
57  * Default implementation using libfirm sets.
58  */
59 static ident *set_new_id_from_chars(void *handle, const char *str, int len)
60 {
61   set *id_set = handle;
62
63   /* GL: Who added this assert?  And why? */
64   //assert(len > 0);
65   return (ident *)set_hinsert0(id_set, str, len, ID_HASH(unsigned char, str, len));
66 }
67
68 /**
69  * Stores a string in the ident module and returns a handle for the string.
70  *
71  * @param handle   the handle for the set
72  * @param str      the string (or whatever) which shall be stored
73  *
74  * Default implementation using libfirm sets.
75  */
76 static ident *set_new_id_from_str(void *handle, const char *str)
77 {
78   assert(str);
79   return (ident *)set_new_id_from_chars(handle, str, strlen(str));
80 }
81
82 /**
83  * Returns a string represented by an ident.
84  *
85  * @param handle   the handle for the set
86  * @param id       the ident
87  *
88  * Default implementation using libfirm sets.
89  */
90 static const char *set_get_id_str(void *handle, ident *id)
91 {
92   struct set_entry *entry = (struct set_entry *)id;
93   (void) handle;
94
95   return (const char *)entry->dptr;
96 }
97
98 /**
99  * Returns the length of the string represented by an ident.
100  *
101  * @param handle   the handle for the set
102  * @param id       the ident
103  *
104  * Default implementation using libfirm sets.
105  */
106 static int set_get_id_strlen(void *handle, ident *id)
107 {
108   struct set_entry *entry = (struct set_entry *)id;
109   (void) handle;
110
111   return entry->size;
112 }
113
114 /**
115  * Default implementation using libfirm sets.
116  */
117 void set_finish_ident(void *handle) {
118   set *id_set = handle;
119
120   del_set(id_set);
121 }
122
123 /**
124  * Default implementation if no new_id_from_str() is provided.
125  */
126 static ident *def_new_id_from_str(void *handle, const char *str)
127 {
128   return impl.new_id_from_chars(handle, str, strlen(str));
129 }
130
131 /**
132  * Default implementation if no get_id_strlen() is provided.
133  */
134 static int def_get_id_strlen(void *handle, ident *id)
135 {
136   return strlen(impl.get_id_str(handle, id));
137 }
138
139 /* Initialize the ident module. */
140 void init_ident(ident_if_t *id_if, int initial_n_idents)
141 {
142   if (id_if) {
143     memcpy(&impl, id_if, sizeof(impl));
144
145     if (! impl.new_id_from_str)
146       impl.new_id_from_str = def_new_id_from_str;
147     if (! impl.get_id_strlen)
148       impl.get_id_strlen = def_get_id_strlen;
149   } else {
150    impl.new_id_from_str    = set_new_id_from_str;
151    impl.new_id_from_chars  = set_new_id_from_chars;
152    impl.get_id_str         = set_get_id_str;
153    impl.get_id_strlen      = set_get_id_strlen;
154    impl.finish_ident       = set_finish_ident;
155
156    /* it's ok to use memcmp here, we check only strings */
157    impl.handle = new_set(memcmp, initial_n_idents);
158   }
159 }
160
161 ident *new_id_from_str(const char *str)
162 {
163   assert(str);
164   return impl.new_id_from_str(impl.handle, str);
165 }
166
167 ident *new_id_from_chars(const char *str, int len)
168 {
169   assert(len > 0);
170   return impl.new_id_from_chars(impl.handle, str, len);
171 }
172
173 const char *get_id_str(ident *id)
174 {
175   return impl.get_id_str(impl.handle, id);
176 }
177
178 int get_id_strlen(ident *id)
179 {
180   return impl.get_id_strlen(impl.handle, id);
181 }
182
183 void finish_ident(void) {
184   if (impl.finish_ident)
185     impl.finish_ident(impl.handle);
186 }
187
188 int id_is_prefix(ident *prefix, ident *id)
189 {
190   if (get_id_strlen(prefix) > get_id_strlen(id)) return 0;
191   return 0 == memcmp(get_id_str(prefix), get_id_str(id), get_id_strlen(prefix));
192 }
193
194 int id_is_suffix(ident *suffix, ident *id)
195 {
196   int suflen = get_id_strlen(suffix);
197   int idlen  = get_id_strlen(id);
198   const char *part;
199
200   if (suflen > idlen) return 0;
201
202   part = get_id_str(id);
203   part = part + (idlen - suflen);
204
205   return 0 == memcmp(get_id_str(suffix), part, suflen);
206 }
207
208 int id_contains_char(ident *id, char c)
209 {
210   return strchr(get_id_str(id), c) != NULL;
211 }
212
213 ident *id_unique(const char *tag)
214 {
215         static unsigned unique_id = 0;
216         char buf[256];
217
218         snprintf(buf, sizeof(buf), tag, unique_id);
219         unique_id++;
220         return new_id_from_str(buf);
221 }