Move event-expr from liblttng-ctl to libcommon
[lttng-tools.git] / src / common / event-expr / event-expr.c
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
11#include <assert.h>
12#include <stddef.h>
13
14#include <common/error.h>
15#include <common/macros.h>
16#include <lttng/event-expr-internal.h>
17
18enum lttng_event_expr_type lttng_event_expr_get_type(
19 const struct lttng_event_expr *expr)
20{
21 enum lttng_event_expr_type type;
22
23 if (!expr) {
24 type = LTTNG_EVENT_EXPR_TYPE_INVALID;
25 goto end;
26 }
27
28 type = expr->type;
29
30end:
31 return type;
32}
33
34static
35struct lttng_event_expr *create_empty_expr(enum lttng_event_expr_type type,
36 size_t size)
37{
38 struct lttng_event_expr *expr;
39
40 expr = zmalloc(size);
41 if (!expr) {
42 goto end;
43 }
44
45 expr->type = type;
46
47end:
48 return expr;
49}
50
51static
52struct lttng_event_expr_field *create_field_event_expr(
53 enum lttng_event_expr_type type,
54 const char *name)
55{
56 struct lttng_event_expr_field *expr =
57 container_of(
58 create_empty_expr(type, sizeof(*expr)),
59 struct lttng_event_expr_field, parent);
60
61 if (!expr) {
62 goto error;
63 }
64
65 assert(name);
66 expr->name = strdup(name);
67 if (!expr->name) {
68 goto error;
69 }
70
71 goto end;
72
73error:
5b5ad96e
FD
74 if (expr) {
75 lttng_event_expr_destroy(&expr->parent);
76 }
77 expr = NULL;
48c47564
PP
78
79end:
80 return expr;
81}
82
83struct lttng_event_expr *lttng_event_expr_event_payload_field_create(
84 const char *field_name)
85{
86 struct lttng_event_expr *expr = NULL;
87
88 if (!field_name) {
89 goto end;
90 }
91
92 expr = &create_field_event_expr(
93 LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD,
94 field_name)->parent;
95
96end:
97 return expr;
98}
99
100struct lttng_event_expr *lttng_event_expr_channel_context_field_create(
101 const char *field_name)
102{
103 struct lttng_event_expr *expr = NULL;
104
105 if (!field_name) {
106 goto end;
107 }
108
109 expr = &create_field_event_expr(
110 LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD,
111 field_name)->parent;
112
113end:
114 return expr;
115}
116
117struct lttng_event_expr *lttng_event_expr_app_specific_context_field_create(
118 const char *provider_name, const char *type_name)
119{
120 struct lttng_event_expr_app_specific_context_field *expr = NULL;
5b5ad96e 121 struct lttng_event_expr *ret_parent_expr;
48c47564
PP
122
123 if (!type_name || !provider_name) {
124 goto error;
125 }
126
127 expr = container_of(create_empty_expr(
128 LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD,
129 sizeof(*expr)),
130 struct lttng_event_expr_app_specific_context_field,
131 parent);
132 if (!expr) {
133 goto error;
134 }
135
136 expr->provider_name = strdup(provider_name);
137 if (!expr->provider_name) {
138 goto error;
139 }
140
141 expr->type_name = strdup(type_name);
142 if (!expr->type_name) {
143 goto error;
144 }
145
5b5ad96e 146 ret_parent_expr = &expr->parent;
48c47564
PP
147 goto end;
148
149error:
5b5ad96e
FD
150 if (expr) {
151 lttng_event_expr_destroy(&expr->parent);
152 }
153 ret_parent_expr = NULL;
48c47564
PP
154
155end:
5b5ad96e 156 return ret_parent_expr;
48c47564
PP
157}
158
159struct lttng_event_expr *lttng_event_expr_array_field_element_create(
160 struct lttng_event_expr *array_field_expr,
161 unsigned int index)
162{
163 struct lttng_event_expr_array_field_element *expr = NULL;
5b5ad96e 164 struct lttng_event_expr *ret_parent_expr;
48c47564
PP
165
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)) {
169 goto error;
170 }
171
172 expr = container_of(create_empty_expr(
173 LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT,
174 sizeof(*expr)),
175 struct lttng_event_expr_array_field_element,
176 parent);
177 if (!expr) {
178 goto error;
179 }
180
181 expr->array_field_expr = array_field_expr;
182 expr->index = index;
5b5ad96e 183 ret_parent_expr = &expr->parent;
48c47564
PP
184 goto end;
185
186error:
5b5ad96e
FD
187 if (expr) {
188 lttng_event_expr_destroy(&expr->parent);
189 }
190 ret_parent_expr = NULL;
48c47564
PP
191
192end:
5b5ad96e 193 return ret_parent_expr;
48c47564
PP
194}
195
196const char *lttng_event_expr_event_payload_field_get_name(
197 const struct lttng_event_expr *expr)
198{
199 const char *ret = NULL;
200
201 if (!expr || expr->type != LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD) {
202 goto end;
203 }
204
205 ret = container_of(expr,
206 const struct lttng_event_expr_field, parent)->name;
207
208end:
209 return ret;
210}
211
212const char *lttng_event_expr_channel_context_field_get_name(
213 const struct lttng_event_expr *expr)
214{
215 const char *ret = NULL;
216
217 if (!expr || expr->type != LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD) {
218 goto end;
219 }
220
221 ret = container_of(expr,
222 const struct lttng_event_expr_field, parent)->name;
223
224end:
225 return ret;
226}
227
228const char *lttng_event_expr_app_specific_context_field_get_provider_name(
229 const struct lttng_event_expr *expr)
230{
231 const char *ret = NULL;
232
233 if (!expr || expr->type != LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD) {
234 goto end;
235 }
236
237 ret = container_of(expr,
238 const struct lttng_event_expr_app_specific_context_field,
239 parent)->provider_name;
240
241end:
242 return ret;
243}
244
245const char *lttng_event_expr_app_specific_context_field_get_type_name(
246 const struct lttng_event_expr *expr)
247{
248 const char *ret = NULL;
249
250 if (!expr || expr->type != LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD) {
251 goto end;
252 }
253
254 ret = container_of(expr,
255 const struct lttng_event_expr_app_specific_context_field,
256 parent)->type_name;
257
258end:
259 return ret;
260}
261
262const struct lttng_event_expr *
263lttng_event_expr_array_field_element_get_parent_expr(
264 const struct lttng_event_expr *expr)
265{
266 const struct lttng_event_expr *ret = NULL;
267
268 if (!expr || expr->type != LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT) {
269 goto end;
270 }
271
272 ret = container_of(expr,
273 const struct lttng_event_expr_array_field_element,
274 parent)->array_field_expr;
275
276end:
277 return ret;
278}
279
280enum lttng_event_expr_status lttng_event_expr_array_field_element_get_index(
281 const struct lttng_event_expr *expr, unsigned int *index)
282{
283 enum lttng_event_expr_status ret = LTTNG_EVENT_EXPR_STATUS_OK;
284
285 if (!expr || expr->type != LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT ||
286 !index) {
287 ret = LTTNG_EVENT_EXPR_STATUS_INVALID;
288 goto end;
289 }
290
291 *index = container_of(expr,
292 const struct lttng_event_expr_array_field_element,
293 parent)->index;
294
295end:
296 return ret;
297}
298
299bool lttng_event_expr_is_equal(const struct lttng_event_expr *expr_a,
300 const struct lttng_event_expr *expr_b)
301{
302 bool is_equal = true;
303
304 if (!expr_a && !expr_b) {
305 /* Both `NULL`: equal */
306 goto end;
307 }
308
309 if (!expr_a || !expr_b) {
310 /* Only one `NULL`: not equal */
311 goto not_equal;
312 }
313
314 if (expr_a->type != expr_b->type) {
315 /* Different types: not equal */
316 goto not_equal;
317 }
318
319 switch (expr_a->type) {
320 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD:
321 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD:
322 {
323 const struct lttng_event_expr_field *field_expr_a =
324 container_of(expr_a,
325 const struct lttng_event_expr_field,
326 parent);
327 const struct lttng_event_expr_field *field_expr_b =
328 container_of(expr_b,
329 const struct lttng_event_expr_field,
330 parent);
331
332 if (strcmp(field_expr_a->name, field_expr_b->name) != 0) {
333 goto not_equal;
334 }
335
336 break;
337 }
338 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD:
339 {
340 const struct lttng_event_expr_app_specific_context_field *field_expr_a =
341 container_of(expr_a,
342 const struct lttng_event_expr_app_specific_context_field,
343 parent);
344 const struct lttng_event_expr_app_specific_context_field *field_expr_b =
345 container_of(expr_b,
346 const struct lttng_event_expr_app_specific_context_field,
347 parent);
348
349 if (strcmp(field_expr_a->provider_name,
350 field_expr_b->provider_name) != 0) {
351 goto not_equal;
352 }
353
354 if (strcmp(field_expr_a->type_name,
355 field_expr_b->type_name) != 0) {
356 goto not_equal;
357 }
358
359 break;
360 }
361 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT:
362 {
363 const struct lttng_event_expr_array_field_element *elem_expr_a =
364 container_of(expr_a,
365 const struct lttng_event_expr_array_field_element,
366 parent);
367 const struct lttng_event_expr_array_field_element *elem_expr_b =
368 container_of(expr_b,
369 const struct lttng_event_expr_array_field_element,
370 parent);
371
372 if (!lttng_event_expr_is_equal(elem_expr_a->array_field_expr,
373 elem_expr_b->array_field_expr)) {
374 goto not_equal;
375 }
376
377 if (elem_expr_a->index != elem_expr_b->index) {
378 goto not_equal;
379 }
380
381 break;
382 }
383 default:
384 break;
385 }
386
387 goto end;
388
389not_equal:
390 is_equal = false;
391
392end:
393 return is_equal;
394}
395
396void lttng_event_expr_destroy(struct lttng_event_expr *expr)
397{
398 if (!expr) {
399 goto end;
400 }
401
402 switch (expr->type) {
403 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD:
404 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD:
405 {
406 struct lttng_event_expr_field *field_expr =
407 container_of(expr,
408 struct lttng_event_expr_field, parent);
409
410 free(field_expr->name);
411 break;
412 }
413 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD:
414 {
415 struct lttng_event_expr_app_specific_context_field *field_expr =
416 container_of(expr,
417 struct lttng_event_expr_app_specific_context_field,
418 parent);
419
420 free(field_expr->provider_name);
421 free(field_expr->type_name);
422 break;
423 }
424 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT:
425 {
426 struct lttng_event_expr_array_field_element *elem_expr =
427 container_of(expr,
428 struct lttng_event_expr_array_field_element,
429 parent);
430
431 lttng_event_expr_destroy(elem_expr->array_field_expr);
432 break;
433 }
434 default:
435 break;
436 }
437
438 free(expr);
439
440end:
441 return;
442}
This page took 0.04012 seconds and 4 git commands to generate.