Commit | Line | Data |
---|---|---|
6dc2ca62 | 1 | /* |
ccd7e1c8 MD |
2 | * types.c |
3 | * | |
d79865b9 | 4 | * BabelTrace - Converter |
6dc2ca62 MD |
5 | * |
6 | * Types registry. | |
7 | * | |
c054553d | 8 | * Copyright 2010, 2011 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> |
de0ba614 | 9 | * |
ccd7e1c8 MD |
10 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
11 | * of this software and associated documentation files (the "Software"), to deal | |
12 | * in the Software without restriction, including without limitation the rights | |
13 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
14 | * copies of the Software, and to permit persons to whom the Software is | |
15 | * furnished to do so, subject to the following conditions: | |
de0ba614 | 16 | * |
ccd7e1c8 MD |
17 | * The above copyright notice and this permission notice shall be included in |
18 | * all copies or substantial portions of the Software. | |
6dc2ca62 MD |
19 | */ |
20 | ||
4c8bfb7e | 21 | #include <babeltrace/format.h> |
6dc2ca62 | 22 | #include <glib.h> |
d1708134 MD |
23 | #include <errno.h> |
24 | ||
c054553d | 25 | static |
c13cbf74 MD |
26 | struct declaration * |
27 | lookup_type_declaration_scope(GQuark type_name, struct type_scope *scope) | |
d1708134 | 28 | { |
c13cbf74 | 29 | return g_hash_table_lookup(scope->type_declarations, |
ac88af75 | 30 | (gconstpointer) (unsigned long) type_name); |
d1708134 MD |
31 | } |
32 | ||
c13cbf74 | 33 | struct declaration *lookup_type_declaration(GQuark type_name, struct type_scope *scope) |
c054553d | 34 | { |
c13cbf74 | 35 | struct declaration *declaration; |
c054553d MD |
36 | |
37 | while (scope) { | |
c13cbf74 MD |
38 | declaration = lookup_type_declaration_scope(type_name, scope); |
39 | if (declaration) | |
40 | return declaration; | |
c054553d MD |
41 | scope = scope->parent_scope; |
42 | } | |
43 | return NULL; | |
44 | } | |
45 | ||
c13cbf74 MD |
46 | int register_type_declaration(GQuark name, struct declaration *declaration, |
47 | struct type_scope *scope) | |
d1708134 | 48 | { |
64893f33 | 49 | if (!name) |
6ee5115e MD |
50 | return -EPERM; |
51 | ||
c054553d | 52 | /* Only lookup in local scope */ |
c13cbf74 | 53 | if (lookup_type_declaration_scope(name, scope)) |
d1708134 MD |
54 | return -EEXIST; |
55 | ||
c13cbf74 | 56 | g_hash_table_insert(scope->type_declarations, |
64893f33 | 57 | (gpointer) (unsigned long) name, |
c13cbf74 MD |
58 | declaration); |
59 | declaration_ref(declaration); | |
ac88af75 MD |
60 | return 0; |
61 | } | |
62 | ||
63 | static | |
64 | struct declaration * | |
c13cbf74 | 65 | lookup_field_declaration_scope(GQuark field_name, struct declaration_scope *scope) |
ac88af75 MD |
66 | { |
67 | return g_hash_table_lookup(scope->declarations, | |
68 | (gconstpointer) (unsigned long) field_name); | |
69 | } | |
70 | ||
71 | struct declaration * | |
c13cbf74 | 72 | lookup_field_declaration(GQuark field_name, struct declaration_scope *scope) |
ac88af75 MD |
73 | { |
74 | struct declaration *declaration; | |
75 | ||
76 | while (scope) { | |
c13cbf74 | 77 | declaration = lookup_field_declaration_scope(field_name, scope); |
ac88af75 MD |
78 | if (declaration) |
79 | return declaration; | |
80 | scope = scope->parent_scope; | |
81 | } | |
82 | return NULL; | |
83 | } | |
84 | ||
c13cbf74 MD |
85 | int register_field_declaration(GQuark field_name, struct declaration *declaration, |
86 | struct declaration_scope *scope) | |
ac88af75 MD |
87 | { |
88 | if (!field_name) | |
89 | return -EPERM; | |
90 | ||
91 | /* Only lookup in local scope */ | |
c13cbf74 | 92 | if (lookup_field_declaration_scope(field_name, scope)) |
ac88af75 MD |
93 | return -EEXIST; |
94 | ||
95 | g_hash_table_insert(scope->declarations, | |
96 | (gpointer) (unsigned long) field_name, | |
97 | declaration); | |
98 | declaration_ref(declaration); | |
d1708134 MD |
99 | return 0; |
100 | } | |
101 | ||
e19c3d69 | 102 | void type_ref(struct type *type) |
4c8bfb7e | 103 | { |
e19c3d69 | 104 | type->ref++; |
4c8bfb7e MD |
105 | } |
106 | ||
e19c3d69 | 107 | void type_unref(struct type *type) |
4c8bfb7e | 108 | { |
e19c3d69 | 109 | if (!--type->ref) |
ac88af75 | 110 | type->type_free(type); |
4c8bfb7e MD |
111 | } |
112 | ||
e19c3d69 | 113 | void declaration_ref(struct declaration *declaration) |
d1708134 | 114 | { |
e19c3d69 | 115 | declaration->ref++; |
d1708134 MD |
116 | } |
117 | ||
e19c3d69 | 118 | void declaration_unref(struct declaration *declaration) |
d1708134 | 119 | { |
e19c3d69 | 120 | if (!--declaration->ref) |
ac88af75 | 121 | declaration->type->declaration_free(declaration); |
c054553d MD |
122 | } |
123 | ||
64893f33 MD |
124 | struct type_scope * |
125 | new_type_scope(struct type_scope *parent_scope) | |
c054553d | 126 | { |
64893f33 | 127 | struct type_scope *scope = g_new(struct type_scope, 1); |
c054553d | 128 | |
c13cbf74 MD |
129 | scope->type_declarations = g_hash_table_new_full(g_direct_hash, |
130 | g_direct_equal, NULL, | |
131 | (GDestroyNotify) declaration_unref); | |
132 | scope->struct_types = g_hash_table_new_full(g_direct_hash, | |
133 | g_direct_equal, NULL, | |
134 | (GDestroyNotify) type_unref); | |
135 | scope->variant_types = g_hash_table_new_full(g_direct_hash, | |
136 | g_direct_equal, NULL, | |
137 | (GDestroyNotify) type_unref); | |
138 | scope->enum_types = g_hash_table_new_full(g_direct_hash, | |
c054553d | 139 | g_direct_equal, NULL, |
e19c3d69 | 140 | (GDestroyNotify) type_unref); |
64893f33 MD |
141 | scope->parent_scope = parent_scope; |
142 | return scope; | |
143 | } | |
144 | ||
145 | void free_type_scope(struct type_scope *scope) | |
146 | { | |
c13cbf74 MD |
147 | g_hash_table_destroy(scope->enum_types); |
148 | g_hash_table_destroy(scope->variant_types); | |
149 | g_hash_table_destroy(scope->struct_types); | |
150 | g_hash_table_destroy(scope->type_declarations); | |
64893f33 MD |
151 | g_free(scope); |
152 | } | |
153 | ||
c13cbf74 MD |
154 | static |
155 | struct type_struct *lookup_struct_type_scope(GQuark struct_name, | |
156 | struct type_scope *scope) | |
157 | { | |
158 | return g_hash_table_lookup(scope->struct_types, | |
159 | (gconstpointer) (unsigned long) struct_name); | |
160 | } | |
161 | ||
162 | struct type_struct *lookup_struct_type(GQuark struct_name, | |
163 | struct type_scope *scope) | |
164 | { | |
165 | struct type_struct *type; | |
166 | ||
167 | while (scope) { | |
168 | type = lookup_struct_type_scope(struct_name, scope); | |
169 | if (type) | |
170 | return type; | |
171 | scope = scope->parent_scope; | |
172 | } | |
173 | return NULL; | |
174 | } | |
175 | ||
176 | int register_struct_type(GQuark struct_name, struct type_struct *struct_type, | |
177 | struct type_scope *scope) | |
178 | { | |
179 | if (!struct_name) | |
180 | return -EPERM; | |
181 | ||
182 | /* Only lookup in local scope */ | |
183 | if (lookup_struct_type_scope(struct_name, scope)) | |
184 | return -EEXIST; | |
185 | ||
186 | g_hash_table_insert(scope->struct_types, | |
187 | (gpointer) (unsigned long) struct_name, | |
188 | struct_type); | |
189 | type_ref(&struct_type->p); | |
190 | return 0; | |
191 | } | |
192 | ||
193 | static | |
194 | struct type_variant *lookup_variant_type_scope(GQuark variant_name, | |
195 | struct type_scope *scope) | |
196 | { | |
197 | return g_hash_table_lookup(scope->variant_types, | |
198 | (gconstpointer) (unsigned long) variant_name); | |
199 | } | |
200 | ||
201 | struct type_variant *lookup_variant_type(GQuark variant_name, | |
202 | struct type_scope *scope) | |
203 | { | |
204 | struct type_variant *type; | |
205 | ||
206 | while (scope) { | |
207 | type = lookup_variant_type_scope(variant_name, scope); | |
208 | if (type) | |
209 | return type; | |
210 | scope = scope->parent_scope; | |
211 | } | |
212 | return NULL; | |
213 | } | |
214 | ||
215 | int register_variant_type(GQuark variant_name, | |
216 | struct type_variant *variant_type, | |
217 | struct type_scope *scope) | |
218 | { | |
219 | if (!variant_name) | |
220 | return -EPERM; | |
221 | ||
222 | /* Only lookup in local scope */ | |
223 | if (lookup_variant_type_scope(variant_name, scope)) | |
224 | return -EEXIST; | |
225 | ||
226 | g_hash_table_insert(scope->variant_types, | |
227 | (gpointer) (unsigned long) variant_name, | |
228 | variant_type); | |
229 | type_ref(&variant_type->p); | |
230 | return 0; | |
231 | } | |
232 | ||
233 | static | |
234 | struct type_enum *lookup_enum_type_scope(GQuark enum_name, | |
235 | struct type_scope *scope) | |
236 | { | |
237 | return g_hash_table_lookup(scope->enum_types, | |
238 | (gconstpointer) (unsigned long) enum_name); | |
239 | } | |
240 | ||
241 | struct type_enum *lookup_enum_type(GQuark enum_name, | |
242 | struct type_scope *scope) | |
243 | { | |
244 | struct type_enum *type; | |
245 | ||
246 | while (scope) { | |
247 | type = lookup_enum_type_scope(enum_name, scope); | |
248 | if (type) | |
249 | return type; | |
250 | scope = scope->parent_scope; | |
251 | } | |
252 | return NULL; | |
253 | } | |
254 | ||
255 | int register_enum_type(GQuark enum_name, struct type_enum *enum_type, | |
256 | struct type_scope *scope) | |
257 | { | |
258 | if (!enum_name) | |
259 | return -EPERM; | |
260 | ||
261 | /* Only lookup in local scope */ | |
262 | if (lookup_enum_type_scope(enum_name, scope)) | |
263 | return -EEXIST; | |
264 | ||
265 | g_hash_table_insert(scope->enum_types, | |
266 | (gpointer) (unsigned long) enum_name, | |
267 | enum_type); | |
268 | type_ref(&enum_type->p); | |
269 | return 0; | |
270 | } | |
271 | ||
64893f33 MD |
272 | struct declaration_scope * |
273 | new_declaration_scope(struct declaration_scope *parent_scope) | |
274 | { | |
275 | struct declaration_scope *scope = g_new(struct declaration_scope, 1); | |
276 | ||
ac88af75 MD |
277 | scope->declarations = g_hash_table_new_full(g_direct_hash, |
278 | g_direct_equal, NULL, | |
279 | (GDestroyNotify) declaration_unref); | |
c054553d MD |
280 | scope->parent_scope = parent_scope; |
281 | return scope; | |
282 | } | |
283 | ||
284 | void free_declaration_scope(struct declaration_scope *scope) | |
285 | { | |
ac88af75 | 286 | g_hash_table_destroy(scope->declarations); |
c054553d | 287 | g_free(scope); |
d1708134 | 288 | } |