Commit | Line | Data |
---|---|---|
6dc2ca62 | 1 | /* |
f6625916 | 2 | * declarations.c |
ccd7e1c8 | 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 |
e1151715 | 26 | struct definition * |
f6625916 MD |
27 | lookup_typedef_declaration_scope(GQuark declaration_name, |
28 | struct declaration_scope *scope) | |
d1708134 | 29 | { |
f6625916 MD |
30 | return g_hash_table_lookup(scope->typedef_declarations, |
31 | (gconstpointer) (unsigned long) declaration_name); | |
d1708134 MD |
32 | } |
33 | ||
f6625916 MD |
34 | struct definition *lookup_typedef_declaration(GQuark declaration_name, |
35 | struct declaration_scope *scope) | |
c054553d | 36 | { |
e1151715 | 37 | struct definition *definition; |
c054553d MD |
38 | |
39 | while (scope) { | |
f6625916 MD |
40 | definition = lookup_typedef_declaration_scope(declaration_name, |
41 | scope); | |
e1151715 MD |
42 | if (definition) |
43 | return definition; | |
c054553d MD |
44 | scope = scope->parent_scope; |
45 | } | |
46 | return NULL; | |
47 | } | |
48 | ||
f6625916 MD |
49 | int register_typedef_declaration(GQuark name, struct declaration *declaration, |
50 | struct declaration_scope *scope) | |
d1708134 | 51 | { |
64893f33 | 52 | if (!name) |
6ee5115e MD |
53 | return -EPERM; |
54 | ||
c054553d | 55 | /* Only lookup in local scope */ |
f6625916 | 56 | if (lookup_typedef_declaration_scope(name, scope)) |
d1708134 MD |
57 | return -EEXIST; |
58 | ||
f6625916 | 59 | g_hash_table_insert(scope->typedef_declarations, |
64893f33 | 60 | (gpointer) (unsigned long) name, |
f6625916 MD |
61 | declaration); |
62 | declaration_ref(declaration); | |
ac88af75 MD |
63 | return 0; |
64 | } | |
65 | ||
66 | static | |
e1151715 | 67 | struct definition * |
f6625916 MD |
68 | lookup_field_definition_scope(GQuark field_name, |
69 | struct definition_scope *scope) | |
ac88af75 | 70 | { |
e1151715 | 71 | return g_hash_table_lookup(scope->definitions, |
ac88af75 MD |
72 | (gconstpointer) (unsigned long) field_name); |
73 | } | |
74 | ||
e1151715 | 75 | struct definition * |
f6625916 MD |
76 | lookup_field_definition(GQuark field_name, |
77 | struct definition_scope *scope) | |
ac88af75 | 78 | { |
e1151715 | 79 | struct definition *definition; |
ac88af75 MD |
80 | |
81 | while (scope) { | |
e1151715 MD |
82 | definition = lookup_field_definition_scope(field_name, scope); |
83 | if (definition) | |
84 | return definition; | |
ac88af75 MD |
85 | scope = scope->parent_scope; |
86 | } | |
87 | return NULL; | |
88 | } | |
89 | ||
e1151715 | 90 | int register_field_definition(GQuark field_name, struct definition *definition, |
f6625916 | 91 | struct definition_scope *scope) |
ac88af75 MD |
92 | { |
93 | if (!field_name) | |
94 | return -EPERM; | |
95 | ||
96 | /* Only lookup in local scope */ | |
e1151715 | 97 | if (lookup_field_definition_scope(field_name, scope)) |
ac88af75 MD |
98 | return -EEXIST; |
99 | ||
e1151715 | 100 | g_hash_table_insert(scope->definitions, |
ac88af75 | 101 | (gpointer) (unsigned long) field_name, |
e1151715 MD |
102 | definition); |
103 | definition_ref(definition); | |
d1708134 MD |
104 | return 0; |
105 | } | |
106 | ||
f6625916 | 107 | void declaration_ref(struct declaration *declaration) |
4c8bfb7e | 108 | { |
f6625916 | 109 | declaration->ref++; |
4c8bfb7e MD |
110 | } |
111 | ||
f6625916 | 112 | void declaration_unref(struct declaration *declaration) |
4c8bfb7e | 113 | { |
f6625916 MD |
114 | if (!--declaration->ref) |
115 | declaration->declaration_free(declaration); | |
4c8bfb7e MD |
116 | } |
117 | ||
e1151715 | 118 | void definition_ref(struct definition *definition) |
d1708134 | 119 | { |
e1151715 | 120 | definition->ref++; |
d1708134 MD |
121 | } |
122 | ||
e1151715 | 123 | void definition_unref(struct definition *definition) |
d1708134 | 124 | { |
e1151715 | 125 | if (!--definition->ref) |
f6625916 | 126 | definition->declaration->definition_free(definition); |
c054553d MD |
127 | } |
128 | ||
f6625916 MD |
129 | struct declaration_scope * |
130 | new_declaration_scope(struct declaration_scope *parent_scope) | |
c054553d | 131 | { |
f6625916 | 132 | struct declaration_scope *scope = g_new(struct declaration_scope, 1); |
c054553d | 133 | |
f6625916 | 134 | scope->typedef_declarations = g_hash_table_new_full(g_direct_hash, |
c13cbf74 | 135 | g_direct_equal, NULL, |
e1151715 | 136 | (GDestroyNotify) definition_unref); |
f6625916 | 137 | scope->struct_declarations = g_hash_table_new_full(g_direct_hash, |
c13cbf74 | 138 | g_direct_equal, NULL, |
f6625916 MD |
139 | (GDestroyNotify) declaration_unref); |
140 | scope->variant_declarations = g_hash_table_new_full(g_direct_hash, | |
c13cbf74 | 141 | g_direct_equal, NULL, |
f6625916 MD |
142 | (GDestroyNotify) declaration_unref); |
143 | scope->enum_declarations = g_hash_table_new_full(g_direct_hash, | |
c054553d | 144 | g_direct_equal, NULL, |
f6625916 | 145 | (GDestroyNotify) declaration_unref); |
64893f33 MD |
146 | scope->parent_scope = parent_scope; |
147 | return scope; | |
148 | } | |
149 | ||
f6625916 | 150 | void free_declaration_scope(struct declaration_scope *scope) |
64893f33 | 151 | { |
f6625916 MD |
152 | g_hash_table_destroy(scope->enum_declarations); |
153 | g_hash_table_destroy(scope->variant_declarations); | |
154 | g_hash_table_destroy(scope->struct_declarations); | |
155 | g_hash_table_destroy(scope->typedef_declarations); | |
64893f33 MD |
156 | g_free(scope); |
157 | } | |
158 | ||
c13cbf74 | 159 | static |
f6625916 MD |
160 | struct declaration_struct *lookup_struct_declaration_scope(GQuark struct_name, |
161 | struct declaration_scope *scope) | |
c13cbf74 | 162 | { |
f6625916 | 163 | return g_hash_table_lookup(scope->struct_declarations, |
c13cbf74 MD |
164 | (gconstpointer) (unsigned long) struct_name); |
165 | } | |
166 | ||
f6625916 MD |
167 | struct declaration_struct *lookup_struct_declaration(GQuark struct_name, |
168 | struct declaration_scope *scope) | |
c13cbf74 | 169 | { |
f6625916 | 170 | struct declaration_struct *declaration; |
c13cbf74 MD |
171 | |
172 | while (scope) { | |
f6625916 MD |
173 | declaration = lookup_struct_declaration_scope(struct_name, scope); |
174 | if (declaration) | |
175 | return declaration; | |
c13cbf74 MD |
176 | scope = scope->parent_scope; |
177 | } | |
178 | return NULL; | |
179 | } | |
180 | ||
f6625916 MD |
181 | int register_struct_declaration(GQuark struct_name, |
182 | struct declaration_struct *struct_declaration, | |
183 | struct declaration_scope *scope) | |
c13cbf74 MD |
184 | { |
185 | if (!struct_name) | |
186 | return -EPERM; | |
187 | ||
188 | /* Only lookup in local scope */ | |
f6625916 | 189 | if (lookup_struct_declaration_scope(struct_name, scope)) |
c13cbf74 MD |
190 | return -EEXIST; |
191 | ||
f6625916 | 192 | g_hash_table_insert(scope->struct_declarations, |
c13cbf74 | 193 | (gpointer) (unsigned long) struct_name, |
f6625916 MD |
194 | struct_declaration); |
195 | declaration_ref(&struct_declaration->p); | |
c13cbf74 MD |
196 | return 0; |
197 | } | |
198 | ||
199 | static | |
f6625916 MD |
200 | struct declaration_variant * |
201 | lookup_variant_declaration_scope(GQuark variant_name, | |
202 | struct declaration_scope *scope) | |
c13cbf74 | 203 | { |
f6625916 | 204 | return g_hash_table_lookup(scope->variant_declarations, |
c13cbf74 MD |
205 | (gconstpointer) (unsigned long) variant_name); |
206 | } | |
207 | ||
f6625916 MD |
208 | struct declaration_variant * |
209 | lookup_variant_declaration(GQuark variant_name, | |
210 | struct declaration_scope *scope) | |
c13cbf74 | 211 | { |
f6625916 | 212 | struct declaration_variant *declaration; |
c13cbf74 MD |
213 | |
214 | while (scope) { | |
f6625916 MD |
215 | declaration = lookup_variant_declaration_scope(variant_name, scope); |
216 | if (declaration) | |
217 | return declaration; | |
c13cbf74 MD |
218 | scope = scope->parent_scope; |
219 | } | |
220 | return NULL; | |
221 | } | |
222 | ||
f6625916 MD |
223 | int register_variant_declaration(GQuark variant_name, |
224 | struct declaration_variant *variant_declaration, | |
225 | struct declaration_scope *scope) | |
c13cbf74 MD |
226 | { |
227 | if (!variant_name) | |
228 | return -EPERM; | |
229 | ||
230 | /* Only lookup in local scope */ | |
f6625916 | 231 | if (lookup_variant_declaration_scope(variant_name, scope)) |
c13cbf74 MD |
232 | return -EEXIST; |
233 | ||
f6625916 | 234 | g_hash_table_insert(scope->variant_declarations, |
c13cbf74 | 235 | (gpointer) (unsigned long) variant_name, |
f6625916 MD |
236 | variant_declaration); |
237 | declaration_ref(&variant_declaration->p); | |
c13cbf74 MD |
238 | return 0; |
239 | } | |
240 | ||
241 | static | |
f6625916 MD |
242 | struct declaration_enum * |
243 | lookup_enum_declaration_scope(GQuark enum_name, | |
244 | struct declaration_scope *scope) | |
c13cbf74 | 245 | { |
f6625916 | 246 | return g_hash_table_lookup(scope->enum_declarations, |
c13cbf74 MD |
247 | (gconstpointer) (unsigned long) enum_name); |
248 | } | |
249 | ||
f6625916 MD |
250 | struct declaration_enum * |
251 | lookup_enum_declaration(GQuark enum_name, | |
252 | struct declaration_scope *scope) | |
c13cbf74 | 253 | { |
f6625916 | 254 | struct declaration_enum *declaration; |
c13cbf74 MD |
255 | |
256 | while (scope) { | |
f6625916 MD |
257 | declaration = lookup_enum_declaration_scope(enum_name, scope); |
258 | if (declaration) | |
259 | return declaration; | |
c13cbf74 MD |
260 | scope = scope->parent_scope; |
261 | } | |
262 | return NULL; | |
263 | } | |
264 | ||
f6625916 MD |
265 | int register_enum_declaration(GQuark enum_name, |
266 | struct declaration_enum *enum_declaration, | |
267 | struct declaration_scope *scope) | |
c13cbf74 MD |
268 | { |
269 | if (!enum_name) | |
270 | return -EPERM; | |
271 | ||
272 | /* Only lookup in local scope */ | |
f6625916 | 273 | if (lookup_enum_declaration_scope(enum_name, scope)) |
c13cbf74 MD |
274 | return -EEXIST; |
275 | ||
f6625916 | 276 | g_hash_table_insert(scope->enum_declarations, |
c13cbf74 | 277 | (gpointer) (unsigned long) enum_name, |
f6625916 MD |
278 | enum_declaration); |
279 | declaration_ref(&enum_declaration->p); | |
c13cbf74 MD |
280 | return 0; |
281 | } | |
282 | ||
e1151715 MD |
283 | struct definition_scope * |
284 | new_definition_scope(struct definition_scope *parent_scope) | |
64893f33 | 285 | { |
e1151715 | 286 | struct definition_scope *scope = g_new(struct definition_scope, 1); |
64893f33 | 287 | |
e1151715 | 288 | scope->definitions = g_hash_table_new_full(g_direct_hash, |
ac88af75 | 289 | g_direct_equal, NULL, |
e1151715 | 290 | (GDestroyNotify) definition_unref); |
c054553d MD |
291 | scope->parent_scope = parent_scope; |
292 | return scope; | |
293 | } | |
294 | ||
e1151715 | 295 | void free_definition_scope(struct definition_scope *scope) |
c054553d | 296 | { |
e1151715 | 297 | g_hash_table_destroy(scope->definitions); |
c054553d | 298 | g_free(scope); |
d1708134 | 299 | } |