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, |
|
68 |
SErrorItem * item, |
|
69 |
SDynamicArray * out_array); |
|
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) { |
|
91 |
SError * self = malloc (sizeof (SError)); |
|
92 |
self->error_list = s_linked_list_new (FREEFUNC (_internal_s_error_domain_item_free)); |
|
93 |
return self; |
|
94 |
}
|
|
95 |
||
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
96 |
void
|
104
by Gustav Hartvigsson
* Passing arguments can not be initialised from within a function... |
97 |
s_error_append (SError * self ,sint error, const char * message, SErrorDomain error_domain) { |
98 |
assert (self != NULL); |
|
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
99 |
SErrorItem * item = malloc (sizeof (SErrorItem)); |
100 |
||
101 |
item->message = s_string_new (message); |
|
102 |
item->error_type = error; |
|
103 |
item->error_domain = error_domain; |
|
104 |
||
105 |
s_linked_list_append (self->error_list, item); |
|
106 |
}
|
|
107 |
||
108 |
SDynamicArray * |
|
109 |
s_error_to_string_array (SError * self) { |
|
104
by Gustav Hartvigsson
* Passing arguments can not be initialised from within a function... |
110 |
assert (self != NULL); |
111 |
||
112 |
size_t out_arr_len = s_linked_list_len (self->error_list); |
|
113 |
||
114 |
SDynamicArray * ret_val = s_dynamic_array_new (out_arr_len, NULL); |
|
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
115 |
|
116 |
s_linked_list_for_each (self->error_list, |
|
117 |
FOREACHFUNC(_internal_s_error_list_for_each_item), |
|
118 |
ret_val); |
|
119 |
||
120 |
return ret_val; |
|
3
by Gustav Hartvigsson
Fixed a few things... |
121 |
}
|
122 |
||
61
by Gustav Hartvigsson
* Made the code more easy to read. |
123 |
void
|
100
by Gustav Hartvigsson
* Fixed README. |
124 |
error_free (SError * self) { |
101
by Gustav Hartvigsson
* Re-Added the inlines... |
125 |
s_linked_list_free (self->error_list, TRUE); |
100
by Gustav Hartvigsson
* Fixed README. |
126 |
free (self); |
3
by Gustav Hartvigsson
Fixed a few things... |
127 |
}
|
128 |
||
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
129 |
void
|
130 |
s_error_teardown () { |
|
104
by Gustav Hartvigsson
* Passing arguments can not be initialised from within a function... |
131 |
s_dbg_print ("Taring down error system."); |
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
132 |
if (_internal_s_error_domain_list) { |
133 |
s_dynamic_array_free (_internal_s_error_domain_list, TRUE); |
|
134 |
} |
|
104
by Gustav Hartvigsson
* Passing arguments can not be initialised from within a function... |
135 |
s_dbg_print ("Done taring down error system."); |
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
136 |
}
|
137 |
||
138 |
||
139 |
||
140 |
/* **************************************************************************
|
|
141 |
*********************** SErrorDomain ***************************************
|
|
142 |
**************************************************************************** */
|
|
143 |
||
144 |
SErrorDomain
|
|
145 |
s_error_get_domain (const schar * name, SErrorDomainToString to_string_func) { |
|
146 |
SErrorDomainItem * item = NULL; |
|
147 |
||
148 |
if (strlen (name) == 0 || to_string_func == NULL) { |
|
149 |
s_err_print ("Domain name or to_string_func not set.\n"); |
|
150 |
return -2; |
|
151 |
} |
|
152 |
||
153 |
if (!(_internal_s_error_domain_list)) { |
|
104
by Gustav Hartvigsson
* Passing arguments can not be initialised from within a function... |
154 |
s_dbg_print ("Array does not exist, lets crete it!"); |
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
155 |
_internal_s_error_domain_list = |
156 |
s_dynamic_array_new (S_ERROR_DOMAIN_RANGE_MAX, |
|
157 |
FREEFUNC (_internal_s_error_domain_item_free)); |
|
158 |
// The default key is always 0 |
|
159 |
item = malloc (sizeof (SErrorDomainItem)); |
|
160 |
item->domain = 0; |
|
161 |
item->to_string_func = s_default_error_domain_to_string; |
|
162 |
item->domain_name = s_string_new ("default"); |
|
163 |
s_dynamic_array_set (_internal_s_error_domain_list, 0, item); |
|
164 |
} |
|
165 |
||
166 |
if (s_string_is_equal (name, "default")) { |
|
104
by Gustav Hartvigsson
* Passing arguments can not be initialised from within a function... |
167 |
s_dbg_print ("Default error domain"); |
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
168 |
if (to_string_func != s_default_error_domain_to_string) { |
169 |
s_err_print ("Trying to override the default error domain to string " |
|
170 |
"callback.\n" |
|
171 |
"This is not allowed! \n"); |
|
172 |
return -1; |
|
173 |
} |
|
174 |
return 0; |
|
175 |
} |
|
176 |
||
177 |
/* We hash the domain name and see it the domain exists. */ |
|
178 |
SErrorDomain domain = s_hash (name) % S_ERROR_DOMAIN_RANGE_MAX; |
|
179 |
||
180 |
SErrorDomainItem * item_2 = (SErrorDomainItem *) s_dynamic_array_get |
|
181 |
(_internal_s_error_domain_list, domain); |
|
182 |
if ((item_2) == NULL) { |
|
183 |
/* |
|
184 |
* The item dose not exist in the array, lets just add it.
|
|
185 |
*/
|
|
186 |
item = malloc (sizeof (SErrorDomainItem)); |
|
187 |
item->domain = domain; |
|
188 |
item->to_string_func = to_string_func; |
|
189 |
item->domain_name = s_string_new (name); |
|
190 |
||
191 |
s_dynamic_array_set (_internal_s_error_domain_list ,domain, item); |
|
192 |
||
193 |
return domain; |
|
194 |
} else { |
|
195 |
/* We got samething. See it it is correct */ |
|
196 |
if (s_string_is_equal(item_2->domain_name, name)) { |
|
197 |
return domain; |
|
198 |
} |
|
199 |
/* |
|
200 |
* We must now check each item untill we reach a NULL.
|
|
201 |
*/
|
|
202 |
for (sint i = domain; |
|
203 |
i <= s_dynamic_array_size (_internal_s_error_domain_list); |
|
204 |
i++) { |
|
205 |
item_2 = (SErrorDomainItem *) s_dynamic_array_get (_internal_s_error_domain_list, i); |
|
206 |
if ((item_2) == NULL) { |
|
207 |
break; // This jumps out of the loop and to the for-loop below. |
|
208 |
} else { |
|
209 |
if (s_string_is_equal (item_2->domain_name, name)) { |
|
210 |
if (item_2->to_string_func != to_string_func) { |
|
211 |
s_err_print ("Trying to override to string function for error " |
|
212 |
"domain %s.\nThis is not allowed!\n", name); |
|
213 |
return -1; |
|
214 |
} else { |
|
215 |
return i; |
|
216 |
} |
|
217 |
} |
|
218 |
} |
|
219 |
} |
|
220 |
} |
|
221 |
||
222 |
/* |
|
223 |
* The error domain does not exist.
|
|
224 |
*/
|
|
225 |
for (/* domain */; |
|
226 |
domain <= s_dynamic_array_size (_internal_s_error_domain_list) + 1; |
|
227 |
domain++) { |
|
228 |
if (!(s_dynamic_array_get(_internal_s_error_domain_list ,domain))) { |
|
229 |
item = malloc (sizeof (SErrorDomainItem)); |
|
230 |
item->domain = domain; |
|
231 |
item->domain_name = s_string_new (name); |
|
232 |
item->to_string_func = to_string_func; |
|
233 |
return domain; |
|
234 |
} |
|
235 |
} |
|
236 |
||
237 |
s_err_print ("Reaching a place where it should not reach. This is a sign " |
|
238 |
"that the devil has been messing with time and space.\n"); |
|
239 |
print_backtrace (); |
|
240 |
||
241 |
return -666; |
|
242 |
}
|
|
243 |
||
244 |
||
245 |
||
246 |
/* **************************************************************************
|
|
247 |
*********************** INTERNALS ******************************************
|
|
248 |
**************************************************************************** */
|
|
249 |
||
250 |
void
|
|
251 |
_internal_s_error_domain_item_free (SErrorDomainItem * self) { |
|
107
by Gustav Hartvigsson
* Removed depricaded functions from SObject code. |
252 |
s_dbg_print ("(SErrorDomainItem) %d, %s", self->domain, self->domain_name); |
104
by Gustav Hartvigsson
* Passing arguments can not be initialised from within a function... |
253 |
s_dbg_print ("Freeing name."); |
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
254 |
free (self->domain_name); |
104
by Gustav Hartvigsson
* Passing arguments can not be initialised from within a function... |
255 |
s_dbg_print ("freeing self."); |
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
256 |
free (self); |
104
by Gustav Hartvigsson
* Passing arguments can not be initialised from within a function... |
257 |
s_dbg_print ("Done."); |
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
258 |
}
|
259 |
||
260 |
void
|
|
261 |
_internal_s_error_list_for_each_item (SDynamicArray * in_array, |
|
262 |
SErrorItem * item, |
|
263 |
SDynamicArray * out_array) { |
|
264 |
SErrorDomainItem * domain_item = s_dynamic_array_get ( |
|
265 |
_internal_s_error_domain_list, |
|
266 |
item->error_domain); |
|
104
by Gustav Hartvigsson
* Passing arguments can not be initialised from within a function... |
267 |
|
103
by Gustav Hartvigsson
* General cleanup/make it pritty. |
268 |
SErrorDomainToString to_string_func = domain_item->to_string_func; |
269 |
s_dynamic_array_append (out_array, to_string_func (item->error_type, |
|
270 |
item->message)); |
|
271 |
}
|
|
272 |
||
273 |
void
|
|
274 |
_internal_s_error_item_free (SErrorItem * self) { |
|
275 |
free (self->message); |
|
276 |
free (self); |
|
277 |
}
|