bzr branch
http://gegoxaren.bato24.eu/bzr/simpletypesystem/trunk
5.2.7
by Gustav Hartvigsson
* Switched licence to a more permisive one. |
1 |
/*
|
2 |
Copyright (c) 2013-2014 Gustav Hartvigsson
|
|
3 |
||
4 |
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5 |
of this software and associated documentation files (the "Software"), to deal
|
|
6 |
in the Software without restriction, including without limitation the rights
|
|
7 |
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8 |
copies of the Software, and to permit persons to whom the Software is
|
|
9 |
furnished to do so, subject to the following conditions:
|
|
10 |
||
11 |
The above copyright notice and this permission notice shall be included in
|
|
12 |
all copies or substantial portions of the Software.
|
|
13 |
||
14 |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15 |
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16 |
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17 |
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18 |
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19 |
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
20 |
THE SOFTWARE.
|
|
21 |
*/
|
|
3
by Gustav Hartvigsson
Fixed a few things... |
22 |
|
23 |
#include "Error.h" |
|
24 |
#include <stdlib.h> |
|
25 |
#include <string.h> |
|
26 |
#include <stdio.h> |
|
22
by Gustav Hartvigsson
* Made code compile |
27 |
#include <assert.h> |
39
by Gustav Hartvigsson
* Added "check" target for testing. |
28 |
#include "utils.h" |
100
by Gustav Hartvigsson
* Fixed README. |
29 |
#include "LinkedList.h" |
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
30 |
#include "DynamicArray.h" |
31 |
||
32 |
||
33 |
/* **************************************************************************
|
|
34 |
*********************** INTERNALS ******************************************
|
|
35 |
**************************************************************************** */
|
|
36 |
||
37 |
typedef
|
|
38 |
struct SErrorItem { |
|
81
by Gustav Hartvigsson
* Re arranged members of structs to prevent struct fragmentation and padding. |
39 |
schar * message; |
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
40 |
SErrorDomain error_domain; |
41 |
sint error_type; |
|
100
by Gustav Hartvigsson
* Fixed README. |
42 |
} SErrorItem; |
43 |
||
44 |
struct SError { |
|
45 |
SLinkedList * error_list; /* SLinkedList<SErrorItem *> */ |
|
3
by Gustav Hartvigsson
Fixed a few things... |
46 |
};
|
47 |
||
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
48 |
|
49 |
typedef
|
|
50 |
struct SErrorDomainItem { |
|
51 |
SErrorDomain domain; |
|
52 |
SErrorDomainToString to_string_func; |
|
53 |
schar * domain_name; |
|
54 |
} SErrorDomainItem; |
|
55 |
||
56 |
static
|
|
57 |
SDynamicArray * |
|
58 |
_internal_s_error_domain_list = NULL; /* <SErrorDomainItem *> */ |
|
59 |
||
60 |
void
|
|
61 |
_internal_s_error_domain_item_free (SErrorDomainItem * self); |
|
62 |
||
63 |
void
|
|
64 |
_internal_s_error_item_free (SErrorItem * self); |
|
65 |
||
66 |
void
|
|
67 |
_internal_s_error_list_for_each_item (SDynamicArray * in_array, |
|
162
by Gustav Hartvigsson
* stuff to do with the unfinished base32 implementation. |
68 |
SErrorItem * item, |
69 |
SDynamicArray * out_array); |
|
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
70 |
|
71 |
schar * |
|
72 |
s_default_error_domain_to_string (sint error_id, schar * msg) { |
|
73 |
schar * ret_val = s_string_new_fmt ("Error %d (%s): %s", |
|
74 |
error_id, |
|
75 |
s_default_error_get_name (error_id), |
|
76 |
msg); |
|
77 |
return ret_val; |
|
78 |
}
|
|
79 |
||
80 |
schar * |
|
81 |
s_default_error_get_name (SDefaultErrorType k) { |
|
82 |
return SDefaultErrorTypeName[k]; |
|
83 |
}
|
|
84 |
||
85 |
/* **************************************************************************
|
|
86 |
************************** SError ******************************************
|
|
87 |
**************************************************************************** */
|
|
88 |
||
104
by Gustav Hartvigsson
* Passing arguments can not be initialised from within a function... |
89 |
SError * |
90 |
s_error_new (void) { |
|
121.1.3
by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set. |
91 |
SError * self = s_malloc (sizeof (SError)); |
108
by Gustav Hartvigsson
libssts: |
92 |
self->error_list = s_linked_list_new (FREEFUNC (_internal_s_error_item_free)); |
104
by Gustav Hartvigsson
* Passing arguments can not be initialised from within a function... |
93 |
return self; |
94 |
}
|
|
95 |
||
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
96 |
void
|
108
by Gustav Hartvigsson
libssts: |
97 |
s_error_append (SError * self , |
98 |
sint error, const char * message, |
|
99 |
SErrorDomain error_domain) { |
|
104
by Gustav Hartvigsson
* Passing arguments can not be initialised from within a function... |
100 |
assert (self != NULL); |
109
by Gustav Hartvigsson
* Made s_error_append () return and print an error if it got an ErrorDomain that is not valid. |
101 |
if (error_domain < 0) { |
102 |
s_err_print ("Invalid ErrorDomain"); |
|
103 |
||
104 |
print_backtrace (); |
|
105 |
||
106 |
return; |
|
107 |
} |
|
108 |
||
121.1.3
by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set. |
109 |
SErrorItem * item = s_malloc (sizeof (SErrorItem)); |
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
110 |
|
111 |
item->message = s_string_new (message); |
|
112 |
item->error_type = error; |
|
113 |
item->error_domain = error_domain; |
|
114 |
||
115 |
s_linked_list_append (self->error_list, item); |
|
116 |
}
|
|
117 |
||
108
by Gustav Hartvigsson
libssts: |
118 |
sboolean
|
119 |
s_error_has_error (SError * self) { |
|
120 |
if (self != NULL) { |
|
121 |
if (s_linked_list_get_current (self->error_list)) { |
|
122 |
return TRUE; |
|
123 |
} |
|
124 |
} |
|
125 |
return FALSE; |
|
126 |
}
|
|
127 |
||
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
128 |
SDynamicArray * |
129 |
s_error_to_string_array (SError * self) { |
|
104
by Gustav Hartvigsson
* Passing arguments can not be initialised from within a function... |
130 |
assert (self != NULL); |
131 |
||
132 |
size_t out_arr_len = s_linked_list_len (self->error_list); |
|
133 |
||
134 |
SDynamicArray * ret_val = s_dynamic_array_new (out_arr_len, NULL); |
|
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
135 |
|
136 |
s_linked_list_for_each (self->error_list, |
|
137 |
FOREACHFUNC(_internal_s_error_list_for_each_item), |
|
138 |
ret_val); |
|
139 |
||
140 |
return ret_val; |
|
3
by Gustav Hartvigsson
Fixed a few things... |
141 |
}
|
142 |
||
61
by Gustav Hartvigsson
* Made the code more easy to read. |
143 |
void
|
108
by Gustav Hartvigsson
libssts: |
144 |
s_error_free (SError * self) { |
101
by Gustav Hartvigsson
* Re-Added the inlines... |
145 |
s_linked_list_free (self->error_list, TRUE); |
121.1.3
by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set. |
146 |
s_free (self); |
3
by Gustav Hartvigsson
Fixed a few things... |
147 |
}
|
148 |
||
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
149 |
void
|
150 |
s_error_teardown () { |
|
108
by Gustav Hartvigsson
libssts: |
151 |
s_dbg_print ("Taring down error system...."); |
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
152 |
if (_internal_s_error_domain_list) { |
153 |
s_dynamic_array_free (_internal_s_error_domain_list, TRUE); |
|
154 |
} |
|
109.1.5
by Gustav Hartvigsson
* Getting closer to fixing the callbacks... |
155 |
s_dbg_print ("Done tearing down error system."); |
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
156 |
}
|
157 |
||
158 |
||
159 |
||
160 |
/* **************************************************************************
|
|
161 |
*********************** SErrorDomain ***************************************
|
|
162 |
**************************************************************************** */
|
|
163 |
||
164 |
SErrorDomain
|
|
165 |
s_error_get_domain (const schar * name, SErrorDomainToString to_string_func) { |
|
166 |
SErrorDomainItem * item = NULL; |
|
167 |
||
168 |
if (strlen (name) == 0 || to_string_func == NULL) { |
|
169 |
s_err_print ("Domain name or to_string_func not set.\n"); |
|
170 |
return -2; |
|
171 |
} |
|
172 |
||
173 |
if (!(_internal_s_error_domain_list)) { |
|
109.1.5
by Gustav Hartvigsson
* Getting closer to fixing the callbacks... |
174 |
s_dbg_print ("Array does not exist, lets create it!"); |
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
175 |
_internal_s_error_domain_list = |
176 |
s_dynamic_array_new (S_ERROR_DOMAIN_RANGE_MAX, |
|
177 |
FREEFUNC (_internal_s_error_domain_item_free)); |
|
178 |
// The default key is always 0 |
|
121.1.3
by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set. |
179 |
item = s_malloc (sizeof (SErrorDomainItem)); |
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
180 |
item->domain = 0; |
181 |
item->to_string_func = s_default_error_domain_to_string; |
|
182 |
item->domain_name = s_string_new ("default"); |
|
183 |
s_dynamic_array_set (_internal_s_error_domain_list, 0, item); |
|
184 |
} |
|
185 |
||
186 |
if (s_string_is_equal (name, "default")) { |
|
187 |
if (to_string_func != s_default_error_domain_to_string) { |
|
188 |
s_err_print ("Trying to override the default error domain to string " |
|
189 |
"callback.\n" |
|
190 |
"This is not allowed! \n"); |
|
191 |
return -1; |
|
192 |
} |
|
193 |
return 0; |
|
194 |
} |
|
195 |
||
196 |
/* We hash the domain name and see it the domain exists. */ |
|
197 |
SErrorDomain domain = s_hash (name) % S_ERROR_DOMAIN_RANGE_MAX; |
|
198 |
||
199 |
SErrorDomainItem * item_2 = (SErrorDomainItem *) s_dynamic_array_get |
|
200 |
(_internal_s_error_domain_list, domain); |
|
201 |
if ((item_2) == NULL) { |
|
202 |
/* |
|
203 |
* The item dose not exist in the array, lets just add it.
|
|
204 |
*/
|
|
121.1.3
by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set. |
205 |
item = s_malloc (sizeof (SErrorDomainItem)); |
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
206 |
item->domain = domain; |
207 |
item->to_string_func = to_string_func; |
|
208 |
item->domain_name = s_string_new (name); |
|
209 |
||
210 |
s_dynamic_array_set (_internal_s_error_domain_list ,domain, item); |
|
211 |
||
212 |
return domain; |
|
213 |
} else { |
|
108
by Gustav Hartvigsson
libssts: |
214 |
/* We got something. See it it is correct */ |
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
215 |
if (s_string_is_equal(item_2->domain_name, name)) { |
108
by Gustav Hartvigsson
libssts: |
216 |
if (item_2->to_string_func != to_string_func) { |
217 |
s_err_print ("Trying to overwrite the to string handler" |
|
218 |
"for error domain %s, this is not allowd.", |
|
219 |
name); |
|
220 |
return -1; |
|
221 |
} |
|
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
222 |
return domain; |
223 |
} |
|
224 |
/* |
|
225 |
* We must now check each item untill we reach a NULL.
|
|
226 |
*/
|
|
227 |
for (sint i = domain; |
|
228 |
i <= s_dynamic_array_size (_internal_s_error_domain_list); |
|
229 |
i++) { |
|
230 |
item_2 = (SErrorDomainItem *) s_dynamic_array_get (_internal_s_error_domain_list, i); |
|
231 |
if ((item_2) == NULL) { |
|
232 |
break; // This jumps out of the loop and to the for-loop below. |
|
233 |
} else { |
|
234 |
if (s_string_is_equal (item_2->domain_name, name)) { |
|
235 |
if (item_2->to_string_func != to_string_func) { |
|
236 |
s_err_print ("Trying to override to string function for error " |
|
237 |
"domain %s.\nThis is not allowed!\n", name); |
|
238 |
return -1; |
|
239 |
} else { |
|
240 |
return i; |
|
241 |
} |
|
242 |
} |
|
243 |
} |
|
244 |
} |
|
245 |
} |
|
246 |
||
247 |
/* |
|
248 |
* The error domain does not exist.
|
|
249 |
*/
|
|
250 |
for (/* domain */; |
|
251 |
domain <= s_dynamic_array_size (_internal_s_error_domain_list) + 1; |
|
252 |
domain++) { |
|
253 |
if (!(s_dynamic_array_get(_internal_s_error_domain_list ,domain))) { |
|
121.1.3
by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set. |
254 |
item = s_malloc (sizeof (SErrorDomainItem)); |
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
255 |
item->domain = domain; |
256 |
item->domain_name = s_string_new (name); |
|
257 |
item->to_string_func = to_string_func; |
|
258 |
return domain; |
|
259 |
} |
|
260 |
} |
|
261 |
||
262 |
s_err_print ("Reaching a place where it should not reach. This is a sign " |
|
263 |
"that the devil has been messing with time and space.\n"); |
|
264 |
print_backtrace (); |
|
265 |
||
266 |
return -666; |
|
267 |
}
|
|
268 |
||
269 |
||
270 |
||
271 |
/* **************************************************************************
|
|
272 |
*********************** INTERNALS ******************************************
|
|
273 |
**************************************************************************** */
|
|
274 |
||
275 |
void
|
|
276 |
_internal_s_error_domain_item_free (SErrorDomainItem * self) { |
|
108
by Gustav Hartvigsson
libssts: |
277 |
s_dbg_print ("(SErrorDomainItem) Freeing: %d, %s", |
278 |
self->domain, |
|
279 |
self->domain_name); |
|
121.1.3
by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set. |
280 |
s_free (self->domain_name); |
281 |
s_free (self); |
|
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
282 |
}
|
283 |
||
284 |
void
|
|
285 |
_internal_s_error_list_for_each_item (SDynamicArray * in_array, |
|
286 |
SErrorItem * item, |
|
287 |
SDynamicArray * out_array) { |
|
288 |
SErrorDomainItem * domain_item = s_dynamic_array_get ( |
|
289 |
_internal_s_error_domain_list, |
|
290 |
item->error_domain); |
|
104
by Gustav Hartvigsson
* Passing arguments can not be initialised from within a function... |
291 |
|
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
292 |
SErrorDomainToString to_string_func = domain_item->to_string_func; |
293 |
s_dynamic_array_append (out_array, to_string_func (item->error_type, |
|
294 |
item->message)); |
|
295 |
}
|
|
296 |
||
297 |
void
|
|
298 |
_internal_s_error_item_free (SErrorItem * self) { |
|
108
by Gustav Hartvigsson
libssts: |
299 |
s_dbg_print ("Running free on errori item!"); |
121.1.3
by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set. |
300 |
s_free (self->message); |
301 |
s_free (self); |
|
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
302 |
}
|