This allows the creation of a variant while not specifying the variant's
tag's name and type which is needed to support untagged variants.
This will allow the support of constructs such as:
variant name {
field_type sel1;
field_type sel2;
field_type sel3;
/* ... */
};
struct {
enum : integer_type { sel1, sel2, sel3, /* ... */ } tag_field;
/* ... */
variant name <tag_field> v;
}
The validation of variant fields thus becomes optional and will
be implemented as part of the freeze() of variants in a later commit.
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
{
struct bt_ctf_field_type_variant *variant = NULL;
{
struct bt_ctf_field_type_variant *variant = NULL;
- if (!enum_tag || bt_ctf_validate_identifier(tag_name) ||
- (enum_tag->declaration->id != CTF_TYPE_ENUM)) {
+ if (tag_name && bt_ctf_validate_identifier(tag_name)) {
variant->field_name_to_index = g_hash_table_new(NULL, NULL);
variant->fields = g_ptr_array_new_with_free_func(
(GDestroyNotify)destroy_structure_field);
variant->field_name_to_index = g_hash_table_new(NULL, NULL);
variant->fields = g_ptr_array_new_with_free_func(
(GDestroyNotify)destroy_structure_field);
- bt_ctf_field_type_get(enum_tag);
- variant->tag = container_of(enum_tag,
- struct bt_ctf_field_type_enumeration, parent);
+ if (enum_tag) {
+ bt_ctf_field_type_get(enum_tag);
+ variant->tag = container_of(enum_tag,
+ struct bt_ctf_field_type_enumeration, parent);
+ }
+
bt_ctf_field_type_init(&variant->parent);
return &variant->parent;
error:
bt_ctf_field_type_init(&variant->parent);
return &variant->parent;
error:
}
variant = container_of(type, struct bt_ctf_field_type_variant, parent);
}
variant = container_of(type, struct bt_ctf_field_type_variant, parent);
+ if (!variant->tag) {
+ goto end;
+ }
+
tag_type = &variant->tag->parent;
bt_ctf_field_type_get(tag_type);
end:
tag_type = &variant->tag->parent;
bt_ctf_field_type_get(tag_type);
end:
}
variant = container_of(type, struct bt_ctf_field_type_variant, parent);
}
variant = container_of(type, struct bt_ctf_field_type_variant, parent);
+ if (variant->tag_name->len == 0) {
+ goto end;
+ }
+
tag_name = variant->tag_name->str;
end:
return tag_name;
tag_name = variant->tag_name->str;
end:
return tag_name;
struct bt_ctf_field_type_variant *variant;
GQuark field_name_quark = g_quark_from_string(field_name);
struct bt_ctf_field_type_variant *variant;
GQuark field_name_quark = g_quark_from_string(field_name);
}
variant = container_of(type, struct bt_ctf_field_type_variant, parent);
}
variant = container_of(type, struct bt_ctf_field_type_variant, parent);
- /* Make sure this name is present in the enum tag */
- for (i = 0; i < variant->tag->entries->len; i++) {
- struct enumeration_mapping *mapping =
- g_ptr_array_index(variant->tag->entries, i);
- if (mapping->string == field_name_quark) {
- name_found = 1;
- break;
+ /* The user has explicitly provided a tag; validate against it. */
+ if (variant->tag) {
+ int name_found = 0;
+
+ /* Make sure this name is present in the enum tag */
+ for (i = 0; i < variant->tag->entries->len; i++) {
+ struct enumeration_mapping *mapping =
+ g_ptr_array_index(variant->tag->entries, i);
+
+ if (mapping->string == field_name_quark) {
+ name_found = 1;
+ break;
+ }
+ }
+
+ if (!name_found) {
+ /* Validation failed */
+ ret = -1;
+ goto end;
- if (!name_found || add_structure_field(variant->fields,
- variant->field_name_to_index, field_type, field_name)) {
+ if (add_structure_field(variant->fields, variant->field_name_to_index,
+ field_type, field_name)) {
GString *variant_field_name = context->field_name;
context->field_name = g_string_new("");
GString *variant_field_name = context->field_name;
context->field_name = g_string_new("");
- g_string_append_printf(context->string,
- "variant <%s> {\n", variant->tag_name->str);
+ if (variant->tag_name->len > 0) {
+ g_string_append_printf(context->string,
+ "variant <%s> {\n", variant->tag_name->str);
+ } else {
+ g_string_append(context->string, "variant {\n");
+ }
+
context->current_indentation_level++;
for (i = 0; i < variant->fields->len; i++) {
struct structure_field *field = variant->fields->pdata[i];
context->current_indentation_level++;
for (i = 0; i < variant->fields->len; i++) {
struct structure_field *field = variant->fields->pdata[i];
*
* @param variant Variant type.
*
*
* @param variant Variant type.
*
- * Returns a field type instance on success, NULL on error.
+ * Returns a field type instance on success, NULL if unset.
*/
extern struct bt_ctf_field_type *bt_ctf_field_type_variant_get_tag_type(
struct bt_ctf_field_type *variant);
*/
extern struct bt_ctf_field_type *bt_ctf_field_type_variant_get_tag_type(
struct bt_ctf_field_type *variant);
*
* @param variant Variant type.
*
*
* @param variant Variant type.
*
- * Returns the tag field's name, NULL on error.
+ * Returns the tag field's name, NULL if unset.
*/
extern const char *bt_ctf_field_type_variant_get_tag_name(
struct bt_ctf_field_type *variant);
*/
extern const char *bt_ctf_field_type_variant_get_tag_name(
struct bt_ctf_field_type *variant);