b8e8ac23d7eee377cfcbc48f230446ddb9fa5d47
[babeltrace.git] / formats / ctf / ir / utils.c
1 /*
2 * utils.c
3 *
4 * Babeltrace CTF IR - Utilities
5 *
6 * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
7 *
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
9 *
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:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 */
28
29 #include <string.h>
30 #include <stdlib.h>
31 #include <glib.h>
32 #include <babeltrace/babeltrace-internal.h>
33 #include <babeltrace/objects.h>
34
35 #define BT_CTF_ATTR_NAME_INDEX 0
36 #define BT_CTF_ATTR_VALUE_INDEX 1
37
38 static
39 const char * const reserved_keywords_str[] = {"align", "callsite",
40 "const", "char", "clock", "double", "enum", "env", "event",
41 "floating_point", "float", "integer", "int", "long", "short", "signed",
42 "stream", "string", "struct", "trace", "typealias", "typedef",
43 "unsigned", "variant", "void" "_Bool", "_Complex", "_Imaginary"};
44
45 static GHashTable *reserved_keywords_set;
46 static int init_done;
47 static int global_data_refcount;
48
49 static __attribute__((constructor))
50 void trace_init(void)
51 {
52 size_t i;
53 const size_t reserved_keywords_count =
54 sizeof(reserved_keywords_str) / sizeof(char *);
55
56 global_data_refcount++;
57 if (init_done) {
58 return;
59 }
60
61 reserved_keywords_set = g_hash_table_new(g_direct_hash, g_direct_equal);
62 for (i = 0; i < reserved_keywords_count; i++) {
63 gpointer quark = GINT_TO_POINTER(g_quark_from_string(
64 reserved_keywords_str[i]));
65
66 g_hash_table_insert(reserved_keywords_set, quark, quark);
67 }
68
69 init_done = 1;
70 }
71
72 static __attribute__((destructor))
73 void trace_finalize(void)
74 {
75 if (--global_data_refcount == 0) {
76 g_hash_table_destroy(reserved_keywords_set);
77 }
78 }
79
80 int bt_ctf_validate_identifier(const char *input_string)
81 {
82 int ret = 0;
83 char *string = NULL;
84 char *save_ptr, *token;
85
86 if (!input_string || input_string[0] == '\0') {
87 ret = -1;
88 goto end;
89 }
90
91 string = strdup(input_string);
92 if (!string) {
93 ret = -1;
94 goto end;
95 }
96
97 token = strtok_r(string, " ", &save_ptr);
98 while (token) {
99 if (g_hash_table_lookup_extended(reserved_keywords_set,
100 GINT_TO_POINTER(g_quark_from_string(token)),
101 NULL, NULL)) {
102 ret = -1;
103 goto end;
104 }
105
106 token = strtok_r(NULL, " ", &save_ptr);
107 }
108 end:
109 free(string);
110 return ret;
111 }
112
113 BT_HIDDEN
114 struct bt_object *bt_ctf_attributes_create(void)
115 {
116 /*
117 * Attributes: array object of array objects, each one
118 * containing two entries: a string object (attributes field
119 * name), and an object (attributes field value).
120 *
121 * Example (JSON representation):
122 *
123 * [
124 * ["hostname", "eeppdesk"],
125 * ["sysname", "Linux"],
126 * ["tracer_major", 2],
127 * ["tracer_minor", 5]
128 * ]
129 */
130 return bt_object_array_create();
131 }
132
133 BT_HIDDEN
134 void bt_ctf_attributes_destroy(struct bt_object *attr_obj)
135 {
136 bt_object_put(attr_obj);
137 }
138
139 BT_HIDDEN
140 int bt_ctf_attributes_get_count(struct bt_object *attr_obj)
141 {
142 return bt_object_array_size(attr_obj);
143 }
144
145 BT_HIDDEN
146 const char *bt_ctf_attributes_get_field_name(struct bt_object *attr_obj,
147 int index)
148 {
149 int rc;
150 const char *ret = NULL;
151 struct bt_object *attr_field_obj = NULL;
152 struct bt_object *attr_field_name_obj = NULL;
153
154 if (!attr_obj || index < 0) {
155 goto end;
156 }
157
158 attr_field_obj = bt_object_array_get(attr_obj, index);
159
160 if (!attr_field_obj) {
161 goto end;
162 }
163
164 attr_field_name_obj = bt_object_array_get(attr_field_obj,
165 BT_CTF_ATTR_NAME_INDEX);
166
167 if (!attr_field_name_obj) {
168 goto end;
169 }
170
171 rc = bt_object_string_get(attr_field_name_obj, &ret);
172
173 if (rc) {
174 ret = NULL;
175 }
176
177 end:
178 BT_OBJECT_PUT(attr_field_name_obj);
179 BT_OBJECT_PUT(attr_field_obj);
180
181 return ret;
182 }
183
184 BT_HIDDEN
185 struct bt_object *bt_ctf_attributes_get_field_value(struct bt_object *attr_obj,
186 int index)
187 {
188 struct bt_object *value_obj = NULL;
189 struct bt_object *attr_field_obj = NULL;
190
191 if (!attr_obj || index < 0) {
192 goto end;
193 }
194
195 attr_field_obj = bt_object_array_get(attr_obj, index);
196
197 if (!attr_field_obj) {
198 goto end;
199 }
200
201 value_obj = bt_object_array_get(attr_field_obj,
202 BT_CTF_ATTR_VALUE_INDEX);
203
204 end:
205 BT_OBJECT_PUT(attr_field_obj);
206
207 return value_obj;
208 }
209
210 static
211 struct bt_object *bt_ctf_attributes_get_field_by_name(
212 struct bt_object *attr_obj, const char *name)
213 {
214 int i;
215 int attr_size;
216 struct bt_object *value_obj = NULL;
217 struct bt_object *attr_field_name_obj = NULL;
218
219 attr_size = bt_object_array_size(attr_obj);
220
221 if (attr_size < 0) {
222 goto error;
223 }
224
225 for (i = 0; i < attr_size; ++i) {
226 int ret;
227 const char *field_name;
228
229 value_obj = bt_object_array_get(attr_obj, i);
230
231 if (!value_obj) {
232 goto error;
233 }
234
235 attr_field_name_obj = bt_object_array_get(value_obj, 0);
236
237 if (!attr_field_name_obj) {
238 goto error;
239 }
240
241 ret = bt_object_string_get(attr_field_name_obj, &field_name);
242 if (ret) {
243 goto error;
244 }
245
246 if (!strcmp(field_name, name)) {
247 BT_OBJECT_PUT(attr_field_name_obj);
248 break;
249 }
250
251 BT_OBJECT_PUT(attr_field_name_obj);
252 BT_OBJECT_PUT(value_obj);
253 }
254
255 return value_obj;
256
257 error:
258 BT_OBJECT_PUT(attr_field_name_obj);
259 BT_OBJECT_PUT(value_obj);
260
261 return value_obj;
262 }
263
264 BT_HIDDEN
265 int bt_ctf_attributes_set_field_value(struct bt_object *attr_obj,
266 const char *name, struct bt_object *value_obj)
267 {
268 int ret = 0;
269 struct bt_object *attr_field_obj = NULL;
270
271 if (!attr_obj || !name || !value_obj) {
272 ret = -1;
273 goto end;
274 }
275
276 attr_field_obj = bt_ctf_attributes_get_field_by_name(attr_obj, name);
277
278 if (attr_field_obj) {
279 ret = bt_object_array_set(attr_field_obj,
280 BT_CTF_ATTR_VALUE_INDEX, value_obj);
281 goto end;
282 }
283
284 attr_field_obj = bt_object_array_create();
285
286 if (!attr_field_obj) {
287 ret = -1;
288 goto end;
289 }
290
291 ret = bt_object_array_append_string(attr_field_obj, name);
292 ret |= bt_object_array_append(attr_field_obj, value_obj);
293
294 if (ret) {
295 goto end;
296 }
297
298 ret = bt_object_array_append(attr_obj, attr_field_obj);
299
300 end:
301 BT_OBJECT_PUT(attr_field_obj);
302
303 return ret;
304 }
305
306 BT_HIDDEN
307 struct bt_object *bt_ctf_attributes_get_field_value_by_name(
308 struct bt_object *attr_obj, const char *name)
309 {
310 struct bt_object *value_obj = NULL;
311 struct bt_object *attr_field_obj = NULL;
312
313 if (!attr_obj || !name) {
314 goto end;
315 }
316
317 attr_field_obj = bt_ctf_attributes_get_field_by_name(attr_obj, name);
318
319 if (!attr_field_obj) {
320 goto end;
321 }
322
323 value_obj = bt_object_array_get(attr_field_obj,
324 BT_CTF_ATTR_VALUE_INDEX);
325
326 end:
327 BT_OBJECT_PUT(attr_field_obj);
328
329 return value_obj;
330 }
331
332 BT_HIDDEN
333 int bt_ctf_attributes_freeze(struct bt_object *attr_obj)
334 {
335 int i;
336 int count;
337 int ret = 0;
338
339 if (!attr_obj) {
340 ret = -1;
341 goto end;
342 }
343
344 count = bt_object_array_size(attr_obj);
345
346 if (count < 0) {
347 ret = -1;
348 goto end;
349 }
350
351 /*
352 * We do not freeze the array itself here, since internal
353 * stuff could need to modify/add attributes. Each attribute
354 * is frozen one by one.
355 */
356 for (i = 0; i < count; ++i) {
357 struct bt_object *obj = NULL;
358
359 obj = bt_ctf_attributes_get_field_value(attr_obj, i);
360
361 if (!obj) {
362 ret = -1;
363 goto end;
364 }
365
366 bt_object_freeze(obj);
367 BT_OBJECT_PUT(obj);
368 }
369
370 end:
371
372 return ret;
373 }
This page took 0.037899 seconds and 3 git commands to generate.