- remove block parameter from new_r_Proj and new_rd_Proj
[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   return (ident *)set_hinsert0(id_set, str, len, ID_HASH(unsigned char, str, len));
64 }
65
66 /**
67  * Stores a string in the ident module and returns a handle for the string.
68  *
69  * @param handle   the handle for the set
70  * @param str      the string (or whatever) which shall be stored
71  *
72  * Default implementation using libfirm sets.
73  */
74 static ident *set_new_id_from_str(void *handle, const char *str)
75 {
76   assert(str);
77   return set_new_id_from_chars(handle, str, strlen(str));
78 }
79
80 /**
81  * Returns a string represented by an ident.
82  *
83  * @param handle   the handle for the set
84  * @param id       the ident
85  *
86  * Default implementation using libfirm sets.
87  */
88 static const char *set_get_id_str(void *handle, ident *id)
89 {
90   struct set_entry *entry = (struct set_entry *)id;
91   (void) handle;
92
93   return (const char *)entry->dptr;
94 }
95
96 /**
97  * Returns the length of the string represented by an ident.
98  *
99  * @param handle   the handle for the set
100  * @param id       the ident
101  *
102  * Default implementation using libfirm sets.
103  */
104 static int set_get_id_strlen(void *handle, ident *id)
105 {
106   struct set_entry *entry = (struct set_entry *)id;
107   (void) handle;
108
109   return entry->size;
110 }
111
112 /**
113  * Default implementation using libfirm sets.
114  */
115 void set_finish_ident(void *handle)
116 {
117   set *id_set = handle;
118
119   del_set(id_set);
120 }
121
122 /**
123  * Default implementation if no new_id_from_str() is provided.
124  */
125 static ident *def_new_id_from_str(void *handle, const char *str)
126 {
127   return impl.new_id_from_chars(handle, str, strlen(str));
128 }
129
130 /**
131  * Default implementation if no get_id_strlen() is provided.
132  */
133 static int def_get_id_strlen(void *handle, ident *id)
134 {
135   return strlen(impl.get_id_str(handle, id));
136 }
137
138 /* Initialize the ident module. */
139 void init_ident(ident_if_t *id_if, int initial_n_idents)
140 {
141   if (id_if) {
142     memcpy(&impl, id_if, sizeof(impl));
143
144     if (! impl.new_id_from_str)
145       impl.new_id_from_str = def_new_id_from_str;
146     if (! impl.get_id_strlen)
147       impl.get_id_strlen = def_get_id_strlen;
148   } else {
149    impl.new_id_from_str    = set_new_id_from_str;
150    impl.new_id_from_chars  = set_new_id_from_chars;
151    impl.get_id_str         = set_get_id_str;
152    impl.get_id_strlen      = set_get_id_strlen;
153    impl.finish_ident       = set_finish_ident;
154
155    /* it's ok to use memcmp here, we check only strings */
156    impl.handle = new_set(memcmp, initial_n_idents);
157   }
158 }
159
160 ident *new_id_from_str(const char *str)
161 {
162   assert(str != NULL);
163   return impl.new_id_from_str(impl.handle, str);
164 }
165
166 ident *new_id_from_chars(const char *str, int len)
167 {
168   return impl.new_id_from_chars(impl.handle, str, len);
169 }
170
171 const char *get_id_str(ident *id)
172 {
173   return impl.get_id_str(impl.handle, id);
174 }
175
176 int get_id_strlen(ident *id)
177 {
178   return impl.get_id_strlen(impl.handle, id);
179 }
180
181 void finish_ident(void)
182 {
183   if (impl.finish_ident)
184     impl.finish_ident(impl.handle);
185 }
186
187 int id_is_prefix(ident *prefix, ident *id)
188 {
189   if (get_id_strlen(prefix) > get_id_strlen(id)) return 0;
190   return 0 == memcmp(get_id_str(prefix), get_id_str(id), get_id_strlen(prefix));
191 }
192
193 int id_is_suffix(ident *suffix, ident *id)
194 {
195   int suflen = get_id_strlen(suffix);
196   int idlen  = get_id_strlen(id);
197   const char *part;
198
199   if (suflen > idlen) return 0;
200
201   part = get_id_str(id);
202   part = part + (idlen - suflen);
203
204   return 0 == memcmp(get_id_str(suffix), part, suflen);
205 }
206
207 int id_contains_char(ident *id, char c)
208 {
209   return strchr(get_id_str(id), c) != NULL;
210 }
211
212 ident *id_unique(const char *tag)
213 {
214         static unsigned unique_id = 0;
215         char buf[256];
216
217         snprintf(buf, sizeof(buf), tag, unique_id);
218         unique_id++;
219         return new_id_from_str(buf);
220 }