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