Fix: kernel consumerd: use of uninitialized variable
[lttng-tools.git] / src / common / event-field-value.c
1 /*
2 * event-field-value.c
3 *
4 * Linux Trace Toolkit Control Library
5 *
6 * Copyright (C) 2020 Philippe Proulx <pproulx@efficios.com>
7 *
8 * SPDX-License-Identifier: LGPL-2.1-only
9 *
10 */
11
12 #define _LGPL_SOURCE
13 #include <assert.h>
14 #include <stddef.h>
15 #include <stdbool.h>
16
17 #include <common/error.h>
18 #include <common/macros.h>
19 #include <lttng/event-field-value-internal.h>
20
21 static
22 struct lttng_event_field_value *create_empty_field_val(
23 enum lttng_event_field_value_type type, size_t size)
24 {
25 struct lttng_event_field_value *field_val;
26
27 field_val = zmalloc(size);
28 if (!field_val) {
29 goto end;
30 }
31
32 field_val->type = type;
33
34 end:
35 return field_val;
36 }
37
38 LTTNG_HIDDEN
39 struct lttng_event_field_value *lttng_event_field_value_uint_create(
40 uint64_t val)
41 {
42 struct lttng_event_field_value_uint *field_val;
43
44 field_val = container_of(create_empty_field_val(
45 LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_INT,
46 sizeof(*field_val)),
47 struct lttng_event_field_value_uint, parent);
48 if (!field_val) {
49 goto error;
50 }
51
52 field_val->val = val;
53 goto end;
54
55 error:
56 lttng_event_field_value_destroy(&field_val->parent);
57
58 end:
59 return &field_val->parent;
60 }
61
62 LTTNG_HIDDEN
63 struct lttng_event_field_value *lttng_event_field_value_int_create(
64 int64_t val)
65 {
66 struct lttng_event_field_value_int *field_val;
67
68 field_val = container_of(create_empty_field_val(
69 LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_INT,
70 sizeof(*field_val)),
71 struct lttng_event_field_value_int, parent);
72 if (!field_val) {
73 goto error;
74 }
75
76 field_val->val = val;
77 goto end;
78
79 error:
80 lttng_event_field_value_destroy(&field_val->parent);
81
82 end:
83 return &field_val->parent;
84 }
85
86 static
87 struct lttng_event_field_value_enum *create_enum_field_val(
88 enum lttng_event_field_value_type type, size_t size)
89 {
90 struct lttng_event_field_value_enum *field_val;
91
92 field_val = container_of(create_empty_field_val(type, size),
93 struct lttng_event_field_value_enum, parent);
94 if (!field_val) {
95 goto error;
96 }
97
98 lttng_dynamic_pointer_array_init(&field_val->labels, free);
99 goto end;
100
101 error:
102 lttng_event_field_value_destroy(&field_val->parent);
103
104 end:
105 return field_val;
106 }
107
108 LTTNG_HIDDEN
109 struct lttng_event_field_value *lttng_event_field_value_enum_uint_create(
110 uint64_t val)
111 {
112 struct lttng_event_field_value_enum_uint *field_val;
113
114 field_val = container_of(create_enum_field_val(
115 LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM,
116 sizeof(*field_val)),
117 struct lttng_event_field_value_enum_uint, parent);
118 if (!field_val) {
119 goto error;
120 }
121
122 field_val->val = val;
123 goto end;
124
125 error:
126 lttng_event_field_value_destroy(&field_val->parent.parent);
127
128 end:
129 return &field_val->parent.parent;
130 }
131
132 LTTNG_HIDDEN
133 struct lttng_event_field_value *lttng_event_field_value_enum_int_create(
134 int64_t val)
135 {
136 struct lttng_event_field_value_enum_int *field_val;
137
138 field_val = container_of(create_enum_field_val(
139 LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM,
140 sizeof(*field_val)),
141 struct lttng_event_field_value_enum_int, parent);
142 if (!field_val) {
143 goto error;
144 }
145
146 field_val->val = val;
147 goto end;
148
149 error:
150 lttng_event_field_value_destroy(&field_val->parent.parent);
151
152 end:
153 return &field_val->parent.parent;
154 }
155
156 LTTNG_HIDDEN
157 struct lttng_event_field_value *lttng_event_field_value_real_create(double val)
158 {
159 struct lttng_event_field_value_real *field_val = container_of(
160 create_empty_field_val(
161 LTTNG_EVENT_FIELD_VALUE_TYPE_REAL,
162 sizeof(*field_val)),
163 struct lttng_event_field_value_real, parent);
164
165 if (!field_val) {
166 goto error;
167 }
168
169 field_val->val = val;
170 goto end;
171
172 error:
173 lttng_event_field_value_destroy(&field_val->parent);
174
175 end:
176 return &field_val->parent;
177 }
178
179 LTTNG_HIDDEN
180 struct lttng_event_field_value *lttng_event_field_value_string_create_with_size(
181 const char *val, size_t size)
182 {
183 struct lttng_event_field_value_string *field_val = container_of(
184 create_empty_field_val(
185 LTTNG_EVENT_FIELD_VALUE_TYPE_STRING,
186 sizeof(*field_val)),
187 struct lttng_event_field_value_string, parent);
188
189 if (!field_val) {
190 goto error;
191 }
192
193 assert(val);
194 field_val->val = strndup(val, size);
195 if (!field_val->val) {
196 goto error;
197 }
198
199 goto end;
200
201 error:
202 lttng_event_field_value_destroy(&field_val->parent);
203
204 end:
205 return &field_val->parent;
206 }
207
208 LTTNG_HIDDEN
209 struct lttng_event_field_value *lttng_event_field_value_string_create(
210 const char *val)
211 {
212 assert(val);
213 return lttng_event_field_value_string_create_with_size(val,
214 strlen(val));
215 }
216
217 static
218 void destroy_field_val(void *field_val)
219 {
220 lttng_event_field_value_destroy(field_val);
221 }
222
223 LTTNG_HIDDEN
224 struct lttng_event_field_value *lttng_event_field_value_array_create(void)
225 {
226 struct lttng_event_field_value_array *field_val = container_of(
227 create_empty_field_val(
228 LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY,
229 sizeof(*field_val)),
230 struct lttng_event_field_value_array, parent);
231
232 if (!field_val) {
233 goto error;
234 }
235
236 lttng_dynamic_pointer_array_init(&field_val->elems, destroy_field_val);
237 goto end;
238
239 error:
240 lttng_event_field_value_destroy(&field_val->parent);
241
242 end:
243 return &field_val->parent;
244 }
245
246 LTTNG_HIDDEN
247 void lttng_event_field_value_destroy(struct lttng_event_field_value *field_val)
248 {
249 if (!field_val) {
250 goto end;
251 }
252
253 switch (field_val->type) {
254 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM:
255 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM:
256 {
257 struct lttng_event_field_value_enum *enum_field_val =
258 container_of(field_val,
259 struct lttng_event_field_value_enum, parent);
260
261 lttng_dynamic_pointer_array_reset(&enum_field_val->labels);
262 break;
263 }
264 case LTTNG_EVENT_FIELD_VALUE_TYPE_STRING:
265 {
266 struct lttng_event_field_value_string *str_field_val =
267 container_of(field_val,
268 struct lttng_event_field_value_string, parent);
269
270 free(str_field_val->val);
271 break;
272 }
273 case LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY:
274 {
275 struct lttng_event_field_value_array *array_field_expr =
276 container_of(field_val,
277 struct lttng_event_field_value_array,
278 parent);
279
280 lttng_dynamic_pointer_array_reset(&array_field_expr->elems);
281 break;
282 }
283 default:
284 break;
285 }
286
287 free(field_val);
288
289 end:
290 return;
291 }
292
293 LTTNG_HIDDEN
294 int lttng_event_field_value_enum_append_label_with_size(
295 struct lttng_event_field_value *field_val,
296 const char *label, size_t size)
297 {
298 int ret;
299 char *new_label;
300
301 assert(field_val);
302 assert(label);
303 new_label = strndup(label, size);
304 if (!new_label) {
305 ret = -1;
306 goto end;
307 }
308
309 ret = lttng_dynamic_pointer_array_add_pointer(
310 &container_of(field_val,
311 struct lttng_event_field_value_enum, parent)->labels,
312 new_label);
313 if (ret == 0) {
314 new_label = NULL;
315 }
316
317 end:
318 free(new_label);
319 return ret;
320 }
321
322 LTTNG_HIDDEN
323 int lttng_event_field_value_enum_append_label(
324 struct lttng_event_field_value *field_val,
325 const char *label)
326 {
327 assert(label);
328 return lttng_event_field_value_enum_append_label_with_size(field_val,
329 label, strlen(label));
330 }
331
332 LTTNG_HIDDEN
333 int lttng_event_field_value_array_append(
334 struct lttng_event_field_value *array_field_val,
335 struct lttng_event_field_value *field_val)
336 {
337 assert(array_field_val);
338 assert(field_val);
339 return lttng_dynamic_pointer_array_add_pointer(
340 &container_of(array_field_val,
341 struct lttng_event_field_value_array, parent)->elems,
342 field_val);
343 }
344
345 LTTNG_HIDDEN
346 int lttng_event_field_value_array_append_unavailable(
347 struct lttng_event_field_value *array_field_val)
348 {
349 assert(array_field_val);
350 return lttng_dynamic_pointer_array_add_pointer(
351 &container_of(array_field_val,
352 struct lttng_event_field_value_array, parent)->elems,
353 NULL);
354 }
355
356 enum lttng_event_field_value_type lttng_event_field_value_get_type(
357 const struct lttng_event_field_value *field_val)
358 {
359 enum lttng_event_field_value_type type;
360
361 if (!field_val) {
362 type = LTTNG_EVENT_FIELD_VALUE_TYPE_INVALID;
363 goto end;
364 }
365
366 type = field_val->type;
367
368 end:
369 return type;
370 }
371
372 enum lttng_event_field_value_status
373 lttng_event_field_value_unsigned_int_get_value(
374 const struct lttng_event_field_value *field_val, uint64_t *val)
375 {
376 enum lttng_event_field_value_status status;
377
378 if (!field_val || !val) {
379 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
380 goto end;
381 }
382
383 switch (field_val->type) {
384 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_INT:
385 *val = container_of(field_val,
386 const struct lttng_event_field_value_uint,
387 parent)->val;
388 break;
389 case LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM:
390 {
391 const struct lttng_event_field_value_enum *field_val_enum = container_of(
392 field_val,
393 const struct lttng_event_field_value_enum,
394 parent);
395 const struct lttng_event_field_value_enum_uint
396 *field_val_enum_uint = container_of(
397 field_val_enum,
398 const struct lttng_event_field_value_enum_uint,
399 parent);
400 *val = field_val_enum_uint->val;
401 break;
402 }
403 default:
404 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
405 goto end;
406 }
407
408 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
409
410 end:
411 return status;
412 }
413
414 enum lttng_event_field_value_status
415 lttng_event_field_value_signed_int_get_value(
416 const struct lttng_event_field_value *field_val, int64_t *val)
417 {
418 enum lttng_event_field_value_status status;
419
420 if (!field_val || !val) {
421 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
422 goto end;
423 }
424
425 switch (field_val->type) {
426 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_INT:
427 *val = container_of(field_val,
428 const struct lttng_event_field_value_int,
429 parent)->val;
430 break;
431 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM:
432 {
433 const struct lttng_event_field_value_enum *field_val_enum = container_of(
434 field_val,
435 const struct lttng_event_field_value_enum,
436 parent);
437 const struct lttng_event_field_value_enum_int
438 *field_val_enum_uint = container_of(
439 field_val_enum,
440 const struct lttng_event_field_value_enum_int,
441 parent);
442 *val = field_val_enum_uint->val;
443 break;
444 }
445 default:
446 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
447 goto end;
448 }
449
450 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
451
452 end:
453 return status;
454 }
455
456 enum lttng_event_field_value_status
457 lttng_event_field_value_real_get_value(
458 const struct lttng_event_field_value *field_val, double *val)
459 {
460 enum lttng_event_field_value_status status;
461
462 if (!field_val || field_val->type != LTTNG_EVENT_FIELD_VALUE_TYPE_REAL ||
463 !val) {
464 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
465 goto end;
466 }
467
468 *val = container_of(field_val,
469 const struct lttng_event_field_value_real, parent)->val;
470 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
471
472 end:
473 return status;
474 }
475
476 static
477 bool is_enum_field_val(const struct lttng_event_field_value *field_val)
478 {
479 return field_val->type == LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM ||
480 field_val->type == LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM;
481 }
482
483 enum lttng_event_field_value_status
484 lttng_event_field_value_enum_get_label_count(
485 const struct lttng_event_field_value *field_val,
486 unsigned int *count)
487 {
488 enum lttng_event_field_value_status status;
489
490 if (!field_val || !is_enum_field_val(field_val) || !count) {
491 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
492 goto end;
493 }
494
495 *count = (unsigned int) lttng_dynamic_pointer_array_get_count(
496 &container_of(field_val,
497 const struct lttng_event_field_value_enum,
498 parent)->labels);
499 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
500
501 end:
502 return status;
503 }
504
505 const char *lttng_event_field_value_enum_get_label_at_index(
506 const struct lttng_event_field_value *field_val,
507 unsigned int index)
508 {
509 const char *ret;
510 const struct lttng_event_field_value_enum *enum_field_val;
511
512 if (!field_val || !is_enum_field_val(field_val)) {
513 ret = NULL;
514 goto end;
515 }
516
517 enum_field_val = container_of(field_val,
518 const struct lttng_event_field_value_enum, parent);
519
520 if (index >= lttng_dynamic_pointer_array_get_count(&enum_field_val->labels)) {
521 ret = NULL;
522 goto end;
523 }
524
525 ret = lttng_dynamic_pointer_array_get_pointer(&enum_field_val->labels,
526 index);
527
528 end:
529 return ret;
530 }
531
532 enum lttng_event_field_value_status lttng_event_field_value_string_get_value(
533 const struct lttng_event_field_value *field_val,
534 const char **value)
535 {
536 enum lttng_event_field_value_status status;
537
538 if (!field_val || field_val->type != LTTNG_EVENT_FIELD_VALUE_TYPE_STRING) {
539 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
540 goto end;
541 }
542
543 *value = container_of(field_val,
544 const struct lttng_event_field_value_string, parent)->val;
545 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
546
547 end:
548 return status;
549 }
550
551 enum lttng_event_field_value_status lttng_event_field_value_array_get_length(
552 const struct lttng_event_field_value *field_val,
553 unsigned int *length)
554 {
555 enum lttng_event_field_value_status status;
556
557 if (!field_val || field_val->type != LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY ||
558 !length) {
559 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
560 goto end;
561 }
562
563 *length = (unsigned int) lttng_dynamic_pointer_array_get_count(
564 &container_of(field_val,
565 const struct lttng_event_field_value_array,
566 parent)->elems);
567 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
568
569 end:
570 return status;
571 }
572
573 enum lttng_event_field_value_status
574 lttng_event_field_value_array_get_element_at_index(
575 const struct lttng_event_field_value *field_val,
576 unsigned int index,
577 const struct lttng_event_field_value **elem_field_val)
578 {
579 enum lttng_event_field_value_status status;
580 const struct lttng_event_field_value_array *array_field_val;
581
582 if (!field_val || field_val->type != LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY ||
583 !elem_field_val) {
584 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
585 goto end;
586 }
587
588 array_field_val = container_of(field_val,
589 const struct lttng_event_field_value_array, parent);
590
591 if (index >= lttng_dynamic_pointer_array_get_count(&array_field_val->elems)) {
592 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
593 goto end;
594 }
595
596 *elem_field_val = lttng_dynamic_pointer_array_get_pointer(
597 &array_field_val->elems, index);
598 if (*elem_field_val) {
599 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
600 } else {
601 status = LTTNG_EVENT_FIELD_VALUE_STATUS_UNAVAILABLE;
602 }
603
604 end:
605 return status;
606 }
This page took 0.042179 seconds and 4 git commands to generate.