Add condition-targeting error query
[lttng-tools.git] / src / common / event-field-value.c
CommitLineData
d28fcdec
PP
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
21static
22struct 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
34end:
35 return field_val;
36}
37
38LTTNG_HIDDEN
39struct 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
55error:
56 lttng_event_field_value_destroy(&field_val->parent);
57
58end:
59 return &field_val->parent;
60}
61
62LTTNG_HIDDEN
63struct 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
79error:
80 lttng_event_field_value_destroy(&field_val->parent);
81
82end:
83 return &field_val->parent;
84}
85
86static
87struct 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
101error:
102 lttng_event_field_value_destroy(&field_val->parent);
103
104end:
105 return field_val;
106}
107
108LTTNG_HIDDEN
109struct 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
125error:
126 lttng_event_field_value_destroy(&field_val->parent.parent);
127
128end:
129 return &field_val->parent.parent;
130}
131
132LTTNG_HIDDEN
133struct 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
149error:
150 lttng_event_field_value_destroy(&field_val->parent.parent);
151
152end:
153 return &field_val->parent.parent;
154}
155
156LTTNG_HIDDEN
157struct 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
172error:
173 lttng_event_field_value_destroy(&field_val->parent);
174
175end:
176 return &field_val->parent;
177}
178
179LTTNG_HIDDEN
180struct 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
201error:
202 lttng_event_field_value_destroy(&field_val->parent);
203
204end:
205 return &field_val->parent;
206}
207
208LTTNG_HIDDEN
209struct 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
217static
218void destroy_field_val(void *field_val)
219{
220 lttng_event_field_value_destroy(field_val);
221}
222
223LTTNG_HIDDEN
224struct 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
239error:
240 lttng_event_field_value_destroy(&field_val->parent);
241
242end:
243 return &field_val->parent;
244}
245
246LTTNG_HIDDEN
247void 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
289end:
290 return;
291}
292
293LTTNG_HIDDEN
294int 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
317end:
318 free(new_label);
319 return ret;
320}
321
322LTTNG_HIDDEN
323int 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
332LTTNG_HIDDEN
333int 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
345LTTNG_HIDDEN
346int 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
356enum 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
368end:
369 return type;
370}
371
372enum lttng_event_field_value_status
373lttng_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:
9918e00a
SM
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;
d28fcdec 401 break;
9918e00a 402 }
d28fcdec
PP
403 default:
404 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
405 goto end;
406 }
407
408 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
409
410end:
411 return status;
412}
413
414enum lttng_event_field_value_status
415lttng_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:
9918e00a
SM
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;
d28fcdec 443 break;
9918e00a 444 }
d28fcdec
PP
445 default:
446 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
447 goto end;
448 }
449
450 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
451
452end:
453 return status;
454}
455
456enum lttng_event_field_value_status
457lttng_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
472end:
473 return status;
474}
475
476static
477bool 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
483enum lttng_event_field_value_status
484lttng_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
501end:
502 return status;
503}
504
505const 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
528end:
529 return ret;
530}
531
7c920b63
PP
532enum 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)
d28fcdec 535{
7c920b63 536 enum lttng_event_field_value_status status;
d28fcdec
PP
537
538 if (!field_val || field_val->type != LTTNG_EVENT_FIELD_VALUE_TYPE_STRING) {
7c920b63 539 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
d28fcdec
PP
540 goto end;
541 }
542
7c920b63 543 *value = container_of(field_val,
d28fcdec 544 const struct lttng_event_field_value_string, parent)->val;
7c920b63 545 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
d28fcdec
PP
546
547end:
7c920b63 548 return status;
d28fcdec
PP
549}
550
551enum 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
569end:
570 return status;
571}
572
573enum lttng_event_field_value_status
574lttng_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
604end:
605 return status;
606}
This page took 0.052288 seconds and 4 git commands to generate.