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