/simpletypesystem/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/simpletypesystem/trunk

« back to all changes in this revision

Viewing changes to libssts/Error.c

  • Committer: Gustav Hartvigsson
  • Date: 2015-10-24 19:55:57 UTC
  • Revision ID: gustav.hartvigsson@gmail.com-20151024195557-lpmkc68r52x4t63h
* General cleanup/make it pritty.
* Added s_dynamic_array_append.
* Implimented the new Error System w/ error domains.
* Added s_string_is_equal
* changed char to schar here and there.
TODO:
  Change the tests to match the new error system.

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
#include <assert.h>
28
28
#include "utils.h"
29
29
#include "LinkedList.h"
30
 
 
31
 
typedef struct SErrorItem {
 
30
#include "DynamicArray.h"
 
31
 
 
32
 
 
33
/* **************************************************************************
 
34
 *********************** INTERNALS ******************************************
 
35
 **************************************************************************** */
 
36
 
 
37
typedef
 
38
struct SErrorItem {
32
39
  schar * message;
33
 
  SErrorType error_type;
 
40
  SErrorDomain error_domain;
 
41
  sint error_type;
34
42
} SErrorItem;
35
43
 
36
44
struct SError {
37
45
  SLinkedList * error_list; /* SLinkedList<SErrorItem *> */
38
46
};
39
47
 
40
 
schar *
41
 
error_to_string_method (SObject * self);
42
 
void
43
 
error_free_method (SError * self);
44
 
 
45
 
SError *
46
 
s_error_new (SErrorType error, char * message) {
47
 
  SError * self = malloc (sizeof (SError));
48
 
  
49
 
  
50
 
  
51
 
  return self;
 
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
 
 
89
void
 
90
s_error_new (SError * self ,sint error, const char * message, SErrorDomain error_domain) {
 
91
  SErrorItem * item = malloc (sizeof (SErrorItem));
 
92
  if (!(self)) {
 
93
    self = malloc (sizeof (SError));
 
94
    self->error_list = s_linked_list_new (FREEFUNC (_internal_s_error_domain_item_free));
 
95
  }
 
96
 
 
97
  item->message = s_string_new (message);
 
98
  item->error_type = error;
 
99
  item->error_domain = error_domain;
 
100
 
 
101
  s_linked_list_append (self->error_list, item);
 
102
}
 
103
 
 
104
SDynamicArray *
 
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));
 
109
 
 
110
  s_linked_list_for_each (self->error_list,
 
111
                          FOREACHFUNC(_internal_s_error_list_for_each_item),
 
112
                          ret_val);
 
113
 
 
114
  return ret_val;
52
115
}
53
116
 
54
117
void
57
120
  free (self);
58
121
}
59
122
 
60
 
#if 0
61
 
schar *
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]);
67
 
  
68
 
  ret_val = s_string_new_fmt ("Error: %s, Message: %s", error_type_str, self->priv->message);
69
 
  free (error_type_str);
70
 
  return ret_val;
71
 
}
72
 
#endif
73
 
 
74
 
 
75
 
schar *
76
 
s_error_get_name (SErrorType k) {
77
 
  return SErrorTypeName[k];
78
 
}
79
 
 
 
123
void
 
124
s_error_teardown () {
 
125
  if (_internal_s_error_domain_list) {
 
126
    s_dynamic_array_free (_internal_s_error_domain_list, TRUE);
 
127
  }
 
128
}
 
129
 
 
130
 
 
131
 
 
132
/* **************************************************************************
 
133
 *********************** SErrorDomain ***************************************
 
134
 **************************************************************************** */
 
135
 
 
136
SErrorDomain
 
137
s_error_get_domain (const schar * name, SErrorDomainToString to_string_func) {
 
138
  SErrorDomainItem * item = NULL;
 
139
 
 
140
  if (strlen (name) == 0 || to_string_func == NULL) {
 
141
    s_err_print ("Domain name or to_string_func not set.\n");
 
142
    return -2;
 
143
  }
 
144
 
 
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));
 
151
    item->domain = 0;
 
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);
 
155
  }
 
156
 
 
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 "
 
160
                   "callback.\n"
 
161
                   "This is not allowed! \n");
 
162
      return -1;
 
163
    }
 
164
    return 0;
 
165
  }
 
166
 
 
167
  /* We hash the domain name and see it the domain exists. */
 
168
  SErrorDomain domain = s_hash (name) % S_ERROR_DOMAIN_RANGE_MAX;
 
169
 
 
170
  SErrorDomainItem * item_2 = (SErrorDomainItem *) s_dynamic_array_get
 
171
                              (_internal_s_error_domain_list, domain);
 
172
  if ((item_2) == NULL) {
 
173
    /*
 
174
     * The item dose not exist in the array, lets just add it.
 
175
     */
 
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);
 
180
 
 
181
    s_dynamic_array_set (_internal_s_error_domain_list ,domain, item);
 
182
 
 
183
    return domain;
 
184
  } else {
 
185
    /* We got samething. See it it is correct */
 
186
    if (s_string_is_equal(item_2->domain_name, name)) {
 
187
      return domain;
 
188
    }
 
189
    /*
 
190
     * We must now check each item untill we reach a NULL.
 
191
     */
 
192
    for (sint i = domain;
 
193
           i <= s_dynamic_array_size (_internal_s_error_domain_list);
 
194
             i++) {
 
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.
 
198
      } else {
 
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);
 
203
            return -1;
 
204
          } else {
 
205
            return i;
 
206
          }
 
207
        }
 
208
      }
 
209
    }
 
210
  }
 
211
 
 
212
  /*
 
213
   * The error domain does not exist.
 
214
   */
 
215
  for (/* domain */;
 
216
       domain <= s_dynamic_array_size (_internal_s_error_domain_list) + 1;
 
217
       domain++) {
 
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;
 
223
      return domain;
 
224
    }
 
225
  }
 
226
 
 
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");
 
229
  print_backtrace ();
 
230
 
 
231
  return -666;
 
232
}
 
233
 
 
234
 
 
235
 
 
236
/* **************************************************************************
 
237
 *********************** INTERNALS ******************************************
 
238
 **************************************************************************** */
 
239
 
 
240
void
 
241
_internal_s_error_domain_item_free (SErrorDomainItem * self) {
 
242
  free (self->domain_name);
 
243
  free (self);
 
244
}
 
245
 
 
246
void
 
247
_internal_s_error_list_for_each_item (SDynamicArray * in_array,
 
248
                                      SErrorItem * item,
 
249
                                      SDynamicArray * out_array) {
 
250
  SErrorDomainItem * domain_item = s_dynamic_array_get (
 
251
                                          _internal_s_error_domain_list,
 
252
                                          item->error_domain);
 
253
  SErrorDomainToString to_string_func = domain_item->to_string_func;
 
254
  s_dynamic_array_append (out_array, to_string_func (item->error_type,
 
255
                                                     item->message));
 
256
}
 
257
 
 
258
void
 
259
_internal_s_error_item_free (SErrorItem * self) {
 
260
  free (self->message);
 
261
  free (self);
 
262
}