{
int ret = 0;
GQuark name_quark = g_quark_from_string(field_name);
+ GQuark underscore_name_quark;
struct structure_field *field;
+ GString *underscore_name = g_string_new(NULL);
+
+ if (!underscore_name) {
+ BT_LOGE_STR("Failed to allocate a GString.");
+ ret = -1;
+ goto end;
+ }
+
+ g_string_assign(underscore_name, "_");
+ g_string_append(underscore_name, field_name);
+ underscore_name_quark = g_quark_from_string(underscore_name->str);
/* Make sure structure does not contain a field of the same name */
if (g_hash_table_lookup_extended(field_name_to_index,
goto end;
}
+ if (g_hash_table_lookup_extended(field_name_to_index,
+ GUINT_TO_POINTER(underscore_name_quark), NULL, NULL)) {
+ BT_LOGW("Structure or variant field type already contains a field type with this name: "
+ "field-name=\"%s\"", underscore_name->str);
+ ret = -1;
+ goto end;
+ }
+
field = g_new0(struct structure_field, 1);
if (!field) {
BT_LOGE_STR("Failed to allocate one structure/variant field type field.");
g_hash_table_insert(field_name_to_index,
GUINT_TO_POINTER(name_quark),
GUINT_TO_POINTER(fields->len));
+ g_hash_table_insert(field_name_to_index,
+ GUINT_TO_POINTER(underscore_name_quark),
+ GUINT_TO_POINTER(fields->len));
g_ptr_array_add(fields, field);
BT_LOGV("Added structure/variant field type field: field-ft-addr=%p, "
"field-name=\"%s\"", field_type, field_name);
end:
+ g_string_free(underscore_name, TRUE);
return ret;
}
goto end;
}
- if (bt_ctf_validate_identifier(field_name)) {
- BT_LOGW("Invalid parameter: field name is not a valid CTF identifier: "
- "struct-ft-addr=%p, field-name=\"%s\"",
- type, field_name);
- ret = -1;
- goto end;
- }
-
if (type->id != BT_CTF_FIELD_TYPE_ID_STRUCT) {
BT_LOGW("Invalid parameter: field type is not a structure field type: "
"addr=%p, ft-id=%s", type,
goto end;
}
- if (bt_ctf_validate_identifier(field_name)) {
- BT_LOGW("Invalid parameter: field name is not a valid CTF identifier: "
- "variant-ft-addr=%p, field-name=\"%s\"",
- type, field_name);
- ret = -1;
- goto end;
- }
-
if (type->id != BT_CTF_FIELD_TYPE_ID_VARIANT) {
BT_LOGW("Invalid parameter: field type is not a variant field type: "
"addr=%p, ft-id=%s", type,
return base_string;
}
+static
+void append_struct_variant_field_name(struct metadata_context *context,
+ const char *name)
+{
+ g_string_append_c(context->string, ' ');
+
+ if (bt_ctf_validate_identifier(name)) {
+ g_string_append_c(context->string, '_');
+ }
+
+ g_string_append(context->string, name);
+}
+
static
int bt_ctf_field_type_integer_serialize(struct bt_ctf_field_type *type,
struct metadata_context *context)
}
if (context->field_name->len) {
- g_string_append_printf(context->string, " %s",
+ append_struct_variant_field_name(context,
context->field_name->str);
g_string_assign(context->field_name, "");
}
}
if (context->field_name->len) {
- g_string_append_printf(context->string, " %s",
+ append_struct_variant_field_name(context,
context->field_name->str);
}
g_string_append(context->string, ";\n");
}
if (context->field_name->len) {
- g_string_append_printf(context->string, " %s;",
+ append_struct_variant_field_name(context,
context->field_name->str);
+ g_string_append_c(context->string, ';');
}
g_string_append_c(context->string, '\n');
}
if (context->field_name->len) {
- g_string_append_printf(context->string, " %s[%u]",
- context->field_name->str, array->length);
+ append_struct_variant_field_name(context,
+ context->field_name->str);
+
+ g_string_append_printf(context->string, "[%u]", array->length);
g_string_assign(context->field_name, "");
} else {
g_string_append_printf(context->string, "[%u]", array->length);
}
if (context->field_name->len) {
- g_string_append_printf(context->string, " %s[%s]",
- context->field_name->str,
+ append_struct_variant_field_name(context,
+ context->field_name->str);
+
+ g_string_append_printf(context->string, "[%s]",
sequence->length_field_name->str);
g_string_assign(context->field_name, "");
} else {
int visit_type_specifier_list(struct ctx *ctx, struct ctf_node *ts_list,
struct bt_ctf_field_type **decl);
+static
+char *remove_underscores_from_field_ref(const char *field_ref)
+{
+ const char *in_ch;
+ char *out_ch;
+ char *ret;
+ enum {
+ UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE,
+ UNDERSCORE_REMOVE_STATE_DO_NOT_REMOVE_NEXT_UNDERSCORE,
+ } state = UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE;
+
+ assert(field_ref);
+ ret = calloc(strlen(field_ref) + 1, 1);
+ if (!ret) {
+ BT_LOGE("Failed to allocate a string: size=%zu",
+ strlen(field_ref) + 1);
+ goto end;
+ }
+
+ in_ch = field_ref;
+ out_ch = ret;
+
+ while (*in_ch != '\0') {
+ switch (*in_ch) {
+ case ' ':
+ case '\t':
+ /* Remove whitespace */
+ in_ch++;
+ continue;
+ case '_':
+ if (state == UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE) {
+ in_ch++;
+ state = UNDERSCORE_REMOVE_STATE_DO_NOT_REMOVE_NEXT_UNDERSCORE;
+ continue;
+ }
+
+ goto copy;
+ case '.':
+ state = UNDERSCORE_REMOVE_STATE_REMOVE_NEXT_UNDERSCORE;
+ goto copy;
+ default:
+ state = UNDERSCORE_REMOVE_STATE_DO_NOT_REMOVE_NEXT_UNDERSCORE;
+ goto copy;
+ }
+
+copy:
+ *out_ch = *in_ch;
+ in_ch++;
+ out_ch++;
+ }
+
+end:
+ return ret;
+}
+
static
int is_unary_string(struct bt_list_head *head)
{
const char *id =
node_type_declarator->u.type_declarator.u.id;
+ if (id[0] == '_') {
+ id++;
+ }
+
*field_name = g_quark_from_string(id);
} else {
*field_name = 0;
/* Lookup unsigned integer definition, create seq. */
_BT_CTF_FIELD_TYPE_INIT(seq_decl);
char *length_name = concatenate_unary_strings(length);
+ char *length_name_no_underscore;
if (!length_name) {
_BT_LOGE_NODE(node_type_declarator,
goto error;
}
+ length_name_no_underscore =
+ remove_underscores_from_field_ref(length_name);
+ if (!length_name_no_underscore) {
+ /* remove_underscores_from_field_ref() logs errors */
+ ret = -EINVAL;
+ goto error;
+ }
seq_decl = bt_ctf_field_type_sequence_create(
- nested_decl, length_name);
+ nested_decl, length_name_no_underscore);
+ free(length_name_no_underscore);
g_free(length_name);
BT_PUT(nested_decl);
if (!seq_decl) {
* At this point, we have a fresh untagged variant; nobody
* else owns it. Set its tag now.
*/
+ char *tag_no_underscore =
+ remove_underscores_from_field_ref(tag);
+
+ if (!tag_no_underscore) {
+ /* remove_underscores_from_field_ref() logs errors */
+ goto error;
+ }
+
ret = bt_ctf_field_type_variant_set_tag_name(
- untagged_variant_decl, tag);
+ untagged_variant_decl, tag_no_underscore);
+ free(tag_no_underscore);
if (ret) {
BT_LOGE("Cannot set variant field type's tag name: "
"tag-name=\"%s\"", tag);