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
);
76 lttng_event_expr_destroy(&expr
->parent
);
82 struct lttng_event_expr
*lttng_event_expr_event_payload_field_create(
83 const char *field_name
)
85 struct lttng_event_expr
*expr
= NULL
;
91 expr
= &create_field_event_expr(
92 LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
,
99 struct lttng_event_expr
*lttng_event_expr_channel_context_field_create(
100 const char *field_name
)
102 struct lttng_event_expr
*expr
= NULL
;
108 expr
= &create_field_event_expr(
109 LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
,
116 struct lttng_event_expr
*lttng_event_expr_app_specific_context_field_create(
117 const char *provider_name
, const char *type_name
)
119 struct lttng_event_expr_app_specific_context_field
*expr
= NULL
;
121 if (!type_name
|| !provider_name
) {
125 expr
= container_of(create_empty_expr(
126 LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
,
128 struct lttng_event_expr_app_specific_context_field
,
134 expr
->provider_name
= strdup(provider_name
);
135 if (!expr
->provider_name
) {
139 expr
->type_name
= strdup(type_name
);
140 if (!expr
->type_name
) {
147 lttng_event_expr_destroy(&expr
->parent
);
150 return &expr
->parent
;
153 struct lttng_event_expr
*lttng_event_expr_array_field_element_create(
154 struct lttng_event_expr
*array_field_expr
,
157 struct lttng_event_expr_array_field_element
*expr
= NULL
;
159 /* The parent array field expression must be an l-value */
160 if (!array_field_expr
||
161 !lttng_event_expr_is_lvalue(array_field_expr
)) {
165 expr
= container_of(create_empty_expr(
166 LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
,
168 struct lttng_event_expr_array_field_element
,
174 expr
->array_field_expr
= array_field_expr
;
179 lttng_event_expr_destroy(&expr
->parent
);
182 return &expr
->parent
;
185 const char *lttng_event_expr_event_payload_field_get_name(
186 const struct lttng_event_expr
*expr
)
188 const char *ret
= NULL
;
190 if (!expr
|| expr
->type
!= LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
) {
194 ret
= container_of(expr
,
195 const struct lttng_event_expr_field
, parent
)->name
;
201 const char *lttng_event_expr_channel_context_field_get_name(
202 const struct lttng_event_expr
*expr
)
204 const char *ret
= NULL
;
206 if (!expr
|| expr
->type
!= LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
) {
210 ret
= container_of(expr
,
211 const struct lttng_event_expr_field
, parent
)->name
;
217 const char *lttng_event_expr_app_specific_context_field_get_provider_name(
218 const struct lttng_event_expr
*expr
)
220 const char *ret
= NULL
;
222 if (!expr
|| expr
->type
!= LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
) {
226 ret
= container_of(expr
,
227 const struct lttng_event_expr_app_specific_context_field
,
228 parent
)->provider_name
;
234 const char *lttng_event_expr_app_specific_context_field_get_type_name(
235 const struct lttng_event_expr
*expr
)
237 const char *ret
= NULL
;
239 if (!expr
|| expr
->type
!= LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
) {
243 ret
= container_of(expr
,
244 const struct lttng_event_expr_app_specific_context_field
,
251 const struct lttng_event_expr
*
252 lttng_event_expr_array_field_element_get_parent_expr(
253 const struct lttng_event_expr
*expr
)
255 const struct lttng_event_expr
*ret
= NULL
;
257 if (!expr
|| expr
->type
!= LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
) {
261 ret
= container_of(expr
,
262 const struct lttng_event_expr_array_field_element
,
263 parent
)->array_field_expr
;
269 enum lttng_event_expr_status
lttng_event_expr_array_field_element_get_index(
270 const struct lttng_event_expr
*expr
, unsigned int *index
)
272 enum lttng_event_expr_status ret
= LTTNG_EVENT_EXPR_STATUS_OK
;
274 if (!expr
|| expr
->type
!= LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
||
276 ret
= LTTNG_EVENT_EXPR_STATUS_INVALID
;
280 *index
= container_of(expr
,
281 const struct lttng_event_expr_array_field_element
,
288 bool lttng_event_expr_is_equal(const struct lttng_event_expr
*expr_a
,
289 const struct lttng_event_expr
*expr_b
)
291 bool is_equal
= true;
293 if (!expr_a
&& !expr_b
) {
294 /* Both `NULL`: equal */
298 if (!expr_a
|| !expr_b
) {
299 /* Only one `NULL`: not equal */
303 if (expr_a
->type
!= expr_b
->type
) {
304 /* Different types: not equal */
308 switch (expr_a
->type
) {
309 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
:
310 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
:
312 const struct lttng_event_expr_field
*field_expr_a
=
314 const struct lttng_event_expr_field
,
316 const struct lttng_event_expr_field
*field_expr_b
=
318 const struct lttng_event_expr_field
,
321 if (strcmp(field_expr_a
->name
, field_expr_b
->name
) != 0) {
327 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
:
329 const struct lttng_event_expr_app_specific_context_field
*field_expr_a
=
331 const struct lttng_event_expr_app_specific_context_field
,
333 const struct lttng_event_expr_app_specific_context_field
*field_expr_b
=
335 const struct lttng_event_expr_app_specific_context_field
,
338 if (strcmp(field_expr_a
->provider_name
,
339 field_expr_b
->provider_name
) != 0) {
343 if (strcmp(field_expr_a
->type_name
,
344 field_expr_b
->type_name
) != 0) {
350 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
:
352 const struct lttng_event_expr_array_field_element
*elem_expr_a
=
354 const struct lttng_event_expr_array_field_element
,
356 const struct lttng_event_expr_array_field_element
*elem_expr_b
=
358 const struct lttng_event_expr_array_field_element
,
361 if (!lttng_event_expr_is_equal(elem_expr_a
->array_field_expr
,
362 elem_expr_b
->array_field_expr
)) {
366 if (elem_expr_a
->index
!= elem_expr_b
->index
) {
385 void lttng_event_expr_destroy(struct lttng_event_expr
*expr
)
391 switch (expr
->type
) {
392 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
:
393 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
:
395 struct lttng_event_expr_field
*field_expr
=
397 struct lttng_event_expr_field
, parent
);
399 free(field_expr
->name
);
402 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
:
404 struct lttng_event_expr_app_specific_context_field
*field_expr
=
406 struct lttng_event_expr_app_specific_context_field
,
409 free(field_expr
->provider_name
);
410 free(field_expr
->type_name
);
413 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
:
415 struct lttng_event_expr_array_field_element
*elem_expr
=
417 struct lttng_event_expr_array_field_element
,
420 lttng_event_expr_destroy(elem_expr
->array_field_expr
);