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