/simpletypesystem/trunk

To get this branch, use:
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
}