4 * Copyright (C) 2020 Philippe Proulx <pproulx@efficios.com>
6 * SPDX-License-Identifier: LGPL-2.1-only
14 #include <common/error.h>
15 #include <common/macros.h>
16 #include <lttng/event-expr-internal.h>
18 enum lttng_event_expr_type
lttng_event_expr_get_type(
19 const struct lttng_event_expr
*expr
)
21 enum lttng_event_expr_type type
;
24 type
= LTTNG_EVENT_EXPR_TYPE_INVALID
;
35 struct lttng_event_expr
*create_empty_expr(enum lttng_event_expr_type type
,
38 struct lttng_event_expr
*expr
;
52 struct lttng_event_expr_field
*create_field_event_expr(
53 enum lttng_event_expr_type type
,
56 struct lttng_event_expr_field
*expr
=
58 create_empty_expr(type
, sizeof(*expr
)),
59 struct lttng_event_expr_field
, parent
);
66 expr
->name
= strdup(name
);
75 lttng_event_expr_destroy(&expr
->parent
);
83 struct lttng_event_expr
*lttng_event_expr_event_payload_field_create(
84 const char *field_name
)
86 struct lttng_event_expr
*expr
= NULL
;
92 expr
= &create_field_event_expr(
93 LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
,
100 struct lttng_event_expr
*lttng_event_expr_channel_context_field_create(
101 const char *field_name
)
103 struct lttng_event_expr
*expr
= NULL
;
109 expr
= &create_field_event_expr(
110 LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
,
117 struct lttng_event_expr
*lttng_event_expr_app_specific_context_field_create(
118 const char *provider_name
, const char *type_name
)
120 struct lttng_event_expr_app_specific_context_field
*expr
= NULL
;
121 struct lttng_event_expr
*ret_parent_expr
;
123 if (!type_name
|| !provider_name
) {
127 expr
= container_of(create_empty_expr(
128 LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
,
130 struct lttng_event_expr_app_specific_context_field
,
136 expr
->provider_name
= strdup(provider_name
);
137 if (!expr
->provider_name
) {
141 expr
->type_name
= strdup(type_name
);
142 if (!expr
->type_name
) {
146 ret_parent_expr
= &expr
->parent
;
151 lttng_event_expr_destroy(&expr
->parent
);
153 ret_parent_expr
= NULL
;
156 return ret_parent_expr
;
159 struct lttng_event_expr
*lttng_event_expr_array_field_element_create(
160 struct lttng_event_expr
*array_field_expr
,
163 struct lttng_event_expr_array_field_element
*expr
= NULL
;
164 struct lttng_event_expr
*ret_parent_expr
;
166 /* The parent array field expression must be an l-value */
167 if (!array_field_expr
||
168 !lttng_event_expr_is_lvalue(array_field_expr
)) {
172 expr
= container_of(create_empty_expr(
173 LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
,
175 struct lttng_event_expr_array_field_element
,
181 expr
->array_field_expr
= array_field_expr
;
183 ret_parent_expr
= &expr
->parent
;
188 lttng_event_expr_destroy(&expr
->parent
);
190 ret_parent_expr
= NULL
;
193 return ret_parent_expr
;
196 const char *lttng_event_expr_event_payload_field_get_name(
197 const struct lttng_event_expr
*expr
)
199 const char *ret
= NULL
;
201 if (!expr
|| expr
->type
!= LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
) {
205 ret
= container_of(expr
,
206 const struct lttng_event_expr_field
, parent
)->name
;
212 const char *lttng_event_expr_channel_context_field_get_name(
213 const struct lttng_event_expr
*expr
)
215 const char *ret
= NULL
;
217 if (!expr
|| expr
->type
!= LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
) {
221 ret
= container_of(expr
,
222 const struct lttng_event_expr_field
, parent
)->name
;
228 const char *lttng_event_expr_app_specific_context_field_get_provider_name(
229 const struct lttng_event_expr
*expr
)
231 const char *ret
= NULL
;
233 if (!expr
|| expr
->type
!= LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
) {
237 ret
= container_of(expr
,
238 const struct lttng_event_expr_app_specific_context_field
,
239 parent
)->provider_name
;
245 const char *lttng_event_expr_app_specific_context_field_get_type_name(
246 const struct lttng_event_expr
*expr
)
248 const char *ret
= NULL
;
250 if (!expr
|| expr
->type
!= LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
) {
254 ret
= container_of(expr
,
255 const struct lttng_event_expr_app_specific_context_field
,
262 const struct lttng_event_expr
*
263 lttng_event_expr_array_field_element_get_parent_expr(
264 const struct lttng_event_expr
*expr
)
266 const struct lttng_event_expr
*ret
= NULL
;
268 if (!expr
|| expr
->type
!= LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
) {
272 ret
= container_of(expr
,
273 const struct lttng_event_expr_array_field_element
,
274 parent
)->array_field_expr
;
280 enum lttng_event_expr_status
lttng_event_expr_array_field_element_get_index(
281 const struct lttng_event_expr
*expr
, unsigned int *index
)
283 enum lttng_event_expr_status ret
= LTTNG_EVENT_EXPR_STATUS_OK
;
285 if (!expr
|| expr
->type
!= LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
||
287 ret
= LTTNG_EVENT_EXPR_STATUS_INVALID
;
291 *index
= container_of(expr
,
292 const struct lttng_event_expr_array_field_element
,
299 bool lttng_event_expr_is_equal(const struct lttng_event_expr
*expr_a
,
300 const struct lttng_event_expr
*expr_b
)
302 bool is_equal
= true;
304 if (!expr_a
&& !expr_b
) {
305 /* Both `NULL`: equal */
309 if (!expr_a
|| !expr_b
) {
310 /* Only one `NULL`: not equal */
314 if (expr_a
->type
!= expr_b
->type
) {
315 /* Different types: not equal */
319 switch (expr_a
->type
) {
320 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
:
321 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
:
323 const struct lttng_event_expr_field
*field_expr_a
=
325 const struct lttng_event_expr_field
,
327 const struct lttng_event_expr_field
*field_expr_b
=
329 const struct lttng_event_expr_field
,
332 if (strcmp(field_expr_a
->name
, field_expr_b
->name
) != 0) {
338 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
:
340 const struct lttng_event_expr_app_specific_context_field
*field_expr_a
=
342 const struct lttng_event_expr_app_specific_context_field
,
344 const struct lttng_event_expr_app_specific_context_field
*field_expr_b
=
346 const struct lttng_event_expr_app_specific_context_field
,
349 if (strcmp(field_expr_a
->provider_name
,
350 field_expr_b
->provider_name
) != 0) {
354 if (strcmp(field_expr_a
->type_name
,
355 field_expr_b
->type_name
) != 0) {
361 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
:
363 const struct lttng_event_expr_array_field_element
*elem_expr_a
=
365 const struct lttng_event_expr_array_field_element
,
367 const struct lttng_event_expr_array_field_element
*elem_expr_b
=
369 const struct lttng_event_expr_array_field_element
,
372 if (!lttng_event_expr_is_equal(elem_expr_a
->array_field_expr
,
373 elem_expr_b
->array_field_expr
)) {
377 if (elem_expr_a
->index
!= elem_expr_b
->index
) {
396 void lttng_event_expr_destroy(struct lttng_event_expr
*expr
)
402 switch (expr
->type
) {
403 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
:
404 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
:
406 struct lttng_event_expr_field
*field_expr
=
408 struct lttng_event_expr_field
, parent
);
410 free(field_expr
->name
);
413 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
:
415 struct lttng_event_expr_app_specific_context_field
*field_expr
=
417 struct lttng_event_expr_app_specific_context_field
,
420 free(field_expr
->provider_name
);
421 free(field_expr
->type_name
);
424 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
:
426 struct lttng_event_expr_array_field_element
*elem_expr
=
428 struct lttng_event_expr_array_field_element
,
431 lttng_event_expr_destroy(elem_expr
->array_field_expr
);