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