#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"
goto error;
}
- ctx->stream_classes = g_hash_table_new_full(g_direct_hash,
- g_direct_equal, NULL, (GDestroyNotify) bt_put);
+ ctx->stream_classes = g_hash_table_new_full(g_int64_hash,
+ g_int64_equal, g_free, (GDestroyNotify) bt_put);
if (!ctx->stream_classes) {
BT_LOGE_STR("Failed to allocate a GHashTable.");
goto error;
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)
{
int uexpr_type = node->u.unary_expression.type;
int uexpr_link = node->u.unary_expression.link;
int cond = node->type != NODE_UNARY_EXPRESSION ||
- (uexpr_type != UNARY_UNSIGNED_CONSTANT) ||
(uexpr_type != UNARY_UNSIGNED_CONSTANT &&
uexpr_type != UNARY_SIGNED_CONSTANT) ||
uexpr_link != UNARY_LINK_UNKNOWN || i != 0;
goto end;
}
- switch (node->u.unary_expression.type) {
+ switch (uexpr_type) {
case UNARY_UNSIGNED_CONSTANT:
*value = (int64_t)
node->u.unary_expression.u.unsigned_constant;
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);
if (!_IS_SET(&set, _EVENT_STREAM_ID_SET)) {
GList *keys = NULL;
+ int64_t *new_stream_id;
struct bt_ctf_stream_class *new_stream_class;
size_t stream_class_count =
g_hash_table_size(ctx->stream_classes) +
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;
}
- stream_id = 0;
+ new_stream_id = g_new0(int64_t, 1);
+ if (!new_stream_id) {
+ BT_LOGE_STR("Failed to allocate a int64_t.");
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ *new_stream_id = stream_id;
/* Move reference to visitor's context */
g_hash_table_insert(ctx->stream_classes,
- (gpointer) stream_id, new_stream_class);
+ new_stream_id, new_stream_class);
+ new_stream_id = NULL;
new_stream_class = NULL;
break;
case 1:
/* Single stream class: get its ID */
if (g_hash_table_size(ctx->stream_classes) == 1) {
keys = g_hash_table_get_keys(ctx->stream_classes);
- stream_id = (int64_t) keys->data;
+ stream_id = *((int64_t *) keys->data);
g_list_free(keys);
} else {
assert(bt_ctf_trace_get_stream_class_count(
assert(stream_id >= 0);
/* We have the stream ID now; get the stream class if found */
- stream_class = g_hash_table_lookup(ctx->stream_classes,
- (gpointer) stream_id);
+ stream_class = g_hash_table_lookup(ctx->stream_classes, &stream_id);
bt_get(stream_class);
if (!stream_class) {
stream_class = bt_ctf_trace_get_stream_class_by_id(ctx->trace,
goto error;
}
- ptr = g_hash_table_lookup(ctx->stream_classes,
- (gpointer) id);
+ ptr = g_hash_table_lookup(ctx->stream_classes, &id);
if (ptr) {
_BT_LOGE_NODE(node,
"Duplicate stream class (same ID): id=%" PRId64,
int visit_stream_decl(struct ctx *ctx, struct ctf_node *node)
{
int64_t id;
+ int64_t *new_id;
int set = 0;
int ret = 0;
struct ctf_node *iter;
*/
existing_stream_class = bt_ctf_trace_get_stream_class_by_id(ctx->trace,
id);
- if (g_hash_table_lookup(ctx->stream_classes, (gpointer) id) ||
+ if (g_hash_table_lookup(ctx->stream_classes, &id) ||
existing_stream_class) {
_BT_LOGE_NODE(node,
"Duplicate stream class (same ID): id=%" PRId64,
goto error;
}
+ new_id = g_new0(int64_t, 1);
+ if (!new_id) {
+ BT_LOGE_STR("Failed to allocate a int64_t.");
+ ret = -ENOMEM;
+ goto error;
+ }
+ *new_id = id;
+
/* Move reference to visitor's context */
- g_hash_table_insert(ctx->stream_classes, (gpointer) (int64_t) id,
+ g_hash_table_insert(ctx->stream_classes, new_id,
stream_class);
stream_class = NULL;
goto end;
goto error;
}
+ if (freq == -1ULL || freq == 0) {
+ _BT_LOGE_NODE(entry_node,
+ "Invalid clock class frequency: freq=%" PRIu64,
+ freq);
+ ret = -EINVAL;
+ goto error;
+ }
+
ret = bt_ctf_clock_class_set_frequency(clock, freq);
if (ret) {
_BT_LOGE_NODE(entry_node,
_SET(set, _CLOCK_PRECISION_SET);
} else if (!strcmp(left, "offset_s")) {
- uint64_t offset_s;
+ int64_t offset_s;
if (_IS_SET(set, _CLOCK_OFFSET_S_SET)) {
_BT_LOGE_DUP_ATTR(entry_node, "offset_s",
goto error;
}
- ret = get_unary_unsigned(
+ ret = get_unary_signed(
&entry_node->u.ctf_expression.right, &offset_s);
if (ret) {
_BT_LOGE_NODE(entry_node,
_SET(set, _CLOCK_OFFSET_S_SET);
} else if (!strcmp(left, "offset")) {
- uint64_t offset;
+ int64_t offset;
if (_IS_SET(set, _CLOCK_OFFSET_SET)) {
_BT_LOGE_DUP_ATTR(entry_node, "offset", "clock class");
goto error;
}
- ret = get_unary_unsigned(
+ ret = get_unary_signed(
&entry_node->u.ctf_expression.right, &offset);
if (ret) {
_BT_LOGE_NODE(entry_node,