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