Fix: destroy_pretty_data: move NULL check earlier
[babeltrace.git] / src / plugins / lttng-utils / debug-info / trace-ir-metadata-field-class-copy.c
CommitLineData
ca9f27f3
FD
1/*
2 * Babeltrace - Trace IR field copy
3 *
4 * Copyright (c) 2015-2019 EfficiOS Inc. and Linux Foundation
5 * Copyright (c) 2018 Philippe Proulx <pproulx@efficios.com>
6 * Copyright (c) 2019 Francis Deslauriers <francis.deslauriers@efficios.com>
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE.
25 */
26
91bc8451 27#define BT_COMP_LOG_SELF_COMP (md_maps->self_comp)
3a3d15f3 28#define BT_LOG_OUTPUT_LEVEL (md_maps->log_level)
350ad6c1 29#define BT_LOG_TAG "PLUGIN/FLT.LTTNG-UTILS.DEBUG-INFO/TRACE-IR-META-FC-COPY"
d9c39b0a 30#include "logging/comp-logging.h"
ca9f27f3 31
578e048b
MJ
32#include "common/assert.h"
33#include "common/common.h"
34#include "compat/compiler.h"
3fadfbc0 35#include <babeltrace2/babeltrace.h>
ca9f27f3
FD
36
37#include "trace-ir-metadata-copy.h"
38#include "trace-ir-metadata-field-class-copy.h"
39
40/*
41 * This fonction walks througth the nested structures field class to resolve a
42 * field path object. A field path is made of indexes inside possibly nested
43 * structures ultimately leading to a field class.
44 */
45static
3a3d15f3
PP
46const bt_field_class *walk_field_path(struct trace_ir_metadata_maps *md_maps,
47 const bt_field_path *fp, const bt_field_class *fc)
ca9f27f3 48{
66ddcddf 49 uint64_t i, fp_item_count;
ca9f27f3
FD
50 const bt_field_class *curr_fc;
51
52 BT_ASSERT(bt_field_class_get_type(fc) == BT_FIELD_CLASS_TYPE_STRUCTURE);
91bc8451 53 BT_COMP_LOGD("Walking field path on field class: fp-addr=%p, fc-addr=%p",
bc463d34 54 fp, fc);
ca9f27f3 55
66ddcddf 56 fp_item_count = bt_field_path_get_item_count(fp);
ca9f27f3 57 curr_fc = fc;
66ddcddf 58 for (i = 0; i < fp_item_count; i++) {
ca9f27f3 59 bt_field_class_type fc_type = bt_field_class_get_type(curr_fc);
66ddcddf
PP
60 const bt_field_path_item *fp_item =
61 bt_field_path_borrow_item_by_index_const(fp, i);
ca9f27f3
FD
62
63 switch (fc_type) {
64 case BT_FIELD_CLASS_TYPE_STRUCTURE:
1e6fd1d7 65 {
66ddcddf
PP
66 const bt_field_class_structure_member *member;
67
68 BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
69 BT_FIELD_PATH_ITEM_TYPE_INDEX);
70 member = bt_field_class_structure_borrow_member_by_index_const(
71 curr_fc,
72 bt_field_path_item_index_get_index(fp_item));
1e6fd1d7
PP
73 curr_fc = bt_field_class_structure_member_borrow_field_class_const(
74 member);
ca9f27f3 75 break;
1e6fd1d7 76 }
0aa006b7
PP
77 case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR:
78 case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR:
79 case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR:
80 case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR:
f29ef814
PP
81 {
82 BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
83 BT_FIELD_PATH_ITEM_TYPE_CURRENT_OPTION_CONTENT);
84 curr_fc = bt_field_class_option_borrow_field_class_const(
85 curr_fc);
86 break;
87 }
45c51519 88 case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
fabfe034
PP
89 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR:
90 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR:
1e6fd1d7 91 {
66ddcddf
PP
92 const bt_field_class_variant_option *option;
93
94 BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
95 BT_FIELD_PATH_ITEM_TYPE_INDEX);
96 option = bt_field_class_variant_borrow_option_by_index_const(
97 curr_fc,
98 bt_field_path_item_index_get_index(fp_item));
1e6fd1d7
PP
99 curr_fc = bt_field_class_variant_option_borrow_field_class_const(
100 option);
ca9f27f3 101 break;
1e6fd1d7 102 }
66ddcddf
PP
103 case BT_FIELD_CLASS_TYPE_STATIC_ARRAY:
104 case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY:
105 {
106 BT_ASSERT(bt_field_path_item_get_type(fp_item) ==
107 BT_FIELD_PATH_ITEM_TYPE_CURRENT_ARRAY_ELEMENT);
108 curr_fc = bt_field_class_array_borrow_element_field_class_const(
109 curr_fc);
110 break;
111 }
ca9f27f3
FD
112 default:
113 abort();
114 }
115 }
116
117 return curr_fc;
118}
119
120static
121const bt_field_class *resolve_field_path_to_field_class(const bt_field_path *fp,
122 struct trace_ir_metadata_maps *md_maps)
123{
124 struct field_class_resolving_context *fc_resolving_ctx;
125 const bt_field_class *fc;
e7ceb9df 126 bt_field_path_scope fp_scope;
ca9f27f3 127
91bc8451 128 BT_COMP_LOGD("Resolving field path: fp-addr=%p", fp);
ca9f27f3
FD
129
130 fc_resolving_ctx = md_maps->fc_resolving_ctx;
131 fp_scope = bt_field_path_get_root_scope(fp);
132
133 switch (fp_scope) {
e7ceb9df 134 case BT_FIELD_PATH_SCOPE_PACKET_CONTEXT:
3a3d15f3
PP
135 fc = walk_field_path(md_maps, fp,
136 fc_resolving_ctx->packet_context);
ca9f27f3 137 break;
e7ceb9df 138 case BT_FIELD_PATH_SCOPE_EVENT_COMMON_CONTEXT:
3a3d15f3
PP
139 fc = walk_field_path(md_maps, fp,
140 fc_resolving_ctx->event_common_context);
ca9f27f3 141 break;
e7ceb9df 142 case BT_FIELD_PATH_SCOPE_EVENT_SPECIFIC_CONTEXT:
3a3d15f3
PP
143 fc = walk_field_path(md_maps, fp,
144 fc_resolving_ctx->event_specific_context);
ca9f27f3 145 break;
e7ceb9df 146 case BT_FIELD_PATH_SCOPE_EVENT_PAYLOAD:
3a3d15f3
PP
147 fc = walk_field_path(md_maps, fp,
148 fc_resolving_ctx->event_payload);
ca9f27f3
FD
149 break;
150 default:
151 abort();
152 }
153
154 return fc;
155}
156
157static inline
158void field_class_integer_set_props(const bt_field_class *input_fc,
159 bt_field_class *output_fc)
160{
161 bt_field_class_integer_set_preferred_display_base(output_fc,
bc463d34 162 bt_field_class_integer_get_preferred_display_base(input_fc));
ca9f27f3 163 bt_field_class_integer_set_field_value_range(output_fc,
bc463d34 164 bt_field_class_integer_get_field_value_range(input_fc));
ca9f27f3
FD
165}
166
f7cfbcc3 167static inline
bc463d34 168int field_class_bool_copy(struct trace_ir_metadata_maps *md_maps,
f7cfbcc3
PP
169 const bt_field_class *in_field_class,
170 bt_field_class *out_field_class)
171{
172 BT_COMP_LOGD("Copying content of boolean field class: "
bc463d34
FD
173 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
174 /*
175 * There is no content to copy. Keep this function call anyway for
176 * logging purposes.
177 */
f7cfbcc3 178 BT_COMP_LOGD("Copied content of boolean field class: "
bc463d34 179 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
f7cfbcc3
PP
180 return 0;
181}
182
dc7ac074
PP
183static inline
184int field_class_bit_array_copy(
185 struct trace_ir_metadata_maps *md_maps,
186 const bt_field_class *in_field_class,
187 bt_field_class *out_field_class)
188{
189 BT_COMP_LOGD("Copying content of bit array field class: "
bc463d34
FD
190 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
191 /*
192 * There is no content to copy. Keep this function call anyway for
193 * logging purposes.
194 */
dc7ac074 195 BT_COMP_LOGD("Copied content of bit array field class: "
bc463d34 196 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
dc7ac074
PP
197 return 0;
198}
199
ca9f27f3
FD
200static inline
201int field_class_unsigned_integer_copy(
202 struct trace_ir_metadata_maps *md_maps,
203 const bt_field_class *in_field_class,
204 bt_field_class *out_field_class)
205{
91bc8451 206 BT_COMP_LOGD("Copying content of unsigned integer field class: "
bc463d34 207 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
208
209 field_class_integer_set_props(in_field_class, out_field_class);
210
91bc8451 211 BT_COMP_LOGD("Copied content of unsigned integer field class: "
bc463d34 212 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
213 return 0;
214}
215
216static inline
217int field_class_signed_integer_copy(
218 struct trace_ir_metadata_maps *md_maps,
219 const bt_field_class *in_field_class,
220 bt_field_class *out_field_class)
221{
91bc8451 222 BT_COMP_LOGD("Copying content of signed integer field class: "
bc463d34 223 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
224
225 field_class_integer_set_props(in_field_class, out_field_class);
226
91bc8451 227 BT_COMP_LOGD("Copied content of signed integer field class: "
bc463d34 228 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
229 return 0;
230}
231
232BT_HIDDEN
233int field_class_unsigned_enumeration_copy(
234 struct trace_ir_metadata_maps *md_maps,
235 const bt_field_class *in_field_class,
236 bt_field_class *out_field_class)
237{
238 uint64_t i, enum_mapping_count;
239 int ret = 0;
240
91bc8451 241 BT_COMP_LOGD("Copying content of unsigned enumeration field class: "
bc463d34 242 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
243
244 /* Copy properties of the inner integer. */
245 field_class_integer_set_props(in_field_class, out_field_class);
246
247 /* Copy all enumeration entries. */
bc463d34
FD
248 enum_mapping_count = bt_field_class_enumeration_get_mapping_count(
249 in_field_class);
ca9f27f3
FD
250 for (i = 0; i < enum_mapping_count; i++) {
251 const char *label;
45c51519 252 const bt_integer_range_set_unsigned *range_set;
9c08c816 253 const bt_field_class_enumeration_unsigned_mapping *u_mapping;
8f3ccfbc 254 const bt_field_class_enumeration_mapping *mapping;
ca9f27f3 255
9c08c816 256 u_mapping = bt_field_class_enumeration_unsigned_borrow_mapping_by_index_const(
bc463d34 257 in_field_class, i);
9c08c816 258 mapping = bt_field_class_enumeration_unsigned_mapping_as_mapping_const(
8f3ccfbc 259 u_mapping);
45c51519 260 label = bt_field_class_enumeration_mapping_get_label(mapping);
9c08c816 261 range_set = bt_field_class_enumeration_unsigned_mapping_borrow_ranges_const(
45c51519 262 u_mapping);
9c08c816 263 ret = bt_field_class_enumeration_unsigned_add_mapping(
45c51519
PP
264 out_field_class, label, range_set);
265 if (ret) {
266 goto error;
ca9f27f3
FD
267 }
268 }
269
91bc8451 270 BT_COMP_LOGD("Copied content of unsigned enumeration field class: "
bc463d34 271 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
272
273error:
274 return ret;
275}
276
277static inline
278int field_class_signed_enumeration_copy(
279 struct trace_ir_metadata_maps *md_maps,
280 const bt_field_class *in_field_class,
281 bt_field_class *out_field_class)
282{
283 uint64_t i, enum_mapping_count;
284 int ret = 0;
285
91bc8451 286 BT_COMP_LOGD("Copying content of signed enumeration field class: "
bc463d34 287 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
288
289 /* Copy properties of the inner integer. */
290 field_class_integer_set_props(in_field_class, out_field_class);
291
292 /* Copy all enumeration entries. */
293 enum_mapping_count =
294 bt_field_class_enumeration_get_mapping_count(in_field_class);
295 for (i = 0; i < enum_mapping_count; i++) {
296 const char *label;
45c51519 297 const bt_integer_range_set_signed *range_set;
9c08c816 298 const bt_field_class_enumeration_signed_mapping *s_mapping;
8f3ccfbc 299 const bt_field_class_enumeration_mapping *mapping;
ca9f27f3 300
9c08c816 301 s_mapping = bt_field_class_enumeration_signed_borrow_mapping_by_index_const(
bc463d34 302 in_field_class, i);
9c08c816 303 mapping = bt_field_class_enumeration_signed_mapping_as_mapping_const(
45c51519
PP
304 s_mapping);
305 label = bt_field_class_enumeration_mapping_get_label(mapping);
9c08c816 306 range_set = bt_field_class_enumeration_signed_mapping_borrow_ranges_const(
45c51519 307 s_mapping);
9c08c816 308 ret = bt_field_class_enumeration_signed_add_mapping(
45c51519
PP
309 out_field_class, label, range_set);
310 if (ret) {
311 goto error;
ca9f27f3
FD
312 }
313 }
314
91bc8451 315 BT_COMP_LOGD("Copied content of signed enumeration field class: "
bc463d34 316 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
317
318error:
319 return ret;
320}
321
322static inline
fe4df857 323int field_class_single_precision_real_copy(
ca9f27f3
FD
324 struct trace_ir_metadata_maps *md_maps,
325 const bt_field_class *in_field_class,
326 bt_field_class *out_field_class)
327{
fe4df857
FD
328 BT_COMP_LOGD("Copying content of single-precision real field class: "
329 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3 330
fe4df857
FD
331 BT_COMP_LOGD("Copied content single-precision real field class:"
332 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3 333
fe4df857
FD
334 return 0;
335}
336
337static inline
338int field_class_double_precision_real_copy(
339 struct trace_ir_metadata_maps *md_maps,
340 const bt_field_class *in_field_class,
341 bt_field_class *out_field_class)
342{
343 BT_COMP_LOGD("Copying content of double-precision real field class: "
344 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
345
346 BT_COMP_LOGD("Copied content double-precision real field class:"
347 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
348
349 return 0;
350}
351
352static inline
353int field_class_structure_copy(
354 struct trace_ir_metadata_maps *md_maps,
355 const bt_field_class *in_field_class,
356 bt_field_class *out_field_class)
357{
358 uint64_t i, struct_member_count;
ca9f27f3
FD
359 int ret = 0;
360
91bc8451 361 BT_COMP_LOGD("Copying content of structure field class: "
bc463d34 362 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
363 /* Get the number of member in that struct. */
364 struct_member_count =
365 bt_field_class_structure_get_member_count(in_field_class);
366
367 /* Iterate over all the members of the struct. */
368 for (i = 0; i < struct_member_count; i++) {
ce45f74a
PP
369 const bt_field_class_structure_member *in_member;
370 bt_field_class_structure_member *out_member;
ca9f27f3 371 const char *member_name;
ce45f74a 372 const bt_field_class *in_member_fc;
ca9f27f3
FD
373 bt_field_class *out_member_field_class;
374
ce45f74a 375 in_member = bt_field_class_structure_borrow_member_by_index_const(
1e6fd1d7 376 in_field_class, i);
ce45f74a
PP
377 in_member_fc = bt_field_class_structure_member_borrow_field_class_const(
378 in_member);
379 member_name = bt_field_class_structure_member_get_name(in_member);
91bc8451 380 BT_COMP_LOGD("Copying structure field class's field: "
bc463d34 381 "index=%" PRId64 ", member-fc-addr=%p, field-name=\"%s\"",
ce45f74a 382 i, in_member_fc, member_name);
ca9f27f3
FD
383
384 out_member_field_class = create_field_class_copy(md_maps,
ce45f74a 385 in_member_fc);
ca9f27f3 386 if (!out_member_field_class) {
91bc8451 387 BT_COMP_LOGE("Cannot copy structure field class's field: "
bc463d34 388 "index=%" PRId64 ", field-fc-addr=%p, field-name=\"%s\"",
ce45f74a 389 i, in_member_fc, member_name);
ca9f27f3
FD
390 ret = -1;
391 goto error;
392 }
ce45f74a 393 ret = copy_field_class_content(md_maps, in_member_fc,
ca9f27f3
FD
394 out_member_field_class);
395 if (ret) {
396 goto error;
397 }
398
d24d5663
PP
399 if (bt_field_class_structure_append_member(out_field_class,
400 member_name, out_member_field_class) !=
401 BT_FIELD_CLASS_STRUCTURE_APPEND_MEMBER_STATUS_OK) {
91bc8451 402 BT_COMP_LOGE("Cannot append structure field class's field: "
ca9f27f3
FD
403 "index=%" PRId64 ", "
404 "field-fc-addr=%p, field-name=\"%s\"",
ce45f74a 405 i, in_member_fc, member_name);
ca9f27f3
FD
406 BT_FIELD_CLASS_PUT_REF_AND_RESET(out_member_field_class);
407 ret = -1;
408 goto error;
409 }
ce45f74a
PP
410
411 out_member = bt_field_class_structure_borrow_member_by_index(
412 out_field_class, i);
413 BT_ASSERT(out_member);
414
415 /*
416 * Safe to use the same value object because it's frozen
417 * at this point.
418 */
419 bt_field_class_structure_member_set_user_attributes(
420 out_member,
421 bt_field_class_structure_member_borrow_user_attributes_const(
422 in_member));
ca9f27f3
FD
423 }
424
91bc8451 425 BT_COMP_LOGD("Copied structure field class: original-fc-addr=%p, copy-fc-addr=%p",
ca9f27f3
FD
426 in_field_class, out_field_class);
427
428error:
429 return ret;
430}
431
432static inline
433int field_class_variant_copy(
434 struct trace_ir_metadata_maps *md_maps,
435 const bt_field_class *in_field_class,
436 bt_field_class *out_field_class)
437{
1ec009b2 438 bt_field_class *out_tag_field_class = NULL;
ca9f27f3 439 uint64_t i, variant_option_count;
45c51519 440 bt_field_class_type fc_type = bt_field_class_get_type(in_field_class);
ca9f27f3
FD
441 int ret = 0;
442
91bc8451 443 BT_COMP_LOGD("Copying content of variant field class: "
bc463d34 444 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
445 variant_option_count =
446 bt_field_class_variant_get_option_count(in_field_class);
447 for (i = 0; i < variant_option_count; i++) {
ce45f74a 448 const bt_field_class *in_option_fc;
ca9f27f3
FD
449 const char *option_name;
450 bt_field_class *out_option_field_class;
ce45f74a
PP
451 const bt_field_class_variant_option *in_option;
452 bt_field_class_variant_option *out_option;
ca9f27f3 453
ce45f74a 454 in_option = bt_field_class_variant_borrow_option_by_index_const(
1e6fd1d7 455 in_field_class, i);
ce45f74a
PP
456 in_option_fc = bt_field_class_variant_option_borrow_field_class_const(
457 in_option);
458 option_name = bt_field_class_variant_option_get_name(in_option);
ca9f27f3 459 out_option_field_class = create_field_class_copy_internal(
ce45f74a 460 md_maps, in_option_fc);
ca9f27f3 461 if (!out_option_field_class) {
91bc8451 462 BT_COMP_LOGE_STR("Cannot copy field class.");
ca9f27f3
FD
463 ret = -1;
464 goto error;
465 }
ce45f74a 466 ret = copy_field_class_content_internal(md_maps, in_option_fc,
bc463d34 467 out_option_field_class);
ca9f27f3 468 if (ret) {
91bc8451 469 BT_COMP_LOGE_STR("Error copying content of option variant "
ca9f27f3
FD
470 "field class'");
471 goto error;
472 }
473
fabfe034
PP
474 if (fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR) {
475 const bt_field_class_variant_with_selector_integer_unsigned_option *spec_opt =
476 bt_field_class_variant_with_selector_integer_unsigned_borrow_option_by_index_const(
45c51519
PP
477 in_field_class, i);
478 const bt_integer_range_set_unsigned *ranges =
fabfe034 479 bt_field_class_variant_with_selector_integer_unsigned_option_borrow_ranges_const(
45c51519
PP
480 spec_opt);
481
fabfe034 482 if (bt_field_class_variant_with_selector_integer_unsigned_append_option(
45c51519
PP
483 out_field_class, option_name,
484 out_option_field_class, ranges) !=
485 BT_FIELD_CLASS_VARIANT_WITH_SELECTOR_APPEND_OPTION_STATUS_OK) {
fabfe034 486 BT_COMP_LOGE_STR("Cannot append option to variant field class with unsigned integer selector'");
45c51519
PP
487 BT_FIELD_CLASS_PUT_REF_AND_RESET(out_tag_field_class);
488 ret = -1;
489 goto error;
490 }
fabfe034
PP
491 } else if (fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR) {
492 const bt_field_class_variant_with_selector_integer_signed_option *spec_opt =
493 bt_field_class_variant_with_selector_integer_signed_borrow_option_by_index_const(
45c51519
PP
494 in_field_class, i);
495 const bt_integer_range_set_signed *ranges =
fabfe034 496 bt_field_class_variant_with_selector_integer_signed_option_borrow_ranges_const(
45c51519
PP
497 spec_opt);
498
fabfe034 499 if (bt_field_class_variant_with_selector_integer_signed_append_option(
45c51519
PP
500 out_field_class, option_name,
501 out_option_field_class, ranges) !=
502 BT_FIELD_CLASS_VARIANT_WITH_SELECTOR_APPEND_OPTION_STATUS_OK) {
fabfe034 503 BT_COMP_LOGE_STR("Cannot append option to variant field class with signed integer selector'");
45c51519
PP
504 BT_FIELD_CLASS_PUT_REF_AND_RESET(out_tag_field_class);
505 ret = -1;
506 goto error;
507 }
508 } else {
509 BT_ASSERT(fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR);
510
511 if (bt_field_class_variant_without_selector_append_option(
512 out_field_class, option_name,
513 out_option_field_class) !=
514 BT_FIELD_CLASS_VARIANT_WITHOUT_SELECTOR_APPEND_OPTION_STATUS_OK) {
515 BT_COMP_LOGE_STR("Cannot append option to variant field class'");
516 BT_FIELD_CLASS_PUT_REF_AND_RESET(out_tag_field_class);
517 ret = -1;
518 goto error;
519 }
ca9f27f3 520 }
ce45f74a
PP
521
522 out_option = bt_field_class_variant_borrow_option_by_index(
523 out_field_class, i);
524 BT_ASSERT(out_option);
525
526 /*
527 * Safe to use the same value object because it's frozen
528 * at this point.
529 */
530 bt_field_class_variant_option_set_user_attributes(
531 out_option,
532 bt_field_class_variant_option_borrow_user_attributes_const(
533 in_option));
ca9f27f3
FD
534 }
535
91bc8451 536 BT_COMP_LOGD("Copied content of variant field class: in-fc-addr=%p, "
ca9f27f3
FD
537 "out-fc-addr=%p", in_field_class, out_field_class);
538
539error:
540 return ret;
541}
542
543static inline
544int field_class_static_array_copy(
545 struct trace_ir_metadata_maps *md_maps,
546 const bt_field_class *in_field_class,
547 bt_field_class *out_field_class)
548{
91bc8451 549 BT_COMP_LOGD("Copying content of static array field class: in-fc-addr=%p, "
bc463d34 550 "out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
551 /*
552 * There is no content to copy. Keep this function call anyway for
553 * logging purposes.
554 */
91bc8451 555 BT_COMP_LOGD("Copied content of static array field class: in-fc-addr=%p, "
bc463d34 556 "out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
557
558 return 0;
559}
560
561static inline
562int field_class_dynamic_array_copy(
563 struct trace_ir_metadata_maps *md_maps,
564 const bt_field_class *in_field_class,
565 bt_field_class *out_field_class)
566{
91bc8451 567 BT_COMP_LOGD("Copying content of dynamic array field class: "
bc463d34 568 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
1367bc7c
PP
569 /*
570 * There is no content to copy. Keep this function call anyway for
571 * logging purposes.
572 */
bc463d34
FD
573 BT_COMP_LOGD("Copied content of dynamic array field class: "
574 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3 575
1367bc7c 576 return 0;
ca9f27f3
FD
577}
578
f29ef814
PP
579static inline
580int field_class_option_copy(
581 struct trace_ir_metadata_maps *md_maps,
582 const bt_field_class *in_field_class,
583 bt_field_class *out_field_class)
584{
585 BT_COMP_LOGD("Copying content of option field class: "
bc463d34 586 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
f29ef814 587
0aa006b7
PP
588 if (bt_field_class_get_type(out_field_class) ==
589 BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR) {
590 bt_field_class_option_with_selector_bool_set_selector_is_reversed(
591 out_field_class,
592 bt_field_class_option_with_selector_bool_selector_is_reversed(
593 in_field_class));
594 }
595
bc463d34
FD
596 BT_COMP_LOGD("Copied content of option field class: "
597 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
f29ef814
PP
598
599 return 0;
600}
601
ca9f27f3
FD
602static inline
603int field_class_string_copy(struct trace_ir_metadata_maps *md_maps,
604 const bt_field_class *in_field_class,
605 bt_field_class *out_field_class)
606{
91bc8451 607 BT_COMP_LOGD("Copying content of string field class: in-fc-addr=%p, "
bc463d34 608 "out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
609 /*
610 * There is no content to copy. Keep this function call anyway for
611 * logging purposes.
612 */
91bc8451 613 BT_COMP_LOGD("Copied content of string field class: in-fc-addr=%p, "
bc463d34 614 "out-fc-addr=%p", in_field_class, out_field_class);
ca9f27f3
FD
615
616 return 0;
617}
618
619static
620bt_field_class *copy_field_class_array_element(struct trace_ir_metadata_maps *md_maps,
621 const bt_field_class *in_elem_fc)
622{
623 int ret;
624 bt_field_class *out_elem_fc =
625 create_field_class_copy_internal(md_maps, in_elem_fc);
626 if (!out_elem_fc) {
91bc8451 627 BT_COMP_LOGE("Error creating output elem field class "
bc463d34
FD
628 "from input elem field class for static array: "
629 "in-fc-addr=%p", in_elem_fc);
ca9f27f3
FD
630 goto error;
631 }
632
633 ret = copy_field_class_content_internal(md_maps, in_elem_fc, out_elem_fc);
634 if (ret) {
91bc8451 635 BT_COMP_LOGE("Error creating output elem field class "
bc463d34
FD
636 "from input elem field class for static array: "
637 "in-fc-addr=%p", in_elem_fc);
ca9f27f3
FD
638 BT_FIELD_CLASS_PUT_REF_AND_RESET(out_elem_fc);
639 goto error;
640 }
641
642error:
643 return out_elem_fc;
644}
645
646BT_HIDDEN
647bt_field_class *create_field_class_copy_internal(struct trace_ir_metadata_maps *md_maps,
648 const bt_field_class *in_field_class)
649{
650 bt_field_class *out_field_class = NULL;
45c51519 651 bt_field_class_type fc_type = bt_field_class_get_type(in_field_class);
ca9f27f3 652
91bc8451 653 BT_COMP_LOGD("Creating bare field class based on field class: in-fc-addr=%p",
bc463d34 654 in_field_class);
ca9f27f3 655
45c51519 656 switch (fc_type) {
f7cfbcc3
PP
657 case BT_FIELD_CLASS_TYPE_BOOL:
658 out_field_class = bt_field_class_bool_create(
bc463d34 659 md_maps->output_trace_class);
f7cfbcc3 660 break;
dc7ac074
PP
661 case BT_FIELD_CLASS_TYPE_BIT_ARRAY:
662 out_field_class = bt_field_class_bit_array_create(
bc463d34
FD
663 md_maps->output_trace_class,
664 bt_field_class_bit_array_get_length(
665 in_field_class));
dc7ac074 666 break;
ca9f27f3 667 case BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER:
9c08c816 668 out_field_class = bt_field_class_integer_unsigned_create(
bc463d34 669 md_maps->output_trace_class);
ca9f27f3
FD
670 break;
671 case BT_FIELD_CLASS_TYPE_SIGNED_INTEGER:
9c08c816 672 out_field_class = bt_field_class_integer_signed_create(
bc463d34 673 md_maps->output_trace_class);
ca9f27f3
FD
674 break;
675 case BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION:
9c08c816 676 out_field_class = bt_field_class_enumeration_unsigned_create(
bc463d34 677 md_maps->output_trace_class);
ca9f27f3
FD
678 break;
679 case BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION:
9c08c816 680 out_field_class = bt_field_class_enumeration_signed_create(
bc463d34 681 md_maps->output_trace_class);
ca9f27f3 682 break;
fe4df857
FD
683 case BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL:
684 out_field_class = bt_field_class_real_single_precision_create(
bc463d34 685 md_maps->output_trace_class);
fe4df857
FD
686 break;
687 case BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL:
688 out_field_class = bt_field_class_real_double_precision_create(
bc463d34 689 md_maps->output_trace_class);
ca9f27f3
FD
690 break;
691 case BT_FIELD_CLASS_TYPE_STRING:
692 out_field_class = bt_field_class_string_create(
bc463d34 693 md_maps->output_trace_class);
ca9f27f3
FD
694 break;
695 case BT_FIELD_CLASS_TYPE_STRUCTURE:
696 out_field_class = bt_field_class_structure_create(
bc463d34 697 md_maps->output_trace_class);
ca9f27f3
FD
698 break;
699 case BT_FIELD_CLASS_TYPE_STATIC_ARRAY:
700 {
701 const bt_field_class *in_elem_fc =
702 bt_field_class_array_borrow_element_field_class_const(
703 in_field_class);
bc463d34
FD
704 uint64_t array_len = bt_field_class_array_static_get_length(
705 in_field_class);
ca9f27f3
FD
706
707 bt_field_class *out_elem_fc = copy_field_class_array_element(
708 md_maps, in_elem_fc);
709 if (!out_elem_fc) {
710 out_field_class = NULL;
711 goto error;
712 }
713
9c08c816 714 out_field_class = bt_field_class_array_static_create(
bc463d34
FD
715 md_maps->output_trace_class,
716 out_elem_fc, array_len);
ca9f27f3
FD
717 break;
718 }
719 case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY:
720 {
721 const bt_field_class *in_elem_fc =
722 bt_field_class_array_borrow_element_field_class_const(
723 in_field_class);
1367bc7c 724 const bt_field_path *length_fp =
9c08c816 725 bt_field_class_array_dynamic_borrow_length_field_path_const(
1367bc7c
PP
726 in_field_class);
727 bt_field_class *out_length_fc = NULL;
ca9f27f3
FD
728
729 bt_field_class *out_elem_fc = copy_field_class_array_element(
1367bc7c 730 md_maps, in_elem_fc);
ca9f27f3
FD
731 if (!out_elem_fc) {
732 out_field_class = NULL;
733 goto error;
734 }
735
1367bc7c
PP
736 if (length_fp) {
737 const bt_field_class *in_length_fc =
738 resolve_field_path_to_field_class(length_fp,
739 md_maps);
740
741 BT_ASSERT(in_length_fc);
742 out_length_fc = g_hash_table_lookup(md_maps->field_class_map,
743 in_length_fc);
744 BT_ASSERT(out_length_fc);
745 }
746
9c08c816 747 out_field_class = bt_field_class_array_dynamic_create(
bc463d34
FD
748 md_maps->output_trace_class,
749 out_elem_fc, out_length_fc);
ca9f27f3
FD
750 break;
751 }
0aa006b7
PP
752 case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR:
753 case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR:
754 case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR:
755 case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR:
f29ef814
PP
756 {
757 const bt_field_class *in_content_fc =
758 bt_field_class_option_borrow_field_class_const(
bc463d34 759 in_field_class);
f29ef814
PP
760 bt_field_class *out_selector_fc = NULL;
761 bt_field_class *out_content_fc;
762 int ret;
763
764 out_content_fc = create_field_class_copy_internal(
bc463d34 765 md_maps, in_content_fc);
f29ef814
PP
766 if (!out_content_fc) {
767 BT_COMP_LOGE_STR("Cannot copy option's content field class.");
768 goto error;
769 }
770
771 ret = copy_field_class_content_internal(md_maps,
772 in_content_fc, out_content_fc);
773 if (ret) {
774 BT_COMP_LOGE_STR("Error copying content of option's "
775 "content field class");
776 goto error;
777 }
778
0aa006b7
PP
779 if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR) {
780 out_field_class =
781 bt_field_class_option_without_selector_create(
782 md_maps->output_trace_class,
783 out_content_fc);
784 } else {
785 const bt_field_path *in_selector_fp =
786 bt_field_class_option_with_selector_borrow_selector_field_path_const(
787 in_field_class);
788 const bt_field_class *in_selector_fc;
f29ef814 789
0aa006b7
PP
790 BT_ASSERT(in_selector_fp);
791 in_selector_fc = resolve_field_path_to_field_class(
792 in_selector_fp, md_maps);
f29ef814
PP
793 BT_ASSERT(in_selector_fc);
794 out_selector_fc = g_hash_table_lookup(
795 md_maps->field_class_map, in_selector_fc);
796 BT_ASSERT(out_selector_fc);
0aa006b7
PP
797
798 if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR) {
799 out_field_class =
800 bt_field_class_option_with_selector_bool_create(
801 md_maps->output_trace_class,
802 out_content_fc, out_selector_fc);
803 } else if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR) {
804 const bt_integer_range_set_unsigned *ranges =
805 bt_field_class_option_with_selector_integer_unsigned_borrow_selector_ranges_const(
806 in_field_class);
807
808 BT_ASSERT(ranges);
809 out_field_class =
810 bt_field_class_option_with_selector_integer_unsigned_create(
811 md_maps->output_trace_class,
812 out_content_fc, out_selector_fc,
813 ranges);
814 } else if (fc_type == BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR) {
815 const bt_integer_range_set_signed *ranges =
816 bt_field_class_option_with_selector_integer_signed_borrow_selector_ranges_const(
817 in_field_class);
818
819 BT_ASSERT(ranges);
820 out_field_class =
821 bt_field_class_option_with_selector_integer_signed_create(
822 md_maps->output_trace_class,
823 out_content_fc, out_selector_fc,
824 ranges);
825 }
f29ef814
PP
826 }
827
0aa006b7 828 BT_ASSERT(out_field_class);
f29ef814
PP
829 break;
830 }
45c51519 831 case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
fabfe034
PP
832 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR:
833 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR:
45c51519
PP
834 {
835 bt_field_class *out_sel_fc = NULL;
836
fabfe034
PP
837 if (fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR ||
838 fc_type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR) {
45c51519
PP
839 const bt_field_class *in_sel_fc;
840 const bt_field_path *sel_fp =
841 bt_field_class_variant_with_selector_borrow_selector_field_path_const(
842 in_field_class);
843
844 BT_ASSERT(sel_fp);
845 in_sel_fc = resolve_field_path_to_field_class(sel_fp,
846 md_maps);
847 BT_ASSERT(in_sel_fc);
848 out_sel_fc = g_hash_table_lookup(
849 md_maps->field_class_map, in_sel_fc);
850 BT_ASSERT(out_sel_fc);
851 }
852
ca9f27f3 853 out_field_class = bt_field_class_variant_create(
45c51519 854 md_maps->output_trace_class, out_sel_fc);
ca9f27f3 855 break;
45c51519 856 }
ca9f27f3
FD
857 default:
858 abort();
859 }
860
861 /*
862 * Add mapping from in_field_class to out_field_class. This simplifies
863 * the resolution of field paths in variant and dynamic array field
864 * classes.
865 */
866 g_hash_table_insert(md_maps->field_class_map,
bc463d34 867 (gpointer) in_field_class, out_field_class);
ca9f27f3
FD
868
869error:
870 if(out_field_class){
91bc8451 871 BT_COMP_LOGD("Created bare field class based on field class: in-fc-addr=%p, "
ca9f27f3
FD
872 "out-fc-addr=%p", in_field_class, out_field_class);
873 } else {
91bc8451 874 BT_COMP_LOGE("Error creating output field class from input field "
ca9f27f3
FD
875 "class: in-fc-addr=%p", in_field_class);
876 }
877
878 return out_field_class;
879}
880
881BT_HIDDEN
882int copy_field_class_content_internal(
883 struct trace_ir_metadata_maps *md_maps,
884 const bt_field_class *in_field_class,
885 bt_field_class *out_field_class)
886{
887 int ret = 0;
ce45f74a
PP
888
889 /*
890 * Safe to use the same value object because it's frozen at this
891 * point.
892 */
893 bt_field_class_set_user_attributes(out_field_class,
894 bt_field_class_borrow_user_attributes_const(in_field_class));
895
ca9f27f3 896 switch(bt_field_class_get_type(in_field_class)) {
f7cfbcc3
PP
897 case BT_FIELD_CLASS_TYPE_BOOL:
898 ret = field_class_bool_copy(md_maps,
899 in_field_class, out_field_class);
900 break;
dc7ac074
PP
901 case BT_FIELD_CLASS_TYPE_BIT_ARRAY:
902 ret = field_class_bit_array_copy(md_maps,
903 in_field_class, out_field_class);
904 break;
ca9f27f3
FD
905 case BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER:
906 ret = field_class_unsigned_integer_copy(md_maps,
907 in_field_class, out_field_class);
908 break;
909 case BT_FIELD_CLASS_TYPE_SIGNED_INTEGER:
910 ret = field_class_signed_integer_copy(md_maps,
911 in_field_class, out_field_class);
912 break;
913 case BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION:
914 ret = field_class_unsigned_enumeration_copy(md_maps,
915 in_field_class, out_field_class);
916 break;
917 case BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION:
918 ret = field_class_signed_enumeration_copy(md_maps,
919 in_field_class, out_field_class);
920 break;
fe4df857
FD
921 case BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL:
922 ret = field_class_single_precision_real_copy(md_maps,
923 in_field_class, out_field_class);
924 break;
925 case BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL:
926 ret = field_class_double_precision_real_copy(md_maps,
ca9f27f3
FD
927 in_field_class, out_field_class);
928 break;
929 case BT_FIELD_CLASS_TYPE_STRING:
930 ret = field_class_string_copy(md_maps,
931 in_field_class, out_field_class);
932 break;
933 case BT_FIELD_CLASS_TYPE_STRUCTURE:
934 ret = field_class_structure_copy(md_maps,
935 in_field_class, out_field_class);
936 break;
937 case BT_FIELD_CLASS_TYPE_STATIC_ARRAY:
938 ret = field_class_static_array_copy(md_maps,
939 in_field_class, out_field_class);
940 break;
941 case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY:
942 ret = field_class_dynamic_array_copy(md_maps,
943 in_field_class, out_field_class);
944 break;
0aa006b7
PP
945 case BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR:
946 case BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR:
947 case BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR:
948 case BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR:
f29ef814
PP
949 ret = field_class_option_copy(md_maps,
950 in_field_class, out_field_class);
951 break;
45c51519 952 case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
fabfe034
PP
953 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR:
954 case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR:
ca9f27f3
FD
955 ret = field_class_variant_copy(md_maps,
956 in_field_class, out_field_class);
957 break;
958 default:
959 abort();
960 }
961
962 return ret;
963}
This page took 0.086493 seconds and 4 git commands to generate.