SoW-2020-0002: Trace Hit Counters: trigger error reporting integration
[lttng-tools.git] / src / common / event-field-value.c
CommitLineData
2463b787
JR
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 *mein_label;
300
301 assert(field_val);
302 assert(label);
303 mein_label = strndup(label, size);
304 if (!mein_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 mein_label);
313 if (ret == 0) {
314 mein_label = NULL;
315 }
316
317end:
318 free(mein_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:
390 *val = container_of(
391 container_of(field_val,
392 const struct lttng_event_field_value_enum,
393 parent),
394 const struct lttng_event_field_value_enum_uint,
395 parent)->val;
396 break;
397 default:
398 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
399 goto end;
400 }
401
402 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
403
404end:
405 return status;
406}
407
408enum lttng_event_field_value_status
409lttng_event_field_value_signed_int_get_value(
410 const struct lttng_event_field_value *field_val, int64_t *val)
411{
412 enum lttng_event_field_value_status status;
413
414 if (!field_val || !val) {
415 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
416 goto end;
417 }
418
419 switch (field_val->type) {
420 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_INT:
421 *val = container_of(field_val,
422 const struct lttng_event_field_value_int,
423 parent)->val;
424 break;
425 case LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM:
426 *val = container_of(
427 container_of(field_val,
428 const struct lttng_event_field_value_enum,
429 parent),
430 const struct lttng_event_field_value_enum_int,
431 parent)->val;
432 break;
433 default:
434 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
435 goto end;
436 }
437
438 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
439
440end:
441 return status;
442}
443
444enum lttng_event_field_value_status
445lttng_event_field_value_real_get_value(
446 const struct lttng_event_field_value *field_val, double *val)
447{
448 enum lttng_event_field_value_status status;
449
450 if (!field_val || field_val->type != LTTNG_EVENT_FIELD_VALUE_TYPE_REAL ||
451 !val) {
452 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
453 goto end;
454 }
455
456 *val = container_of(field_val,
457 const struct lttng_event_field_value_real, parent)->val;
458 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
459
460end:
461 return status;
462}
463
464static
465bool ist_enum_field_val(const struct lttng_event_field_value *field_val)
466{
467 return field_val->type == LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM ||
468 field_val->type == LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM;
469}
470
471enum lttng_event_field_value_status
472lttng_event_field_value_enum_get_label_count(
473 const struct lttng_event_field_value *field_val,
474 unsigned int *count)
475{
476 enum lttng_event_field_value_status status;
477
478 if (!field_val || !ist_enum_field_val(field_val) || !count) {
479 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
480 goto end;
481 }
482
483 *count = (unsigned int) lttng_dynamic_pointer_array_get_count(
484 &container_of(field_val,
485 const struct lttng_event_field_value_enum,
486 parent)->labels);
487 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
488
489end:
490 return status;
491}
492
493const char *lttng_event_field_value_enum_get_label_at_index(
494 const struct lttng_event_field_value *field_val,
495 unsigned int index)
496{
497 const char *ret;
498 const struct lttng_event_field_value_enum *enum_field_val;
499
500 if (!field_val || !ist_enum_field_val(field_val)) {
501 ret = NULL;
502 goto end;
503 }
504
505 enum_field_val = container_of(field_val,
506 const struct lttng_event_field_value_enum, parent);
507
508 if (index >= lttng_dynamic_pointer_array_get_count(&enum_field_val->labels)) {
509 ret = NULL;
510 goto end;
511 }
512
513 ret = lttng_dynamic_pointer_array_get_pointer(&enum_field_val->labels,
514 index);
515
516end:
517 return ret;
518}
519
520const char *lttng_event_field_value_string_get_value(
521 const struct lttng_event_field_value *field_val)
522{
523 const char *ret;
524
525 if (!field_val || field_val->type != LTTNG_EVENT_FIELD_VALUE_TYPE_STRING) {
526 ret = NULL;
527 goto end;
528 }
529
530 ret = container_of(field_val,
531 const struct lttng_event_field_value_string, parent)->val;
532
533end:
534 return ret;
535}
536
537enum lttng_event_field_value_status lttng_event_field_value_array_get_length(
538 const struct lttng_event_field_value *field_val,
539 unsigned int *length)
540{
541 enum lttng_event_field_value_status status;
542
543 if (!field_val || field_val->type != LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY ||
544 !length) {
545 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
546 goto end;
547 }
548
549 *length = (unsigned int) lttng_dynamic_pointer_array_get_count(
550 &container_of(field_val,
551 const struct lttng_event_field_value_array,
552 parent)->elems);
553 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
554
555end:
556 return status;
557}
558
559enum lttng_event_field_value_status
560lttng_event_field_value_array_get_element_at_index(
561 const struct lttng_event_field_value *field_val,
562 unsigned int index,
563 const struct lttng_event_field_value **elem_field_val)
564{
565 enum lttng_event_field_value_status status;
566 const struct lttng_event_field_value_array *array_field_val;
567
568 if (!field_val || field_val->type != LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY ||
569 !elem_field_val) {
570 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
571 goto end;
572 }
573
574 array_field_val = container_of(field_val,
575 const struct lttng_event_field_value_array, parent);
576
577 if (index >= lttng_dynamic_pointer_array_get_count(&array_field_val->elems)) {
578 status = LTTNG_EVENT_FIELD_VALUE_STATUS_INVALID;
579 goto end;
580 }
581
582 *elem_field_val = lttng_dynamic_pointer_array_get_pointer(
583 &array_field_val->elems, index);
584 if (*elem_field_val) {
585 status = LTTNG_EVENT_FIELD_VALUE_STATUS_OK;
586 } else {
587 status = LTTNG_EVENT_FIELD_VALUE_STATUS_UNAVAILABLE;
588 }
589
590end:
591 return status;
592}
This page took 0.043999 seconds and 5 git commands to generate.