fix weak external functions
[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   set *id_set = handle;
117
118   del_set(id_set);
119 }
120
121 /**
122  * Default implementation if no new_id_from_str() is provided.
123  */
124 static ident *def_new_id_from_str(void *handle, const char *str)
125 {
126   return impl.new_id_from_chars(handle, str, strlen(str));
127 }
128
129 /**
130  * Default implementation if no get_id_strlen() is provided.
131  */
132 static int def_get_id_strlen(void *handle, ident *id)
133 {
134   return strlen(impl.get_id_str(handle, id));
135 }
136
137 /* Initialize the ident module. */
138 void init_ident(ident_if_t *id_if, int initial_n_idents)
139 {
140   if (id_if) {
141     memcpy(&impl, id_if, sizeof(impl));
142
143     if (! impl.new_id_from_str)
144       impl.new_id_from_str = def_new_id_from_str;
145     if (! impl.get_id_strlen)
146       impl.get_id_strlen = def_get_id_strlen;
147   } else {
148    impl.new_id_from_str    = set_new_id_from_str;
149    impl.new_id_from_chars  = set_new_id_from_chars;
150    impl.get_id_str         = set_get_id_str;
151    impl.get_id_strlen      = set_get_id_strlen;
152    impl.finish_ident       = set_finish_ident;
153
154    /* it's ok to use memcmp here, we check only strings */
155    impl.handle = new_set(memcmp, initial_n_idents);
156   }
157 }
158
159 ident *new_id_from_str(const char *str)
160 {
161   assert(str != NULL);
162   return impl.new_id_from_str(impl.handle, str);
163 }
164
165 ident *new_id_from_chars(const char *str, int len)
166 {
167   return impl.new_id_from_chars(impl.handle, str, len);
168 }
169
170 const char *get_id_str(ident *id)
171 {
172   return impl.get_id_str(impl.handle, id);
173 }
174
175 int get_id_strlen(ident *id)
176 {
177   return impl.get_id_strlen(impl.handle, id);
178 }
179
180 void finish_ident(void) {
181   if (impl.finish_ident)
182     impl.finish_ident(impl.handle);
183 }
184
185 int id_is_prefix(ident *prefix, ident *id)
186 {
187   if (get_id_strlen(prefix) > get_id_strlen(id)) return 0;
188   return 0 == memcmp(get_id_str(prefix), get_id_str(id), get_id_strlen(prefix));
189 }
190
191 int id_is_suffix(ident *suffix, ident *id)
192 {
193   int suflen = get_id_strlen(suffix);
194   int idlen  = get_id_strlen(id);
195   const char *part;
196
197   if (suflen > idlen) return 0;
198
199   part = get_id_str(id);
200   part = part + (idlen - suflen);
201
202   return 0 == memcmp(get_id_str(suffix), part, suflen);
203 }
204
205 int id_contains_char(ident *id, char c)
206 {
207   return strchr(get_id_str(id), c) != NULL;
208 }
209
210 ident *id_unique(const char *tag)
211 {
212         static unsigned unique_id = 0;
213         char buf[256];
214
215         snprintf(buf, sizeof(buf), tag, unique_id);
216         unique_id++;
217         return new_id_from_str(buf);
218 }