#include <errno.h>
#include <babeltrace/compat/uuid-internal.h>
#include <babeltrace/endian-internal.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/ctf-ir/trace.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/event.h>
-#include <babeltrace/ctf-ir/event-class.h>
-#include <babeltrace/ctf-ir/field-types.h>
+#include <babeltrace/babeltrace.h>
#include <babeltrace/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/clock-class.h>
#include "scanner.h"
#include "parser.h"
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)
{
static
int is_align_valid(uint64_t align)
{
- return (align != 0) && !(align & (align - 1));
+ return (align != 0) && !(align & (align - 1ULL));
}
static
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) {
/* Do not allow typedef and typealias of untagged variants */
if (bt_ctf_field_type_is_variant(type_decl)) {
if (bt_ctf_field_type_variant_get_tag_name(type_decl)) {
- _BT_LOGE_NODE(node,
+ _BT_LOGE_NODE(target,
"Type definition of untagged variant field type is not allowed.");
ret = -EPERM;
goto end;
* abstract or not (if it has an identifier). Check it here.
*/
if (qdummy_field_name != 0) {
- _BT_LOGE_NODE(node,
+ _BT_LOGE_NODE(target,
"Expecting empty identifier: id=\"%s\"",
g_quark_to_string(qdummy_field_name));
ret = -EINVAL;
* 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);
switch (stream_class_count) {
case 0:
/* Create implicit stream class if there's none */
+ stream_id = 0;
new_stream_class = create_reset_stream_class(ctx);
if (!new_stream_class) {
_BT_LOGE_NODE(node,
goto error;
}
- ret = bt_ctf_stream_class_set_id(new_stream_class, 0);
+ ret = bt_ctf_stream_class_set_id(new_stream_class,
+ stream_id);
if (ret) {
_BT_LOGE_NODE(node,
"Cannot set stream class's ID: "
goto error;
}
+ *new_stream_id = stream_id;
+
/* Move reference to visitor's context */
g_hash_table_insert(ctx->stream_classes,
new_stream_id, new_stream_class);