4 * Linux Trace Toolkit Control Library
6 * Copyright (C) 2020 Philippe Proulx <pproulx@efficios.com>
8 * SPDX-License-Identifier: LGPL-2.1-only
16 #include <common/error.h>
17 #include <common/macros.h>
18 #include <lttng/event-expr-internal.h>
20 enum lttng_event_expr_type
lttng_event_expr_get_type(
21 const struct lttng_event_expr
*expr
)
23 enum lttng_event_expr_type type
;
26 type
= LTTNG_EVENT_EXPR_TYPE_INVALID
;
37 struct lttng_event_expr
*create_empty_expr(enum lttng_event_expr_type type
,
40 struct lttng_event_expr
*expr
;
54 struct lttng_event_expr_field
*create_field_event_expr(
55 enum lttng_event_expr_type type
,
58 struct lttng_event_expr_field
*expr
=
60 create_empty_expr(type
, sizeof(*expr
)),
61 struct lttng_event_expr_field
, parent
);
68 expr
->name
= strdup(name
);
77 lttng_event_expr_destroy(&expr
->parent
);
85 struct lttng_event_expr
*lttng_event_expr_event_payload_field_create(
86 const char *field_name
)
88 struct lttng_event_expr
*expr
= NULL
;
94 expr
= &create_field_event_expr(
95 LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
,
102 struct lttng_event_expr
*lttng_event_expr_channel_context_field_create(
103 const char *field_name
)
105 struct lttng_event_expr
*expr
= NULL
;
111 expr
= &create_field_event_expr(
112 LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
,
119 struct lttng_event_expr
*lttng_event_expr_app_specific_context_field_create(
120 const char *provider_name
, const char *type_name
)
122 struct lttng_event_expr_app_specific_context_field
*expr
= NULL
;
123 struct lttng_event_expr
*ret_parent_expr
;
125 if (!type_name
|| !provider_name
) {
129 expr
= container_of(create_empty_expr(
130 LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
,
132 struct lttng_event_expr_app_specific_context_field
,
138 expr
->provider_name
= strdup(provider_name
);
139 if (!expr
->provider_name
) {
143 expr
->type_name
= strdup(type_name
);
144 if (!expr
->type_name
) {
148 ret_parent_expr
= &expr
->parent
;
153 lttng_event_expr_destroy(&expr
->parent
);
155 ret_parent_expr
= NULL
;
158 return ret_parent_expr
;
161 struct lttng_event_expr
*lttng_event_expr_array_field_element_create(
162 struct lttng_event_expr
*array_field_expr
,
165 struct lttng_event_expr_array_field_element
*expr
= NULL
;
166 struct lttng_event_expr
*ret_parent_expr
;
168 /* The parent array field expression must be an l-value */
169 if (!array_field_expr
||
170 !lttng_event_expr_is_lvalue(array_field_expr
)) {
174 expr
= container_of(create_empty_expr(
175 LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
,
177 struct lttng_event_expr_array_field_element
,
183 expr
->array_field_expr
= array_field_expr
;
185 ret_parent_expr
= &expr
->parent
;
190 lttng_event_expr_destroy(&expr
->parent
);
192 ret_parent_expr
= NULL
;
195 return ret_parent_expr
;
198 const char *lttng_event_expr_event_payload_field_get_name(
199 const struct lttng_event_expr
*expr
)
201 const char *ret
= NULL
;
203 if (!expr
|| expr
->type
!= LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
) {
207 ret
= container_of(expr
,
208 const struct lttng_event_expr_field
, parent
)->name
;
214 const char *lttng_event_expr_channel_context_field_get_name(
215 const struct lttng_event_expr
*expr
)
217 const char *ret
= NULL
;
219 if (!expr
|| expr
->type
!= LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
) {
223 ret
= container_of(expr
,
224 const struct lttng_event_expr_field
, parent
)->name
;
230 const char *lttng_event_expr_app_specific_context_field_get_provider_name(
231 const struct lttng_event_expr
*expr
)
233 const char *ret
= NULL
;
235 if (!expr
|| expr
->type
!= LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
) {
239 ret
= container_of(expr
,
240 const struct lttng_event_expr_app_specific_context_field
,
241 parent
)->provider_name
;
247 const char *lttng_event_expr_app_specific_context_field_get_type_name(
248 const struct lttng_event_expr
*expr
)
250 const char *ret
= NULL
;
252 if (!expr
|| expr
->type
!= LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
) {
256 ret
= container_of(expr
,
257 const struct lttng_event_expr_app_specific_context_field
,
264 const struct lttng_event_expr
*
265 lttng_event_expr_array_field_element_get_parent_expr(
266 const struct lttng_event_expr
*expr
)
268 const struct lttng_event_expr
*ret
= NULL
;
270 if (!expr
|| expr
->type
!= LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
) {
274 ret
= container_of(expr
,
275 const struct lttng_event_expr_array_field_element
,
276 parent
)->array_field_expr
;
282 enum lttng_event_expr_status
lttng_event_expr_array_field_element_get_index(
283 const struct lttng_event_expr
*expr
, unsigned int *index
)
285 enum lttng_event_expr_status ret
= LTTNG_EVENT_EXPR_STATUS_OK
;
287 if (!expr
|| expr
->type
!= LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
||
289 ret
= LTTNG_EVENT_EXPR_STATUS_INVALID
;
293 *index
= container_of(expr
,
294 const struct lttng_event_expr_array_field_element
,
301 bool lttng_event_expr_is_equal(const struct lttng_event_expr
*expr_a
,
302 const struct lttng_event_expr
*expr_b
)
304 bool is_equal
= true;
306 if (!expr_a
&& !expr_b
) {
307 /* Both `NULL`: equal */
311 if (!expr_a
|| !expr_b
) {
312 /* Only one `NULL`: not equal */
316 if (expr_a
->type
!= expr_b
->type
) {
317 /* Different types: not equal */
321 switch (expr_a
->type
) {
322 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
:
323 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
:
325 const struct lttng_event_expr_field
*field_expr_a
=
327 const struct lttng_event_expr_field
,
329 const struct lttng_event_expr_field
*field_expr_b
=
331 const struct lttng_event_expr_field
,
334 if (strcmp(field_expr_a
->name
, field_expr_b
->name
) != 0) {
340 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
:
342 const struct lttng_event_expr_app_specific_context_field
*field_expr_a
=
344 const struct lttng_event_expr_app_specific_context_field
,
346 const struct lttng_event_expr_app_specific_context_field
*field_expr_b
=
348 const struct lttng_event_expr_app_specific_context_field
,
351 if (strcmp(field_expr_a
->provider_name
,
352 field_expr_b
->provider_name
) != 0) {
356 if (strcmp(field_expr_a
->type_name
,
357 field_expr_b
->type_name
) != 0) {
363 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
:
365 const struct lttng_event_expr_array_field_element
*elem_expr_a
=
367 const struct lttng_event_expr_array_field_element
,
369 const struct lttng_event_expr_array_field_element
*elem_expr_b
=
371 const struct lttng_event_expr_array_field_element
,
374 if (!lttng_event_expr_is_equal(elem_expr_a
->array_field_expr
,
375 elem_expr_b
->array_field_expr
)) {
379 if (elem_expr_a
->index
!= elem_expr_b
->index
) {
398 void lttng_event_expr_destroy(struct lttng_event_expr
*expr
)
404 switch (expr
->type
) {
405 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
:
406 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
:
408 struct lttng_event_expr_field
*field_expr
=
410 struct lttng_event_expr_field
, parent
);
412 free(field_expr
->name
);
415 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
:
417 struct lttng_event_expr_app_specific_context_field
*field_expr
=
419 struct lttng_event_expr_app_specific_context_field
,
422 free(field_expr
->provider_name
);
423 free(field_expr
->type_name
);
426 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
:
428 struct lttng_event_expr_array_field_element
*elem_expr
=
430 struct lttng_event_expr_array_field_element
,
433 lttng_event_expr_destroy(elem_expr
->array_field_expr
);