Force usage of assert() condition when NDEBUG is defined
[lttng-tools.git] / src / common / event-expr / event-expr.c
CommitLineData
48c47564
PP
1/*
2 * event-expr.c
3 *
48c47564
PP
4 * Copyright (C) 2020 Philippe Proulx <pproulx@efficios.com>
5 *
6 * SPDX-License-Identifier: LGPL-2.1-only
7 *
8 */
9
10#define _LGPL_SOURCE
48c47564
PP
11#include <stddef.h>
12
1aa9c49c 13#include <common/bytecode/bytecode.h>
48c47564
PP
14#include <common/error.h>
15#include <common/macros.h>
6a751b95 16#include <common/mi-lttng.h>
48c47564 17#include <lttng/event-expr-internal.h>
1aa9c49c
JR
18#include <lttng/event-expr.h>
19#include <stdio.h>
48c47564
PP
20
21enum lttng_event_expr_type lttng_event_expr_get_type(
22 const struct lttng_event_expr *expr)
23{
24 enum lttng_event_expr_type type;
25
26 if (!expr) {
27 type = LTTNG_EVENT_EXPR_TYPE_INVALID;
28 goto end;
29 }
30
31 type = expr->type;
32
33end:
34 return type;
35}
36
37static
38struct lttng_event_expr *create_empty_expr(enum lttng_event_expr_type type,
39 size_t size)
40{
41 struct lttng_event_expr *expr;
42
43 expr = zmalloc(size);
44 if (!expr) {
45 goto end;
46 }
47
48 expr->type = type;
49
50end:
51 return expr;
52}
53
54static
55struct lttng_event_expr_field *create_field_event_expr(
56 enum lttng_event_expr_type type,
57 const char *name)
58{
59 struct lttng_event_expr_field *expr =
60 container_of(
61 create_empty_expr(type, sizeof(*expr)),
62 struct lttng_event_expr_field, parent);
63
64 if (!expr) {
65 goto error;
66 }
67
a0377dfe 68 LTTNG_ASSERT(name);
48c47564
PP
69 expr->name = strdup(name);
70 if (!expr->name) {
71 goto error;
72 }
73
74 goto end;
75
76error:
5b5ad96e
FD
77 if (expr) {
78 lttng_event_expr_destroy(&expr->parent);
79 }
80 expr = NULL;
48c47564
PP
81
82end:
83 return expr;
84}
85
86struct lttng_event_expr *lttng_event_expr_event_payload_field_create(
87 const char *field_name)
88{
89 struct lttng_event_expr *expr = NULL;
90
91 if (!field_name) {
92 goto end;
93 }
94
95 expr = &create_field_event_expr(
96 LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD,
97 field_name)->parent;
98
99end:
100 return expr;
101}
102
103struct lttng_event_expr *lttng_event_expr_channel_context_field_create(
104 const char *field_name)
105{
106 struct lttng_event_expr *expr = NULL;
107
108 if (!field_name) {
109 goto end;
110 }
111
112 expr = &create_field_event_expr(
113 LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD,
114 field_name)->parent;
115
116end:
117 return expr;
118}
119
120struct lttng_event_expr *lttng_event_expr_app_specific_context_field_create(
121 const char *provider_name, const char *type_name)
122{
123 struct lttng_event_expr_app_specific_context_field *expr = NULL;
5b5ad96e 124 struct lttng_event_expr *ret_parent_expr;
48c47564
PP
125
126 if (!type_name || !provider_name) {
127 goto error;
128 }
129
130 expr = container_of(create_empty_expr(
131 LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD,
132 sizeof(*expr)),
133 struct lttng_event_expr_app_specific_context_field,
134 parent);
135 if (!expr) {
136 goto error;
137 }
138
139 expr->provider_name = strdup(provider_name);
140 if (!expr->provider_name) {
141 goto error;
142 }
143
144 expr->type_name = strdup(type_name);
145 if (!expr->type_name) {
146 goto error;
147 }
148
5b5ad96e 149 ret_parent_expr = &expr->parent;
48c47564
PP
150 goto end;
151
152error:
5b5ad96e
FD
153 if (expr) {
154 lttng_event_expr_destroy(&expr->parent);
155 }
156 ret_parent_expr = NULL;
48c47564
PP
157
158end:
5b5ad96e 159 return ret_parent_expr;
48c47564
PP
160}
161
162struct lttng_event_expr *lttng_event_expr_array_field_element_create(
163 struct lttng_event_expr *array_field_expr,
164 unsigned int index)
165{
166 struct lttng_event_expr_array_field_element *expr = NULL;
5b5ad96e 167 struct lttng_event_expr *ret_parent_expr;
48c47564
PP
168
169 /* The parent array field expression must be an l-value */
170 if (!array_field_expr ||
171 !lttng_event_expr_is_lvalue(array_field_expr)) {
172 goto error;
173 }
174
175 expr = container_of(create_empty_expr(
176 LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT,
177 sizeof(*expr)),
178 struct lttng_event_expr_array_field_element,
179 parent);
180 if (!expr) {
181 goto error;
182 }
183
184 expr->array_field_expr = array_field_expr;
185 expr->index = index;
5b5ad96e 186 ret_parent_expr = &expr->parent;
48c47564
PP
187 goto end;
188
189error:
5b5ad96e 190 ret_parent_expr = NULL;
48c47564
PP
191
192end:
5b5ad96e 193 return ret_parent_expr;
48c47564
PP
194}
195
196const char *lttng_event_expr_event_payload_field_get_name(
197 const struct lttng_event_expr *expr)
198{
199 const char *ret = NULL;
200
201 if (!expr || expr->type != LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD) {
202 goto end;
203 }
204
205 ret = container_of(expr,
206 const struct lttng_event_expr_field, parent)->name;
207
208end:
209 return ret;
210}
211
212const char *lttng_event_expr_channel_context_field_get_name(
213 const struct lttng_event_expr *expr)
214{
215 const char *ret = NULL;
216
217 if (!expr || expr->type != LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD) {
218 goto end;
219 }
220
221 ret = container_of(expr,
222 const struct lttng_event_expr_field, parent)->name;
223
224end:
225 return ret;
226}
227
228const char *lttng_event_expr_app_specific_context_field_get_provider_name(
229 const struct lttng_event_expr *expr)
230{
231 const char *ret = NULL;
232
233 if (!expr || expr->type != LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD) {
234 goto end;
235 }
236
237 ret = container_of(expr,
238 const struct lttng_event_expr_app_specific_context_field,
239 parent)->provider_name;
240
241end:
242 return ret;
243}
244
245const char *lttng_event_expr_app_specific_context_field_get_type_name(
246 const struct lttng_event_expr *expr)
247{
248 const char *ret = NULL;
249
250 if (!expr || expr->type != LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD) {
251 goto end;
252 }
253
254 ret = container_of(expr,
255 const struct lttng_event_expr_app_specific_context_field,
256 parent)->type_name;
257
258end:
259 return ret;
260}
261
262const struct lttng_event_expr *
263lttng_event_expr_array_field_element_get_parent_expr(
264 const struct lttng_event_expr *expr)
265{
266 const struct lttng_event_expr *ret = NULL;
267
268 if (!expr || expr->type != LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT) {
269 goto end;
270 }
271
272 ret = container_of(expr,
273 const struct lttng_event_expr_array_field_element,
274 parent)->array_field_expr;
275
276end:
277 return ret;
278}
279
280enum lttng_event_expr_status lttng_event_expr_array_field_element_get_index(
281 const struct lttng_event_expr *expr, unsigned int *index)
282{
283 enum lttng_event_expr_status ret = LTTNG_EVENT_EXPR_STATUS_OK;
284
285 if (!expr || expr->type != LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT ||
286 !index) {
287 ret = LTTNG_EVENT_EXPR_STATUS_INVALID;
288 goto end;
289 }
290
291 *index = container_of(expr,
292 const struct lttng_event_expr_array_field_element,
293 parent)->index;
294
295end:
296 return ret;
297}
298
299bool lttng_event_expr_is_equal(const struct lttng_event_expr *expr_a,
300 const struct lttng_event_expr *expr_b)
301{
302 bool is_equal = true;
303
304 if (!expr_a && !expr_b) {
305 /* Both `NULL`: equal */
306 goto end;
307 }
308
309 if (!expr_a || !expr_b) {
310 /* Only one `NULL`: not equal */
311 goto not_equal;
312 }
313
314 if (expr_a->type != expr_b->type) {
315 /* Different types: not equal */
316 goto not_equal;
317 }
318
319 switch (expr_a->type) {
320 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD:
321 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD:
322 {
323 const struct lttng_event_expr_field *field_expr_a =
324 container_of(expr_a,
325 const struct lttng_event_expr_field,
326 parent);
327 const struct lttng_event_expr_field *field_expr_b =
328 container_of(expr_b,
329 const struct lttng_event_expr_field,
330 parent);
331
332 if (strcmp(field_expr_a->name, field_expr_b->name) != 0) {
333 goto not_equal;
334 }
335
336 break;
337 }
338 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD:
339 {
340 const struct lttng_event_expr_app_specific_context_field *field_expr_a =
341 container_of(expr_a,
342 const struct lttng_event_expr_app_specific_context_field,
343 parent);
344 const struct lttng_event_expr_app_specific_context_field *field_expr_b =
345 container_of(expr_b,
346 const struct lttng_event_expr_app_specific_context_field,
347 parent);
348
349 if (strcmp(field_expr_a->provider_name,
350 field_expr_b->provider_name) != 0) {
351 goto not_equal;
352 }
353
354 if (strcmp(field_expr_a->type_name,
355 field_expr_b->type_name) != 0) {
356 goto not_equal;
357 }
358
359 break;
360 }
361 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT:
362 {
363 const struct lttng_event_expr_array_field_element *elem_expr_a =
364 container_of(expr_a,
365 const struct lttng_event_expr_array_field_element,
366 parent);
367 const struct lttng_event_expr_array_field_element *elem_expr_b =
368 container_of(expr_b,
369 const struct lttng_event_expr_array_field_element,
370 parent);
371
372 if (!lttng_event_expr_is_equal(elem_expr_a->array_field_expr,
373 elem_expr_b->array_field_expr)) {
374 goto not_equal;
375 }
376
377 if (elem_expr_a->index != elem_expr_b->index) {
378 goto not_equal;
379 }
380
381 break;
382 }
383 default:
384 break;
385 }
386
387 goto end;
388
389not_equal:
390 is_equal = false;
391
392end:
393 return is_equal;
394}
395
396void lttng_event_expr_destroy(struct lttng_event_expr *expr)
397{
398 if (!expr) {
399 goto end;
400 }
401
402 switch (expr->type) {
403 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD:
404 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD:
405 {
406 struct lttng_event_expr_field *field_expr =
407 container_of(expr,
408 struct lttng_event_expr_field, parent);
409
410 free(field_expr->name);
411 break;
412 }
413 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD:
414 {
415 struct lttng_event_expr_app_specific_context_field *field_expr =
416 container_of(expr,
417 struct lttng_event_expr_app_specific_context_field,
418 parent);
419
420 free(field_expr->provider_name);
421 free(field_expr->type_name);
422 break;
423 }
424 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT:
425 {
426 struct lttng_event_expr_array_field_element *elem_expr =
427 container_of(expr,
428 struct lttng_event_expr_array_field_element,
429 parent);
430
431 lttng_event_expr_destroy(elem_expr->array_field_expr);
432 break;
433 }
434 default:
435 break;
436 }
437
438 free(expr);
439
440end:
441 return;
442}
1aa9c49c
JR
443
444static int event_expr_to_bytecode_recursive(const struct lttng_event_expr *expr,
445 struct lttng_bytecode_alloc **bytecode,
446 struct lttng_bytecode_alloc **bytecode_reloc)
447{
448 int status;
449 enum lttng_event_expr_status event_expr_status;
450
451 switch (lttng_event_expr_get_type(expr)) {
452 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD:
453 {
454 const char *name;
455
456 status = bytecode_push_get_payload_root(bytecode);
457 if (status) {
458 ERR("Failed to get payload root from bytecode");
459 goto end;
460 }
461
462 name = lttng_event_expr_event_payload_field_get_name(expr);
463 if (!name) {
464 ERR("Failed to get payload field name from event expression");
465 status = -1;
466 goto end;
467 }
468
469 status = bytecode_push_get_symbol(
470 bytecode, bytecode_reloc, name);
471 if (status) {
472 ERR("Failed to push 'get symbol %s' in bytecode", name);
473 goto end;
474 }
475
476 break;
477 }
478 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD:
479 {
480 const char *name;
481
482 status = bytecode_push_get_context_root(bytecode);
483 if (status) {
484 ERR("Failed to get context root from bytecode");
485 goto end;
486 }
487
488 name = lttng_event_expr_channel_context_field_get_name(expr);
489 if (!name) {
490 ERR("Failed to get channel context field name from event expression");
491 status = -1;
492 goto end;
493 }
494
495 status = bytecode_push_get_symbol(
496 bytecode, bytecode_reloc, name);
497 if (status) {
498 ERR("Failed to push 'get symbol %s' in bytecode", name);
499 goto end;
500 }
501
502 break;
503 }
504 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD:
505 {
506 int ret;
507 char *name = NULL;
508 const char *provider_name, *type_name;
509
510 status = bytecode_push_get_app_context_root(bytecode);
511 if (status) {
512 ERR("Failed to get application context root from bytecode");
513 goto end;
514 }
515
516 provider_name = lttng_event_expr_app_specific_context_field_get_provider_name(
517 expr);
518 if (!provider_name) {
519 ERR("Failed to get application context provider name from event expression");
520 status = -1;
521 goto end;
522 }
523
524 type_name = lttng_event_expr_app_specific_context_field_get_type_name(
525 expr);
526 if (!type_name) {
527 ERR("Failed to get application context type name from event expression");
528 status = -1;
529 goto end;
530 }
531
532 /*
533 * Reconstitute the app context field name from its two parts.
534 */
535 ret = asprintf(&name, "%s:%s", provider_name, type_name);
536 if (ret < 0) {
537 PERROR("Failed to format application specific context: provider_name = '%s', type_name = '%s'",
538 provider_name, type_name);
539 status = -1;
540 goto end;
541 }
542
543 status = bytecode_push_get_symbol(
544 bytecode, bytecode_reloc, name);
545 free(name);
546 if (status) {
547 ERR("Failed to push 'get symbol %s:%s' in bytecode",
548 provider_name, type_name);
549 goto end;
550 }
551
552 break;
553 }
554 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT:
555 {
556 unsigned int index;
557 const struct lttng_event_expr *parent;
558
559 parent = lttng_event_expr_array_field_element_get_parent_expr(
560 expr);
561 if (!parent) {
562 ERR("Failed to get parent expression from array event expression");
563 status = -1;
564 goto end;
565 }
566
567 status = event_expr_to_bytecode_recursive(
568 parent, bytecode, bytecode_reloc);
569 if (status) {
570 goto end;
571 }
572
573 event_expr_status =
574 lttng_event_expr_array_field_element_get_index(
575 expr, &index);
576 if (event_expr_status != LTTNG_EVENT_EXPR_STATUS_OK) {
577 ERR("Failed to get array field element index from event expression");
578 status = -1;
579 goto end;
580 }
581
582 status = bytecode_push_get_index_u64(bytecode, index);
583 if (status) {
584 ERR("Failed to push 'get index %u' in bytecode", index);
585 goto end;
586 }
587
588 break;
589 }
590 default:
591 abort();
592 }
593
594 status = 0;
595end:
596 return status;
597}
598
599LTTNG_HIDDEN
600int lttng_event_expr_to_bytecode(const struct lttng_event_expr *expr,
601 struct lttng_bytecode **bytecode_out)
602{
603 int status;
604 struct return_op ret_insn;
605 struct lttng_bytecode_alloc *bytecode = NULL;
606 struct lttng_bytecode_alloc *bytecode_reloc = NULL;
607
608 status = bytecode_init(&bytecode);
609 if (status) {
610 ERR("Failed to initialize bytecode");
611 goto end;
612 }
613
614 status = bytecode_init(&bytecode_reloc);
615 if (status) {
616 ERR("Failed to initialize relocation bytecode");
617 goto end;
618 }
619
620 status = event_expr_to_bytecode_recursive(
621 expr, &bytecode, &bytecode_reloc);
622 if (status) {
623 /* Errors already logged. */
624 goto end;
625 }
626
627 ret_insn.op = BYTECODE_OP_RETURN;
628 bytecode_push(&bytecode, &ret_insn, 1, sizeof(ret_insn));
629
630 /* Append symbol table to bytecode. */
631 bytecode->b.reloc_table_offset = bytecode_get_len(&bytecode->b);
632 status = bytecode_push(&bytecode, bytecode_reloc->b.data, 1,
633 bytecode_get_len(&bytecode_reloc->b));
634 if (status) {
635 ERR("Failed to push symbol table to bytecode");
636 goto end;
637 }
638
639 /* Copy the `lttng_bytecode` out of the `lttng_bytecode_alloc`. */
640 *bytecode_out = lttng_bytecode_copy(&bytecode->b);
641 if (!*bytecode_out) {
642 status = -1;
643 goto end;
644 }
645
646end:
647 if (bytecode) {
648 free(bytecode);
649 }
650
651 if (bytecode_reloc) {
652 free(bytecode_reloc);
653 }
654
655 return status;
656}
6a751b95
JR
657
658static
659enum lttng_error_code lttng_event_expr_event_payload_field_mi_serialize(
660 const struct lttng_event_expr *expression,
661 struct mi_writer *writer)
662{
663 int ret;
664 enum lttng_error_code ret_code;
665 const char *name = NULL;
666
a0377dfe
FD
667 LTTNG_ASSERT(expression);
668 LTTNG_ASSERT(writer);
669 LTTNG_ASSERT(expression->type == LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD);
6a751b95
JR
670
671 name = lttng_event_expr_event_payload_field_get_name(expression);
a0377dfe 672 LTTNG_ASSERT(name);
6a751b95
JR
673
674 /* Open event expr payload field element. */
675 ret = mi_lttng_writer_open_element(
676 writer, mi_lttng_element_event_expr_payload_field);
677 if (ret) {
678 goto mi_error;
679 }
680
681 /* Name. */
682 ret = mi_lttng_writer_write_element_string(
683 writer, config_element_name, name);
684 if (ret) {
685 goto mi_error;
686 }
687
688 /* Close event expr payload field element. */
689 ret = mi_lttng_writer_close_element(writer);
690 if (ret) {
691 goto mi_error;
692 }
693
694 ret_code = LTTNG_OK;
695 goto end;
696
697mi_error:
698 ret_code = LTTNG_ERR_MI_IO_FAIL;
699end:
700 return ret_code;
701}
702
703static
704enum lttng_error_code lttng_event_expr_channel_context_field_mi_serialize(
705 const struct lttng_event_expr *expression,
706 struct mi_writer *writer)
707{
708 int ret;
709 enum lttng_error_code ret_code;
710 const char *name = NULL;
711
a0377dfe
FD
712 LTTNG_ASSERT(expression);
713 LTTNG_ASSERT(writer);
714 LTTNG_ASSERT(expression->type == LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD);
6a751b95
JR
715
716 name = lttng_event_expr_channel_context_field_get_name(expression);
a0377dfe 717 LTTNG_ASSERT(name);
6a751b95
JR
718
719 /* Open event expr channel context field element. */
720 ret = mi_lttng_writer_open_element(writer,
721 mi_lttng_element_event_expr_channel_context_field);
722 if (ret) {
723 goto mi_error;
724 }
725
726 /* Name. */
727 ret = mi_lttng_writer_write_element_string(
728 writer, config_element_name, name);
729 if (ret) {
730 goto mi_error;
731 }
732
733 /* Close event expr channel context field element. */
734 ret = mi_lttng_writer_close_element(writer);
735 if (ret) {
736 goto mi_error;
737 }
738
739 ret_code = LTTNG_OK;
740 goto end;
741
742mi_error:
743 ret_code = LTTNG_ERR_MI_IO_FAIL;
744end:
745 return ret_code;
746}
747
748static
749enum lttng_error_code lttng_event_expr_app_specific_context_field_mi_serialize(
750 const struct lttng_event_expr *expression,
751 struct mi_writer *writer)
752{
753 int ret;
754 enum lttng_error_code ret_code;
755 const char *provider_name = NULL;
756 const char *type_name = NULL;
757
a0377dfe
FD
758 LTTNG_ASSERT(expression);
759 LTTNG_ASSERT(writer);
760 LTTNG_ASSERT(expression->type ==
6a751b95
JR
761 LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD);
762
763 provider_name = lttng_event_expr_app_specific_context_field_get_provider_name(
764 expression);
a0377dfe 765 LTTNG_ASSERT(provider_name);
6a751b95
JR
766
767 type_name = lttng_event_expr_app_specific_context_field_get_type_name(
768 expression);
a0377dfe 769 LTTNG_ASSERT(provider_name);
6a751b95
JR
770
771 /* Open event expr app specific context field element. */
772 ret = mi_lttng_writer_open_element(writer,
773 mi_lttng_element_event_expr_app_specific_context_field);
774 if (ret) {
775 goto mi_error;
776 }
777
778 /* Provider name. */
779 ret = mi_lttng_writer_write_element_string(writer,
780 mi_lttng_element_event_expr_provider_name,
781 provider_name);
782 if (ret) {
783 goto mi_error;
784 }
785
786 /* Type name. */
787 ret = mi_lttng_writer_write_element_string(writer,
788 mi_lttng_element_event_expr_type_name, type_name);
789 if (ret) {
790 goto mi_error;
791 }
792
793 /* Close event expr app specific context field element. */
794 ret = mi_lttng_writer_close_element(writer);
795 if (ret) {
796 goto mi_error;
797 }
798
799 ret_code = LTTNG_OK;
800 goto end;
801
802mi_error:
803 ret_code = LTTNG_ERR_MI_IO_FAIL;
804end:
805 return ret_code;
806}
807
808static
809enum lttng_error_code lttng_event_expr_array_field_element_mi_serialize(
810 const struct lttng_event_expr *expression,
811 struct mi_writer *writer)
812{
813 int ret;
814 enum lttng_error_code ret_code;
815 enum lttng_event_expr_status status;
816 const struct lttng_event_expr *parent_expr = NULL;
817 unsigned int index;
818
a0377dfe
FD
819 LTTNG_ASSERT(expression);
820 LTTNG_ASSERT(writer);
821 LTTNG_ASSERT(expression->type == LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT);
6a751b95
JR
822
823 status = lttng_event_expr_array_field_element_get_index(
824 expression, &index);
a0377dfe 825 LTTNG_ASSERT(status == LTTNG_EVENT_EXPR_STATUS_OK);
6a751b95
JR
826
827 parent_expr = lttng_event_expr_array_field_element_get_parent_expr(
828 expression);
a0377dfe 829 LTTNG_ASSERT(parent_expr != NULL);
6a751b95
JR
830
831 /* Open event expr array field element. */
832 ret = mi_lttng_writer_open_element(writer,
833 mi_lttng_element_event_expr_array_field_element);
834 if (ret) {
835 goto mi_error;
836 }
837
838 /* Index. */
839 ret = mi_lttng_writer_write_element_unsigned_int(
840 writer, mi_lttng_element_event_expr_index, index);
841 if (ret) {
842 goto mi_error;
843 }
844
845 /* Parent expression. */
846 ret_code = lttng_event_expr_mi_serialize(parent_expr, writer);
847 if (ret_code != LTTNG_OK) {
848 goto end;
849 }
850
851 /* Close event expr array field element. */
852 ret = mi_lttng_writer_close_element(writer);
853 if (ret) {
854 goto mi_error;
855 }
856
857 ret_code = LTTNG_OK;
858 goto end;
859
860mi_error:
861 ret_code = LTTNG_ERR_MI_IO_FAIL;
862end:
863 return ret_code;
864}
865
866LTTNG_HIDDEN
867enum lttng_error_code lttng_event_expr_mi_serialize(
868 const struct lttng_event_expr *expression,
869 struct mi_writer *writer)
870{
871 int ret;
872 enum lttng_error_code ret_code;
873
a0377dfe
FD
874 LTTNG_ASSERT(expression);
875 LTTNG_ASSERT(writer);
6a751b95
JR
876
877 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_event_expr);
878 if (ret) {
879 goto mi_error;
880 }
881
882 switch (expression->type) {
883 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD:
884 ret_code = lttng_event_expr_event_payload_field_mi_serialize(
885 expression, writer);
886 break;
887 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD:
888 ret_code = lttng_event_expr_channel_context_field_mi_serialize(
889 expression, writer);
890 break;
891 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD:
892 ret_code = lttng_event_expr_app_specific_context_field_mi_serialize(
893 expression, writer);
894 break;
895 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT:
896 ret_code = lttng_event_expr_array_field_element_mi_serialize(
897 expression, writer);
898 break;
899 default:
900 abort();
901 }
902
903 if (ret_code != LTTNG_OK) {
904 goto end;
905 }
906
907 ret = mi_lttng_writer_close_element(writer);
908 if (ret) {
909 goto mi_error;
910 }
911
912 ret_code = LTTNG_OK;
913 goto end;
914
915mi_error:
916 ret_code = LTTNG_ERR_MI_IO_FAIL;
917
918end:
919 return ret_code;
920}
This page took 0.060018 seconds and 4 git commands to generate.