/simpletypesystem/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/simpletypesystem/trunk
150 by Gustav Hartvigsson
* Fixed the tests in the CMake file
1
#include "defs.h"
2
#include "types.h"
3
#include "Map.h"
4
5
struct STypeSystem {
6
  STypeInfo** type_map;
7
  size_t last_item;
8
  size_t len;
9
};
10
11
12
STypeSystem * _type_system_object = NULL;
13
14
#define _INIT_TYPE_SYSTEM() {\
15
  if (_type_system_object == NULL) { \
16
    _s_internal_type_system_init();\
17
  }\
18
}
19
20
void
21
_s_internal_type_system_init () {
22
  _type_system_object = s_malloc (sizeof (STypeSystem));
23
  
24
  STypeInfo** type_map = _type_system_object->type_map =
25
               s_calloc (S_TYPE_MAX, sizeof (spointer));
26
  
27
  for (sint i; i < S_TYPE_MAX; i++) {
28
    type_map[i] = NULL;
29
  }
30
  /* The first time we run this we must make sure that we fill out the
31
   * fundamental types correctly */
32
  for (sint i = 0; i < S_TYPE_LAST_PREDEFINED; i++) {
33
    schar * name = STypeName[i];
34
    STypeInfo * ti = s_malloc (sizeof(STypeInfo));
35
    ti->name = s_string_new (name);
36
    ti->id = i;
37
    type_map[i] = ti;
38
  }
39
}
40
41
void
42
s_type_info_free (STypeInfo * ti) {
43
  if (ti) {
44
    s_free (ti->name);
45
    s_free (ti);
46
  }
47
}
48
49
const STypeInfo *
50
s_type_register_return_type_info (schar * name, SType parent) {
51
  _INIT_TYPE_SYSTEM();
52
  
53
  STypeInfo** type_map = _type_system_object->type_map;
54
  
55
  hash_t k = s_hash (name) % S_TYPE_MAX;
56
  
57
  if (k < S_TYPE_LAST_PREDEFINED) { /* Push it up a bit... */
58
    k += S_TYPE_LAST_PREDEFINED;
59
  }
60
  
61
  
62
  /* See if we have anyhing in that possision, if not, we just add it to that
63
   * possition.
64
   *
65
   * If the taken we look up through the array for a free spot.
66
   */
67
  if (type_map[k]) {
68
    while (type_map[k]) {
69
      if (s_string_is_equal (type_map[k]->name, name)) {
70
        return type_map[k];
71
      }
72
      k++;
73
    }
74
  }
75
  
76
  STypeInfo * ti = s_malloc (sizeof (STypeInfo));
77
  ti->name = NULL;
78
  
79
  ti->id = k;
80
  ti->parent = parent;
81
  ti->name = name;
82
  
83
  /*
84
   * Check if we are out-of-bounds and reallocs the array.
85
   */
86
  if (_type_system_object->len < k) {
87
    /* new size is k + 11, cus' why not? */
88
    _type_system_object->len = k + 11;
89
    type_map = s_realloc (type_map, _type_system_object->len);
90
  }
91
  
92
  type_map[k] = ti;
93
  
94
  if (_type_system_object->last_item < k) {
95
    _type_system_object->last_item = k;
96
  }
97
  
98
  return ti;
99
}
100
101
SType
102
s_type_register (schar * name, SType parent) {
103
  return s_type_register_return_type_info (name, parent)->id;
104
}
105
106
char *
107
s_type_get_name (SType k) {
108
  _INIT_TYPE_SYSTEM();
109
  
110
  if (k < S_TYPE_LAST_PREDEFINED) {
111
    return s_string_new(STypeName[k]);
112
  }
113
  
114
  if (!_type_system_object) {
115
    s_warn_print ("Typesystem not initialised.\n Returning.\n");
116
    return NULL;
117
  }
118
  
119
  STypeInfo** type_map = _type_system_object->type_map;
120
  if (type_map[k]) {
121
    return s_string_new (type_map[k]->name);
122
  } else {
123
    return NULL;
124
  }
125
  
126
}
127
128
SType
129
s_type_get_type (schar * name) {
130
  _INIT_TYPE_SYSTEM();
131
  /*
132
   * First do a dumb check if names are in the list of predefined.
133
   */
134
  for (size_t i; i < S_TYPE_LAST_PREDEFINED; i++) {
135
    if (s_string_is_equal (STypeName[i], name)) {
136
      return i;
137
    }
138
  }
139
  
140
  hash_t k = s_hash (name) % S_TYPE_MAX;
141
  
142
  STypeInfo ** type_map = _type_system_object->type_map;
143
  
144
  if (type_map[k]) {
145
    while (type_map[k]) {
146
      if (s_string_is_equal (type_map[k]->name, name)) {
147
        return type_map[k]->id;
148
      }
149
      k++;
150
    }
151
  }
152
  
153
  return S_TYPE_NONE;
154
  
155
}
156
157
SType
158
s_type_get_parent (SType type) {
159
  _INIT_TYPE_SYSTEM();
160
  if (type < S_TYPE_LAST_PREDEFINED) {
161
    return S_TYPE_NONE;
162
  }
163
  
164
  if (_type_system_object->type_map[type]) {
165
    return _type_system_object->type_map[type]->parent;
166
  }
167
  
168
  return S_TYPE_NONE;
169
  
170
}
171
172
SType *
173
s_type_get_array_of_parents (SType type, size_t * out_size) {
174
  _INIT_TYPE_SYSTEM();
175
  
176
  /* The array will hopefully not me longer than this... */
177
  SType * array = s_calloc (sizeof (SType), S_TYPE_MAX);
178
  
179
  STypeInfo ** type_map = _type_system_object->type_map;
180
  
181
  size_t len = 0;
182
  hash_t k = type;
183
  while (TRUE) {
184
    hash_t new_k = 0;
185
    if (type_map[k]) {
186
      new_k = type_map[k]->parent;
187
      array[len] = new_k;
188
      k = new_k;
189
    } else {
190
      break;
191
    }
192
    len++;
193
    if (k == S_TYPE_NONE || k == S_TYPE_INVALID) {
194
      break;
195
    }
196
  }
197
  
198
  *out_size = len;
199
  
151 by Gustav Hartvigsson
* Fixed all warnings (exept the depricated warning...)
200
  if (len == 0) {
150 by Gustav Hartvigsson
* Fixed the tests in the CMake file
201
    s_free (array);
202
    return NULL;
203
  }
204
  
205
  /* truncate array */
206
  array = s_realloc (array, sizeof(SType) * len);
151 by Gustav Hartvigsson
* Fixed all warnings (exept the depricated warning...)
207
  array[len] = (SType) NULL;
150 by Gustav Hartvigsson
* Fixed the tests in the CMake file
208
  
209
  return array;
210
}
211
152 by Gustav Hartvigsson
* Made SRandom compile
212
213
150 by Gustav Hartvigsson
* Fixed the tests in the CMake file
214
void
215
s_type_system_teardown () {
216
  if (!_type_system_object) {
217
    return;
218
  }
219
  
220
  STypeInfo** type_map = _type_system_object->type_map;
221
  
222
  for (sint i = 0; i < _type_system_object->len; i++ ) {
223
    if (type_map[i]) {
224
      s_free (type_map[i]);
225
    }
226
  }
227
  s_free (_type_system_object);
228
}