lib: remove unused includes
[babeltrace.git] / src / lib / trace-ir / resolve-field-path.c
CommitLineData
44c440bc 1/*
0235b0db 2 * SPDX-License-Identifier: MIT
44c440bc 3 *
0235b0db 4 * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
44c440bc
PP
5 */
6
350ad6c1 7#define BT_LOG_TAG "LIB/RESOLVE-FIELD-PATH"
c2d9d9cf 8#include "lib/logging.h"
44c440bc 9
d98421f2 10#include "lib/assert-cond.h"
578e048b 11#include "common/assert.h"
43c59509 12#include <babeltrace2/trace-ir/field-path.h>
c4f23e30 13#include <stdbool.h>
44c440bc 14#include <stdint.h>
44c440bc
PP
15#include <glib.h>
16
578e048b
MJ
17#include "field-class.h"
18#include "field-path.h"
19#include "resolve-field-path.h"
20
44c440bc 21static
5cd6d0e5
PP
22bool find_field_class_recursive(struct bt_field_class *fc,
23 struct bt_field_class *tgt_fc, struct bt_field_path *field_path)
44c440bc
PP
24{
25 bool found = false;
26
5cd6d0e5 27 if (tgt_fc == fc) {
44c440bc
PP
28 found = true;
29 goto end;
30 }
31
ebdb6693 32 if (bt_field_class_type_is(fc->type, BT_FIELD_CLASS_TYPE_OPTION)) {
b38aea74 33 struct bt_field_class_option *opt_fc = (void *) fc;
b38aea74
PP
34 struct bt_field_path_item item = {
35 .type = BT_FIELD_PATH_ITEM_TYPE_CURRENT_OPTION_CONTENT,
36 .index = UINT64_C(-1),
37 };
38
39 bt_field_path_append_item(field_path, &item);
40 found = find_field_class_recursive(opt_fc->content_fc,
41 tgt_fc, field_path);
42 if (found) {
43 goto end;
44 }
45
46 bt_field_path_remove_last_item(field_path);
ebdb6693
PP
47 } else if (fc->type == BT_FIELD_CLASS_TYPE_STRUCTURE ||
48 bt_field_class_type_is(fc->type,
49 BT_FIELD_CLASS_TYPE_VARIANT)) {
5cd6d0e5
PP
50 struct bt_field_class_named_field_class_container *container_fc =
51 (void *) fc;
44c440bc
PP
52 uint64_t i;
53
5cd6d0e5
PP
54 for (i = 0; i < container_fc->named_fcs->len; i++) {
55 struct bt_named_field_class *named_fc =
45c51519 56 container_fc->named_fcs->pdata[i];
66ddcddf
PP
57 struct bt_field_path_item item = {
58 .type = BT_FIELD_PATH_ITEM_TYPE_INDEX,
59 .index = i,
60 };
44c440bc 61
66ddcddf 62 bt_field_path_append_item(field_path, &item);
5cd6d0e5
PP
63 found = find_field_class_recursive(named_fc->fc,
64 tgt_fc, field_path);
44c440bc
PP
65 if (found) {
66 goto end;
67 }
68
66ddcddf 69 bt_field_path_remove_last_item(field_path);
44c440bc 70 }
ebdb6693 71 } else if (bt_field_class_type_is(fc->type, BT_FIELD_CLASS_TYPE_ARRAY)) {
5cd6d0e5 72 struct bt_field_class_array *array_fc = (void *) fc;
66ddcddf
PP
73 struct bt_field_path_item item = {
74 .type = BT_FIELD_PATH_ITEM_TYPE_CURRENT_ARRAY_ELEMENT,
75 .index = UINT64_C(-1),
76 };
44c440bc 77
66ddcddf 78 bt_field_path_append_item(field_path, &item);
5cd6d0e5
PP
79 found = find_field_class_recursive(array_fc->element_fc,
80 tgt_fc, field_path);
66ddcddf
PP
81 if (found) {
82 goto end;
83 }
84
85 bt_field_path_remove_last_item(field_path);
44c440bc
PP
86 }
87
88end:
89 return found;
90}
91
92static
5cd6d0e5 93int find_field_class(struct bt_field_class *root_fc,
e7ceb9df 94 enum bt_field_path_scope root_scope, struct bt_field_class *tgt_fc,
44c440bc
PP
95 struct bt_field_path **ret_field_path)
96{
97 int ret = 0;
98 struct bt_field_path *field_path = NULL;
99
5cd6d0e5 100 if (!root_fc) {
44c440bc
PP
101 goto end;
102 }
103
104 field_path = bt_field_path_create();
105 if (!field_path) {
106 ret = -1;
107 goto end;
108 }
109
110 field_path->root = root_scope;
5cd6d0e5 111 if (!find_field_class_recursive(root_fc, tgt_fc, field_path)) {
44c440bc 112 /* Not found here */
65300d60 113 BT_OBJECT_PUT_REF_AND_RESET(field_path);
44c440bc
PP
114 }
115
116end:
117 *ret_field_path = field_path;
118 return ret;
119}
120
121static
5cd6d0e5 122struct bt_field_path *find_field_class_in_ctx(struct bt_field_class *fc,
44c440bc
PP
123 struct bt_resolve_field_path_context *ctx)
124{
125 struct bt_field_path *field_path = NULL;
126 int ret;
127
e7ceb9df 128 ret = find_field_class(ctx->packet_context, BT_FIELD_PATH_SCOPE_PACKET_CONTEXT,
5cd6d0e5 129 fc, &field_path);
44c440bc
PP
130 if (ret || field_path) {
131 goto end;
132 }
133
5cd6d0e5 134 ret = find_field_class(ctx->event_common_context,
e7ceb9df 135 BT_FIELD_PATH_SCOPE_EVENT_COMMON_CONTEXT, fc, &field_path);
44c440bc
PP
136 if (ret || field_path) {
137 goto end;
138 }
139
5cd6d0e5 140 ret = find_field_class(ctx->event_specific_context,
e7ceb9df 141 BT_FIELD_PATH_SCOPE_EVENT_SPECIFIC_CONTEXT, fc, &field_path);
44c440bc
PP
142 if (ret || field_path) {
143 goto end;
144 }
145
e7ceb9df 146 ret = find_field_class(ctx->event_payload, BT_FIELD_PATH_SCOPE_EVENT_PAYLOAD,
5cd6d0e5 147 fc, &field_path);
44c440bc
PP
148 if (ret || field_path) {
149 goto end;
150 }
151
152end:
153 return field_path;
154}
155
d98421f2 156BT_ASSERT_COND_DEV_FUNC
44c440bc
PP
157static inline
158bool target_is_before_source(struct bt_field_path *src_field_path,
159 struct bt_field_path *tgt_field_path)
160{
161 bool is_valid = true;
162 uint64_t src_i = 0, tgt_i = 0;
163
164 if (tgt_field_path->root < src_field_path->root) {
165 goto end;
166 }
167
168 if (tgt_field_path->root > src_field_path->root) {
169 is_valid = false;
170 goto end;
171 }
172
173 BT_ASSERT(tgt_field_path->root == src_field_path->root);
174
66ddcddf
PP
175 for (src_i = 0, tgt_i = 0; src_i < src_field_path->items->len &&
176 tgt_i < tgt_field_path->items->len; src_i++, tgt_i++) {
177 struct bt_field_path_item *src_fp_item =
178 bt_field_path_borrow_item_by_index_inline(
179 src_field_path, src_i);
180 struct bt_field_path_item *tgt_fp_item =
181 bt_field_path_borrow_item_by_index_inline(
182 tgt_field_path, tgt_i);
183
184 if (src_fp_item->type == BT_FIELD_PATH_ITEM_TYPE_INDEX &&
185 tgt_fp_item->type == BT_FIELD_PATH_ITEM_TYPE_INDEX) {
186 if (tgt_fp_item->index > src_fp_item->index) {
187 is_valid = false;
188 goto end;
189 }
44c440bc
PP
190 }
191
192 src_i++;
193 tgt_i++;
194 }
195
196end:
197 return is_valid;
198}
199
d98421f2 200BT_ASSERT_COND_DEV_FUNC
44c440bc 201static inline
5cd6d0e5 202struct bt_field_class *borrow_root_field_class(
e7ceb9df 203 struct bt_resolve_field_path_context *ctx, enum bt_field_path_scope scope)
44c440bc
PP
204{
205 switch (scope) {
e7ceb9df 206 case BT_FIELD_PATH_SCOPE_PACKET_CONTEXT:
44c440bc 207 return ctx->packet_context;
e7ceb9df 208 case BT_FIELD_PATH_SCOPE_EVENT_COMMON_CONTEXT:
44c440bc 209 return ctx->event_common_context;
e7ceb9df 210 case BT_FIELD_PATH_SCOPE_EVENT_SPECIFIC_CONTEXT:
44c440bc 211 return ctx->event_specific_context;
e7ceb9df 212 case BT_FIELD_PATH_SCOPE_EVENT_PAYLOAD:
44c440bc
PP
213 return ctx->event_payload;
214 default:
498e7994 215 bt_common_abort();
44c440bc
PP
216 }
217
218 return NULL;
219}
220
d98421f2 221BT_ASSERT_COND_DEV_FUNC
44c440bc 222static inline
66ddcddf
PP
223struct bt_field_class *borrow_child_field_class(
224 struct bt_field_class *parent_fc,
225 struct bt_field_path_item *fp_item)
44c440bc 226{
5cd6d0e5 227 struct bt_field_class *child_fc = NULL;
44c440bc 228
ebdb6693
PP
229 if (bt_field_class_type_is(parent_fc->type,
230 BT_FIELD_CLASS_TYPE_OPTION)) {
b38aea74
PP
231 struct bt_field_class_option *opt_fc = (void *) parent_fc;
232
233 BT_ASSERT(fp_item->type ==
234 BT_FIELD_PATH_ITEM_TYPE_CURRENT_OPTION_CONTENT);
235 child_fc = opt_fc->content_fc;
ebdb6693
PP
236 } else if (parent_fc->type == BT_FIELD_CLASS_TYPE_STRUCTURE ||
237 bt_field_class_type_is(parent_fc->type,
238 BT_FIELD_CLASS_TYPE_VARIANT)) {
45c51519
PP
239 struct bt_field_class_named_field_class_container *container_fc =
240 (void *) parent_fc;
66ddcddf 241 struct bt_named_field_class *named_fc;
44c440bc 242
66ddcddf 243 BT_ASSERT(fp_item->type == BT_FIELD_PATH_ITEM_TYPE_INDEX);
45c51519 244 named_fc = container_fc->named_fcs->pdata[fp_item->index];
5cd6d0e5 245 child_fc = named_fc->fc;
ebdb6693
PP
246 } else if (bt_field_class_type_is(parent_fc->type,
247 BT_FIELD_CLASS_TYPE_ARRAY)) {
5cd6d0e5 248 struct bt_field_class_array *array_fc = (void *) parent_fc;
44c440bc 249
66ddcddf
PP
250 BT_ASSERT(fp_item->type ==
251 BT_FIELD_PATH_ITEM_TYPE_CURRENT_ARRAY_ELEMENT);
5cd6d0e5 252 child_fc = array_fc->element_fc;
44c440bc
PP
253 }
254
5cd6d0e5 255 return child_fc;
44c440bc
PP
256}
257
d98421f2 258BT_ASSERT_COND_DEV_FUNC
44c440bc 259static inline
5cd6d0e5 260bool target_field_path_in_different_scope_has_struct_fc_only(
44c440bc
PP
261 struct bt_field_path *src_field_path,
262 struct bt_field_path *tgt_field_path,
263 struct bt_resolve_field_path_context *ctx)
264{
265 bool is_valid = true;
266 uint64_t i = 0;
5cd6d0e5 267 struct bt_field_class *fc;
44c440bc
PP
268
269 if (src_field_path->root == tgt_field_path->root) {
270 goto end;
271 }
272
5cd6d0e5 273 fc = borrow_root_field_class(ctx, tgt_field_path->root);
44c440bc 274
66ddcddf
PP
275 for (i = 0; i < tgt_field_path->items->len; i++) {
276 struct bt_field_path_item *fp_item =
277 bt_field_path_borrow_item_by_index_inline(
278 tgt_field_path, i);
44c440bc 279
ebdb6693
PP
280 if (bt_field_class_type_is(fc->type,
281 BT_FIELD_CLASS_TYPE_ARRAY) ||
282 bt_field_class_type_is(fc->type,
283 BT_FIELD_CLASS_TYPE_OPTION) ||
284 bt_field_class_type_is(fc->type,
285 BT_FIELD_CLASS_TYPE_VARIANT)) {
44c440bc
PP
286 is_valid = false;
287 goto end;
288 }
289
66ddcddf
PP
290 BT_ASSERT(fp_item->type == BT_FIELD_PATH_ITEM_TYPE_INDEX);
291 fc = borrow_child_field_class(fc, fp_item);
44c440bc
PP
292 }
293
294end:
295 return is_valid;
296}
297
d98421f2 298BT_ASSERT_COND_DEV_FUNC
44c440bc 299static inline
5cd6d0e5 300bool lca_is_structure_field_class(struct bt_field_path *src_field_path,
44c440bc
PP
301 struct bt_field_path *tgt_field_path,
302 struct bt_resolve_field_path_context *ctx)
303{
304 bool is_valid = true;
5cd6d0e5
PP
305 struct bt_field_class *src_fc;
306 struct bt_field_class *tgt_fc;
307 struct bt_field_class *prev_fc = NULL;
44c440bc
PP
308 uint64_t src_i = 0, tgt_i = 0;
309
310 if (src_field_path->root != tgt_field_path->root) {
311 goto end;
312 }
313
5cd6d0e5
PP
314 src_fc = borrow_root_field_class(ctx, src_field_path->root);
315 tgt_fc = borrow_root_field_class(ctx, tgt_field_path->root);
316 BT_ASSERT(src_fc);
317 BT_ASSERT(tgt_fc);
44c440bc 318
66ddcddf
PP
319 for (src_i = 0, tgt_i = 0; src_i < src_field_path->items->len &&
320 tgt_i < tgt_field_path->items->len; src_i++, tgt_i++) {
321 struct bt_field_path_item *src_fp_item =
322 bt_field_path_borrow_item_by_index_inline(
323 src_field_path, src_i);
324 struct bt_field_path_item *tgt_fp_item =
325 bt_field_path_borrow_item_by_index_inline(
326 tgt_field_path, tgt_i);
44c440bc 327
5cd6d0e5
PP
328 if (src_fc != tgt_fc) {
329 if (!prev_fc) {
44c440bc
PP
330 /*
331 * This is correct: the LCA is the root
e6276565
PP
332 * scope field class, which must be a
333 * structure field class.
44c440bc
PP
334 */
335 break;
336 }
337
864cad70 338 if (prev_fc->type != BT_FIELD_CLASS_TYPE_STRUCTURE) {
44c440bc
PP
339 is_valid = false;
340 }
341
342 break;
343 }
344
5cd6d0e5 345 prev_fc = src_fc;
66ddcddf
PP
346 src_fc = borrow_child_field_class(src_fc, src_fp_item);
347 tgt_fc = borrow_child_field_class(tgt_fc, tgt_fp_item);
44c440bc
PP
348 }
349
350end:
351 return is_valid;
352}
353
d98421f2 354BT_ASSERT_COND_DEV_FUNC
44c440bc 355static inline
5cd6d0e5 356bool lca_to_target_has_struct_fc_only(struct bt_field_path *src_field_path,
44c440bc
PP
357 struct bt_field_path *tgt_field_path,
358 struct bt_resolve_field_path_context *ctx)
359{
360 bool is_valid = true;
5cd6d0e5
PP
361 struct bt_field_class *src_fc;
362 struct bt_field_class *tgt_fc;
44c440bc
PP
363 uint64_t src_i = 0, tgt_i = 0;
364
365 if (src_field_path->root != tgt_field_path->root) {
366 goto end;
367 }
368
5cd6d0e5
PP
369 src_fc = borrow_root_field_class(ctx, src_field_path->root);
370 tgt_fc = borrow_root_field_class(ctx, tgt_field_path->root);
371 BT_ASSERT(src_fc);
372 BT_ASSERT(tgt_fc);
373 BT_ASSERT(src_fc == tgt_fc);
44c440bc
PP
374
375 /* Find LCA */
66ddcddf
PP
376 for (src_i = 0, tgt_i = 0; src_i < src_field_path->items->len &&
377 tgt_i < tgt_field_path->items->len; src_i++, tgt_i++) {
378 struct bt_field_path_item *src_fp_item =
379 bt_field_path_borrow_item_by_index_inline(
380 src_field_path, src_i);
381 struct bt_field_path_item *tgt_fp_item =
382 bt_field_path_borrow_item_by_index_inline(
383 tgt_field_path, tgt_i);
44c440bc
PP
384
385 if (src_i != tgt_i) {
5cd6d0e5 386 /* Next field class is different: LCA is `tgt_fc` */
44c440bc
PP
387 break;
388 }
389
66ddcddf
PP
390 src_fc = borrow_child_field_class(src_fc, src_fp_item);
391 tgt_fc = borrow_child_field_class(tgt_fc, tgt_fp_item);
44c440bc
PP
392 }
393
5cd6d0e5 394 /* Only structure field classes to the target */
66ddcddf
PP
395 for (; tgt_i < tgt_field_path->items->len; tgt_i++) {
396 struct bt_field_path_item *tgt_fp_item =
397 bt_field_path_borrow_item_by_index_inline(
398 tgt_field_path, tgt_i);
44c440bc 399
ebdb6693
PP
400 if (bt_field_class_type_is(tgt_fc->type,
401 BT_FIELD_CLASS_TYPE_ARRAY) ||
402 bt_field_class_type_is(tgt_fc->type,
403 BT_FIELD_CLASS_TYPE_OPTION) ||
404 bt_field_class_type_is(tgt_fc->type,
405 BT_FIELD_CLASS_TYPE_VARIANT)) {
44c440bc
PP
406 is_valid = false;
407 goto end;
408 }
409
66ddcddf 410 tgt_fc = borrow_child_field_class(tgt_fc, tgt_fp_item);
44c440bc
PP
411 }
412
413end:
414 return is_valid;
415}
416
d98421f2 417BT_ASSERT_COND_DEV_FUNC
44c440bc 418static inline
5cd6d0e5
PP
419bool field_path_is_valid(struct bt_field_class *src_fc,
420 struct bt_field_class *tgt_fc,
44c440bc
PP
421 struct bt_resolve_field_path_context *ctx)
422{
423 bool is_valid = true;
5cd6d0e5
PP
424 struct bt_field_path *src_field_path = find_field_class_in_ctx(
425 src_fc, ctx);
426 struct bt_field_path *tgt_field_path = find_field_class_in_ctx(
427 tgt_fc, ctx);
44c440bc
PP
428
429 if (!src_field_path) {
d98421f2 430 BT_ASSERT_COND_DEV_MSG("Cannot find requesting field class in "
5cd6d0e5 431 "resolving context: %!+F", src_fc);
44c440bc
PP
432 is_valid = false;
433 goto end;
434 }
435
436 if (!tgt_field_path) {
d98421f2 437 BT_ASSERT_COND_DEV_MSG("Cannot find target field class in "
5cd6d0e5 438 "resolving context: %!+F", tgt_fc);
44c440bc
PP
439 is_valid = false;
440 goto end;
441 }
442
443 /* Target must be before source */
444 if (!target_is_before_source(src_field_path, tgt_field_path)) {
d98421f2 445 BT_ASSERT_COND_DEV_MSG("Target field class is located after "
e6276565 446 "requesting field class: %![req-fc-]+F, %![tgt-fc-]+F",
5cd6d0e5 447 src_fc, tgt_fc);
44c440bc
PP
448 is_valid = false;
449 goto end;
450 }
451
452 /*
453 * If target is in a different scope than source, there are no
5cd6d0e5 454 * array or variant field classes on the way to the target.
44c440bc 455 */
5cd6d0e5 456 if (!target_field_path_in_different_scope_has_struct_fc_only(
44c440bc 457 src_field_path, tgt_field_path, ctx)) {
d98421f2 458 BT_ASSERT_COND_DEV_MSG("Target field class is located in a "
e6276565
PP
459 "different scope than requesting field class, "
460 "but within an array or a variant field class: "
5cd6d0e5
PP
461 "%![req-fc-]+F, %![tgt-fc-]+F",
462 src_fc, tgt_fc);
44c440bc
PP
463 is_valid = false;
464 goto end;
465 }
466
e6276565 467 /* Same scope: LCA must be a structure field class */
5cd6d0e5 468 if (!lca_is_structure_field_class(src_field_path, tgt_field_path, ctx)) {
d98421f2 469 BT_ASSERT_COND_DEV_MSG("Lowest common ancestor of target and "
e6276565 470 "requesting field classes is not a structure field class: "
5cd6d0e5
PP
471 "%![req-fc-]+F, %![tgt-fc-]+F",
472 src_fc, tgt_fc);
44c440bc
PP
473 is_valid = false;
474 goto end;
475 }
476
477 /* Same scope: path from LCA to target has no array/variant FTs */
5cd6d0e5 478 if (!lca_to_target_has_struct_fc_only(src_field_path, tgt_field_path,
44c440bc 479 ctx)) {
d98421f2 480 BT_ASSERT_COND_DEV_MSG("Path from lowest common ancestor of target "
e6276565
PP
481 "and requesting field classes to target field class "
482 "contains an array or a variant field class: "
5cd6d0e5 483 "%![req-fc-]+F, %![tgt-fc-]+F", src_fc, tgt_fc);
44c440bc
PP
484 is_valid = false;
485 goto end;
486 }
487
488end:
65300d60
PP
489 bt_object_put_ref(src_field_path);
490 bt_object_put_ref(tgt_field_path);
44c440bc
PP
491 return is_valid;
492}
493
494static
5cd6d0e5
PP
495struct bt_field_path *resolve_field_path(struct bt_field_class *src_fc,
496 struct bt_field_class *tgt_fc,
1778c2a4
PP
497 struct bt_resolve_field_path_context *ctx,
498 const char *api_func)
44c440bc 499{
1778c2a4
PP
500 BT_ASSERT_PRE_DEV_FROM_FUNC(api_func, "valid-field-class",
501 field_path_is_valid(src_fc, tgt_fc, ctx),
e6276565 502 "Invalid target field class: %![req-fc-]+F, %![tgt-fc-]+F",
5cd6d0e5
PP
503 src_fc, tgt_fc);
504 return find_field_class_in_ctx(tgt_fc, ctx);
44c440bc
PP
505}
506
5cd6d0e5 507int bt_resolve_field_paths(struct bt_field_class *fc,
1778c2a4
PP
508 struct bt_resolve_field_path_context *ctx,
509 const char *api_func)
44c440bc
PP
510{
511 int ret = 0;
512
5cd6d0e5 513 BT_ASSERT(fc);
44c440bc 514
5cd6d0e5 515 /* Resolving part for dynamic array and variant field classes */
ebdb6693
PP
516 if (bt_field_class_type_is(fc->type,
517 BT_FIELD_CLASS_TYPE_OPTION_WITH_SELECTOR_FIELD)) {
de821fe5 518 struct bt_field_class_option_with_selector_field *opt_fc = (void *) fc;
b38aea74 519
81b8fa44
PP
520 BT_ASSERT(opt_fc->selector_fc);
521 BT_ASSERT(!opt_fc->selector_field_path);
522 opt_fc->selector_field_path = resolve_field_path(
1778c2a4 523 fc, opt_fc->selector_fc, ctx, __func__);
81b8fa44
PP
524 if (!opt_fc->selector_field_path) {
525 ret = -1;
526 goto end;
b38aea74 527 }
ebdb6693 528 } else if (fc->type == BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD) {
9c08c816 529 struct bt_field_class_array_dynamic *dyn_array_fc = (void *) fc;
44c440bc 530
81b8fa44
PP
531 BT_ASSERT(dyn_array_fc->length_fc);
532 BT_ASSERT(!dyn_array_fc->length_field_path);
533 dyn_array_fc->length_field_path = resolve_field_path(
1778c2a4 534 fc, dyn_array_fc->length_fc, ctx, __func__);
81b8fa44
PP
535 if (!dyn_array_fc->length_field_path) {
536 ret = -1;
537 goto end;
44c440bc 538 }
ebdb6693
PP
539 } else if (bt_field_class_type_is(fc->type,
540 BT_FIELD_CLASS_TYPE_VARIANT_WITH_SELECTOR_FIELD)) {
de821fe5 541 struct bt_field_class_variant_with_selector_field *var_fc =
45c51519 542 (void *) fc;
5cd6d0e5
PP
543
544 if (var_fc->selector_fc) {
545 BT_ASSERT(!var_fc->selector_field_path);
546 var_fc->selector_field_path =
547 resolve_field_path(fc,
1778c2a4
PP
548 (void *) var_fc->selector_fc, ctx,
549 __func__);
5cd6d0e5 550 if (!var_fc->selector_field_path) {
44c440bc
PP
551 ret = -1;
552 goto end;
553 }
554 }
555 }
44c440bc
PP
556
557 /* Recursive part */
ebdb6693 558 if (bt_field_class_type_is(fc->type, BT_FIELD_CLASS_TYPE_OPTION)) {
b38aea74
PP
559 struct bt_field_class_option *opt_fc = (void *) fc;
560
1778c2a4 561 ret = bt_resolve_field_paths(opt_fc->content_fc, ctx, api_func);
ebdb6693
PP
562 } else if (fc->type == BT_FIELD_CLASS_TYPE_STRUCTURE ||
563 bt_field_class_type_is(fc->type,
564 BT_FIELD_CLASS_TYPE_VARIANT)) {
5cd6d0e5
PP
565 struct bt_field_class_named_field_class_container *container_fc =
566 (void *) fc;
44c440bc
PP
567 uint64_t i;
568
5cd6d0e5
PP
569 for (i = 0; i < container_fc->named_fcs->len; i++) {
570 struct bt_named_field_class *named_fc =
45c51519 571 container_fc->named_fcs->pdata[i];
44c440bc 572
1778c2a4
PP
573 ret = bt_resolve_field_paths(named_fc->fc, ctx,
574 api_func);
44c440bc
PP
575 if (ret) {
576 goto end;
577 }
578 }
ebdb6693
PP
579 } else if (bt_field_class_type_is(fc->type,
580 BT_FIELD_CLASS_TYPE_ARRAY)) {
5cd6d0e5 581 struct bt_field_class_array *array_fc = (void *) fc;
44c440bc 582
1778c2a4
PP
583 ret = bt_resolve_field_paths(array_fc->element_fc, ctx,
584 api_func);
44c440bc
PP
585 }
586
587end:
588 return ret;
589}
This page took 0.10877 seconds and 4 git commands to generate.