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
;
47 urcu_ref_init(&expr
->ref
);
55 struct lttng_event_expr_field
*create_field_event_expr(
56 enum lttng_event_expr_type type
,
59 struct lttng_event_expr_field
*expr
=
61 create_empty_expr(type
, sizeof(*expr
)),
62 struct lttng_event_expr_field
, parent
);
69 expr
->name
= strdup(name
);
77 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
;
122 if (!type_name
|| !provider_name
) {
126 expr
= container_of(create_empty_expr(
127 LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
,
129 struct lttng_event_expr_app_specific_context_field
,
135 expr
->provider_name
= strdup(provider_name
);
136 if (!expr
->provider_name
) {
140 expr
->type_name
= strdup(type_name
);
141 if (!expr
->type_name
) {
148 lttng_event_expr_destroy(&expr
->parent
);
151 return &expr
->parent
;
154 struct lttng_event_expr
*lttng_event_expr_array_field_element_create(
155 struct lttng_event_expr
*array_field_expr
,
158 struct lttng_event_expr_array_field_element
*expr
= NULL
;
160 /* The parent array field expression must be an l-value */
161 if (!array_field_expr
||
162 !lttng_event_expr_is_lvalue(array_field_expr
)) {
166 expr
= container_of(create_empty_expr(
167 LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
,
169 struct lttng_event_expr_array_field_element
,
175 expr
->array_field_expr
= array_field_expr
;
180 lttng_event_expr_destroy(&expr
->parent
);
183 return &expr
->parent
;
186 const char *lttng_event_expr_event_payload_field_get_name(
187 const struct lttng_event_expr
*expr
)
189 const char *ret
= NULL
;
191 if (!expr
|| expr
->type
!= LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
) {
195 ret
= container_of(expr
,
196 const struct lttng_event_expr_field
, parent
)->name
;
202 const char *lttng_event_expr_channel_context_field_get_name(
203 const struct lttng_event_expr
*expr
)
205 const char *ret
= NULL
;
207 if (!expr
|| expr
->type
!= LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
) {
211 ret
= container_of(expr
,
212 const struct lttng_event_expr_field
, parent
)->name
;
218 const char *lttng_event_expr_app_specific_context_field_get_provider_name(
219 const struct lttng_event_expr
*expr
)
221 const char *ret
= NULL
;
223 if (!expr
|| expr
->type
!= LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
) {
227 ret
= container_of(expr
,
228 const struct lttng_event_expr_app_specific_context_field
,
229 parent
)->provider_name
;
235 const char *lttng_event_expr_app_specific_context_field_get_type_name(
236 const struct lttng_event_expr
*expr
)
238 const char *ret
= NULL
;
240 if (!expr
|| expr
->type
!= LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
) {
244 ret
= container_of(expr
,
245 const struct lttng_event_expr_app_specific_context_field
,
252 const struct lttng_event_expr
*
253 lttng_event_expr_array_field_element_get_parent_expr(
254 const struct lttng_event_expr
*expr
)
256 const struct lttng_event_expr
*ret
= NULL
;
258 if (!expr
|| expr
->type
!= LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
) {
262 ret
= container_of(expr
,
263 const struct lttng_event_expr_array_field_element
,
264 parent
)->array_field_expr
;
270 enum lttng_event_expr_status
lttng_event_expr_array_field_element_get_index(
271 const struct lttng_event_expr
*expr
, unsigned int *index
)
273 enum lttng_event_expr_status ret
= LTTNG_EVENT_EXPR_STATUS_OK
;
275 if (!expr
|| expr
->type
!= LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
||
277 ret
= LTTNG_EVENT_EXPR_STATUS_INVALID
;
281 *index
= container_of(expr
,
282 const struct lttng_event_expr_array_field_element
,
289 bool lttng_event_expr_is_equal(const struct lttng_event_expr
*expr_a
,
290 const struct lttng_event_expr
*expr_b
)
292 bool is_equal
= true;
294 if (!expr_a
&& !expr_b
) {
295 /* Both `NULL`: equal */
299 if (!expr_a
|| !expr_b
) {
300 /* Only one `NULL`: not equal */
304 if (expr_a
->type
!= expr_b
->type
) {
305 /* Different types: not equal */
309 switch (expr_a
->type
) {
310 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
:
311 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
:
313 const struct lttng_event_expr_field
*field_expr_a
=
315 const struct lttng_event_expr_field
,
317 const struct lttng_event_expr_field
*field_expr_b
=
319 const struct lttng_event_expr_field
,
322 if (strcmp(field_expr_a
->name
, field_expr_b
->name
) != 0) {
328 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
:
330 const struct lttng_event_expr_app_specific_context_field
*field_expr_a
=
332 const struct lttng_event_expr_app_specific_context_field
,
334 const struct lttng_event_expr_app_specific_context_field
*field_expr_b
=
336 const struct lttng_event_expr_app_specific_context_field
,
339 if (strcmp(field_expr_a
->provider_name
,
340 field_expr_b
->provider_name
) != 0) {
344 if (strcmp(field_expr_a
->type_name
,
345 field_expr_b
->type_name
) != 0) {
351 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
:
353 const struct lttng_event_expr_array_field_element
*elem_expr_a
=
355 const struct lttng_event_expr_array_field_element
,
357 const struct lttng_event_expr_array_field_element
*elem_expr_b
=
359 const struct lttng_event_expr_array_field_element
,
362 if (!lttng_event_expr_is_equal(elem_expr_a
->array_field_expr
,
363 elem_expr_b
->array_field_expr
)) {
367 if (elem_expr_a
->index
!= elem_expr_b
->index
) {
387 void event_expr_destroy_ref(struct urcu_ref
*ref
)
389 struct lttng_event_expr
*expr
=
390 container_of(ref
, struct lttng_event_expr
, ref
);
392 switch (expr
->type
) {
393 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
:
394 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
:
396 struct lttng_event_expr_field
*field_expr
=
398 struct lttng_event_expr_field
, parent
);
400 free(field_expr
->name
);
403 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
:
405 struct lttng_event_expr_app_specific_context_field
*field_expr
=
407 struct lttng_event_expr_app_specific_context_field
,
410 free(field_expr
->provider_name
);
411 free(field_expr
->type_name
);
414 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
:
416 struct lttng_event_expr_array_field_element
*elem_expr
=
418 struct lttng_event_expr_array_field_element
,
421 lttng_event_expr_destroy(elem_expr
->array_field_expr
);
432 void lttng_event_expr_get(struct lttng_event_expr
*expr
)
434 urcu_ref_get(&expr
->ref
);
438 void lttng_event_expr_put(struct lttng_event_expr
*expr
) {
442 urcu_ref_put(&expr
->ref
, event_expr_destroy_ref
);
445 void lttng_event_expr_destroy(struct lttng_event_expr
*expr
)
447 lttng_event_expr_put(expr
);