/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,
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
}