4 * BabelTrace - Enumeration Type
6 * Copyright 2010, 2011 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
19 #include <babeltrace/compiler.h>
20 #include <babeltrace/format.h>
25 struct definition
*_enum_definition_new(struct declaration
*declaration
,
26 struct definition_scope
*parent_scope
,
27 GQuark field_name
, int index
);
29 void _enum_definition_free(struct definition
*definition
);
32 void enum_range_set_free(void *ptr
)
38 * Returns a GArray or NULL.
39 * Caller must release the GArray with g_array_unref().
41 GArray
*enum_uint_to_quark_set(const struct declaration_enum
*enum_declaration
,
44 struct enum_range_to_quark
*iter
;
45 GArray
*qs
, *ranges
= NULL
;
47 /* Single values lookup */
48 qs
= g_hash_table_lookup(enum_declaration
->table
.value_to_quark_set
, &v
);
51 cds_list_for_each_entry(iter
, &enum_declaration
->table
.range_to_quark
, node
) {
52 if (iter
->range
.start
._unsigned
> v
|| iter
->range
.end
._unsigned
< v
)
59 ranges
= g_array_sized_new(FALSE
, TRUE
,
60 sizeof(struct enum_range
),
62 g_array_set_size(ranges
, qs_len
+ 1);
64 memcpy(ranges
->data
, qs
->data
,
65 sizeof(struct enum_range
) * qs_len
);
66 g_array_index(ranges
, struct enum_range
, qs_len
) = iter
->range
;
68 g_array_set_size(ranges
, ranges
->len
+ 1);
69 g_array_index(ranges
, struct enum_range
, ranges
->len
) = iter
->range
;
80 * Returns a GArray or NULL.
81 * Caller must release the GArray with g_array_unref().
83 GArray
*enum_int_to_quark_set(const struct declaration_enum
*enum_declaration
,
86 struct enum_range_to_quark
*iter
;
87 GArray
*qs
, *ranges
= NULL
;
89 /* Single values lookup */
90 qs
= g_hash_table_lookup(enum_declaration
->table
.value_to_quark_set
, &v
);
93 cds_list_for_each_entry(iter
, &enum_declaration
->table
.range_to_quark
, node
) {
94 if (iter
->range
.start
._signed
> v
|| iter
->range
.end
._signed
< v
)
101 ranges
= g_array_sized_new(FALSE
, TRUE
,
102 sizeof(struct enum_range
),
104 g_array_set_size(ranges
, qs_len
+ 1);
106 memcpy(ranges
->data
, qs
->data
,
107 sizeof(struct enum_range
) * qs_len
);
108 g_array_index(ranges
, struct enum_range
, qs_len
) = iter
->range
;
110 g_array_set_size(ranges
, ranges
->len
+ 1);
111 g_array_index(ranges
, struct enum_range
, ranges
->len
) = iter
->range
;
121 #if (__WORDSIZE == 32)
123 guint
enum_val_hash(gconstpointer key
)
125 int64_t ukey
= *(const int64_t *)key
;
127 return (guint
)ukey
^ (guint
)(ukey
>> 32);
131 gboolean
enum_val_equal(gconstpointer a
, gconstpointer b
)
133 int64_t ua
= *(const int64_t *)a
;
134 int64_t ub
= *(const int64_t *)b
;
140 void enum_val_free(void *ptr
)
146 void enum_signed_insert_value_to_quark_set(struct declaration_enum
*enum_declaration
,
152 array
= g_hash_table_lookup(enum_declaration
->table
.value_to_quark_set
, &v
);
154 array
= g_array_sized_new(FALSE
, TRUE
, sizeof(GQuark
), 1);
155 g_array_set_size(array
, 1);
156 g_array_index(array
, GQuark
, array
->len
- 1) = q
;
157 valuep
= g_new(int64_t, 1);
159 g_hash_table_insert(enum_declaration
->table
.value_to_quark_set
, valuep
, array
);
161 g_array_set_size(array
, array
->len
+ 1);
162 g_array_index(array
, GQuark
, array
->len
- 1) = q
;
167 void enum_unsigned_insert_value_to_quark_set(struct declaration_enum
*enum_declaration
,
168 uint64_t v
, GQuark q
)
173 array
= g_hash_table_lookup(enum_declaration
->table
.value_to_quark_set
, &v
);
175 array
= g_array_sized_new(FALSE
, TRUE
, sizeof(GQuark
), 1);
176 g_array_set_size(array
, 1);
177 g_array_index(array
, GQuark
, array
->len
- 1) = q
;
178 valuep
= g_new(uint64_t, 1);
180 g_hash_table_insert(enum_declaration
->table
.value_to_quark_set
, valuep
, array
);
182 g_array_set_size(array
, array
->len
+ 1);
183 g_array_index(array
, GQuark
, array
->len
- 1) = q
;
186 #else /* __WORDSIZE != 32 */
188 guint
enum_val_hash(gconstpointer key
)
190 return g_direct_hash(key
);
194 gboolean
enum_val_equal(gconstpointer a
, gconstpointer b
)
196 return g_direct_equal(a
, b
);
200 void enum_val_free(void *ptr
)
205 void enum_signed_insert_value_to_quark_set(struct declaration_enum
*enum_declaration
,
210 array
= g_hash_table_lookup(enum_declaration
->table
.value_to_quark_set
,
213 array
= g_array_sized_new(FALSE
, TRUE
, sizeof(GQuark
), 1);
214 g_array_set_size(array
, 1);
215 g_array_index(array
, GQuark
, array
->len
- 1) = q
;
216 g_hash_table_insert(enum_declaration
->table
.value_to_quark_set
,
217 (gpointer
) v
, array
);
219 g_array_set_size(array
, array
->len
+ 1);
220 g_array_index(array
, GQuark
, array
->len
- 1) = q
;
225 void enum_unsigned_insert_value_to_quark_set(struct declaration_enum
*enum_declaration
,
226 uint64_t v
, GQuark q
)
230 array
= g_hash_table_lookup(enum_declaration
->table
.value_to_quark_set
,
233 array
= g_array_sized_new(FALSE
, TRUE
, sizeof(GQuark
), 1);
234 g_array_set_size(array
, 1);
235 g_array_index(array
, GQuark
, array
->len
- 1) = q
;
236 g_hash_table_insert(enum_declaration
->table
.value_to_quark_set
,
237 (gpointer
) v
, array
);
239 g_array_set_size(array
, array
->len
+ 1);
240 g_array_index(array
, GQuark
, array
->len
- 1) = q
;
243 #endif /* __WORDSIZE != 32 */
245 GArray
*enum_quark_to_range_set(const struct declaration_enum
*enum_declaration
,
248 return g_hash_table_lookup(enum_declaration
->table
.quark_to_range_set
,
249 (gconstpointer
) (unsigned long) q
);
253 void enum_signed_insert_range_to_quark(struct declaration_enum
*enum_declaration
,
254 int64_t start
, int64_t end
, GQuark q
)
256 struct enum_range_to_quark
*rtoq
;
258 rtoq
= g_new(struct enum_range_to_quark
, 1);
259 cds_list_add(&rtoq
->node
, &enum_declaration
->table
.range_to_quark
);
260 rtoq
->range
.start
._signed
= start
;
261 rtoq
->range
.end
._signed
= end
;
266 void enum_unsigned_insert_range_to_quark(struct declaration_enum
*enum_declaration
,
267 uint64_t start
, uint64_t end
, GQuark q
)
269 struct enum_range_to_quark
*rtoq
;
271 rtoq
= g_new(struct enum_range_to_quark
, 1);
272 cds_list_add(&rtoq
->node
, &enum_declaration
->table
.range_to_quark
);
273 rtoq
->range
.start
._unsigned
= start
;
274 rtoq
->range
.end
._unsigned
= end
;
278 void enum_signed_insert(struct declaration_enum
*enum_declaration
,
279 int64_t start
, int64_t end
, GQuark q
)
282 struct enum_range
*range
;
285 enum_signed_insert_value_to_quark_set(enum_declaration
, start
, q
);
294 enum_signed_insert_range_to_quark(enum_declaration
, start
, end
, q
);
297 array
= g_hash_table_lookup(enum_declaration
->table
.quark_to_range_set
,
298 (gconstpointer
) (unsigned long) q
);
300 array
= g_array_sized_new(FALSE
, TRUE
,
301 sizeof(struct enum_range
), 1);
302 g_hash_table_insert(enum_declaration
->table
.quark_to_range_set
,
303 (gpointer
) (unsigned long) q
,
306 g_array_set_size(array
, array
->len
+ 1);
307 range
= &g_array_index(array
, struct enum_range
, array
->len
- 1);
308 range
->start
._signed
= start
;
309 range
->end
._signed
= end
;
312 void enum_unsigned_insert(struct declaration_enum
*enum_declaration
,
313 uint64_t start
, uint64_t end
, GQuark q
)
316 struct enum_range
*range
;
320 enum_unsigned_insert_value_to_quark_set(enum_declaration
, start
, q
);
329 enum_unsigned_insert_range_to_quark(enum_declaration
, start
, end
, q
);
332 array
= g_hash_table_lookup(enum_declaration
->table
.quark_to_range_set
,
333 (gconstpointer
) (unsigned long) q
);
335 array
= g_array_sized_new(FALSE
, TRUE
,
336 sizeof(struct enum_range
), 1);
337 g_hash_table_insert(enum_declaration
->table
.quark_to_range_set
,
338 (gpointer
) (unsigned long) q
,
341 g_array_set_size(array
, array
->len
+ 1);
342 range
= &g_array_index(array
, struct enum_range
, array
->len
- 1);
343 range
->start
._unsigned
= start
;
344 range
->end
._unsigned
= end
;
347 size_t enum_get_nr_enumerators(struct declaration_enum
*enum_declaration
)
349 return g_hash_table_size(enum_declaration
->table
.quark_to_range_set
);
353 void _enum_declaration_free(struct declaration
*declaration
)
355 struct declaration_enum
*enum_declaration
=
356 container_of(declaration
, struct declaration_enum
, p
);
357 struct enum_range_to_quark
*iter
, *tmp
;
359 g_hash_table_destroy(enum_declaration
->table
.value_to_quark_set
);
360 cds_list_for_each_entry_safe(iter
, tmp
, &enum_declaration
->table
.range_to_quark
, node
) {
361 cds_list_del(&iter
->node
);
364 g_hash_table_destroy(enum_declaration
->table
.quark_to_range_set
);
365 declaration_unref(&enum_declaration
->integer_declaration
->p
);
366 g_free(enum_declaration
);
369 struct declaration_enum
*
370 enum_declaration_new(struct declaration_integer
*integer_declaration
)
372 struct declaration_enum
*enum_declaration
;
374 enum_declaration
= g_new(struct declaration_enum
, 1);
376 enum_declaration
->table
.value_to_quark_set
= g_hash_table_new_full(enum_val_hash
,
379 enum_range_set_free
);
380 CDS_INIT_LIST_HEAD(&enum_declaration
->table
.range_to_quark
);
381 enum_declaration
->table
.quark_to_range_set
= g_hash_table_new_full(g_direct_hash
,
383 NULL
, enum_range_set_free
);
384 declaration_ref(&integer_declaration
->p
);
385 enum_declaration
->integer_declaration
= integer_declaration
;
386 enum_declaration
->p
.id
= CTF_TYPE_ENUM
;
387 enum_declaration
->p
.alignment
= 1;
388 enum_declaration
->p
.declaration_free
= _enum_declaration_free
;
389 enum_declaration
->p
.definition_new
= _enum_definition_new
;
390 enum_declaration
->p
.definition_free
= _enum_definition_free
;
391 enum_declaration
->p
.ref
= 1;
392 return enum_declaration
;
397 _enum_definition_new(struct declaration
*declaration
,
398 struct definition_scope
*parent_scope
,
399 GQuark field_name
, int index
)
401 struct declaration_enum
*enum_declaration
=
402 container_of(declaration
, struct declaration_enum
, p
);
403 struct definition_enum
*_enum
;
404 struct definition
*definition_integer_parent
;
406 _enum
= g_new(struct definition_enum
, 1);
407 declaration_ref(&enum_declaration
->p
);
408 _enum
->p
.declaration
= declaration
;
409 _enum
->declaration
= enum_declaration
;
411 _enum
->p
.index
= index
;
413 definition_integer_parent
=
414 enum_declaration
->integer_declaration
->p
.definition_new(&enum_declaration
->integer_declaration
->p
,
415 parent_scope
, field_name
, 0);
416 _enum
->integer
= container_of(definition_integer_parent
,
417 struct definition_integer
, p
);
422 void _enum_definition_free(struct definition
*definition
)
424 struct definition_enum
*_enum
=
425 container_of(definition
, struct definition_enum
, p
);
427 definition_unref(&_enum
->integer
->p
);
428 declaration_unref(_enum
->p
.declaration
);
430 g_array_unref(_enum
->value
);