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