27
27
#include <assert.h>
29
29
#include "LinkedList.h"
31
typedef struct SErrorItem {
30
#include "DynamicArray.h"
33
/* **************************************************************************
34
*********************** INTERNALS ******************************************
35
**************************************************************************** */
33
SErrorType error_type;
40
SErrorDomain error_domain;
37
45
SLinkedList * error_list; /* SLinkedList<SErrorItem *> */
41
error_to_string_method (SObject * self);
43
error_free_method (SError * self);
46
s_error_new (SErrorType error, char * message) {
47
SError * self = malloc (sizeof (SError));
50
struct SErrorDomainItem {
52
SErrorDomainToString to_string_func;
58
_internal_s_error_domain_list = NULL; /* <SErrorDomainItem *> */
61
_internal_s_error_domain_item_free (SErrorDomainItem * self);
64
_internal_s_error_item_free (SErrorItem * self);
67
_internal_s_error_list_for_each_item (SDynamicArray * in_array,
69
SDynamicArray * out_array);
72
s_default_error_domain_to_string (sint error_id, schar * msg) {
73
schar * ret_val = s_string_new_fmt ("Error %d (%s): %s",
75
s_default_error_get_name (error_id),
81
s_default_error_get_name (SDefaultErrorType k) {
82
return SDefaultErrorTypeName[k];
85
/* **************************************************************************
86
************************** SError ******************************************
87
**************************************************************************** */
90
s_error_new (SError * self ,sint error, const char * message, SErrorDomain error_domain) {
91
SErrorItem * item = malloc (sizeof (SErrorItem));
93
self = malloc (sizeof (SError));
94
self->error_list = s_linked_list_new (FREEFUNC (_internal_s_error_domain_item_free));
97
item->message = s_string_new (message);
98
item->error_type = error;
99
item->error_domain = error_domain;
101
s_linked_list_append (self->error_list, item);
105
s_error_to_string_array (SError * self) {
106
SDynamicArray * ret_val = s_dynamic_array_new (
107
s_linked_list_len (self->error_list),
108
FREEFUNC (_internal_s_error_domain_item_free));
110
s_linked_list_for_each (self->error_list,
111
FOREACHFUNC(_internal_s_error_list_for_each_item),
62
error_to_string_method (SObject * obj) {
63
SError * self = S_ERROR (obj);
64
schar * ret_val = NULL;
65
schar * error_type_str = NULL;
66
error_type_str = s_string_new (SErrorTypeName[self->priv->error_type]);
68
ret_val = s_string_new_fmt ("Error: %s, Message: %s", error_type_str, self->priv->message);
69
free (error_type_str);
76
s_error_get_name (SErrorType k) {
77
return SErrorTypeName[k];
124
s_error_teardown () {
125
if (_internal_s_error_domain_list) {
126
s_dynamic_array_free (_internal_s_error_domain_list, TRUE);
132
/* **************************************************************************
133
*********************** SErrorDomain ***************************************
134
**************************************************************************** */
137
s_error_get_domain (const schar * name, SErrorDomainToString to_string_func) {
138
SErrorDomainItem * item = NULL;
140
if (strlen (name) == 0 || to_string_func == NULL) {
141
s_err_print ("Domain name or to_string_func not set.\n");
145
if (!(_internal_s_error_domain_list)) {
146
_internal_s_error_domain_list =
147
s_dynamic_array_new (S_ERROR_DOMAIN_RANGE_MAX,
148
FREEFUNC (_internal_s_error_domain_item_free));
149
// The default key is always 0
150
item = malloc (sizeof (SErrorDomainItem));
152
item->to_string_func = s_default_error_domain_to_string;
153
item->domain_name = s_string_new ("default");
154
s_dynamic_array_set (_internal_s_error_domain_list, 0, item);
157
if (s_string_is_equal (name, "default")) {
158
if (to_string_func != s_default_error_domain_to_string) {
159
s_err_print ("Trying to override the default error domain to string "
161
"This is not allowed! \n");
167
/* We hash the domain name and see it the domain exists. */
168
SErrorDomain domain = s_hash (name) % S_ERROR_DOMAIN_RANGE_MAX;
170
SErrorDomainItem * item_2 = (SErrorDomainItem *) s_dynamic_array_get
171
(_internal_s_error_domain_list, domain);
172
if ((item_2) == NULL) {
174
* The item dose not exist in the array, lets just add it.
176
item = malloc (sizeof (SErrorDomainItem));
177
item->domain = domain;
178
item->to_string_func = to_string_func;
179
item->domain_name = s_string_new (name);
181
s_dynamic_array_set (_internal_s_error_domain_list ,domain, item);
185
/* We got samething. See it it is correct */
186
if (s_string_is_equal(item_2->domain_name, name)) {
190
* We must now check each item untill we reach a NULL.
192
for (sint i = domain;
193
i <= s_dynamic_array_size (_internal_s_error_domain_list);
195
item_2 = (SErrorDomainItem *) s_dynamic_array_get (_internal_s_error_domain_list, i);
196
if ((item_2) == NULL) {
197
break; // This jumps out of the loop and to the for-loop below.
199
if (s_string_is_equal (item_2->domain_name, name)) {
200
if (item_2->to_string_func != to_string_func) {
201
s_err_print ("Trying to override to string function for error "
202
"domain %s.\nThis is not allowed!\n", name);
213
* The error domain does not exist.
216
domain <= s_dynamic_array_size (_internal_s_error_domain_list) + 1;
218
if (!(s_dynamic_array_get(_internal_s_error_domain_list ,domain))) {
219
item = malloc (sizeof (SErrorDomainItem));
220
item->domain = domain;
221
item->domain_name = s_string_new (name);
222
item->to_string_func = to_string_func;
227
s_err_print ("Reaching a place where it should not reach. This is a sign "
228
"that the devil has been messing with time and space.\n");
236
/* **************************************************************************
237
*********************** INTERNALS ******************************************
238
**************************************************************************** */
241
_internal_s_error_domain_item_free (SErrorDomainItem * self) {
242
free (self->domain_name);
247
_internal_s_error_list_for_each_item (SDynamicArray * in_array,
249
SDynamicArray * out_array) {
250
SErrorDomainItem * domain_item = s_dynamic_array_get (
251
_internal_s_error_domain_list,
253
SErrorDomainToString to_string_func = domain_item->to_string_func;
254
s_dynamic_array_append (out_array, to_string_func (item->error_type,
259
_internal_s_error_item_free (SErrorItem * self) {
260
free (self->message);