* Based on older ctf-visitor-generate-io-struct.c.
*
* Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- * Copyright 2015-2016 - Philippe Proulx <philippe.proulx@efficios.com>
+ * Copyright 2015-2018 - Philippe Proulx <philippe.proulx@efficios.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
#include <stdbool.h>
#include <stdlib.h>
#include <ctype.h>
-#include <assert.h>
+#include <babeltrace/assert-internal.h>
#include <glib.h>
#include <inttypes.h>
#include <errno.h>
+#include <babeltrace/common-internal.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/ctf-ir/field-types-internal.h>
-#include <babeltrace/ctf-ir/clock-class.h>
+#include <babeltrace/babeltrace.h>
#include "scanner.h"
#include "parser.h"
#include "ast.h"
#include "decoder.h"
+#include "ctf-meta.h"
+#include "ctf-meta-visitors.h"
/* Bit value (left shift) */
#define _BV(_val) (1 << (_val))
/* Set bit in a set of bits */
#define _SET(_set, _mask) (*(_set) |= (_mask))
+/* Try to push scope, or go to the `error` label */
+#define _TRY_PUSH_SCOPE_OR_GOTO_ERROR() \
+ do { \
+ ret = ctx_push_scope(ctx); \
+ if (ret) { \
+ BT_LOGE_STR("Cannot push scope."); \
+ goto error; \
+ } \
+ } while (0)
+
/* Bits for verifying existing attributes in various declarations */
enum {
_CLOCK_NAME_SET = _BV(0),
_EVENT_ID_SET = _BV(1),
_EVENT_MODEL_EMF_URI_SET = _BV(2),
_EVENT_STREAM_ID_SET = _BV(3),
- _EVENT_LOGLEVEL_SET = _BV(4),
+ _EVENT_LOG_LEVEL_SET = _BV(4),
_EVENT_CONTEXT_SET = _BV(5),
_EVENT_FIELDS_SET = _BV(6),
};
enum loglevel {
- LOGLEVEL_EMERG = 0,
- LOGLEVEL_ALERT = 1,
- LOGLEVEL_CRIT = 2,
- LOGLEVEL_ERR = 3,
- LOGLEVEL_WARNING = 4,
- LOGLEVEL_NOTICE = 5,
- LOGLEVEL_INFO = 6,
- LOGLEVEL_DEBUG_SYSTEM = 7,
- LOGLEVEL_DEBUG_PROGRAM = 8,
- LOGLEVEL_DEBUG_PROCESS = 9,
- LOGLEVEL_DEBUG_MODULE = 10,
- LOGLEVEL_DEBUG_UNIT = 11,
- LOGLEVEL_DEBUG_FUNCTION = 12,
- LOGLEVEL_DEBUG_LINE = 13,
- LOGLEVEL_DEBUG = 14,
+ LOG_LEVEL_EMERG = 0,
+ LOG_LEVEL_ALERT = 1,
+ LOG_LEVEL_CRIT = 2,
+ LOG_LEVEL_ERR = 3,
+ LOG_LEVEL_WARNING = 4,
+ LOG_LEVEL_NOTICE = 5,
+ LOG_LEVEL_INFO = 6,
+ LOG_LEVEL_DEBUG_SYSTEM = 7,
+ LOG_LEVEL_DEBUG_PROGRAM = 8,
+ LOG_LEVEL_DEBUG_PROCESS = 9,
+ LOG_LEVEL_DEBUG_MODULE = 10,
+ LOG_LEVEL_DEBUG_UNIT = 11,
+ LOG_LEVEL_DEBUG_FUNCTION = 12,
+ LOG_LEVEL_DEBUG_LINE = 13,
+ LOG_LEVEL_DEBUG = 14,
_NR_LOGLEVELS = 15,
};
-/* Prefixes of type aliases */
+/* Prefixes of class aliases */
#define _PREFIX_ALIAS 'a'
#define _PREFIX_ENUM 'e'
#define _PREFIX_STRUCT 's'
#define _PREFIX_VARIANT 'v'
/* First entry in a BT list */
-#define _BT_LIST_FIRST_ENTRY(_ptr, _type, _member) \
- bt_list_entry((_ptr)->next, _type, _member)
-
-#define _BT_CTF_FIELD_TYPE_INIT(_name) struct bt_ctf_field_type *_name = NULL;
+#define _BT_LIST_FIRST_ENTRY(_ptr, _class, _member) \
+ bt_list_entry((_ptr)->next, _class, _member)
#define _BT_LOGE_DUP_ATTR(_node, _attr, _entity) \
_BT_LOGE_LINENO((_node)->lineno, \
*/
struct ctx_decl_scope {
/*
- * Alias name to field type.
+ * Alias name to field class.
*
- * GQuark -> struct bt_ctf_field_type *
+ * GQuark -> struct ctf_field_class * (owned by this)
*/
GHashTable *decl_map;
* Visitor context (private).
*/
struct ctx {
- /* Trace being filled (owned by this) */
- struct bt_ctf_trace *trace;
+ /* Trace IR trace being filled (owned by this) */
+ struct bt_private_trace *trace;
- /* Current declaration scope (top of the stack) */
+ /* CTF meta trace being filled (owned by this) */
+ struct ctf_trace_class *ctf_tc;
+
+ /* Current declaration scope (top of the stack) (owned by this) */
struct ctx_decl_scope *current_scope;
- /* 1 if trace declaration is visited */
- int is_trace_visited;
+ /* True if trace declaration is visited */
+ bool is_trace_visited;
- /* 1 if this is an LTTng trace */
+ /* True if this is an LTTng trace */
bool is_lttng;
- /* Eventual name suffix of the trace to set */
- char *trace_name_suffix;
-
- /* Trace attributes */
- enum bt_ctf_byte_order trace_bo;
- uint64_t trace_major;
- uint64_t trace_minor;
- unsigned char trace_uuid[BABELTRACE_UUID_LEN];
-
- /*
- * Stream IDs to stream classes.
- *
- * int64_t -> struct bt_ctf_stream_class *
- */
- GHashTable *stream_classes;
+ /* Eventual name suffix of the trace to set (owned by this) */
+ char *trace_class_name_suffix;
/* Config passed by the user */
struct ctf_metadata_decoder_config decoder_config;
/*
* Visitor (public).
*/
-struct ctf_visitor_generate_ir { };
+struct ctf_visitor_generate_ir;
/**
* Creates a new declaration scope.
}
scope->decl_map = g_hash_table_new_full(g_direct_hash, g_direct_equal,
- NULL, (GDestroyNotify) bt_ctf_field_type_put);
+ NULL, (GDestroyNotify) ctf_field_class_destroy);
scope->parent_scope = par_scope;
end:
{
GQuark qname = 0;
- assert(name);
+ BT_ASSERT(name);
/* Prefix character + original string + '\0' */
char *prname = g_new(char, strlen(name) + 2);
}
/**
- * Looks up a prefixed type alias within a declaration scope.
+ * Looks up a prefixed class alias within a declaration scope.
*
* @param scope Declaration scope
* @param prefix Prefix character
* @param name Alias name
- * @param level Number of levels to dig (-1 means infinite)
- * @returns Declaration, or NULL if not found
+ * @param levels Number of levels to dig into (-1 means infinite)
+ * @param copy True to return a copy
+ * @returns Declaration (owned by caller if \p copy is true),
+ * or NULL if not found
*/
static
-struct bt_ctf_field_type *ctx_decl_scope_lookup_prefix_alias(
- struct ctx_decl_scope *scope, char prefix,
- const char *name, int levels)
+struct ctf_field_class *ctx_decl_scope_lookup_prefix_alias(
+ struct ctx_decl_scope *scope, char prefix, const char *name,
+ int levels, bool copy)
{
GQuark qname = 0;
int cur_levels = 0;
- _BT_CTF_FIELD_TYPE_INIT(decl);
+ struct ctf_field_class *decl = NULL;
struct ctx_decl_scope *cur_scope = scope;
- assert(scope);
- assert(name);
+ BT_ASSERT(scope);
+ BT_ASSERT(name);
qname = get_prefixed_named_quark(prefix, name);
if (!qname) {
- goto error;
+ goto end;
}
if (levels < 0) {
(gconstpointer) GUINT_TO_POINTER(qname));
if (decl) {
/* Caller's reference */
- bt_get(decl);
- break;
+ if (copy) {
+ decl = ctf_field_class_copy(decl);
+ BT_ASSERT(decl);
+ }
+
+ goto end;
}
cur_scope = cur_scope->parent_scope;
cur_levels++;
}
+end:
return decl;
-
-error:
- return NULL;
}
/**
- * Looks up a type alias within a declaration scope.
+ * Looks up a class alias within a declaration scope.
*
* @param scope Declaration scope
* @param name Alias name
- * @param level Number of levels to dig (-1 means infinite)
- * @returns Declaration, or NULL if not found
+ * @param levels Number of levels to dig into (-1 means infinite)
+ * @param copy True to return a copy
+ * @returns Declaration (owned by caller if \p copy is true),
+ * or NULL if not found
*/
static
-struct bt_ctf_field_type *ctx_decl_scope_lookup_alias(
- struct ctx_decl_scope *scope, const char *name, int levels)
+struct ctf_field_class *ctx_decl_scope_lookup_alias(
+ struct ctx_decl_scope *scope, const char *name, int levels,
+ bool copy)
{
return ctx_decl_scope_lookup_prefix_alias(scope, _PREFIX_ALIAS,
- name, levels);
+ name, levels, copy);
}
/**
*
* @param scope Declaration scope
* @param name Enumeration name
- * @param level Number of levels to dig (-1 means infinite)
- * @returns Declaration, or NULL if not found
+ * @param levels Number of levels to dig into (-1 means infinite)
+ * @param copy True to return a copy
+ * @returns Declaration (owned by caller if \p copy is true),
+ * or NULL if not found
*/
static
-struct bt_ctf_field_type *ctx_decl_scope_lookup_enum(
- struct ctx_decl_scope *scope, const char *name, int levels)
+struct ctf_field_class_enum *ctx_decl_scope_lookup_enum(
+ struct ctx_decl_scope *scope, const char *name, int levels,
+ bool copy)
{
- return ctx_decl_scope_lookup_prefix_alias(scope, _PREFIX_ENUM,
- name, levels);
+ return (void *) ctx_decl_scope_lookup_prefix_alias(scope, _PREFIX_ENUM,
+ name, levels, copy);
}
/**
*
* @param scope Declaration scope
* @param name Structure name
- * @param level Number of levels to dig (-1 means infinite)
- * @returns Declaration, or NULL if not found
+ * @param levels Number of levels to dig into (-1 means infinite)
+ * @param copy True to return a copy
+ * @returns Declaration (owned by caller if \p copy is true),
+ * or NULL if not found
*/
static
-struct bt_ctf_field_type *ctx_decl_scope_lookup_struct(
- struct ctx_decl_scope *scope, const char *name, int levels)
+struct ctf_field_class_struct *ctx_decl_scope_lookup_struct(
+ struct ctx_decl_scope *scope, const char *name, int levels,
+ bool copy)
{
- return ctx_decl_scope_lookup_prefix_alias(scope, _PREFIX_STRUCT,
- name, levels);
+ return (void *) ctx_decl_scope_lookup_prefix_alias(scope,
+ _PREFIX_STRUCT, name, levels, copy);
}
/**
*
* @param scope Declaration scope
* @param name Variant name
- * @param level Number of levels to dig (-1 means infinite)
- * @returns Declaration, or NULL if not found
+ * @param levels Number of levels to dig into (-1 means infinite)
+ * @param copy True to return a copy
+ * @returns Declaration (owned by caller if \p copy is true),
+ * or NULL if not found
*/
static
-struct bt_ctf_field_type *ctx_decl_scope_lookup_variant(
- struct ctx_decl_scope *scope, const char *name, int levels)
+struct ctf_field_class_variant *ctx_decl_scope_lookup_variant(
+ struct ctx_decl_scope *scope, const char *name, int levels,
+ bool copy)
{
- return ctx_decl_scope_lookup_prefix_alias(scope, _PREFIX_VARIANT,
- name, levels);
+ return (void *) ctx_decl_scope_lookup_prefix_alias(scope,
+ _PREFIX_VARIANT, name, levels, copy);
}
/**
- * Registers a prefixed type alias within a declaration scope.
+ * Registers a prefixed class alias within a declaration scope.
*
* @param scope Declaration scope
* @param prefix Prefix character
* @param name Alias name (non-NULL)
- * @param decl Declaration to register
+ * @param decl Field class to register (copied)
* @returns 0 if registration went okay, negative value otherwise
*/
static
int ctx_decl_scope_register_prefix_alias(struct ctx_decl_scope *scope,
- char prefix, const char *name, struct bt_ctf_field_type *decl)
+ char prefix, const char *name, struct ctf_field_class *decl)
{
int ret = 0;
GQuark qname = 0;
- _BT_CTF_FIELD_TYPE_INIT(edecl);
- assert(scope);
- assert(name);
- assert(decl);
+ BT_ASSERT(scope);
+ BT_ASSERT(name);
+ BT_ASSERT(decl);
qname = get_prefixed_named_quark(prefix, name);
if (!qname) {
ret = -ENOMEM;
- goto error;
+ goto end;
}
/* Make sure alias does not exist in local scope */
- edecl = ctx_decl_scope_lookup_prefix_alias(scope, prefix, name, 1);
- if (edecl) {
- BT_PUT(edecl);
+ if (ctx_decl_scope_lookup_prefix_alias(scope, prefix, name, 1,
+ false)) {
ret = -EEXIST;
- goto error;
+ goto end;
}
- g_hash_table_insert(scope->decl_map,
- GUINT_TO_POINTER(qname), decl);
-
- /* Hash table's reference */
- bt_get(decl);
-
- return 0;
+ decl = ctf_field_class_copy(decl);
+ BT_ASSERT(decl);
+ g_hash_table_insert(scope->decl_map, GUINT_TO_POINTER(qname), decl);
-error:
+end:
return ret;
}
/**
- * Registers a type alias within a declaration scope.
+ * Registers a class alias within a declaration scope.
*
* @param scope Declaration scope
* @param name Alias name (non-NULL)
- * @param decl Declaration to register
+ * @param decl Field class to register (copied)
* @returns 0 if registration went okay, negative value otherwise
*/
static
int ctx_decl_scope_register_alias(struct ctx_decl_scope *scope,
- const char *name, struct bt_ctf_field_type *decl)
+ const char *name, struct ctf_field_class *decl)
{
return ctx_decl_scope_register_prefix_alias(scope, _PREFIX_ALIAS,
- name, decl);
+ name, (void *) decl);
}
/**
*
* @param scope Declaration scope
* @param name Enumeration name (non-NULL)
- * @param decl Enumeration declaration to register
+ * @param decl Enumeration field class to register (copied)
* @returns 0 if registration went okay, negative value otherwise
*/
static
int ctx_decl_scope_register_enum(struct ctx_decl_scope *scope,
- const char *name, struct bt_ctf_field_type *decl)
+ const char *name, struct ctf_field_class_enum *decl)
{
return ctx_decl_scope_register_prefix_alias(scope, _PREFIX_ENUM,
- name, decl);
+ name, (void *) decl);
}
/**
*
* @param scope Declaration scope
* @param name Structure name (non-NULL)
- * @param decl Structure declaration to register
+ * @param decl Structure field class to register (copied)
* @returns 0 if registration went okay, negative value otherwise
*/
static
int ctx_decl_scope_register_struct(struct ctx_decl_scope *scope,
- const char *name, struct bt_ctf_field_type *decl)
+ const char *name, struct ctf_field_class_struct *decl)
{
return ctx_decl_scope_register_prefix_alias(scope, _PREFIX_STRUCT,
- name, decl);
+ name, (void *) decl);
}
/**
*
* @param scope Declaration scope
* @param name Variant name (non-NULL)
- * @param decl Variant declaration to register
+ * @param decl Variant field class to register
* @returns 0 if registration went okay, negative value otherwise
*/
static
int ctx_decl_scope_register_variant(struct ctx_decl_scope *scope,
- const char *name, struct bt_ctf_field_type *decl)
+ const char *name, struct ctf_field_class_variant *decl)
{
return ctx_decl_scope_register_prefix_alias(scope, _PREFIX_VARIANT,
- name, decl);
+ name, (void *) decl);
}
/**
void ctx_destroy(struct ctx *ctx)
{
struct ctx_decl_scope *scope;
- /*
- * Destroy all scopes, from current one to the root scope.
- */
if (!ctx) {
goto end;
scope = ctx->current_scope;
+ /*
+ * Destroy all scopes, from current one to the root scope.
+ */
while (scope) {
struct ctx_decl_scope *parent_scope = scope->parent_scope;
scope = parent_scope;
}
- bt_put(ctx->trace);
+ bt_object_put_ref(ctx->trace);
+
+ if (ctx->ctf_tc) {
+ ctf_trace_class_destroy(ctx->ctf_tc);
+ }
- if (ctx->stream_classes) {
- g_hash_table_destroy(ctx->stream_classes);
+ if (ctx->trace_class_name_suffix) {
+ free(ctx->trace_class_name_suffix);
}
- free(ctx->trace_name_suffix);
g_free(ctx);
end:
* @returns New visitor context, or NULL on error
*/
static
-struct ctx *ctx_create(struct bt_ctf_trace *trace,
- const struct ctf_metadata_decoder_config *decoder_config,
- const char *trace_name_suffix)
+struct ctx *ctx_create(const struct ctf_metadata_decoder_config *decoder_config,
+ const char *trace_class_name_suffix)
{
struct ctx *ctx = NULL;
- struct ctx_decl_scope *scope = NULL;
- assert(decoder_config);
+ BT_ASSERT(decoder_config);
ctx = g_new0(struct ctx, 1);
if (!ctx) {
goto error;
}
- /* Root declaration scope */
- scope = ctx_decl_scope_create(NULL);
- if (!scope) {
- BT_LOGE_STR("Cannot create declaration scope.");
+ ctx->trace = bt_private_trace_create();
+ if (!ctx->trace) {
+ BT_LOGE_STR("Cannot create empty trace.");
goto error;
}
- ctx->stream_classes = g_hash_table_new_full(g_direct_hash,
- g_direct_equal, NULL, (GDestroyNotify) bt_put);
- if (!ctx->stream_classes) {
- BT_LOGE_STR("Failed to allocate a GHashTable.");
+ ctx->ctf_tc = ctf_trace_class_create();
+ if (!ctx->ctf_tc) {
+ BT_LOGE_STR("Cannot create CTF trace class.");
goto error;
}
- if (trace_name_suffix) {
- ctx->trace_name_suffix = strdup(trace_name_suffix);
- if (!ctx->trace_name_suffix) {
+ /* Root declaration scope */
+ ctx->current_scope = ctx_decl_scope_create(NULL);
+ if (!ctx->current_scope) {
+ BT_LOGE_STR("Cannot create declaration scope.");
+ goto error;
+ }
+
+ if (trace_class_name_suffix) {
+ ctx->trace_class_name_suffix = strdup(trace_class_name_suffix);
+ if (!ctx->trace_class_name_suffix) {
BT_LOGE_STR("Failed to copy string.");
goto error;
}
}
- ctx->trace = trace;
- ctx->current_scope = scope;
- scope = NULL;
- ctx->trace_bo = BT_CTF_BYTE_ORDER_NATIVE;
ctx->decoder_config = *decoder_config;
- return ctx;
+ goto end;
error:
ctx_destroy(ctx);
- ctx_decl_scope_destroy(scope);
- return NULL;
+ ctx = NULL;
+
+end:
+ return ctx;
}
/**
int ret = 0;
struct ctx_decl_scope *new_scope;
- assert(ctx);
+ BT_ASSERT(ctx);
new_scope = ctx_decl_scope_create(ctx->current_scope);
if (!new_scope) {
BT_LOGE_STR("Cannot create declaration scope.");
{
struct ctx_decl_scope *parent_scope = NULL;
- assert(ctx);
+ BT_ASSERT(ctx);
if (!ctx->current_scope) {
goto end;
}
static
-int visit_type_specifier_list(struct ctx *ctx, struct ctf_node *ts_list,
- struct bt_ctf_field_type **decl);
+int visit_field_class_specifier_list(struct ctx *ctx, struct ctf_node *ts_list,
+ struct ctf_field_class **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;
+
+ BT_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)
struct ctf_node *node;
str = g_string_new(NULL);
- assert(str);
+ BT_ASSERT(str);
bt_list_for_each_entry(node, head, siblings) {
char *src_string;
int ret = 0;
struct ctf_node *node;
+ *value = 0;
+
if (bt_list_empty(head)) {
ret = -1;
goto end;
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
-enum bt_ctf_byte_order byte_order_from_unary_expr(struct ctf_node *unary_expr)
+enum ctf_byte_order byte_order_from_unary_expr(struct ctf_node *unary_expr)
{
const char *str;
- enum bt_ctf_byte_order bo = BT_CTF_BYTE_ORDER_UNKNOWN;
+ enum ctf_byte_order bo = -1;
if (unary_expr->u.unary_expression.type != UNARY_STRING) {
_BT_LOGE_NODE(unary_expr,
str = unary_expr->u.unary_expression.u.string;
if (!strcmp(str, "be") || !strcmp(str, "network")) {
- bo = BT_CTF_BYTE_ORDER_BIG_ENDIAN;
+ bo = CTF_BYTE_ORDER_BIG;
} else if (!strcmp(str, "le")) {
- bo = BT_CTF_BYTE_ORDER_LITTLE_ENDIAN;
+ bo = CTF_BYTE_ORDER_LITTLE;
} else if (!strcmp(str, "native")) {
- bo = BT_CTF_BYTE_ORDER_NATIVE;
+ bo = CTF_BYTE_ORDER_DEFAULT;
} else {
_BT_LOGE_NODE(unary_expr,
"Unexpected \"byte_order\" attribute value: "
}
static
-enum bt_ctf_byte_order get_real_byte_order(struct ctx *ctx,
- struct ctf_node *uexpr)
+enum ctf_byte_order get_real_byte_order(struct ctx *ctx,
+ struct ctf_node *uexpr)
{
- enum bt_ctf_byte_order bo = byte_order_from_unary_expr(uexpr);
+ enum ctf_byte_order bo = byte_order_from_unary_expr(uexpr);
- if (bo == BT_CTF_BYTE_ORDER_NATIVE) {
- bo = bt_ctf_trace_get_native_byte_order(ctx->trace);
+ if (bo == CTF_BYTE_ORDER_DEFAULT) {
+ bo = ctx->ctf_tc->default_byte_order;
}
return bo;
static
int is_align_valid(uint64_t align)
{
- return (align != 0) && !(align & (align - 1));
+ return (align != 0) && !(align & (align - UINT64_C(1)));
}
static
-int get_type_specifier_name(struct ctx *ctx, struct ctf_node *type_specifier,
- GString *str)
+int get_class_specifier_name(struct ctx *ctx, struct ctf_node *cls_specifier,
+ GString *str)
{
int ret = 0;
- if (type_specifier->type != NODE_TYPE_SPECIFIER) {
- _BT_LOGE_NODE(type_specifier,
+ if (cls_specifier->type != NODE_TYPE_SPECIFIER) {
+ _BT_LOGE_NODE(cls_specifier,
"Unexpected node type: node-type=%d",
- type_specifier->type);
+ cls_specifier->type);
ret = -EINVAL;
goto end;
}
- switch (type_specifier->u.type_specifier.type) {
+ switch (cls_specifier->u.field_class_specifier.type) {
case TYPESPEC_VOID:
g_string_append(str, "void");
break;
g_string_append(str, "const");
break;
case TYPESPEC_ID_TYPE:
- if (type_specifier->u.type_specifier.id_type) {
+ if (cls_specifier->u.field_class_specifier.id_type) {
g_string_append(str,
- type_specifier->u.type_specifier.id_type);
+ cls_specifier->u.field_class_specifier.id_type);
}
break;
case TYPESPEC_STRUCT:
{
- struct ctf_node *node = type_specifier->u.type_specifier.node;
+ struct ctf_node *node = cls_specifier->u.field_class_specifier.node;
if (!node->u._struct.name) {
- _BT_LOGE_NODE(node, "Unexpected empty structure field type name.");
+ _BT_LOGE_NODE(node, "Unexpected empty structure field class name.");
ret = -EINVAL;
goto end;
}
}
case TYPESPEC_VARIANT:
{
- struct ctf_node *node = type_specifier->u.type_specifier.node;
+ struct ctf_node *node = cls_specifier->u.field_class_specifier.node;
if (!node->u.variant.name) {
- _BT_LOGE_NODE(node, "Unexpected empty variant field type name.");
+ _BT_LOGE_NODE(node, "Unexpected empty variant field class name.");
ret = -EINVAL;
goto end;
}
}
case TYPESPEC_ENUM:
{
- struct ctf_node *node = type_specifier->u.type_specifier.node;
+ struct ctf_node *node = cls_specifier->u.field_class_specifier.node;
if (!node->u._enum.enum_id) {
_BT_LOGE_NODE(node,
- "Unexpected empty enumeration field type (`enum`) name.");
+ "Unexpected empty enumeration field class (`enum`) name.");
ret = -EINVAL;
goto end;
}
case TYPESPEC_INTEGER:
case TYPESPEC_STRING:
default:
- _BT_LOGE_NODE(type_specifier->u.type_specifier.node,
- "Unexpected type specifier type: %d",
- type_specifier->u.type_specifier.type);
+ _BT_LOGE_NODE(cls_specifier->u.field_class_specifier.node,
+ "Unexpected field class specifier type: %d",
+ cls_specifier->u.field_class_specifier.type);
ret = -EINVAL;
goto end;
}
}
static
-int get_type_specifier_list_name(struct ctx *ctx,
- struct ctf_node *type_specifier_list, GString *str)
+int get_class_specifier_list_name(struct ctx *ctx,
+ struct ctf_node *cls_specifier_list, GString *str)
{
int ret = 0;
struct ctf_node *iter;
int alias_item_nr = 0;
struct bt_list_head *head =
- &type_specifier_list->u.type_specifier_list.head;
+ &cls_specifier_list->u.field_class_specifier_list.head;
bt_list_for_each_entry(iter, head, siblings) {
if (alias_item_nr != 0) {
}
alias_item_nr++;
- ret = get_type_specifier_name(ctx, iter, str);
+ ret = get_class_specifier_name(ctx, iter, str);
if (ret) {
goto end;
}
}
static
-GQuark create_typealias_identifier(struct ctx *ctx,
- struct ctf_node *type_specifier_list,
- struct ctf_node *node_type_declarator)
+GQuark create_class_alias_identifier(struct ctx *ctx,
+ struct ctf_node *cls_specifier_list,
+ struct ctf_node *node_field_class_declarator)
{
int ret;
char *str_c;
GQuark qalias = 0;
struct ctf_node *iter;
struct bt_list_head *pointers =
- &node_type_declarator->u.type_declarator.pointers;
+ &node_field_class_declarator->u.field_class_declarator.pointers;
str = g_string_new("");
- ret = get_type_specifier_list_name(ctx, type_specifier_list, str);
+ ret = get_class_specifier_list_name(ctx, cls_specifier_list, str);
if (ret) {
g_string_free(str, TRUE);
goto end;
}
static
-int visit_type_declarator(struct ctx *ctx, struct ctf_node *type_specifier_list,
- GQuark *field_name, struct ctf_node *node_type_declarator,
- struct bt_ctf_field_type **field_decl,
- struct bt_ctf_field_type *nested_decl)
+int visit_field_class_declarator(struct ctx *ctx,
+ struct ctf_node *cls_specifier_list,
+ GQuark *field_name, struct ctf_node *node_field_class_declarator,
+ struct ctf_field_class **field_decl,
+ struct ctf_field_class *nested_decl)
{
/*
* During this whole function, nested_decl is always OURS,
* whereas field_decl is an output which we create, but
* belongs to the caller (it is moved).
*/
-
int ret = 0;
*field_decl = NULL;
- /* Validate type declarator node */
- if (node_type_declarator) {
- if (node_type_declarator->u.type_declarator.type ==
+ /* Validate field class declarator node */
+ if (node_field_class_declarator) {
+ if (node_field_class_declarator->u.field_class_declarator.type ==
TYPEDEC_UNKNOWN) {
- _BT_LOGE_NODE(node_type_declarator,
- "Unexpected type declarator type: type=%d",
- node_type_declarator->u.type_declarator.type);
+ _BT_LOGE_NODE(node_field_class_declarator,
+ "Unexpected field class declarator type: type=%d",
+ node_field_class_declarator->u.field_class_declarator.type);
ret = -EINVAL;
goto error;
}
/* TODO: GCC bitfields not supported yet */
- if (node_type_declarator->u.type_declarator.bitfield_len !=
+ if (node_field_class_declarator->u.field_class_declarator.bitfield_len !=
NULL) {
- _BT_LOGE_NODE(node_type_declarator,
+ _BT_LOGE_NODE(node_field_class_declarator,
"GCC bitfields are not supported as of this version.");
ret = -EPERM;
goto error;
/* Find the right nested declaration if not provided */
if (!nested_decl) {
struct bt_list_head *pointers =
- &node_type_declarator->u.type_declarator.pointers;
+ &node_field_class_declarator->u.field_class_declarator.pointers;
- if (node_type_declarator && !bt_list_empty(pointers)) {
+ if (node_field_class_declarator && !bt_list_empty(pointers)) {
GQuark qalias;
- _BT_CTF_FIELD_TYPE_INIT(nested_decl_copy);
/*
* If we have a pointer declarator, it HAS to
- * be present in the typealiases (else fail).
+ * be present in the field class aliases (else
+ * fail).
*/
- qalias = create_typealias_identifier(ctx,
- type_specifier_list, node_type_declarator);
+ qalias = create_class_alias_identifier(ctx,
+ cls_specifier_list, node_field_class_declarator);
nested_decl =
ctx_decl_scope_lookup_alias(ctx->current_scope,
- g_quark_to_string(qalias), -1);
+ g_quark_to_string(qalias), -1, true);
if (!nested_decl) {
- _BT_LOGE_NODE(node_type_declarator,
- "Cannot find type alias: name=\"%s\"",
+ _BT_LOGE_NODE(node_field_class_declarator,
+ "Cannot find class alias: name=\"%s\"",
g_quark_to_string(qalias));
ret = -EINVAL;
goto error;
}
- /* Make a copy of it */
- nested_decl_copy = bt_ctf_field_type_copy(nested_decl);
- BT_PUT(nested_decl);
- if (!nested_decl_copy) {
- _BT_LOGE_NODE(node_type_declarator,
- "Cannot copy nested field type.");
- ret = -EINVAL;
- goto error;
- }
-
- BT_MOVE(nested_decl, nested_decl_copy);
+ if (nested_decl->type == CTF_FIELD_CLASS_TYPE_INT) {
+ /* Pointer: force integer's base to 16 */
+ struct ctf_field_class_int *int_fc =
+ (void *) nested_decl;
- /* Force integer's base to 16 since it's a pointer */
- if (bt_ctf_field_type_is_integer(nested_decl)) {
- ret = bt_ctf_field_type_integer_set_base(
- nested_decl,
- BT_CTF_INTEGER_BASE_HEXADECIMAL);
- assert(ret == 0);
+ int_fc->disp_base =
+ BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL;
}
} else {
- ret = visit_type_specifier_list(ctx,
- type_specifier_list, &nested_decl);
+ ret = visit_field_class_specifier_list(ctx,
+ cls_specifier_list, &nested_decl);
if (ret) {
- assert(!nested_decl);
+ BT_ASSERT(!nested_decl);
goto error;
}
}
}
- assert(nested_decl);
+ BT_ASSERT(nested_decl);
- if (!node_type_declarator) {
- BT_MOVE(*field_decl, nested_decl);
+ if (!node_field_class_declarator) {
+ *field_decl = nested_decl;
+ nested_decl = NULL;
goto end;
}
- if (node_type_declarator->u.type_declarator.type == TYPEDEC_ID) {
- if (node_type_declarator->u.type_declarator.u.id) {
+ if (node_field_class_declarator->u.field_class_declarator.type == TYPEDEC_ID) {
+ if (node_field_class_declarator->u.field_class_declarator.u.id) {
const char *id =
- node_type_declarator->u.type_declarator.u.id;
+ node_field_class_declarator->u.field_class_declarator.u.id;
+
+ if (id[0] == '_') {
+ id++;
+ }
*field_name = g_quark_from_string(id);
} else {
*field_name = 0;
}
- BT_MOVE(*field_decl, nested_decl);
+ *field_decl = nested_decl;
+ nested_decl = NULL;
goto end;
} else {
struct ctf_node *first;
- _BT_CTF_FIELD_TYPE_INIT(decl);
- _BT_CTF_FIELD_TYPE_INIT(outer_field_decl);
+ struct ctf_field_class *decl = NULL;
+ struct ctf_field_class *outer_field_decl = NULL;
struct bt_list_head *length =
- &node_type_declarator->
- u.type_declarator.u.nested.length;
+ &node_field_class_declarator->
+ u.field_class_declarator.u.nested.length;
/* Create array/sequence, pass nested_decl as child */
if (bt_list_empty(length)) {
- _BT_LOGE_NODE(node_type_declarator,
+ _BT_LOGE_NODE(node_field_class_declarator,
"Expecting length field reference or value.");
ret = -EINVAL;
goto error;
switch (first->u.unary_expression.type) {
case UNARY_UNSIGNED_CONSTANT:
{
- size_t len;
- _BT_CTF_FIELD_TYPE_INIT(array_decl);
-
- len = first->u.unary_expression.u.unsigned_constant;
- array_decl = bt_ctf_field_type_array_create(nested_decl,
- len);
- BT_PUT(nested_decl);
- if (!array_decl) {
- _BT_LOGE_NODE(first,
- "Cannot create array field type.");
- ret = -ENOMEM;
- goto error;
- }
-
- BT_MOVE(decl, array_decl);
+ struct ctf_field_class_array *array_decl = NULL;
+
+ array_decl = ctf_field_class_array_create();
+ BT_ASSERT(array_decl);
+ array_decl->length =
+ first->u.unary_expression.u.unsigned_constant;
+ array_decl->base.elem_fc = nested_decl;
+ nested_decl = NULL;
+ decl = (void *) array_decl;
break;
}
case UNARY_STRING:
{
/* Lookup unsigned integer definition, create seq. */
- _BT_CTF_FIELD_TYPE_INIT(seq_decl);
+ struct ctf_field_class_sequence *seq_decl = NULL;
char *length_name = concatenate_unary_strings(length);
if (!length_name) {
- _BT_LOGE_NODE(node_type_declarator,
+ _BT_LOGE_NODE(node_field_class_declarator,
"Cannot concatenate unary strings.");
ret = -EINVAL;
goto error;
}
- seq_decl = bt_ctf_field_type_sequence_create(
- nested_decl, length_name);
- g_free(length_name);
- BT_PUT(nested_decl);
- if (!seq_decl) {
- _BT_LOGE_NODE(node_type_declarator,
- "Cannot create sequence field type.");
- ret = -ENOMEM;
- goto error;
+ if (strncmp(length_name, "env.", 4) == 0) {
+ /* This is, in fact, an array */
+ const char *env_entry_name = &length_name[4];
+ struct ctf_trace_class_env_entry *env_entry =
+ ctf_trace_class_borrow_env_entry_by_name(
+ ctx->ctf_tc, env_entry_name);
+ struct ctf_field_class_array *array_decl;
+
+ if (!env_entry) {
+ _BT_LOGE_NODE(node_field_class_declarator,
+ "Cannot find environment entry: "
+ "name=\"%s\"", env_entry_name);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (env_entry->type != CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT) {
+ _BT_LOGE_NODE(node_field_class_declarator,
+ "Wrong environment entry type "
+ "(expecting integer): "
+ "name=\"%s\"", env_entry_name);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (env_entry->value.i < 0) {
+ _BT_LOGE_NODE(node_field_class_declarator,
+ "Invalid, negative array length: "
+ "env-entry-name=\"%s\", "
+ "value=%" PRId64,
+ env_entry_name,
+ env_entry->value.i);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ array_decl = ctf_field_class_array_create();
+ BT_ASSERT(array_decl);
+ array_decl->length =
+ (uint64_t) env_entry->value.i;
+ array_decl->base.elem_fc = nested_decl;
+ nested_decl = NULL;
+ decl = (void *) array_decl;
+ } else {
+ char *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 = ctf_field_class_sequence_create();
+ BT_ASSERT(seq_decl);
+ seq_decl->base.elem_fc = nested_decl;
+ nested_decl = NULL;
+ g_string_assign(seq_decl->length_ref,
+ length_name_no_underscore);
+ free(length_name_no_underscore);
+ decl = (void *) seq_decl;
}
- BT_MOVE(decl, seq_decl);
+ g_free(length_name);
break;
}
default:
goto error;
}
- assert(!nested_decl);
- assert(decl);
- assert(!*field_decl);
+ BT_ASSERT(!nested_decl);
+ BT_ASSERT(decl);
+ BT_ASSERT(!*field_decl);
/*
* At this point, we found the next nested declaration.
* nested declaration as the content of the outer
* container, MOVING its ownership.
*/
- ret = visit_type_declarator(ctx, type_specifier_list,
+ ret = visit_field_class_declarator(ctx, cls_specifier_list,
field_name,
- node_type_declarator->
- u.type_declarator.u.nested.type_declarator,
+ node_field_class_declarator->
+ u.field_class_declarator.u.nested.field_class_declarator,
&outer_field_decl, decl);
decl = NULL;
if (ret) {
- assert(!outer_field_decl);
+ BT_ASSERT(!outer_field_decl);
ret = -EINVAL;
goto error;
}
- assert(outer_field_decl);
- BT_MOVE(*field_decl, outer_field_decl);
+ BT_ASSERT(outer_field_decl);
+ *field_decl = outer_field_decl;
+ outer_field_decl = NULL;
}
-end:
- BT_PUT(nested_decl);
- assert(*field_decl);
-
- return 0;
+ BT_ASSERT(*field_decl);
+ goto end;
error:
- BT_PUT(nested_decl);
- BT_PUT(*field_decl);
+ ctf_field_class_destroy(*field_decl);
+ *field_decl = NULL;
+
+ if (ret >= 0) {
+ ret = -1;
+ }
+end:
+ ctf_field_class_destroy(nested_decl);
+ nested_decl = NULL;
return ret;
}
static
int visit_struct_decl_field(struct ctx *ctx,
- struct bt_ctf_field_type *struct_decl,
- struct ctf_node *type_specifier_list,
- struct bt_list_head *type_declarators)
+ struct ctf_field_class_struct *struct_decl,
+ struct ctf_node *cls_specifier_list,
+ struct bt_list_head *field_class_declarators)
{
int ret = 0;
struct ctf_node *iter;
- _BT_CTF_FIELD_TYPE_INIT(field_decl);
+ struct ctf_field_class *field_decl = NULL;
- bt_list_for_each_entry(iter, type_declarators, siblings) {
+ bt_list_for_each_entry(iter, field_class_declarators, siblings) {
field_decl = NULL;
GQuark qfield_name;
const char *field_name;
- _BT_CTF_FIELD_TYPE_INIT(efield_decl);
- ret = visit_type_declarator(ctx, type_specifier_list,
+ ret = visit_field_class_declarator(ctx, cls_specifier_list,
&qfield_name, iter, &field_decl, NULL);
if (ret) {
- assert(!field_decl);
- _BT_LOGE_NODE(type_specifier_list,
- "Cannot visit type declarator: ret=%d", ret);
+ BT_ASSERT(!field_decl);
+ _BT_LOGE_NODE(cls_specifier_list,
+ "Cannot visit field class declarator: ret=%d", ret);
goto error;
}
- assert(field_decl);
+ BT_ASSERT(field_decl);
field_name = g_quark_to_string(qfield_name);
/* Check if field with same name already exists */
- efield_decl =
- bt_ctf_field_type_structure_get_field_type_by_name(
- struct_decl, field_name);
- if (efield_decl) {
- BT_PUT(efield_decl);
- _BT_LOGE_NODE(type_specifier_list,
- "Duplicate field in structure field type: "
+ if (ctf_field_class_struct_borrow_member_by_name(
+ struct_decl, field_name)) {
+ _BT_LOGE_NODE(cls_specifier_list,
+ "Duplicate field in structure field class: "
"field-name=\"%s\"", field_name);
ret = -EINVAL;
goto error;
}
/* Add field to structure */
- ret = bt_ctf_field_type_structure_add_field(struct_decl,
- field_decl, field_name);
- BT_PUT(field_decl);
- if (ret) {
- _BT_LOGE_NODE(type_specifier_list,
- "Cannot add field to structure field type: "
- "field-name=\"%s\", ret=%d",
- g_quark_to_string(qfield_name), ret);
- goto error;
- }
+ ctf_field_class_struct_append_member(struct_decl,
+ field_name, field_decl);
+ field_decl = NULL;
}
return 0;
error:
- BT_PUT(field_decl);
-
+ ctf_field_class_destroy(field_decl);
+ field_decl = NULL;
return ret;
}
static
int visit_variant_decl_field(struct ctx *ctx,
- struct bt_ctf_field_type *variant_decl,
- struct ctf_node *type_specifier_list,
- struct bt_list_head *type_declarators)
+ struct ctf_field_class_variant *variant_decl,
+ struct ctf_node *cls_specifier_list,
+ struct bt_list_head *field_class_declarators)
{
int ret = 0;
struct ctf_node *iter;
- _BT_CTF_FIELD_TYPE_INIT(field_decl);
+ struct ctf_field_class *field_decl = NULL;
- bt_list_for_each_entry(iter, type_declarators, siblings) {
+ bt_list_for_each_entry(iter, field_class_declarators, siblings) {
field_decl = NULL;
GQuark qfield_name;
const char *field_name;
- _BT_CTF_FIELD_TYPE_INIT(efield_decl);
- ret = visit_type_declarator(ctx, type_specifier_list,
+ ret = visit_field_class_declarator(ctx, cls_specifier_list,
&qfield_name, iter, &field_decl, NULL);
if (ret) {
- assert(!field_decl);
- _BT_LOGE_NODE(type_specifier_list,
- "Cannot visit type declarator: ret=%d", ret);
+ BT_ASSERT(!field_decl);
+ _BT_LOGE_NODE(cls_specifier_list,
+ "Cannot visit field class declarator: ret=%d", ret);
goto error;
}
- assert(field_decl);
+ BT_ASSERT(field_decl);
field_name = g_quark_to_string(qfield_name);
/* Check if field with same name already exists */
- efield_decl =
- bt_ctf_field_type_variant_get_field_type_by_name(
- variant_decl, field_name);
- if (efield_decl) {
- BT_PUT(efield_decl);
- _BT_LOGE_NODE(type_specifier_list,
- "Duplicate field in variant field type: "
+ if (ctf_field_class_variant_borrow_option_by_name(
+ variant_decl, field_name)) {
+ _BT_LOGE_NODE(cls_specifier_list,
+ "Duplicate field in variant field class: "
"field-name=\"%s\"", field_name);
ret = -EINVAL;
goto error;
}
/* Add field to structure */
- ret = bt_ctf_field_type_variant_add_field(variant_decl,
- field_decl, field_name);
- BT_PUT(field_decl);
- if (ret) {
- _BT_LOGE_NODE(type_specifier_list,
- "Cannot add field to variant field type: "
- "field-name=\"%s\", ret=%d",
- g_quark_to_string(qfield_name), ret);
- goto error;
- }
+ ctf_field_class_variant_append_option(variant_decl,
+ field_name, field_decl);
+ field_decl = NULL;
}
return 0;
error:
- BT_PUT(field_decl);
-
+ ctf_field_class_destroy(field_decl);
+ field_decl = NULL;
return ret;
}
static
-int visit_typedef(struct ctx *ctx, struct ctf_node *type_specifier_list,
- struct bt_list_head *type_declarators)
+int visit_field_class_def(struct ctx *ctx, struct ctf_node *cls_specifier_list,
+ struct bt_list_head *field_class_declarators)
{
int ret = 0;
GQuark qidentifier;
struct ctf_node *iter;
- _BT_CTF_FIELD_TYPE_INIT(type_decl);
+ struct ctf_field_class *class_decl = NULL;
- bt_list_for_each_entry(iter, type_declarators, siblings) {
- ret = visit_type_declarator(ctx, type_specifier_list,
- &qidentifier, iter, &type_decl, NULL);
+ bt_list_for_each_entry(iter, field_class_declarators, siblings) {
+ ret = visit_field_class_declarator(ctx, cls_specifier_list,
+ &qidentifier, iter, &class_decl, NULL);
if (ret) {
_BT_LOGE_NODE(iter,
- "Cannot visit type declarator: ret=%d", ret);
+ "Cannot visit field class declarator: ret=%d", ret);
ret = -EINVAL;
goto end;
}
- /* 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)) {
+ /* Do not allow field class def and alias of untagged variants */
+ if (class_decl->type == CTF_FIELD_CLASS_TYPE_VARIANT) {
+ struct ctf_field_class_variant *var_fc =
+ (void *) class_decl;
+
+ if (var_fc->tag_path.path->len == 0) {
_BT_LOGE_NODE(iter,
- "Type definition of untagged variant field type is not allowed.");
+ "Type definition of untagged variant field class is not allowed.");
ret = -EPERM;
goto end;
}
}
ret = ctx_decl_scope_register_alias(ctx->current_scope,
- g_quark_to_string(qidentifier), type_decl);
+ g_quark_to_string(qidentifier), class_decl);
if (ret) {
_BT_LOGE_NODE(iter,
- "Cannot register type definition: name=\"%s\"",
+ "Cannot register field class alias: name=\"%s\"",
g_quark_to_string(qidentifier));
goto end;
}
}
end:
- BT_PUT(type_decl);
-
+ ctf_field_class_destroy(class_decl);
+ class_decl = NULL;
return ret;
}
static
-int visit_typealias(struct ctx *ctx, struct ctf_node *target,
- struct ctf_node *alias)
+int visit_field_class_alias(struct ctx *ctx, struct ctf_node *target,
+ struct ctf_node *alias)
{
int ret = 0;
GQuark qalias;
struct ctf_node *node;
GQuark qdummy_field_name;
- _BT_CTF_FIELD_TYPE_INIT(type_decl);
+ struct ctf_field_class *class_decl = NULL;
- /* Create target type declaration */
- if (bt_list_empty(&target->u.typealias_target.type_declarators)) {
+ /* Create target field class */
+ if (bt_list_empty(&target->u.field_class_alias_target.field_class_declarators)) {
node = NULL;
} else {
node = _BT_LIST_FIRST_ENTRY(
- &target->u.typealias_target.type_declarators,
+ &target->u.field_class_alias_target.field_class_declarators,
struct ctf_node, siblings);
}
- ret = visit_type_declarator(ctx,
- target->u.typealias_target.type_specifier_list,
- &qdummy_field_name, node, &type_decl, NULL);
+ ret = visit_field_class_declarator(ctx,
+ target->u.field_class_alias_target.field_class_specifier_list,
+ &qdummy_field_name, node, &class_decl, NULL);
if (ret) {
- assert(!type_decl);
+ BT_ASSERT(!class_decl);
_BT_LOGE_NODE(node,
- "Cannot visit type declarator: ret=%d", ret);
+ "Cannot visit field class declarator: ret=%d", ret);
goto end;
}
- /* 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,
- "Type definition of untagged variant field type is not allowed.");
+ /* Do not allow field class def and alias of untagged variants */
+ if (class_decl->type == CTF_FIELD_CLASS_TYPE_VARIANT) {
+ struct ctf_field_class_variant *var_fc = (void *) class_decl;
+
+ if (var_fc->tag_path.path->len == 0) {
+ _BT_LOGE_NODE(target,
+ "Type definition of untagged variant field class 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;
}
/* Create alias identifier */
- node = _BT_LIST_FIRST_ENTRY(&alias->u.typealias_alias.type_declarators,
+ node = _BT_LIST_FIRST_ENTRY(&alias->u.field_class_alias_name.field_class_declarators,
struct ctf_node, siblings);
- qalias = create_typealias_identifier(ctx,
- alias->u.typealias_alias.type_specifier_list, node);
+ qalias = create_class_alias_identifier(ctx,
+ alias->u.field_class_alias_name.field_class_specifier_list, node);
ret = ctx_decl_scope_register_alias(ctx->current_scope,
- g_quark_to_string(qalias), type_decl);
+ g_quark_to_string(qalias), class_decl);
if (ret) {
_BT_LOGE_NODE(node,
- "Cannot register type alias: name=\"%s\"",
+ "Cannot register class alias: name=\"%s\"",
g_quark_to_string(qalias));
goto end;
}
end:
- BT_PUT(type_decl);
-
+ ctf_field_class_destroy(class_decl);
+ class_decl = NULL;
return ret;
}
static
int visit_struct_decl_entry(struct ctx *ctx, struct ctf_node *entry_node,
- struct bt_ctf_field_type *struct_decl)
+ struct ctf_field_class_struct *struct_decl)
{
int ret = 0;
switch (entry_node->type) {
case NODE_TYPEDEF:
- ret = visit_typedef(ctx,
- entry_node->u._typedef.type_specifier_list,
- &entry_node->u._typedef.type_declarators);
+ ret = visit_field_class_def(ctx,
+ entry_node->u.field_class_def.field_class_specifier_list,
+ &entry_node->u.field_class_def.field_class_declarators);
if (ret) {
_BT_LOGE_NODE(entry_node,
- "Cannot add type definition found in structure field type: ret=%d",
+ "Cannot add field class found in structure field class: ret=%d",
ret);
goto end;
}
break;
case NODE_TYPEALIAS:
- ret = visit_typealias(ctx, entry_node->u.typealias.target,
- entry_node->u.typealias.alias);
+ ret = visit_field_class_alias(ctx, entry_node->u.field_class_alias.target,
+ entry_node->u.field_class_alias.alias);
if (ret) {
_BT_LOGE_NODE(entry_node,
- "Cannot add type alias found in structure field type: ret=%d",
+ "Cannot add field class alias found in structure field class: ret=%d",
ret);
goto end;
}
/* Field */
ret = visit_struct_decl_field(ctx, struct_decl,
entry_node->u.struct_or_variant_declaration.
- type_specifier_list,
+ field_class_specifier_list,
&entry_node->u.struct_or_variant_declaration.
- type_declarators);
+ field_class_declarators);
if (ret) {
goto end;
}
static
int visit_variant_decl_entry(struct ctx *ctx, struct ctf_node *entry_node,
- struct bt_ctf_field_type *variant_decl)
+ struct ctf_field_class_variant *variant_decl)
{
int ret = 0;
switch (entry_node->type) {
case NODE_TYPEDEF:
- ret = visit_typedef(ctx,
- entry_node->u._typedef.type_specifier_list,
- &entry_node->u._typedef.type_declarators);
+ ret = visit_field_class_def(ctx,
+ entry_node->u.field_class_def.field_class_specifier_list,
+ &entry_node->u.field_class_def.field_class_declarators);
if (ret) {
_BT_LOGE_NODE(entry_node,
- "Cannot add type definition found in variant field type: ret=%d",
+ "Cannot add field class found in variant field class: ret=%d",
ret);
goto end;
}
break;
case NODE_TYPEALIAS:
- ret = visit_typealias(ctx, entry_node->u.typealias.target,
- entry_node->u.typealias.alias);
+ ret = visit_field_class_alias(ctx, entry_node->u.field_class_alias.target,
+ entry_node->u.field_class_alias.alias);
if (ret) {
_BT_LOGE_NODE(entry_node,
- "Cannot add type alias found in variant field type: ret=%d",
+ "Cannot add field class alias found in variant field class: ret=%d",
ret);
goto end;
}
/* Field */
ret = visit_variant_decl_field(ctx, variant_decl,
entry_node->u.struct_or_variant_declaration.
- type_specifier_list,
+ field_class_specifier_list,
&entry_node->u.struct_or_variant_declaration.
- type_declarators);
+ field_class_declarators);
if (ret) {
goto end;
}
static
int visit_struct_decl(struct ctx *ctx, const char *name,
- struct bt_list_head *decl_list, int has_body,
- struct bt_list_head *min_align,
- struct bt_ctf_field_type **struct_decl)
+ struct bt_list_head *decl_list, int has_body,
+ struct bt_list_head *min_align,
+ struct ctf_field_class_struct **struct_decl)
{
int ret = 0;
+ BT_ASSERT(struct_decl);
*struct_decl = NULL;
/* For named struct (without body), lookup in declaration scope */
if (!has_body) {
- _BT_CTF_FIELD_TYPE_INIT(struct_decl_copy);
-
if (!name) {
- BT_LOGE_STR("Bodyless structure field type: missing name.");
+ BT_LOGE_STR("Bodyless structure field class: missing name.");
ret = -EPERM;
goto error;
}
*struct_decl = ctx_decl_scope_lookup_struct(ctx->current_scope,
- name, -1);
+ name, -1, true);
if (!*struct_decl) {
- BT_LOGE("Cannot find structure field type: name=\"struct %s\"",
+ BT_LOGE("Cannot find structure field class: name=\"struct %s\"",
name);
ret = -EINVAL;
goto error;
}
-
- /* Make a copy of it */
- struct_decl_copy = bt_ctf_field_type_copy(*struct_decl);
- if (!struct_decl_copy) {
- BT_LOGE_STR("Cannot create copy of structure field type.");
- ret = -EINVAL;
- goto error;
- }
-
- BT_MOVE(*struct_decl, struct_decl_copy);
} else {
struct ctf_node *entry_node;
uint64_t min_align_value = 0;
if (name) {
- _BT_CTF_FIELD_TYPE_INIT(estruct_decl);
-
- estruct_decl = ctx_decl_scope_lookup_struct(
- ctx->current_scope, name, 1);
- if (estruct_decl) {
- BT_PUT(estruct_decl);
- BT_LOGE("Structure field type already declared in local scope: "
+ if (ctx_decl_scope_lookup_struct(
+ ctx->current_scope, name, 1, false)) {
+ BT_LOGE("Structure field class already declared in local scope: "
"name=\"struct %s\"", name);
ret = -EINVAL;
goto error;
if (!bt_list_empty(min_align)) {
ret = get_unary_unsigned(min_align, &min_align_value);
if (ret) {
- BT_LOGE("Unexpected unary expression for structure field type's `align` attribute: "
+ BT_LOGE("Unexpected unary expression for structure field class's `align` attribute: "
"ret=%d", ret);
goto error;
}
}
- *struct_decl = bt_ctf_field_type_structure_create();
- if (!*struct_decl) {
- BT_LOGE_STR("Cannot create empty structure field type.");
- ret = -ENOMEM;
- goto error;
- }
+ *struct_decl = ctf_field_class_struct_create();
+ BT_ASSERT(*struct_decl);
if (min_align_value != 0) {
- ret = bt_ctf_field_type_set_alignment(*struct_decl,
- min_align_value);
- if (ret) {
- BT_LOGE("Cannot set structure field type's alignment: "
- "ret=%d", ret);
- goto error;
- }
+ (*struct_decl)->base.alignment = min_align_value;
}
- ret = ctx_push_scope(ctx);
- if (ret) {
- BT_LOGE_STR("Cannot push scope.");
- goto error;
- }
+ _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
bt_list_for_each_entry(entry_node, decl_list, siblings) {
ret = visit_struct_decl_entry(ctx, entry_node,
*struct_decl);
if (ret) {
_BT_LOGE_NODE(entry_node,
- "Cannot visit structure field type entry: "
+ "Cannot visit structure field class entry: "
"ret=%d", ret);
ctx_pop_scope(ctx);
goto error;
ret = ctx_decl_scope_register_struct(ctx->current_scope,
name, *struct_decl);
if (ret) {
- BT_LOGE("Cannot register structure field type in declaration scope: "
+ BT_LOGE("Cannot register structure field class in declaration scope: "
"name=\"struct %s\", ret=%d", name, ret);
goto error;
}
return 0;
error:
- BT_PUT(*struct_decl);
-
+ ctf_field_class_destroy((void *) *struct_decl);
+ *struct_decl = NULL;
return ret;
}
static
int visit_variant_decl(struct ctx *ctx, const char *name,
const char *tag, struct bt_list_head *decl_list,
- int has_body, struct bt_ctf_field_type **variant_decl)
+ int has_body, struct ctf_field_class_variant **variant_decl)
{
int ret = 0;
- _BT_CTF_FIELD_TYPE_INIT(untagged_variant_decl);
+ struct ctf_field_class_variant *untagged_variant_decl = NULL;
+ BT_ASSERT(variant_decl);
*variant_decl = NULL;
/* For named variant (without body), lookup in declaration scope */
if (!has_body) {
- _BT_CTF_FIELD_TYPE_INIT(variant_decl_copy);
-
if (!name) {
- BT_LOGE_STR("Bodyless variant field type: missing name.");
+ BT_LOGE_STR("Bodyless variant field class: missing name.");
ret = -EPERM;
goto error;
}
untagged_variant_decl =
ctx_decl_scope_lookup_variant(ctx->current_scope,
- name, -1);
+ name, -1, true);
if (!untagged_variant_decl) {
- BT_LOGE("Cannot find variant field type: name=\"variant %s\"",
+ BT_LOGE("Cannot find variant field class: name=\"variant %s\"",
name);
ret = -EINVAL;
goto error;
}
-
- /* Make a copy of it */
- variant_decl_copy = bt_ctf_field_type_copy(
- untagged_variant_decl);
- if (!variant_decl_copy) {
- BT_LOGE_STR("Cannot create copy of variant field type.");
- ret = -EINVAL;
- goto error;
- }
-
- BT_MOVE(untagged_variant_decl, variant_decl_copy);
} else {
struct ctf_node *entry_node;
if (name) {
- struct bt_ctf_field_type *evariant_decl =
- ctx_decl_scope_lookup_struct(ctx->current_scope,
- name, 1);
-
- if (evariant_decl) {
- BT_PUT(evariant_decl);
- BT_LOGE("Variant field type already declared in local scope: "
+ if (ctx_decl_scope_lookup_variant(ctx->current_scope,
+ name, 1, false)) {
+ BT_LOGE("Variant field class already declared in local scope: "
"name=\"variant %s\"", name);
ret = -EINVAL;
goto error;
}
}
- untagged_variant_decl = bt_ctf_field_type_variant_create(NULL,
- NULL);
- if (!untagged_variant_decl) {
- BT_LOGE_STR("Cannot create empty variant field type.");
- ret = -ENOMEM;
- goto error;
- }
-
- ret = ctx_push_scope(ctx);
- if (ret) {
- BT_LOGE_STR("Cannot push scope.");
- goto error;
- }
+ untagged_variant_decl = ctf_field_class_variant_create();
+ BT_ASSERT(untagged_variant_decl);
+ _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
bt_list_for_each_entry(entry_node, decl_list, siblings) {
ret = visit_variant_decl_entry(ctx, entry_node,
untagged_variant_decl);
if (ret) {
_BT_LOGE_NODE(entry_node,
- "Cannot visit variant field type entry: "
+ "Cannot visit variant field class entry: "
"ret=%d", ret);
ctx_pop_scope(ctx);
goto error;
ctx->current_scope, name,
untagged_variant_decl);
if (ret) {
- BT_LOGE("Cannot register variant field type in declaration scope: "
+ BT_LOGE("Cannot register variant field class in declaration scope: "
"name=\"variant %s\", ret=%d", name, ret);
goto error;
}
* return untagged variant.
*/
if (!tag) {
- BT_MOVE(*variant_decl, untagged_variant_decl);
+ *variant_decl = untagged_variant_decl;
+ untagged_variant_decl = NULL;
} else {
/*
* At this point, we have a fresh untagged variant; nobody
* else owns it. Set its tag now.
*/
- ret = bt_ctf_field_type_variant_set_tag_name(
- untagged_variant_decl, tag);
- if (ret) {
- BT_LOGE("Cannot set variant field type's tag name: "
- "tag-name=\"%s\"", tag);
+ char *tag_no_underscore =
+ remove_underscores_from_field_ref(tag);
+
+ if (!tag_no_underscore) {
+ /* remove_underscores_from_field_ref() logs errors */
goto error;
}
- BT_MOVE(*variant_decl, untagged_variant_decl);
+ g_string_assign(untagged_variant_decl->tag_ref,
+ tag_no_underscore);
+ free(tag_no_underscore);
+ *variant_decl = untagged_variant_decl;
+ untagged_variant_decl = NULL;
}
- assert(!untagged_variant_decl);
- assert(*variant_decl);
-
+ BT_ASSERT(!untagged_variant_decl);
+ BT_ASSERT(*variant_decl);
return 0;
error:
- BT_PUT(untagged_variant_decl);
- BT_PUT(*variant_decl);
-
+ ctf_field_class_destroy((void *) untagged_variant_decl);
+ untagged_variant_decl = NULL;
+ ctf_field_class_destroy((void *) *variant_decl);
+ *variant_decl = NULL;
return ret;
}
+struct uori {
+ bool is_signed;
+ union {
+ uint64_t u;
+ uint64_t i;
+ } value;
+};
+
static
int visit_enum_decl_entry(struct ctx *ctx, struct ctf_node *enumerator,
- struct bt_ctf_field_type *enum_decl, int64_t *last, int is_signed)
+ struct ctf_field_class_enum *enum_decl, struct uori *last)
{
int ret = 0;
int nr_vals = 0;
struct ctf_node *iter;
- int64_t start = 0, end = 0;
+ struct uori start = {
+ .is_signed = false,
+ .value.u = 0,
+ };
+ struct uori end = {
+ .is_signed = false,
+ .value.u = 0,
+ };
const char *label = enumerator->u.enumerator.id;
+ const char *effective_label = label;
struct bt_list_head *values = &enumerator->u.enumerator.values;
bt_list_for_each_entry(iter, values, siblings) {
- int64_t *target;
+ struct uori *target;
if (iter->type != NODE_UNARY_EXPRESSION) {
_BT_LOGE_NODE(iter,
- "Wrong expression for enumeration field type label: "
+ "Wrong expression for enumeration field class label: "
"node-type=%d, label=\"%s\"", iter->type,
label);
ret = -EINVAL;
switch (iter->u.unary_expression.type) {
case UNARY_SIGNED_CONSTANT:
- *target = iter->u.unary_expression.u.signed_constant;
+ target->is_signed = true;
+ target->value.i =
+ iter->u.unary_expression.u.signed_constant;
break;
case UNARY_UNSIGNED_CONSTANT:
- *target = (int64_t)
+ target->is_signed = false;
+ target->value.u =
iter->u.unary_expression.u.unsigned_constant;
break;
default:
_BT_LOGE_NODE(iter,
- "Invalid enumeration field type entry: "
+ "Invalid enumeration field class entry: "
"expecting constant signed or unsigned integer: "
"node-type=%d, label=\"%s\"",
iter->u.unary_expression.type, label);
if (nr_vals > 1) {
_BT_LOGE_NODE(iter,
- "Invalid enumeration field type entry: label=\"%s\"",
+ "Invalid enumeration field class entry: label=\"%s\"",
label);
ret = -EINVAL;
goto error;
end = start;
}
- *last = end + 1;
-
- if (is_signed) {
- ret = bt_ctf_field_type_enumeration_add_mapping(enum_decl, label,
- start, end);
+ if (end.is_signed) {
+ last->value.i = end.value.i + 1;
} else {
- ret = bt_ctf_field_type_enumeration_add_mapping_unsigned(enum_decl,
- label, (uint64_t) start, (uint64_t) end);
+ last->value.u = end.value.u + 1;
}
- if (ret) {
- _BT_LOGE_NODE(enumerator,
- "Cannot add mapping to enumeration field type: "
- "label=\"%s\", ret=%d, "
- "start-value-unsigned=%" PRIu64 ", "
- "end-value-unsigned=%" PRIu64, label, ret,
- (uint64_t) start, (uint64_t) end);
- goto error;
+
+ if (label[0] == '_') {
+ /*
+ * Strip the first underscore of any enumeration field
+ * class's label in case this enumeration FC is used as
+ * a variant FC tag later. The variant FC choice names
+ * could also start with `_`, in which case the prefix
+ * is removed, and it the resulting choice name needs to
+ * match tag labels.
+ */
+ effective_label = &label[1];
}
+ ctf_field_class_enum_append_mapping(enum_decl, effective_label,
+ start.value.u, end.value.u);
return 0;
error:
static
int visit_enum_decl(struct ctx *ctx, const char *name,
- struct ctf_node *container_type,
- struct bt_list_head *enumerator_list,
- int has_body,
- struct bt_ctf_field_type **enum_decl)
+ struct ctf_node *container_cls,
+ struct bt_list_head *enumerator_list,
+ int has_body, struct ctf_field_class_enum **enum_decl)
{
int ret = 0;
GQuark qdummy_id;
- _BT_CTF_FIELD_TYPE_INIT(integer_decl);
+ struct ctf_field_class_int *integer_decl = NULL;
+ BT_ASSERT(enum_decl);
*enum_decl = NULL;
/* For named enum (without body), lookup in declaration scope */
if (!has_body) {
- _BT_CTF_FIELD_TYPE_INIT(enum_decl_copy);
-
if (!name) {
- BT_LOGE_STR("Bodyless enumeration field type: missing name.");
+ BT_LOGE_STR("Bodyless enumeration field class: missing name.");
ret = -EPERM;
goto error;
}
*enum_decl = ctx_decl_scope_lookup_enum(ctx->current_scope,
- name, -1);
+ name, -1, true);
if (!*enum_decl) {
- BT_LOGE("Cannot find enumeration field type: "
+ BT_LOGE("Cannot find enumeration field class: "
"name=\"enum %s\"", name);
ret = -EINVAL;
goto error;
}
-
- /* Make a copy of it */
- enum_decl_copy = bt_ctf_field_type_copy(*enum_decl);
- if (!enum_decl_copy) {
- BT_LOGE_STR("Cannot create copy of enumeration field type.");
- ret = -EINVAL;
- goto error;
- }
-
- BT_PUT(*enum_decl);
- BT_MOVE(*enum_decl, enum_decl_copy);
} else {
struct ctf_node *iter;
- int64_t last_value = 0;
+ struct uori last_value = {
+ .is_signed = false,
+ .value.u = 0,
+ };
if (name) {
- _BT_CTF_FIELD_TYPE_INIT(eenum_decl);
-
- eenum_decl = ctx_decl_scope_lookup_enum(
- ctx->current_scope, name, 1);
- if (eenum_decl) {
- BT_PUT(eenum_decl);
- BT_LOGE("Enumeration field type already declared in local scope: "
+ if (ctx_decl_scope_lookup_enum(ctx->current_scope,
+ name, 1, false)) {
+ BT_LOGE("Enumeration field class already declared in local scope: "
"name=\"enum %s\"", name);
ret = -EINVAL;
goto error;
}
}
- if (!container_type) {
- integer_decl = ctx_decl_scope_lookup_alias(
- ctx->current_scope, "int", -1);
+ if (!container_cls) {
+ integer_decl = (void *) ctx_decl_scope_lookup_alias(
+ ctx->current_scope, "int", -1, true);
if (!integer_decl) {
- BT_LOGE_STR("Cannot find implicit `int` field type alias for enumeration field type.");
+ BT_LOGE_STR("Cannot find implicit `int` field class alias for enumeration field class.");
ret = -EINVAL;
goto error;
}
} else {
- ret = visit_type_declarator(ctx, container_type,
- &qdummy_id, NULL, &integer_decl, NULL);
+ ret = visit_field_class_declarator(ctx, container_cls,
+ &qdummy_id, NULL, (void *) &integer_decl,
+ NULL);
if (ret) {
- assert(!integer_decl);
+ BT_ASSERT(!integer_decl);
ret = -EINVAL;
goto error;
}
}
- assert(integer_decl);
+ BT_ASSERT(integer_decl);
- if (!bt_ctf_field_type_is_integer(integer_decl)) {
- BT_LOGE("Container field type for enumeration field type is not an integer field type: "
- "ft-id=%s",
- bt_ctf_field_type_id_string(
- bt_ctf_field_type_get_type_id(integer_decl)));
+ if (integer_decl->base.base.type != CTF_FIELD_CLASS_TYPE_INT) {
+ BT_LOGE("Container field class for enumeration field class is not an integer field class: "
+ "fc-type=%d", integer_decl->base.base.type);
ret = -EINVAL;
goto error;
}
- *enum_decl = bt_ctf_field_type_enumeration_create(integer_decl);
- if (!*enum_decl) {
- BT_LOGE_STR("Cannot create enumeration field type.");
- ret = -ENOMEM;
- goto error;
- }
+ *enum_decl = ctf_field_class_enum_create();
+ BT_ASSERT(*enum_decl);
+ (*enum_decl)->base.base.base.alignment =
+ integer_decl->base.base.alignment;
+ ctf_field_class_int_copy_content((void *) *enum_decl,
+ (void *) integer_decl);
+ last_value.is_signed = (*enum_decl)->base.is_signed;
bt_list_for_each_entry(iter, enumerator_list, siblings) {
ret = visit_enum_decl_entry(ctx, iter, *enum_decl,
- &last_value,
- bt_ctf_field_type_integer_get_signed(integer_decl));
+ &last_value);
if (ret) {
_BT_LOGE_NODE(iter,
- "Cannot visit enumeration field type entry: "
+ "Cannot visit enumeration field class entry: "
"ret=%d", ret);
goto error;
}
ret = ctx_decl_scope_register_enum(ctx->current_scope,
name, *enum_decl);
if (ret) {
- BT_LOGE("Cannot register enumeration field type in declaration scope: "
+ BT_LOGE("Cannot register enumeration field class in declaration scope: "
"ret=%d", ret);
goto error;
}
}
}
- BT_PUT(integer_decl);
-
- return 0;
+ goto end;
error:
- BT_PUT(integer_decl);
- BT_PUT(*enum_decl);
+ ctf_field_class_destroy((void *) *enum_decl);
+ *enum_decl = NULL;
+end:
+ ctf_field_class_destroy((void *) integer_decl);
+ integer_decl = NULL;
return ret;
}
static
-int visit_type_specifier(struct ctx *ctx,
- struct ctf_node *type_specifier_list,
- struct bt_ctf_field_type **decl)
+int visit_field_class_specifier(struct ctx *ctx,
+ struct ctf_node *cls_specifier_list,
+ struct ctf_field_class **decl)
{
int ret = 0;
GString *str = NULL;
- _BT_CTF_FIELD_TYPE_INIT(decl_copy);
*decl = NULL;
str = g_string_new("");
- ret = get_type_specifier_list_name(ctx, type_specifier_list, str);
+ ret = get_class_specifier_list_name(ctx, cls_specifier_list, str);
if (ret) {
- _BT_LOGE_NODE(type_specifier_list,
- "Cannot get type specifier list's name: ret=%d", ret);
+ _BT_LOGE_NODE(cls_specifier_list,
+ "Cannot get field class specifier list's name: ret=%d", ret);
goto error;
}
- *decl = ctx_decl_scope_lookup_alias(ctx->current_scope, str->str, -1);
+ *decl = ctx_decl_scope_lookup_alias(ctx->current_scope, str->str, -1,
+ true);
if (!*decl) {
- _BT_LOGE_NODE(type_specifier_list,
- "Cannot find type alias: name=\"%s\"", str->str);
- ret = -EINVAL;
- goto error;
- }
-
- /* Make a copy of the type declaration */
- decl_copy = bt_ctf_field_type_copy(*decl);
- if (!decl_copy) {
- _BT_LOGE_NODE(type_specifier_list,
- "Cannot create field type copy.");
+ _BT_LOGE_NODE(cls_specifier_list,
+ "Cannot find field class alias: name=\"%s\"", str->str);
ret = -EINVAL;
goto error;
}
- BT_MOVE(*decl, decl_copy);
- (void) g_string_free(str, TRUE);
- str = NULL;
-
- return 0;
+ goto end;
error:
+ ctf_field_class_destroy(*decl);
+ *decl = NULL;
+
+end:
if (str) {
- (void) g_string_free(str, TRUE);
+ g_string_free(str, TRUE);
}
- BT_PUT(*decl);
-
return ret;
}
static
int visit_integer_decl(struct ctx *ctx,
- struct bt_list_head *expressions,
- struct bt_ctf_field_type **integer_decl)
+ struct bt_list_head *expressions,
+ struct ctf_field_class_int **integer_decl)
{
int set = 0;
int ret = 0;
int signedness = 0;
struct ctf_node *expression;
uint64_t alignment = 0, size = 0;
- struct bt_ctf_clock_class *mapped_clock = NULL;
- enum bt_ctf_string_encoding encoding = BT_CTF_STRING_ENCODING_NONE;
- enum bt_ctf_integer_base base = BT_CTF_INTEGER_BASE_DECIMAL;
- enum bt_ctf_byte_order byte_order =
- bt_ctf_trace_get_native_byte_order(ctx->trace);
+ struct bt_private_clock_class *mapped_clock_class = NULL;
+ enum ctf_encoding encoding = CTF_ENCODING_NONE;
+ enum bt_field_class_integer_preferred_display_base base =
+ BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL;
+ enum ctf_byte_order byte_order = ctx->ctf_tc->default_byte_order;
*integer_decl = NULL;
if (!strcmp(left->u.unary_expression.u.string, "signed")) {
if (_IS_SET(&set, _INTEGER_SIGNED_SET)) {
_BT_LOGE_DUP_ATTR(left, "signed",
- "integer field type");
+ "integer field class");
ret = -EPERM;
goto error;
}
signedness = get_boolean(right);
if (signedness < 0) {
_BT_LOGE_NODE(right,
- "Invalid boolean value for integer field type's `signed` attribute: "
+ "Invalid boolean value for integer field class's `signed` attribute: "
"ret=%d", ret);
ret = -EINVAL;
goto error;
"byte_order")) {
if (_IS_SET(&set, _INTEGER_BYTE_ORDER_SET)) {
_BT_LOGE_DUP_ATTR(left, "byte_order",
- "integer field type");
+ "integer field class");
ret = -EPERM;
goto error;
}
byte_order = get_real_byte_order(ctx, right);
- if (byte_order == BT_CTF_BYTE_ORDER_UNKNOWN) {
+ if (byte_order == -1) {
_BT_LOGE_NODE(right,
- "Invalid `byte_order` attribute in integer field type: "
+ "Invalid `byte_order` attribute in integer field class: "
"ret=%d", ret);
ret = -EINVAL;
goto error;
} else if (!strcmp(left->u.unary_expression.u.string, "size")) {
if (_IS_SET(&set, _INTEGER_SIZE_SET)) {
_BT_LOGE_DUP_ATTR(left, "size",
- "integer field type");
+ "integer field class");
ret = -EPERM;
goto error;
}
if (right->u.unary_expression.type !=
UNARY_UNSIGNED_CONSTANT) {
_BT_LOGE_NODE(right,
- "Invalid `size` attribute in integer field type: "
+ "Invalid `size` attribute in integer field class: "
"expecting unsigned constant integer: "
"node-type=%d",
right->u.unary_expression.type);
size = right->u.unary_expression.u.unsigned_constant;
if (size == 0) {
_BT_LOGE_NODE(right,
- "Invalid `size` attribute in integer field type: "
+ "Invalid `size` attribute in integer field class: "
"expecting positive constant integer: "
"size=%" PRIu64, size);
ret = -EINVAL;
goto error;
} else if (size > 64) {
_BT_LOGE_NODE(right,
- "Invalid `size` attribute in integer field type: "
+ "Invalid `size` attribute in integer field class: "
"integer fields over 64 bits are not supported as of this version: "
"size=%" PRIu64, size);
ret = -EINVAL;
"align")) {
if (_IS_SET(&set, _INTEGER_ALIGN_SET)) {
_BT_LOGE_DUP_ATTR(left, "align",
- "integer field type");
+ "integer field class");
ret = -EPERM;
goto error;
}
if (right->u.unary_expression.type !=
UNARY_UNSIGNED_CONSTANT) {
_BT_LOGE_NODE(right,
- "Invalid `align` attribute in integer field type: "
+ "Invalid `align` attribute in integer field class: "
"expecting unsigned constant integer: "
"node-type=%d",
right->u.unary_expression.type);
right->u.unary_expression.u.unsigned_constant;
if (!is_align_valid(alignment)) {
_BT_LOGE_NODE(right,
- "Invalid `align` attribute in integer field type: "
+ "Invalid `align` attribute in integer field class: "
"expecting power of two: "
"align=%" PRIu64, alignment);
ret = -EINVAL;
} else if (!strcmp(left->u.unary_expression.u.string, "base")) {
if (_IS_SET(&set, _INTEGER_BASE_SET)) {
_BT_LOGE_DUP_ATTR(left, "base",
- "integer field type");
+ "integer field class");
ret = -EPERM;
goto error;
}
switch (constant) {
case 2:
- base = BT_CTF_INTEGER_BASE_BINARY;
+ base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY;
break;
case 8:
- base = BT_CTF_INTEGER_BASE_OCTAL;
+ base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL;
break;
case 10:
- base = BT_CTF_INTEGER_BASE_DECIMAL;
+ base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL;
break;
case 16:
- base = BT_CTF_INTEGER_BASE_HEXADECIMAL;
+ base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL;
break;
default:
_BT_LOGE_NODE(right,
- "Invalid `base` attribute in integer field type: "
+ "Invalid `base` attribute in integer field class: "
"base=%" PRIu64,
right->u.unary_expression.u.unsigned_constant);
ret = -EINVAL;
&expression->u.ctf_expression.right);
if (!s_right) {
_BT_LOGE_NODE(right,
- "Unexpected unary expression for integer field type's `base` attribute.");
+ "Unexpected unary expression for integer field class's `base` attribute.");
ret = -EINVAL;
goto error;
}
!strcmp(s_right, "d") ||
!strcmp(s_right, "i") ||
!strcmp(s_right, "u")) {
- base = BT_CTF_INTEGER_BASE_DECIMAL;
+ base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL;
} else if (!strcmp(s_right, "hexadecimal") ||
!strcmp(s_right, "hex") ||
!strcmp(s_right, "x") ||
!strcmp(s_right, "X") ||
!strcmp(s_right, "p")) {
- base = BT_CTF_INTEGER_BASE_HEXADECIMAL;
+ base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL;
} else if (!strcmp(s_right, "octal") ||
!strcmp(s_right, "oct") ||
!strcmp(s_right, "o")) {
- base = BT_CTF_INTEGER_BASE_OCTAL;
+ base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL;
} else if (!strcmp(s_right, "binary") ||
!strcmp(s_right, "b")) {
- base = BT_CTF_INTEGER_BASE_BINARY;
+ base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY;
} else {
_BT_LOGE_NODE(right,
- "Unexpected unary expression for integer field type's `base` attribute: "
+ "Unexpected unary expression for integer field class's `base` attribute: "
"base=\"%s\"", s_right);
g_free(s_right);
ret = -EINVAL;
}
default:
_BT_LOGE_NODE(right,
- "Invalid `base` attribute in integer field type: "
+ "Invalid `base` attribute in integer field class: "
"expecting unsigned constant integer or unary string.");
ret = -EINVAL;
goto error;
if (_IS_SET(&set, _INTEGER_ENCODING_SET)) {
_BT_LOGE_DUP_ATTR(left, "encoding",
- "integer field type");
+ "integer field class");
ret = -EPERM;
goto error;
}
if (right->u.unary_expression.type != UNARY_STRING) {
_BT_LOGE_NODE(right,
- "Invalid `encoding` attribute in integer field type: "
+ "Invalid `encoding` attribute in integer field class: "
"expecting unary string.");
ret = -EINVAL;
goto error;
&expression->u.ctf_expression.right);
if (!s_right) {
_BT_LOGE_NODE(right,
- "Unexpected unary expression for integer field type's `encoding` attribute.");
+ "Unexpected unary expression for integer field class's `encoding` attribute.");
ret = -EINVAL;
goto error;
}
if (!strcmp(s_right, "UTF8") ||
!strcmp(s_right, "utf8") ||
!strcmp(s_right, "utf-8") ||
- !strcmp(s_right, "UTF-8")) {
- encoding = BT_CTF_STRING_ENCODING_UTF8;
- } else if (!strcmp(s_right, "ASCII") ||
+ !strcmp(s_right, "UTF-8") ||
+ !strcmp(s_right, "ASCII") ||
!strcmp(s_right, "ascii")) {
- encoding = BT_CTF_STRING_ENCODING_ASCII;
+ encoding = CTF_ENCODING_UTF8;
} else if (!strcmp(s_right, "none")) {
- encoding = BT_CTF_STRING_ENCODING_NONE;
+ encoding = CTF_ENCODING_NONE;
} else {
_BT_LOGE_NODE(right,
- "Invalid `encoding` attribute in integer field type: "
+ "Invalid `encoding` attribute in integer field class: "
"unknown encoding: encoding=\"%s\"",
s_right);
g_free(s_right);
if (_IS_SET(&set, _INTEGER_MAP_SET)) {
_BT_LOGE_DUP_ATTR(left, "map",
- "integer field type");
+ "integer field class");
ret = -EPERM;
goto error;
}
if (right->u.unary_expression.type != UNARY_STRING) {
_BT_LOGE_NODE(right,
- "Invalid `map` attribute in integer field type: "
+ "Invalid `map` attribute in integer field class: "
"expecting unary string.");
ret = -EINVAL;
goto error;
if (!s_right) {
_BT_LOGE_NODE(right,
- "Unexpected unary expression for integer field type's `map` attribute.");
+ "Unexpected unary expression for integer field class's `map` attribute.");
ret = -EINVAL;
goto error;
}
_BT_LOGE_NODE(right,
- "Invalid `map` attribute in integer field type: "
+ "Invalid `map` attribute in integer field class: "
"cannot find clock class at this point: name=\"%s\"",
s_right);
_SET(&set, _INTEGER_MAP_SET);
continue;
}
- mapped_clock = bt_ctf_trace_get_clock_class_by_name(
- ctx->trace, clock_name);
- if (!mapped_clock) {
+ mapped_clock_class =
+ ctf_trace_class_borrow_clock_class_by_name(
+ ctx->ctf_tc, clock_name);
+ if (!mapped_clock_class) {
_BT_LOGE_NODE(right,
- "Invalid `map` attribute in integer field type: "
+ "Invalid `map` attribute in integer field class: "
"cannot find clock class at this point: name=\"%s\"",
clock_name);
ret = -EINVAL;
_SET(&set, _INTEGER_MAP_SET);
} else {
_BT_LOGW_NODE(left,
- "Unknown attribute in integer field type: "
+ "Unknown attribute in integer field class: "
"attr-name=\"%s\"",
left->u.unary_expression.u.string);
}
}
if (!_IS_SET(&set, _INTEGER_SIZE_SET)) {
- BT_LOGE_STR("Missing `size` attribute in integer field type.");
+ BT_LOGE_STR("Missing `size` attribute in integer field class.");
ret = -EPERM;
goto error;
}
}
}
- *integer_decl = bt_ctf_field_type_integer_create((unsigned int) size);
- if (!*integer_decl) {
- BT_LOGE_STR("Cannot create integer field type.");
- ret = -ENOMEM;
- goto error;
- }
-
- ret = bt_ctf_field_type_integer_set_signed(*integer_decl, signedness);
- ret |= bt_ctf_field_type_integer_set_base(*integer_decl, base);
- ret |= bt_ctf_field_type_integer_set_encoding(*integer_decl, encoding);
- ret |= bt_ctf_field_type_set_alignment(*integer_decl,
- (unsigned int) alignment);
- ret |= bt_ctf_field_type_set_byte_order(*integer_decl, byte_order);
-
- if (mapped_clock) {
- /* Move clock */
- ret |= bt_ctf_field_type_integer_set_mapped_clock_class(
- *integer_decl, mapped_clock);
- bt_put(mapped_clock);
- mapped_clock = NULL;
- }
-
- if (ret) {
- BT_LOGE_STR("Cannot configure integer field type.");
- ret = -EINVAL;
- goto error;
- }
-
+ *integer_decl = ctf_field_class_int_create();
+ BT_ASSERT(*integer_decl);
+ (*integer_decl)->base.base.alignment = alignment;
+ (*integer_decl)->base.byte_order = byte_order;
+ (*integer_decl)->base.size = size;
+ (*integer_decl)->is_signed = (signedness > 0);
+ (*integer_decl)->disp_base = base;
+ (*integer_decl)->encoding = encoding;
+ (*integer_decl)->mapped_clock_class = bt_object_get_ref(mapped_clock_class);
return 0;
error:
- if (mapped_clock) {
- bt_put(mapped_clock);
- }
-
- BT_PUT(*integer_decl);
-
+ ctf_field_class_destroy((void *) *integer_decl);
+ *integer_decl = NULL;
return ret;
}
static
int visit_floating_point_number_decl(struct ctx *ctx,
- struct bt_list_head *expressions,
- struct bt_ctf_field_type **float_decl)
+ struct bt_list_head *expressions,
+ struct ctf_field_class_float **float_decl)
{
int set = 0;
int ret = 0;
struct ctf_node *expression;
uint64_t alignment = 1, exp_dig = 0, mant_dig = 0;
- enum bt_ctf_byte_order byte_order =
- bt_ctf_trace_get_native_byte_order(ctx->trace);
+ enum ctf_byte_order byte_order = ctx->ctf_tc->default_byte_order;
*float_decl = NULL;
if (!strcmp(left->u.unary_expression.u.string, "byte_order")) {
if (_IS_SET(&set, _FLOAT_BYTE_ORDER_SET)) {
_BT_LOGE_DUP_ATTR(left, "byte_order",
- "floating point number field type");
+ "floating point number field class");
ret = -EPERM;
goto error;
}
byte_order = get_real_byte_order(ctx, right);
- if (byte_order == BT_CTF_BYTE_ORDER_UNKNOWN) {
+ if (byte_order == -1) {
_BT_LOGE_NODE(right,
- "Invalid `byte_order` attribute in floating point number field type: "
+ "Invalid `byte_order` attribute in floating point number field class: "
"ret=%d", ret);
ret = -EINVAL;
goto error;
"exp_dig")) {
if (_IS_SET(&set, _FLOAT_EXP_DIG_SET)) {
_BT_LOGE_DUP_ATTR(left, "exp_dig",
- "floating point number field type");
+ "floating point number field class");
ret = -EPERM;
goto error;
}
if (right->u.unary_expression.type !=
UNARY_UNSIGNED_CONSTANT) {
_BT_LOGE_NODE(right,
- "Invalid `exp_dig` attribute in floating point number field type: "
+ "Invalid `exp_dig` attribute in floating point number field class: "
"expecting unsigned constant integer: "
"node-type=%d",
right->u.unary_expression.type);
"mant_dig")) {
if (_IS_SET(&set, _FLOAT_MANT_DIG_SET)) {
_BT_LOGE_DUP_ATTR(left, "mant_dig",
- "floating point number field type");
+ "floating point number field class");
ret = -EPERM;
goto error;
}
if (right->u.unary_expression.type !=
UNARY_UNSIGNED_CONSTANT) {
_BT_LOGE_NODE(right,
- "Invalid `mant_dig` attribute in floating point number field type: "
+ "Invalid `mant_dig` attribute in floating point number field class: "
"expecting unsigned constant integer: "
"node-type=%d",
right->u.unary_expression.type);
"align")) {
if (_IS_SET(&set, _FLOAT_ALIGN_SET)) {
_BT_LOGE_DUP_ATTR(left, "align",
- "floating point number field type");
+ "floating point number field class");
ret = -EPERM;
goto error;
}
if (right->u.unary_expression.type !=
UNARY_UNSIGNED_CONSTANT) {
_BT_LOGE_NODE(right,
- "Invalid `align` attribute in floating point number field type: "
+ "Invalid `align` attribute in floating point number field class: "
"expecting unsigned constant integer: "
"node-type=%d",
right->u.unary_expression.type);
if (!is_align_valid(alignment)) {
_BT_LOGE_NODE(right,
- "Invalid `align` attribute in floating point number field type: "
+ "Invalid `align` attribute in floating point number field class: "
"expecting power of two: "
"align=%" PRIu64, alignment);
ret = -EINVAL;
_SET(&set, _FLOAT_ALIGN_SET);
} else {
_BT_LOGW_NODE(left,
- "Unknown attribute in floating point number field type: "
+ "Unknown attribute in floating point number field class: "
"attr-name=\"%s\"",
left->u.unary_expression.u.string);
}
}
if (!_IS_SET(&set, _FLOAT_MANT_DIG_SET)) {
- BT_LOGE_STR("Missing `mant_dig` attribute in floating point number field type.");
+ BT_LOGE_STR("Missing `mant_dig` attribute in floating point number field class.");
ret = -EPERM;
goto error;
}
if (!_IS_SET(&set, _FLOAT_EXP_DIG_SET)) {
- BT_LOGE_STR("Missing `exp_dig` attribute in floating point number field type.");
+ BT_LOGE_STR("Missing `exp_dig` attribute in floating point number field class.");
+ ret = -EPERM;
+ goto error;
+ }
+
+ if (mant_dig != 24 && mant_dig != 53) {
+ BT_LOGE_STR("`mant_dig` attribute: expecting 24 or 53.");
+ ret = -EPERM;
+ goto error;
+ }
+
+ if (mant_dig == 24 && exp_dig != 8) {
+ BT_LOGE_STR("`exp_dig` attribute: expecting 8 because `mant_dig` is 24.");
+ ret = -EPERM;
+ goto error;
+ }
+
+ if (mant_dig == 53 && exp_dig != 11) {
+ BT_LOGE_STR("`exp_dig` attribute: expecting 11 because `mant_dig` is 53.");
ret = -EPERM;
goto error;
}
}
}
- *float_decl = bt_ctf_field_type_floating_point_create();
- if (!*float_decl) {
- BT_LOGE_STR("Cannot create floating point number field type.");
- ret = -ENOMEM;
- goto error;
- }
-
- ret = bt_ctf_field_type_floating_point_set_exponent_digits(
- *float_decl, exp_dig);
- ret |= bt_ctf_field_type_floating_point_set_mantissa_digits(
- *float_decl, mant_dig);
- ret |= bt_ctf_field_type_set_byte_order(*float_decl, byte_order);
- ret |= bt_ctf_field_type_set_alignment(*float_decl, alignment);
- if (ret) {
- BT_LOGE_STR("Cannot configure floating point number field type.");
- ret = -EINVAL;
- goto error;
- }
-
+ *float_decl = ctf_field_class_float_create();
+ BT_ASSERT(*float_decl);
+ (*float_decl)->base.base.alignment = alignment;
+ (*float_decl)->base.byte_order = byte_order;
+ (*float_decl)->base.size = mant_dig + exp_dig;
return 0;
error:
- BT_PUT(*float_decl);
-
+ ctf_field_class_destroy((void *) *float_decl);
+ *float_decl = NULL;
return ret;
}
static
int visit_string_decl(struct ctx *ctx,
- struct bt_list_head *expressions,
- struct bt_ctf_field_type **string_decl)
+ struct bt_list_head *expressions,
+ struct ctf_field_class_string **string_decl)
{
int set = 0;
int ret = 0;
struct ctf_node *expression;
- enum bt_ctf_string_encoding encoding = BT_CTF_STRING_ENCODING_UTF8;
+ enum ctf_encoding encoding = CTF_ENCODING_UTF8;
*string_decl = NULL;
if (_IS_SET(&set, _STRING_ENCODING_SET)) {
_BT_LOGE_DUP_ATTR(left, "encoding",
- "string field type");
+ "string field class");
ret = -EPERM;
goto error;
}
if (right->u.unary_expression.type != UNARY_STRING) {
_BT_LOGE_NODE(right,
- "Invalid `encoding` attribute in string field type: "
+ "Invalid `encoding` attribute in string field class: "
"expecting unary string.");
ret = -EINVAL;
goto error;
&expression->u.ctf_expression.right);
if (!s_right) {
_BT_LOGE_NODE(right,
- "Unexpected unary expression for string field type's `encoding` attribute.");
+ "Unexpected unary expression for string field class's `encoding` attribute.");
ret = -EINVAL;
goto error;
}
if (!strcmp(s_right, "UTF8") ||
!strcmp(s_right, "utf8") ||
!strcmp(s_right, "utf-8") ||
- !strcmp(s_right, "UTF-8")) {
- encoding = BT_CTF_STRING_ENCODING_UTF8;
- } else if (!strcmp(s_right, "ASCII") ||
+ !strcmp(s_right, "UTF-8") ||
+ !strcmp(s_right, "ASCII") ||
!strcmp(s_right, "ascii")) {
- encoding = BT_CTF_STRING_ENCODING_ASCII;
+ encoding = CTF_ENCODING_UTF8;
} else if (!strcmp(s_right, "none")) {
- encoding = BT_CTF_STRING_ENCODING_NONE;
+ encoding = CTF_ENCODING_NONE;
} else {
_BT_LOGE_NODE(right,
- "Invalid `encoding` attribute in string field type: "
+ "Invalid `encoding` attribute in string field class: "
"unknown encoding: encoding=\"%s\"",
s_right);
g_free(s_right);
_SET(&set, _STRING_ENCODING_SET);
} else {
_BT_LOGW_NODE(left,
- "Unknown attribute in string field type: "
+ "Unknown attribute in string field class: "
"attr-name=\"%s\"",
left->u.unary_expression.u.string);
}
}
- *string_decl = bt_ctf_field_type_string_create();
- if (!*string_decl) {
- BT_LOGE_STR("Cannot create string field type.");
- ret = -ENOMEM;
- goto error;
- }
-
- ret = bt_ctf_field_type_string_set_encoding(*string_decl, encoding);
- if (ret) {
- BT_LOGE_STR("Cannot configure string field type.");
- ret = -EINVAL;
- goto error;
- }
-
+ *string_decl = ctf_field_class_string_create();
+ BT_ASSERT(*string_decl);
+ (*string_decl)->encoding = encoding;
return 0;
error:
- BT_PUT(*string_decl);
-
+ ctf_field_class_destroy((void *) *string_decl);
+ *string_decl = NULL;
return ret;
}
static
-int visit_type_specifier_list(struct ctx *ctx,
- struct ctf_node *ts_list,
- struct bt_ctf_field_type **decl)
+int visit_field_class_specifier_list(struct ctx *ctx,
+ struct ctf_node *ts_list, struct ctf_field_class **decl)
{
int ret = 0;
struct ctf_node *first, *node;
goto error;
}
- first = _BT_LIST_FIRST_ENTRY(&ts_list->u.type_specifier_list.head,
+ first = _BT_LIST_FIRST_ENTRY(&ts_list->u.field_class_specifier_list.head,
struct ctf_node, siblings);
if (first->type != NODE_TYPE_SPECIFIER) {
_BT_LOGE_NODE(first,
goto error;
}
- node = first->u.type_specifier.node;
+ node = first->u.field_class_specifier.node;
- switch (first->u.type_specifier.type) {
+ switch (first->u.field_class_specifier.type) {
case TYPESPEC_INTEGER:
ret = visit_integer_decl(ctx, &node->u.integer.expressions,
- decl);
+ (void *) decl);
if (ret) {
- assert(!*decl);
+ BT_ASSERT(!*decl);
goto error;
}
break;
case TYPESPEC_FLOATING_POINT:
ret = visit_floating_point_number_decl(ctx,
- &node->u.floating_point.expressions, decl);
+ &node->u.floating_point.expressions, (void *) decl);
if (ret) {
- assert(!*decl);
+ BT_ASSERT(!*decl);
goto error;
}
break;
case TYPESPEC_STRING:
ret = visit_string_decl(ctx,
- &node->u.string.expressions, decl);
+ &node->u.string.expressions, (void *) decl);
if (ret) {
- assert(!*decl);
+ BT_ASSERT(!*decl);
goto error;
}
break;
ret = visit_struct_decl(ctx, node->u._struct.name,
&node->u._struct.declaration_list,
node->u._struct.has_body,
- &node->u._struct.min_align, decl);
+ &node->u._struct.min_align, (void *) decl);
if (ret) {
- assert(!*decl);
+ BT_ASSERT(!*decl);
goto error;
}
break;
ret = visit_variant_decl(ctx, node->u.variant.name,
node->u.variant.choice,
&node->u.variant.declaration_list,
- node->u.variant.has_body, decl);
+ node->u.variant.has_body, (void *) decl);
if (ret) {
- assert(!*decl);
+ BT_ASSERT(!*decl);
goto error;
}
break;
case TYPESPEC_ENUM:
ret = visit_enum_decl(ctx, node->u._enum.enum_id,
- node->u._enum.container_type,
+ node->u._enum.container_field_class,
&node->u._enum.enumerator_list,
- node->u._enum.has_body, decl);
+ node->u._enum.has_body, (void *) decl);
if (ret) {
- assert(!*decl);
+ BT_ASSERT(!*decl);
goto error;
}
break;
case TYPESPEC_IMAGINARY:
case TYPESPEC_CONST:
case TYPESPEC_ID_TYPE:
- ret = visit_type_specifier(ctx, ts_list, decl);
+ ret = visit_field_class_specifier(ctx, ts_list, decl);
if (ret) {
_BT_LOGE_NODE(first,
- "Cannot visit type specifier: ret=%d",
+ "Cannot visit field class specifier: ret=%d",
ret);
- assert(!*decl);
+ BT_ASSERT(!*decl);
goto error;
}
break;
default:
_BT_LOGE_NODE(first,
- "Unexpected type specifier type: node-type=%d",
- first->u.type_specifier.type);
+ "Unexpected field class specifier type: node-type=%d",
+ first->u.field_class_specifier.type);
ret = -EINVAL;
goto error;
}
- assert(*decl);
-
+ BT_ASSERT(*decl);
return 0;
error:
- BT_PUT(*decl);
-
+ ctf_field_class_destroy((void *) *decl);
+ *decl = NULL;
return ret;
}
static
int visit_event_decl_entry(struct ctx *ctx, struct ctf_node *node,
- struct bt_ctf_event_class *event_class, int64_t *stream_id,
- int *set)
+ struct ctf_event_class *event_class, uint64_t *stream_id,
+ int *set)
{
int ret = 0;
char *left = NULL;
- _BT_CTF_FIELD_TYPE_INIT(decl);
switch (node->type) {
case NODE_TYPEDEF:
- ret = visit_typedef(ctx, node->u._typedef.type_specifier_list,
- &node->u._typedef.type_declarators);
+ ret = visit_field_class_def(ctx, node->u.field_class_def.field_class_specifier_list,
+ &node->u.field_class_def.field_class_declarators);
if (ret) {
_BT_LOGE_NODE(node,
- "Cannot add type definition found in event class.");
+ "Cannot add field class found in event class.");
goto error;
}
break;
case NODE_TYPEALIAS:
- ret = visit_typealias(ctx, node->u.typealias.target,
- node->u.typealias.alias);
+ ret = visit_field_class_alias(ctx, node->u.field_class_alias.target,
+ node->u.field_class_alias.alias);
if (ret) {
_BT_LOGE_NODE(node,
- "Cannot add type alias found in event class.");
+ "Cannot add field class alias found in event class.");
goto error;
}
break;
if (!strcmp(left, "name")) {
/* This is already known at this stage */
if (_IS_SET(set, _EVENT_NAME_SET)) {
- _BT_LOGE_DUP_ATTR(node, "name",
- "event class");
+ _BT_LOGE_DUP_ATTR(node, "name", "event class");
ret = -EPERM;
goto error;
}
_SET(set, _EVENT_NAME_SET);
} else if (!strcmp(left, "id")) {
- int64_t id;
+ int64_t id = -1;
if (_IS_SET(set, _EVENT_ID_SET)) {
- _BT_LOGE_DUP_ATTR(node, "id",
- "event class");
+ _BT_LOGE_DUP_ATTR(node, "id", "event class");
ret = -EPERM;
goto error;
}
goto error;
}
- ret = bt_ctf_event_class_set_id(event_class, id);
- if (ret) {
- _BT_LOGE_NODE(node,
- "Cannot set event class's ID: "
- "id=%" PRId64, id);
- goto error;
- }
-
+ event_class->id = id;
_SET(set, _EVENT_ID_SET);
} else if (!strcmp(left, "stream_id")) {
if (_IS_SET(set, _EVENT_STREAM_ID_SET)) {
}
ret = get_unary_unsigned(&node->u.ctf_expression.right,
- (uint64_t *) stream_id);
+ stream_id);
+
/*
* Only read "stream_id" if get_unary_unsigned()
* succeeded.
goto error;
}
- ret = visit_type_specifier_list(ctx,
+ ret = visit_field_class_specifier_list(ctx,
_BT_LIST_FIRST_ENTRY(
&node->u.ctf_expression.right,
struct ctf_node, siblings),
- &decl);
- if (ret) {
- _BT_LOGE_NODE(node,
- "Cannot create event class's context field type.");
- goto error;
- }
-
- assert(decl);
- ret = bt_ctf_event_class_set_context_type(
- event_class, decl);
- BT_PUT(decl);
+ &event_class->spec_context_fc);
if (ret) {
_BT_LOGE_NODE(node,
- "Cannot set event class's context field type.");
+ "Cannot create event class's context field class.");
goto error;
}
+ BT_ASSERT(event_class->spec_context_fc);
_SET(set, _EVENT_CONTEXT_SET);
} else if (!strcmp(left, "fields")) {
if (_IS_SET(set, _EVENT_FIELDS_SET)) {
goto error;
}
- ret = visit_type_specifier_list(ctx,
+ ret = visit_field_class_specifier_list(ctx,
_BT_LIST_FIRST_ENTRY(
&node->u.ctf_expression.right,
struct ctf_node, siblings),
- &decl);
+ &event_class->payload_fc);
if (ret) {
_BT_LOGE_NODE(node,
- "Cannot create event class's payload field type.");
- goto error;
- }
-
- assert(decl);
- ret = bt_ctf_event_class_set_payload_type(
- event_class, decl);
- BT_PUT(decl);
- if (ret) {
- _BT_LOGE_NODE(node,
- "Cannot set event class's payload field type.");
+ "Cannot create event class's payload field class.");
goto error;
}
+ BT_ASSERT(event_class->payload_fc);
_SET(set, _EVENT_FIELDS_SET);
} else if (!strcmp(left, "loglevel")) {
uint64_t loglevel_value;
- enum bt_ctf_event_class_log_level log_level =
- BT_CTF_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED;
+ enum bt_event_class_log_level log_level = -1;
- if (_IS_SET(set, _EVENT_LOGLEVEL_SET)) {
+ if (_IS_SET(set, _EVENT_LOG_LEVEL_SET)) {
_BT_LOGE_DUP_ATTR(node, "loglevel",
"event class");
ret = -EPERM;
switch (loglevel_value) {
case 0:
- log_level = BT_CTF_EVENT_CLASS_LOG_LEVEL_EMERGENCY;
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY;
break;
case 1:
- log_level = BT_CTF_EVENT_CLASS_LOG_LEVEL_ALERT;
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_ALERT;
break;
case 2:
- log_level = BT_CTF_EVENT_CLASS_LOG_LEVEL_CRITICAL;
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_CRITICAL;
break;
case 3:
- log_level = BT_CTF_EVENT_CLASS_LOG_LEVEL_ERROR;
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_ERROR;
break;
case 4:
- log_level = BT_CTF_EVENT_CLASS_LOG_LEVEL_WARNING;
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_WARNING;
break;
case 5:
- log_level = BT_CTF_EVENT_CLASS_LOG_LEVEL_NOTICE;
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_NOTICE;
break;
case 6:
- log_level = BT_CTF_EVENT_CLASS_LOG_LEVEL_INFO;
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_INFO;
break;
case 7:
- log_level = BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM;
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM;
break;
case 8:
- log_level = BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM;
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM;
break;
case 9:
- log_level = BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS;
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS;
break;
case 10:
- log_level = BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE;
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE;
break;
case 11:
- log_level = BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT;
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT;
break;
case 12:
- log_level = BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION;
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION;
break;
case 13:
- log_level = BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE;
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE;
break;
case 14:
- log_level = BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG;
+ log_level = BT_EVENT_CLASS_LOG_LEVEL_DEBUG;
break;
default:
_BT_LOGW_NODE(node, "Not setting event class's log level because its value is unknown: "
"log-level=%" PRIu64, loglevel_value);
}
- if (log_level != BT_CTF_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED) {
- ret = bt_ctf_event_class_set_log_level(
- event_class, log_level);
- if (ret) {
- _BT_LOGE_NODE(node,
- "Cannot set event class's log level.");
- goto error;
- }
+ if (log_level != -1) {
+ event_class->log_level = log_level;
}
- _SET(set, _EVENT_LOGLEVEL_SET);
+ _SET(set, _EVENT_LOG_LEVEL_SET);
} else if (!strcmp(left, "model.emf.uri")) {
char *right;
_BT_LOGW_NODE(node,
"Not setting event class's EMF URI because it's empty.");
} else {
- ret = bt_ctf_event_class_set_emf_uri(
- event_class, right);
- if (ret) {
- _BT_LOGE_NODE(node,
- "Cannot set event class's EMF URI.");
- goto error;
- }
+ g_string_assign(event_class->emf_uri,
+ right);
}
g_free(right);
goto error;
}
- return 0;
+ goto end;
error:
if (left) {
g_free(left);
}
- BT_PUT(decl);
-
+end:
return ret;
}
error:
g_free(left);
-
- return NULL;
-}
-
-static
-int reset_event_decl_types(struct ctx *ctx,
- struct bt_ctf_event_class *event_class)
-{
- int ret = 0;
-
- /* Context type. */
- ret = bt_ctf_event_class_set_context_type(event_class, NULL);
- if (ret) {
- BT_LOGE("Cannot reset initial event class's context field type: "
- "event-name=\"%s\"",
- bt_ctf_event_class_get_name(event_class));
- goto end;
- }
-
- /* Event payload. */
- ret = bt_ctf_event_class_set_payload_type(event_class, NULL);
- if (ret) {
- BT_LOGE("Cannot reset initial event class's payload field type: "
- "event-name=\"%s\"",
- bt_ctf_event_class_get_name(event_class));
- goto end;
- }
-end:
- return ret;
-}
-
-static
-int reset_stream_decl_types(struct ctx *ctx,
- struct bt_ctf_stream_class *stream_class)
-{
- int ret = 0;
-
- /* Packet context. */
- ret = bt_ctf_stream_class_set_packet_context_type(stream_class, NULL);
- if (ret) {
- BT_LOGE_STR("Cannot reset initial stream class's packet context field type.");
- goto end;
- }
-
- /* Event header. */
- ret = bt_ctf_stream_class_set_event_header_type(stream_class, NULL);
- if (ret) {
- BT_LOGE_STR("Cannot reset initial stream class's event header field type.");
- goto end;
- }
-
- /* Event context. */
- ret = bt_ctf_stream_class_set_event_context_type(stream_class, NULL);
- if (ret) {
- BT_LOGE_STR("Cannot reset initial stream class's event context field type.");
- goto end;
- }
-end:
- return ret;
-}
-
-static
-struct bt_ctf_stream_class *create_reset_stream_class(struct ctx *ctx)
-{
- int ret;
- struct bt_ctf_stream_class *stream_class;
-
- stream_class = bt_ctf_stream_class_create_empty(NULL);
- if (!stream_class) {
- BT_LOGE_STR("Cannot create empty stream class.");
- goto error;
- }
-
- /*
- * Set packet context, event header, and event context to NULL to
- * override the default ones.
- */
- ret = reset_stream_decl_types(ctx, stream_class);
- if (ret) {
- goto error;
- }
-
- return stream_class;
-
-error:
- BT_PUT(stream_class);
-
return NULL;
}
{
int ret = 0;
int set = 0;
- int64_t event_id;
struct ctf_node *iter;
- int64_t stream_id = -1;
+ uint64_t stream_id = 0;
char *event_name = NULL;
- struct bt_ctf_event_class *event_class = NULL;
- struct bt_ctf_event_class *eevent_class;
- struct bt_ctf_stream_class *stream_class = NULL;
+ struct ctf_event_class *event_class = NULL;
+ struct ctf_stream_class *stream_class = NULL;
struct bt_list_head *decl_list = &node->u.event.declaration_list;
bool pop_scope = false;
goto error;
}
- event_class = bt_ctf_event_class_create(event_name);
-
- /*
- * Unset context and fields to override the default ones.
- */
- ret = reset_event_decl_types(ctx, event_class);
- if (ret) {
- _BT_LOGE_NODE(node,
- "Cannot reset event class's field types: "
- "ret=%d", ret);
- goto error;
- }
-
- ret = ctx_push_scope(ctx);
- if (ret) {
- BT_LOGE_STR("Cannot push scope.");
- goto error;
- }
-
+ event_class = ctf_event_class_create();
+ BT_ASSERT(event_class);
+ g_string_assign(event_class->name, event_name);
+ _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
pop_scope = true;
bt_list_for_each_entry(iter, decl_list, siblings) {
}
if (!_IS_SET(&set, _EVENT_STREAM_ID_SET)) {
- GList *keys = NULL;
- struct bt_ctf_stream_class *new_stream_class;
- size_t stream_class_count =
- g_hash_table_size(ctx->stream_classes) +
- bt_ctf_trace_get_stream_class_count(ctx->trace);
-
/*
* Allow missing stream_id if there is only a single
* stream class.
*/
- switch (stream_class_count) {
+ switch (ctx->ctf_tc->stream_classes->len) {
case 0:
/* Create implicit stream class if there's none */
- new_stream_class = create_reset_stream_class(ctx);
- if (!new_stream_class) {
- _BT_LOGE_NODE(node,
- "Cannot create empty stream class.");
- ret = -EINVAL;
- goto error;
- }
-
- ret = bt_ctf_stream_class_set_id(new_stream_class, 0);
- if (ret) {
- _BT_LOGE_NODE(node,
- "Cannot set stream class's ID: "
- "id=0, ret=%d", ret);
- BT_PUT(new_stream_class);
- goto error;
- }
-
stream_id = 0;
-
- /* Move reference to visitor's context */
- g_hash_table_insert(ctx->stream_classes,
- (gpointer) stream_id, new_stream_class);
- new_stream_class = NULL;
+ stream_class = ctf_stream_class_create();
+ BT_ASSERT(stream_class);
+ stream_class->id = stream_id;
+ g_ptr_array_add(ctx->ctf_tc->stream_classes,
+ stream_class);
+ stream_class = stream_class;
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;
- g_list_free(keys);
- } else {
- assert(bt_ctf_trace_get_stream_class_count(
- ctx->trace) == 1);
- stream_class =
- bt_ctf_trace_get_stream_class_by_index(
- ctx->trace, 0);
- assert(stream_class);
- stream_id = bt_ctf_stream_class_get_id(
- stream_class);
- BT_PUT(stream_class);
- }
+ stream_class = ctx->ctf_tc->stream_classes->pdata[0];
+ stream_id = stream_class->id;
break;
default:
_BT_LOGE_NODE(node,
}
}
- 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);
- bt_get(stream_class);
if (!stream_class) {
- stream_class = bt_ctf_trace_get_stream_class_by_id(ctx->trace,
- stream_id);
+ stream_class = ctf_trace_class_borrow_stream_class_by_id(
+ ctx->ctf_tc, stream_id);
if (!stream_class) {
_BT_LOGE_NODE(node,
"Cannot find stream class at this point: "
}
}
- assert(stream_class);
+ BT_ASSERT(stream_class);
if (!_IS_SET(&set, _EVENT_ID_SET)) {
/* Allow only one event without ID per stream */
- if (bt_ctf_stream_class_get_event_class_count(stream_class) !=
- 0) {
+ if (stream_class->event_classes->len != 0) {
_BT_LOGE_NODE(node,
"Missing `id` attribute in event class.");
ret = -EPERM;
}
/* Automatic ID */
- ret = bt_ctf_event_class_set_id(event_class, 0);
- if (ret) {
- _BT_LOGE_NODE(node,
- "Cannot set event class's ID: id=0, ret=%d",
- ret);
- goto error;
- }
+ event_class->id = 0;
}
- event_id = bt_ctf_event_class_get_id(event_class);
- if (event_id < 0) {
- _BT_LOGE_NODE(node, "Cannot get event class's ID.");
- ret = -EINVAL;
- goto error;
- }
-
- eevent_class = bt_ctf_stream_class_get_event_class_by_id(stream_class,
- event_id);
- if (eevent_class) {
- BT_PUT(eevent_class);
+ if (ctf_stream_class_borrow_event_class_by_id(stream_class,
+ event_class->id)) {
_BT_LOGE_NODE(node,
"Duplicate event class (same ID) in the same stream class: "
- "id=%" PRId64, event_id);
+ "id=%" PRId64, event_class->id);
ret = -EEXIST;
goto error;
}
- ret = bt_ctf_stream_class_add_event_class(stream_class, event_class);
- BT_PUT(event_class);
- if (ret) {
- _BT_LOGE_NODE(node,
- "Cannot add event class to stream class: ret=%d", ret);
- goto error;
- }
-
+ ctf_stream_class_append_event_class(stream_class, event_class);
+ event_class = NULL;
goto end;
error:
- bt_put(event_class);
+ ctf_event_class_destroy(event_class);
+ event_class = NULL;
+
+ if (ret >= 0) {
+ ret = -1;
+ }
end:
if (pop_scope) {
ctx_pop_scope(ctx);
}
- g_free(event_name);
- bt_put(stream_class);
+ if (event_name) {
+ g_free(event_name);
+ }
+
return ret;
}
static
-int auto_map_fields_to_trace_clock_class(struct ctx *ctx,
- struct bt_ctf_field_type *packet_context_field_type,
- const char **field_names)
+int auto_map_field_to_trace_clock_class(struct ctx *ctx,
+ struct ctf_field_class *fc)
{
- _BT_CTF_FIELD_TYPE_INIT(ft);
- struct bt_ctf_clock_class *clock_class = NULL;
- struct bt_ctf_clock_class *mapped_clock_class = NULL;
+ struct bt_private_clock_class *clock_class_to_map_to = NULL;
+ struct ctf_field_class_int *int_fc = (void *) fc;
int ret = 0;
- const char **field_name;
+ uint64_t clock_class_count;
- if (ctx->decoder_config.strict) {
+ if (!fc) {
goto end;
}
- if (!packet_context_field_type) {
+ if (fc->type != CTF_FIELD_CLASS_TYPE_INT &&
+ fc->type != CTF_FIELD_CLASS_TYPE_ENUM) {
goto end;
}
- if (!bt_ctf_field_type_is_structure(packet_context_field_type)) {
+ if (int_fc->mapped_clock_class) {
+ /* Already mapped */
goto end;
}
- if (bt_ctf_trace_get_clock_class_count(ctx->trace) != 1) {
+ clock_class_count = ctx->ctf_tc->clock_classes->len;
+
+ switch (clock_class_count) {
+ case 0:
+ /*
+ * No clock class exists in the trace at this point. Create an
+ * implicit one at 1 GHz, named `default`, and use this clock
+ * class.
+ */
+ clock_class_to_map_to = bt_private_clock_class_create();
+ BT_ASSERT(clock_class_to_map_to);
+ bt_private_clock_class_set_frequency(clock_class_to_map_to,
+ UINT64_C(1000000000));
+ ret = bt_private_clock_class_set_name(clock_class_to_map_to,
+ "default");
+ BT_ASSERT(ret == 0);
+ g_ptr_array_add(ctx->ctf_tc->clock_classes,
+ bt_object_get_ref(clock_class_to_map_to));
+ break;
+ case 1:
+ /*
+ * Only one clock class exists in the trace at this point: use
+ * this one.
+ */
+ clock_class_to_map_to =
+ bt_object_get_ref(ctx->ctf_tc->clock_classes->pdata[0]);
+ break;
+ default:
+ /*
+ * Timestamp field not mapped to a clock class and there's more
+ * than one clock class in the trace: this is an error.
+ */
+ BT_LOGE_STR("Timestamp field found with no mapped clock class, "
+ "but there's more than one clock class in the trace at this point.");
+ ret = -1;
goto end;
}
- clock_class = bt_ctf_trace_get_clock_class_by_index(ctx->trace, 0);
- assert(clock_class);
+ BT_ASSERT(clock_class_to_map_to);
+ int_fc->mapped_clock_class = bt_object_get_ref(clock_class_to_map_to);
- for (field_name = field_names; *field_name; field_name++) {
- ft = bt_ctf_field_type_structure_get_field_type_by_name(
- packet_context_field_type, *field_name);
+end:
+ bt_object_put_ref(clock_class_to_map_to);
+ return ret;
+}
- if (ft && bt_ctf_field_type_is_integer(ft)) {
- mapped_clock_class =
- bt_ctf_field_type_integer_get_mapped_clock_class(ft);
+static
+int auto_map_fields_to_trace_clock_class(struct ctx *ctx,
+ struct ctf_field_class *root_fc, const char *field_name)
+{
+ int ret = 0;
+ uint64_t i, count;
+ struct ctf_field_class_struct *struct_fc = (void *) root_fc;
+ struct ctf_field_class_variant *var_fc = (void *) root_fc;
- if (!mapped_clock_class) {
- ret = bt_ctf_field_type_integer_set_mapped_clock_class(
- ft, clock_class);
- if (ret) {
- BT_LOGE("Cannot map field type's field to trace's clock class: "
- "field-name=\"%s\", ret=%d",
- *field_name, ret);
- goto end;
- }
+ if (!root_fc) {
+ goto end;
+ }
+
+ if (root_fc->type != CTF_FIELD_CLASS_TYPE_STRUCT &&
+ root_fc->type != CTF_FIELD_CLASS_TYPE_VARIANT) {
+ goto end;
+ }
+
+ if (root_fc->type == CTF_FIELD_CLASS_TYPE_STRUCT) {
+ count = struct_fc->members->len;
+ } else {
+ count = var_fc->options->len;
+ }
+
+ for (i = 0; i < count; i++) {
+ struct ctf_named_field_class *named_fc = NULL;
+
+ if (root_fc->type == CTF_FIELD_CLASS_TYPE_STRUCT) {
+ named_fc = ctf_field_class_struct_borrow_member_by_index(
+ struct_fc, i);
+ } else if (root_fc->type == CTF_FIELD_CLASS_TYPE_VARIANT) {
+ named_fc = ctf_field_class_variant_borrow_option_by_index(
+ var_fc, i);
+ }
+
+ if (strcmp(named_fc->name->str, field_name) == 0) {
+ ret = auto_map_field_to_trace_clock_class(ctx,
+ named_fc->fc);
+ if (ret) {
+ BT_LOGE("Cannot automatically map field to trace's clock class: "
+ "field-name=\"%s\"", field_name);
+ goto end;
}
}
- BT_PUT(mapped_clock_class);
- BT_PUT(ft);
+ ret = auto_map_fields_to_trace_clock_class(ctx, named_fc->fc,
+ field_name);
+ if (ret) {
+ BT_LOGE("Cannot automatically map structure or variant field class's fields to trace's clock class: "
+ "field-name=\"%s\", root-field-name=\"%s\"",
+ field_name, named_fc->name->str);
+ goto end;
+ }
}
end:
- bt_put(mapped_clock_class);
- bt_put(clock_class);
- bt_put(ft);
return ret;
}
static
int visit_stream_decl_entry(struct ctx *ctx, struct ctf_node *node,
- struct bt_ctf_stream_class *stream_class, int *set)
+ struct ctf_stream_class *stream_class, int *set)
{
int ret = 0;
char *left = NULL;
- _BT_CTF_FIELD_TYPE_INIT(decl);
switch (node->type) {
case NODE_TYPEDEF:
- ret = visit_typedef(ctx, node->u._typedef.type_specifier_list,
- &node->u._typedef.type_declarators);
+ ret = visit_field_class_def(ctx, node->u.field_class_def.field_class_specifier_list,
+ &node->u.field_class_def.field_class_declarators);
if (ret) {
_BT_LOGE_NODE(node,
- "Cannot add type definition found in stream class.");
+ "Cannot add field class found in stream class.");
goto error;
}
break;
case NODE_TYPEALIAS:
- ret = visit_typealias(ctx, node->u.typealias.target,
- node->u.typealias.alias);
+ ret = visit_field_class_alias(ctx, node->u.field_class_alias.target,
+ node->u.field_class_alias.alias);
if (ret) {
_BT_LOGE_NODE(node,
- "Cannot add type alias found in stream class.");
+ "Cannot add field class alias found in stream class.");
goto error;
}
break;
if (!strcmp(left, "id")) {
int64_t id;
- gpointer ptr;
if (_IS_SET(set, _STREAM_ID_SET)) {
_BT_LOGE_DUP_ATTR(node, "id",
ret = get_unary_unsigned(&node->u.ctf_expression.right,
(uint64_t *) &id);
+
/* Only read "id" if get_unary_unsigned() succeeded. */
if (ret || (!ret && id < 0)) {
_BT_LOGE_NODE(node,
goto error;
}
- ptr = g_hash_table_lookup(ctx->stream_classes,
- (gpointer) id);
- if (ptr) {
+ if (ctf_trace_class_borrow_stream_class_by_id(
+ ctx->ctf_tc, id)) {
_BT_LOGE_NODE(node,
"Duplicate stream class (same ID): id=%" PRId64,
id);
goto error;
}
- ret = bt_ctf_stream_class_set_id(stream_class, id);
- if (ret) {
- _BT_LOGE_NODE(node,
- "Cannot set stream class's ID: "
- "id=%" PRId64 ", ret=%d", id, ret);
- goto error;
- }
-
+ stream_class->id = id;
_SET(set, _STREAM_ID_SET);
} else if (!strcmp(left, "event.header")) {
- const char *field_names[] = {
- "timestamp",
- "ts",
- NULL,
- };
-
if (_IS_SET(set, _STREAM_EVENT_HEADER_SET)) {
_BT_LOGE_NODE(node,
"Duplicate `event.header` entry in stream class.");
goto error;
}
- ret = visit_type_specifier_list(ctx,
+ ret = visit_field_class_specifier_list(ctx,
_BT_LIST_FIRST_ENTRY(
&node->u.ctf_expression.right,
struct ctf_node, siblings),
- &decl);
+ &stream_class->event_header_fc);
if (ret) {
_BT_LOGE_NODE(node,
- "Cannot create stream class's event header field type.");
+ "Cannot create stream class's event header field class.");
goto error;
}
- assert(decl);
+ BT_ASSERT(stream_class->event_header_fc);
ret = auto_map_fields_to_trace_clock_class(ctx,
- decl, field_names);
- if (ret) {
- _BT_LOGE_NODE(node,
- "Cannot automatically map specific event header field type fields to trace's clock class.");
- goto error;
- }
-
- ret = bt_ctf_stream_class_set_event_header_type(
- stream_class, decl);
- BT_PUT(decl);
+ stream_class->event_header_fc, "timestamp");
if (ret) {
_BT_LOGE_NODE(node,
- "Cannot set stream class's event header field type.");
+ "Cannot automatically map specific event header field class fields named `timestamp` to trace's clock class.");
goto error;
}
goto error;
}
- ret = visit_type_specifier_list(ctx,
+ ret = visit_field_class_specifier_list(ctx,
_BT_LIST_FIRST_ENTRY(
&node->u.ctf_expression.right,
struct ctf_node, siblings),
- &decl);
- if (ret) {
- _BT_LOGE_NODE(node,
- "Cannot create stream class's event context field type.");
- goto error;
- }
-
- assert(decl);
-
- ret = bt_ctf_stream_class_set_event_context_type(
- stream_class, decl);
- BT_PUT(decl);
+ &stream_class->event_common_context_fc);
if (ret) {
_BT_LOGE_NODE(node,
- "Cannot set stream class's event context field type.");
+ "Cannot create stream class's event context field class.");
goto error;
}
+ BT_ASSERT(stream_class->event_common_context_fc);
_SET(set, _STREAM_EVENT_CONTEXT_SET);
} else if (!strcmp(left, "packet.context")) {
- const char *field_names[] = {
- "timestamp_begin",
- "timestamp_end",
- NULL,
- };
-
if (_IS_SET(set, _STREAM_PACKET_CONTEXT_SET)) {
_BT_LOGE_NODE(node,
"Duplicate `packet.context` entry in stream class.");
goto error;
}
- ret = visit_type_specifier_list(ctx,
+ ret = visit_field_class_specifier_list(ctx,
_BT_LIST_FIRST_ENTRY(
&node->u.ctf_expression.right,
struct ctf_node, siblings),
- &decl);
+ &stream_class->packet_context_fc);
if (ret) {
_BT_LOGE_NODE(node,
- "Cannot create stream class's packet context field type.");
+ "Cannot create stream class's packet context field class.");
goto error;
}
- assert(decl);
+ BT_ASSERT(stream_class->packet_context_fc);
ret = auto_map_fields_to_trace_clock_class(ctx,
- decl, field_names);
+ stream_class->packet_context_fc,
+ "timestamp_begin");
if (ret) {
_BT_LOGE_NODE(node,
- "Cannot automatically map specific packet context field type fields to trace's clock class.");
+ "Cannot automatically map specific packet context field class fields named `timestamp_begin` to trace's clock class.");
goto error;
}
- ret = bt_ctf_stream_class_set_packet_context_type(
- stream_class, decl);
- BT_PUT(decl);
+ ret = auto_map_fields_to_trace_clock_class(ctx,
+ stream_class->packet_context_fc,
+ "timestamp_end");
if (ret) {
_BT_LOGE_NODE(node,
- "Cannot set stream class's packet context field type.");
+ "Cannot automatically map specific packet context field class fields named `timestamp_end` to trace's clock class.");
goto error;
}
error:
g_free(left);
- BT_PUT(decl);
-
return ret;
}
static
int visit_stream_decl(struct ctx *ctx, struct ctf_node *node)
{
- int64_t id;
int set = 0;
int ret = 0;
struct ctf_node *iter;
- struct bt_ctf_stream_class *stream_class = NULL;
- struct bt_ctf_stream_class *existing_stream_class = NULL;
+ struct ctf_stream_class *stream_class = NULL;
struct bt_list_head *decl_list = &node->u.stream.declaration_list;
if (node->visited) {
}
node->visited = TRUE;
- stream_class = create_reset_stream_class(ctx);
- if (!stream_class) {
- _BT_LOGE_NODE(node, "Cannot create empty stream class.");
- ret = -EINVAL;
- goto error;
- }
-
- ret = ctx_push_scope(ctx);
- if (ret) {
- BT_LOGE_STR("Cannot push scope.");
- goto error;
- }
+ stream_class = ctf_stream_class_create();
+ BT_ASSERT(stream_class);
+ _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
bt_list_for_each_entry(iter, decl_list, siblings) {
ret = visit_stream_decl_entry(ctx, iter, stream_class, &set);
ctx_pop_scope(ctx);
if (_IS_SET(&set, _STREAM_ID_SET)) {
- /* Check that packet header has stream_id field */
- _BT_CTF_FIELD_TYPE_INIT(stream_id_decl);
- _BT_CTF_FIELD_TYPE_INIT(packet_header_decl);
+ /* Check that packet header has `stream_id` field */
+ struct ctf_named_field_class *named_fc = NULL;
- packet_header_decl =
- bt_ctf_trace_get_packet_header_type(ctx->trace);
- if (!packet_header_decl) {
+ if (!ctx->ctf_tc->packet_header_fc) {
_BT_LOGE_NODE(node,
"Stream class has a `id` attribute, "
- "but trace has no packet header field type.");
+ "but trace has no packet header field class.");
goto error;
}
- stream_id_decl =
- bt_ctf_field_type_structure_get_field_type_by_name(
- packet_header_decl, "stream_id");
- BT_PUT(packet_header_decl);
- if (!stream_id_decl) {
+ named_fc = ctf_field_class_struct_borrow_member_by_name(
+ (void *) ctx->ctf_tc->packet_header_fc, "stream_id");
+ if (!named_fc) {
_BT_LOGE_NODE(node,
"Stream class has a `id` attribute, "
- "but trace's packet header field type has no `stream_id` field.");
+ "but trace's packet header field class has no `stream_id` field.");
goto error;
}
- if (!bt_ctf_field_type_is_integer(stream_id_decl)) {
- BT_PUT(stream_id_decl);
+ if (named_fc->fc->type != CTF_FIELD_CLASS_TYPE_INT &&
+ named_fc->fc->type != CTF_FIELD_CLASS_TYPE_ENUM) {
_BT_LOGE_NODE(node,
"Stream class has a `id` attribute, "
- "but trace's packet header field type's `stream_id` field is not an integer field type.");
+ "but trace's packet header field class's `stream_id` field is not an integer field class.");
goto error;
}
-
- BT_PUT(stream_id_decl);
} else {
/* Allow only _one_ ID-less stream */
- if (g_hash_table_size(ctx->stream_classes) != 0) {
+ if (ctx->ctf_tc->stream_classes->len != 0) {
_BT_LOGE_NODE(node,
"Missing `id` attribute in stream class as there's more than one stream class in the trace.");
ret = -EPERM;
}
/* Automatic ID: 0 */
- ret = bt_ctf_stream_class_set_id(stream_class, 0);
- assert(ret == 0);
- }
-
- id = bt_ctf_stream_class_get_id(stream_class);
- if (id < 0) {
- _BT_LOGE_NODE(node,
- "Cannot get stream class's ID.");
- ret = -EINVAL;
- goto error;
+ stream_class->id = 0;
}
/*
* Make sure that this stream class's ID is currently unique in
* the trace.
*/
- existing_stream_class = bt_ctf_trace_get_stream_class_by_id(ctx->trace,
- id);
- if (g_hash_table_lookup(ctx->stream_classes, (gpointer) id) ||
- existing_stream_class) {
+ if (ctf_trace_class_borrow_stream_class_by_id(ctx->ctf_tc,
+ stream_class->id)) {
_BT_LOGE_NODE(node,
"Duplicate stream class (same ID): id=%" PRId64,
- id);
+ stream_class->id);
ret = -EINVAL;
goto error;
}
- /* Move reference to visitor's context */
- g_hash_table_insert(ctx->stream_classes, (gpointer) (int64_t) id,
- stream_class);
+ g_ptr_array_add(ctx->ctf_tc->stream_classes, stream_class);
stream_class = NULL;
goto end;
error:
- bt_put(stream_class);
+ ctf_stream_class_destroy(stream_class);
+ stream_class = NULL;
end:
- bt_put(existing_stream_class);
return ret;
}
{
int ret = 0;
char *left = NULL;
- _BT_CTF_FIELD_TYPE_INIT(packet_header_decl);
+ uint64_t val;
switch (node->type) {
case NODE_TYPEDEF:
- ret = visit_typedef(ctx, node->u._typedef.type_specifier_list,
- &node->u._typedef.type_declarators);
+ ret = visit_field_class_def(ctx, node->u.field_class_def.field_class_specifier_list,
+ &node->u.field_class_def.field_class_declarators);
if (ret) {
_BT_LOGE_NODE(node,
- "Cannot add type definition found in trace (`trace` block).");
+ "Cannot add field class found in trace (`trace` block).");
goto error;
}
break;
case NODE_TYPEALIAS:
- ret = visit_typealias(ctx, node->u.typealias.target,
- node->u.typealias.alias);
+ ret = visit_field_class_alias(ctx, node->u.field_class_alias.target,
+ node->u.field_class_alias.alias);
if (ret) {
_BT_LOGE_NODE(node,
- "Cannot add type alias found in trace (`trace` block).");
+ "Cannot add field class alias found in trace (`trace` block).");
goto error;
}
break;
}
ret = get_unary_unsigned(&node->u.ctf_expression.right,
- &ctx->trace_major);
+ &val);
if (ret) {
_BT_LOGE_NODE(node,
"Unexpected unary expression for trace's `major` attribute.");
goto error;
}
+ if (val != 1) {
+ _BT_LOGE_NODE(node,
+ "Invalid trace's `minor` attribute: expecting 1.");
+ goto error;
+ }
+
+ ctx->ctf_tc->major = val;
_SET(set, _TRACE_MAJOR_SET);
} else if (!strcmp(left, "minor")) {
if (_IS_SET(set, _TRACE_MINOR_SET)) {
}
ret = get_unary_unsigned(&node->u.ctf_expression.right,
- &ctx->trace_minor);
+ &val);
if (ret) {
_BT_LOGE_NODE(node,
"Unexpected unary expression for trace's `minor` attribute.");
goto error;
}
+ if (val != 8) {
+ _BT_LOGE_NODE(node,
+ "Invalid trace's `minor` attribute: expecting 8.");
+ goto error;
+ }
+
+ ctx->ctf_tc->minor = val;
_SET(set, _TRACE_MINOR_SET);
} else if (!strcmp(left, "uuid")) {
if (_IS_SET(set, _TRACE_UUID_SET)) {
}
ret = get_unary_uuid(&node->u.ctf_expression.right,
- ctx->trace_uuid);
+ ctx->ctf_tc->uuid);
if (ret) {
_BT_LOGE_NODE(node,
"Invalid trace's `uuid` attribute.");
goto error;
}
- ret = bt_ctf_trace_set_uuid(ctx->trace, ctx->trace_uuid);
- if (ret) {
- _BT_LOGE_NODE(node, "Cannot set trace's UUID.");
- goto error;
- }
-
+ ctx->ctf_tc->is_uuid_set = true;
_SET(set, _TRACE_UUID_SET);
} else if (!strcmp(left, "byte_order")) {
- /* Native byte order is already known at this stage */
+ /* Default byte order is already known at this stage */
if (_IS_SET(set, _TRACE_BYTE_ORDER_SET)) {
_BT_LOGE_DUP_ATTR(node, "byte_order",
"trace");
goto error;
}
+ BT_ASSERT(ctx->ctf_tc->default_byte_order != -1);
_SET(set, _TRACE_BYTE_ORDER_SET);
} else if (!strcmp(left, "packet.header")) {
if (_IS_SET(set, _TRACE_PACKET_HEADER_SET)) {
goto error;
}
- ret = visit_type_specifier_list(ctx,
+ ret = visit_field_class_specifier_list(ctx,
_BT_LIST_FIRST_ENTRY(
&node->u.ctf_expression.right,
struct ctf_node, siblings),
- &packet_header_decl);
+ &ctx->ctf_tc->packet_header_fc);
if (ret) {
_BT_LOGE_NODE(node,
- "Cannot create trace's packet header field type.");
- goto error;
- }
-
- assert(packet_header_decl);
- ret = bt_ctf_trace_set_packet_header_type(ctx->trace,
- packet_header_decl);
- BT_PUT(packet_header_decl);
- if (ret) {
- _BT_LOGE_NODE(node,
- "Cannot set trace's packet header field type.");
+ "Cannot create trace's packet header field class.");
goto error;
}
+ BT_ASSERT(ctx->ctf_tc->packet_header_fc);
_SET(set, _TRACE_PACKET_HEADER_SET);
} else {
_BT_LOGW_NODE(node,
error:
g_free(left);
- BT_PUT(packet_header_decl);
-
return ret;
}
goto error;
}
- ret = ctx_push_scope(ctx);
- if (ret) {
- BT_LOGE_STR("Cannot push scope.");
- goto error;
- }
+ _TRY_PUSH_SCOPE_OR_GOTO_ERROR();
bt_list_for_each_entry(iter, decl_list, siblings) {
ret = visit_trace_decl_entry(ctx, iter, &set);
goto error;
}
- ctx->is_trace_visited = TRUE;
+ ctx->is_trace_visited = true;
end:
return 0;
goto error;
}
- if (!ctx->decoder_config.strict) {
- if (strcmp(left, "tracer_name") == 0) {
- if (strncmp(right, "lttng", 5) == 0) {
- BT_LOGI("Non-strict mode: detected LTTng trace from `%s` environment value: "
- "tracer-name=\"%s\"",
- left, right);
- ctx->is_lttng = 1;
- }
+ if (strcmp(left, "tracer_name") == 0) {
+ if (strncmp(right, "lttng", 5) == 0) {
+ BT_LOGI("Detected LTTng trace from `%s` environment value: "
+ "tracer-name=\"%s\"",
+ left, right);
+ ctx->is_lttng = true;
}
}
- ret = bt_ctf_trace_set_environment_field_string(
- ctx->trace, left, right);
+ ctf_trace_class_append_env_entry(ctx->ctf_tc,
+ left, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR,
+ right, 0);
g_free(right);
-
- if (ret) {
- _BT_LOGE_NODE(entry_node,
- "Cannot add string environment entry to trace: "
- "name=\"%s\", ret=%d", left, ret);
- goto error;
- }
} else if (is_unary_unsigned(right_head) ||
is_unary_signed(right_head)) {
int64_t v;
goto error;
}
- ret = bt_ctf_trace_set_environment_field_integer(
- ctx->trace, left, v);
- if (ret) {
- _BT_LOGE_NODE(entry_node,
- "Cannot add integer environment entry to trace: "
- "name=\"%s\", ret=%d", left, ret);
- goto error;
- }
+ ctf_trace_class_append_env_entry(ctx->ctf_tc,
+ left, CTF_TRACE_CLASS_ENV_ENTRY_TYPE_INT,
+ NULL, v);
} else {
_BT_LOGW_NODE(entry_node,
"Environment entry has unknown type: "
error:
g_free(left);
-
return ret;
}
}
if (!strcmp(left, "byte_order")) {
- enum bt_ctf_byte_order bo;
+ enum ctf_byte_order bo;
if (_IS_SET(&set, _TRACE_BYTE_ORDER_SET)) {
_BT_LOGE_DUP_ATTR(node, "byte_order",
&node->u.ctf_expression.right,
struct ctf_node, siblings);
bo = byte_order_from_unary_expr(right_node);
- if (bo == BT_CTF_BYTE_ORDER_UNKNOWN) {
+ if (bo == -1) {
_BT_LOGE_NODE(node,
"Invalid `byte_order` attribute in trace (`trace` block): "
"expecting `le`, `be`, or `network`.");
ret = -EINVAL;
goto error;
- } else if (bo == BT_CTF_BYTE_ORDER_NATIVE) {
+ } else if (bo == CTF_BYTE_ORDER_DEFAULT) {
_BT_LOGE_NODE(node,
"Invalid `byte_order` attribute in trace (`trace` block): "
"cannot be set to `native` here.");
goto error;
}
- ctx->trace_bo = bo;
- ret = bt_ctf_trace_set_native_byte_order(
- ctx->trace, bo);
- if (ret) {
- _BT_LOGE_NODE(node,
- "Cannot set trace's byte order: "
- "ret=%d", ret);
- goto error;
- }
+ ctx->ctf_tc->default_byte_order = bo;
}
g_free(left);
error:
g_free(left);
-
return ret;
}
static
int visit_clock_decl_entry(struct ctx *ctx, struct ctf_node *entry_node,
- struct bt_ctf_clock_class *clock, int *set)
+ struct bt_private_clock_class *clock, int *set, int64_t *offset_seconds,
+ uint64_t *offset_cycles)
{
int ret = 0;
char *left = NULL;
goto error;
}
- ret = bt_ctf_clock_class_set_name(clock, right);
+ ret = bt_private_clock_class_set_name(clock, right);
if (ret) {
_BT_LOGE_NODE(entry_node,
"cannot set clock class's name");
g_free(right);
_SET(set, _CLOCK_NAME_SET);
} else if (!strcmp(left, "uuid")) {
- unsigned char uuid[BABELTRACE_UUID_LEN];
+ uint8_t uuid[BABELTRACE_UUID_LEN];
if (_IS_SET(set, _CLOCK_UUID_SET)) {
_BT_LOGE_DUP_ATTR(entry_node, "uuid", "clock class");
goto error;
}
- ret = bt_ctf_clock_class_set_uuid(clock, uuid);
- if (ret) {
- _BT_LOGE_NODE(entry_node,
- "Cannot set clock class's UUID.");
- goto error;
- }
-
+ bt_private_clock_class_set_uuid(clock, uuid);
_SET(set, _CLOCK_UUID_SET);
} else if (!strcmp(left, "description")) {
char *right;
goto error;
}
- ret = bt_ctf_clock_class_set_description(clock, right);
+ ret = bt_private_clock_class_set_description(clock, right);
if (ret) {
_BT_LOGE_NODE(entry_node,
"Cannot set clock class's description.");
g_free(right);
_SET(set, _CLOCK_DESCRIPTION_SET);
} else if (!strcmp(left, "freq")) {
- uint64_t freq;
+ uint64_t freq = UINT64_C(-1);
if (_IS_SET(set, _CLOCK_FREQ_SET)) {
_BT_LOGE_DUP_ATTR(entry_node, "freq", "clock class");
goto error;
}
- ret = bt_ctf_clock_class_set_frequency(clock, freq);
- if (ret) {
+ if (freq == UINT64_C(-1) || freq == 0) {
_BT_LOGE_NODE(entry_node,
- "Cannot set clock class's frequency.");
+ "Invalid clock class frequency: freq=%" PRIu64,
+ freq);
+ ret = -EINVAL;
goto error;
}
+ bt_private_clock_class_set_frequency(clock, freq);
_SET(set, _CLOCK_FREQ_SET);
} else if (!strcmp(left, "precision")) {
uint64_t precision;
goto error;
}
- ret = bt_ctf_clock_class_set_precision(clock, precision);
- if (ret) {
- _BT_LOGE_NODE(entry_node,
- "Cannot set clock class's precision.");
- goto error;
- }
-
+ bt_private_clock_class_set_precision(clock, precision);
_SET(set, _CLOCK_PRECISION_SET);
} else if (!strcmp(left, "offset_s")) {
- uint64_t offset_s;
-
if (_IS_SET(set, _CLOCK_OFFSET_S_SET)) {
_BT_LOGE_DUP_ATTR(entry_node, "offset_s",
"clock class");
goto error;
}
- ret = get_unary_unsigned(
- &entry_node->u.ctf_expression.right, &offset_s);
+ ret = get_unary_signed(
+ &entry_node->u.ctf_expression.right, offset_seconds);
if (ret) {
_BT_LOGE_NODE(entry_node,
"Unexpected unary expression for clock class's `offset_s` attribute.");
goto error;
}
- ret = bt_ctf_clock_class_set_offset_s(clock, offset_s);
- if (ret) {
- _BT_LOGE_NODE(entry_node,
- "Cannot set clock class's offset in seconds.");
- goto error;
- }
-
_SET(set, _CLOCK_OFFSET_S_SET);
} else if (!strcmp(left, "offset")) {
- uint64_t offset;
-
if (_IS_SET(set, _CLOCK_OFFSET_SET)) {
_BT_LOGE_DUP_ATTR(entry_node, "offset", "clock class");
ret = -EPERM;
}
ret = get_unary_unsigned(
- &entry_node->u.ctf_expression.right, &offset);
+ &entry_node->u.ctf_expression.right, offset_cycles);
if (ret) {
_BT_LOGE_NODE(entry_node,
"Unexpected unary expression for clock class's `offset` attribute.");
goto error;
}
- ret = bt_ctf_clock_class_set_offset_cycles(clock, offset);
- if (ret) {
- _BT_LOGE_NODE(entry_node,
- "Cannot set clock class's offset in cycles.");
- goto error;
- }
-
_SET(set, _CLOCK_OFFSET_SET);
} else if (!strcmp(left, "absolute")) {
struct ctf_node *right;
goto error;
}
- ret = bt_ctf_clock_class_set_is_absolute(clock, ret);
- if (ret) {
- _BT_LOGE_NODE(entry_node,
- "Cannot set clock class's absolute flag.");
- goto error;
- }
-
+ bt_private_clock_class_set_is_absolute(clock, ret);
_SET(set, _CLOCK_ABSOLUTE_SET);
} else {
_BT_LOGW_NODE(entry_node,
g_free(left);
left = NULL;
-
return 0;
error:
g_free(left);
-
return ret;
}
-static
-int64_t cycles_from_ns(uint64_t frequency, int64_t ns)
+static inline
+uint64_t cycles_from_ns(uint64_t frequency, uint64_t ns)
{
- int64_t cycles;
+ uint64_t cycles;
/* 1GHz */
- if (frequency == 1000000000ULL) {
+ if (frequency == UINT64_C(1000000000)) {
cycles = ns;
} else {
cycles = (uint64_t) (((double) ns * (double) frequency) / 1e9);
}
static
-int apply_clock_class_offset(struct ctx *ctx, struct bt_ctf_clock_class *clock)
+void calibrate_clock_class_offsets(int64_t *offset_seconds,
+ uint64_t *offset_cycles, uint64_t freq)
+{
+ if (*offset_cycles >= freq) {
+ const uint64_t s_in_offset_cycles = *offset_cycles / freq;
+
+ *offset_seconds += (int64_t) s_in_offset_cycles;
+ *offset_cycles -= (s_in_offset_cycles * freq);
+ }
+}
+
+static
+void apply_clock_class_offset(struct ctx *ctx,
+ struct bt_private_clock_class *clock)
{
- int ret;
uint64_t freq;
- int64_t offset_cycles;
- int64_t offset_to_apply;
+ int64_t offset_s_to_apply = ctx->decoder_config.clock_class_offset_s;
+ uint64_t offset_ns_to_apply;
+ int64_t cur_offset_s;
+ uint64_t cur_offset_cycles;
- freq = bt_ctf_clock_class_get_frequency(clock);
- if (freq == -1ULL) {
- BT_LOGE_STR("Cannot get clock class's frequency.");
- ret = -1;
+ if (ctx->decoder_config.clock_class_offset_s == 0 &&
+ ctx->decoder_config.clock_class_offset_ns == 0) {
goto end;
}
- ret = bt_ctf_clock_class_get_offset_cycles(clock, &offset_cycles);
- if (ret) {
- BT_LOGE_STR("Cannot get clock class's offset in cycles.");
- ret = -1;
- goto end;
+ /* Transfer nanoseconds to seconds as much as possible */
+ if (ctx->decoder_config.clock_class_offset_ns < 0) {
+ const int64_t abs_ns = -ctx->decoder_config.clock_class_offset_ns;
+ const int64_t abs_extra_s = abs_ns / INT64_C(1000000000) + 1;
+ const int64_t extra_s = -abs_extra_s;
+ const int64_t offset_ns = ctx->decoder_config.clock_class_offset_ns -
+ (extra_s * INT64_C(1000000000));
+
+ BT_ASSERT(offset_ns > 0);
+ offset_ns_to_apply = (uint64_t) offset_ns;
+ offset_s_to_apply += extra_s;
+ } else {
+ const int64_t extra_s = ctx->decoder_config.clock_class_offset_ns /
+ INT64_C(1000000000);
+ const int64_t offset_ns = ctx->decoder_config.clock_class_offset_ns -
+ (extra_s * INT64_C(1000000000));
+
+ BT_ASSERT(offset_ns >= 0);
+ offset_ns_to_apply = (uint64_t) offset_ns;
+ offset_s_to_apply += extra_s;
}
- offset_to_apply =
- ctx->decoder_config.clock_class_offset_s * 1000000000LL +
- ctx->decoder_config.clock_class_offset_ns;
- offset_cycles += cycles_from_ns(freq, offset_to_apply);
- ret = bt_ctf_clock_class_set_offset_cycles(clock, offset_cycles);
+ freq = bt_clock_class_get_frequency(
+ bt_private_clock_class_as_clock_class(clock));
+ bt_clock_class_get_offset(bt_private_clock_class_as_clock_class(clock),
+ &cur_offset_s, &cur_offset_cycles);
+
+ /* Apply offsets */
+ cur_offset_s += offset_s_to_apply;
+ cur_offset_cycles += cycles_from_ns(freq, offset_ns_to_apply);
+
+ /*
+ * Recalibrate offsets because the part in cycles can be greater
+ * than the frequency at this point.
+ */
+ calibrate_clock_class_offsets(&cur_offset_s, &cur_offset_cycles, freq);
+
+ /* Set final offsets */
+ bt_private_clock_class_set_offset(clock, cur_offset_s, cur_offset_cycles);
end:
- return ret;
+ return;
}
static
{
int ret = 0;
int set = 0;
- struct bt_ctf_clock_class *clock;
+ struct bt_private_clock_class *clock;
struct ctf_node *entry_node;
struct bt_list_head *decl_list = &clock_node->u.clock.declaration_list;
const char *clock_class_name;
+ int64_t offset_seconds = 0;
+ uint64_t offset_cycles = 0;
+ uint64_t freq;
if (clock_node->visited) {
return 0;
}
clock_node->visited = TRUE;
- clock = bt_ctf_clock_class_create(NULL);
+
+ /* CTF 1.8's default frequency for a clock class is 1 GHz */
+ clock = bt_private_clock_class_create();
if (!clock) {
_BT_LOGE_NODE(clock_node,
"Cannot create default clock class.");
ret = -ENOMEM;
- goto error;
+ goto end;
}
+ /* CTF: not absolute by default */
+ bt_private_clock_class_set_is_absolute(clock, BT_FALSE);
+
bt_list_for_each_entry(entry_node, decl_list, siblings) {
- ret = visit_clock_decl_entry(ctx, entry_node, clock, &set);
+ ret = visit_clock_decl_entry(ctx, entry_node, clock, &set,
+ &offset_seconds, &offset_cycles);
if (ret) {
_BT_LOGE_NODE(entry_node,
"Cannot visit clock class's entry: ret=%d",
ret);
- goto error;
+ goto end;
}
}
_BT_LOGE_NODE(clock_node,
"Missing `name` attribute in clock class.");
ret = -EPERM;
- goto error;
+ goto end;
}
- clock_class_name = bt_ctf_clock_class_get_name(clock);
- assert(clock_class_name);
+ clock_class_name = bt_clock_class_get_name(
+ bt_private_clock_class_as_clock_class(clock));
+ BT_ASSERT(clock_class_name);
if (ctx->is_lttng && strcmp(clock_class_name, "monotonic") == 0) {
/*
* Old versions of LTTng forgot to set its clock class
* it's a condition to be able to sort notifications
* from different sources.
*/
- ret = bt_ctf_clock_class_set_is_absolute(clock, 1);
- if (ret) {
- _BT_LOGE_NODE(clock_node,
- "Cannot set clock class's absolute flag.");
- goto error;
- }
+ bt_private_clock_class_set_is_absolute(clock, BT_TRUE);
}
- ret = apply_clock_class_offset(ctx, clock);
- if (ret) {
- _BT_LOGE_NODE(clock_node,
- "Cannot apply clock class's custom offset.");
- goto error;
- }
-
- ret = bt_ctf_trace_add_clock_class(ctx->trace, clock);
- if (ret) {
- _BT_LOGE_NODE(clock_node,
- "Cannot add clock class to trace.");
- goto error;
- }
-
-error:
- BT_PUT(clock);
+ /*
+ * Adjust offsets so that the part in cycles is less than the
+ * frequency (move to the part in seconds).
+ */
+ freq = bt_clock_class_get_frequency(
+ bt_private_clock_class_as_clock_class(clock));
+ calibrate_clock_class_offsets(&offset_seconds, &offset_cycles, freq);
+ BT_ASSERT(offset_cycles < bt_clock_class_get_frequency(
+ bt_private_clock_class_as_clock_class(clock)));
+ bt_private_clock_class_set_offset(clock, offset_seconds, offset_cycles);
+ apply_clock_class_offset(ctx, clock);
+ g_ptr_array_add(ctx->ctf_tc->clock_classes, bt_object_get_ref(clock));
+end:
+ BT_OBJECT_PUT_REF_AND_RESET(clock);
return ret;
}
switch (root_decl_node->type) {
case NODE_TYPEDEF:
- ret = visit_typedef(ctx,
- root_decl_node->u._typedef.type_specifier_list,
- &root_decl_node->u._typedef.type_declarators);
+ ret = visit_field_class_def(ctx,
+ root_decl_node->u.field_class_def.field_class_specifier_list,
+ &root_decl_node->u.field_class_def.field_class_declarators);
if (ret) {
_BT_LOGE_NODE(root_decl_node,
- "Cannot add type definition found in root scope.");
+ "Cannot add field class found in root scope.");
goto end;
}
break;
case NODE_TYPEALIAS:
- ret = visit_typealias(ctx, root_decl_node->u.typealias.target,
- root_decl_node->u.typealias.alias);
+ ret = visit_field_class_alias(ctx, root_decl_node->u.field_class_alias.target,
+ root_decl_node->u.field_class_alias.alias);
if (ret) {
_BT_LOGE_NODE(root_decl_node,
- "Cannot add type alias found in root scope.");
+ "Cannot add field class alias found in root scope.");
goto end;
}
break;
case NODE_TYPE_SPECIFIER_LIST:
{
- _BT_CTF_FIELD_TYPE_INIT(decl);
+ struct ctf_field_class *decl = NULL;
/*
- * Just add the type specifier to the root
+ * Just add the field class specifier to the root
* declaration scope. Put local reference.
*/
- ret = visit_type_specifier_list(ctx, root_decl_node, &decl);
+ ret = visit_field_class_specifier_list(ctx, root_decl_node, &decl);
if (ret) {
_BT_LOGE_NODE(root_decl_node,
- "Cannot visit root scope's field type: "
+ "Cannot visit root scope's field class: "
"ret=%d", ret);
- assert(!decl);
+ BT_ASSERT(!decl);
goto end;
}
- BT_PUT(decl);
+ ctf_field_class_destroy(decl);
+ decl = NULL;
break;
}
default:
}
static
-int set_trace_name(struct ctx *ctx)
+int try_set_trace_class_name(struct ctx *ctx)
{
- GString *name;
+ GString *name = NULL;
int ret = 0;
- struct bt_value *value = NULL;
+ struct ctf_trace_class_env_entry *env_entry;
+
+ if (ctx->ctf_tc->name->len > 0) {
+ /* Already set */
+ goto end;
+ }
- assert(bt_ctf_trace_get_stream_class_count(ctx->trace) == 0);
name = g_string_new(NULL);
if (!name) {
BT_LOGE_STR("Failed to allocate a GString.");
* Check if we have a trace environment string value named `hostname`.
* If so, use it as the trace name's prefix.
*/
- value = bt_ctf_trace_get_environment_field_value_by_name(ctx->trace,
+ env_entry = ctf_trace_class_borrow_env_entry_by_name(ctx->ctf_tc,
"hostname");
- if (bt_value_is_string(value)) {
- const char *hostname;
+ if (env_entry &&
+ env_entry->type == CTF_TRACE_CLASS_ENV_ENTRY_TYPE_STR) {
+ g_string_append(name, env_entry->value.str->str);
- ret = bt_value_string_get(value, &hostname);
- assert(ret == 0);
- g_string_append(name, hostname);
-
- if (ctx->trace_name_suffix) {
+ if (ctx->trace_class_name_suffix) {
g_string_append_c(name, G_DIR_SEPARATOR);
}
}
- if (ctx->trace_name_suffix) {
- g_string_append(name, ctx->trace_name_suffix);
- }
-
- ret = bt_ctf_trace_set_name(ctx->trace, name->str);
- if (ret) {
- BT_LOGE("Cannot set trace's name: name=\"%s\"", name->str);
- goto error;
+ if (ctx->trace_class_name_suffix) {
+ g_string_append(name, ctx->trace_class_name_suffix);
}
+ g_string_assign(ctx->ctf_tc->name, name->str);
goto end;
-error:
- ret = -1;
-
end:
- bt_put(value);
-
if (name) {
g_string_free(name, TRUE);
}
return ret;
}
-static
-int move_ctx_stream_classes_to_trace(struct ctx *ctx)
-{
- int ret = 0;
- GHashTableIter iter;
- gpointer key, stream_class;
-
- if (g_hash_table_size(ctx->stream_classes) > 0 &&
- bt_ctf_trace_get_stream_class_count(ctx->trace) == 0) {
- /*
- * We're about to add the first stream class to the
- * trace. This will freeze the trace, and after this
- * we cannot set the name anymore. At this point,
- * set the trace name.
- */
- ret = set_trace_name(ctx);
- if (ret) {
- BT_LOGE_STR("Cannot set trace's name.");
- goto end;
- }
- }
-
- g_hash_table_iter_init(&iter, ctx->stream_classes);
-
- while (g_hash_table_iter_next(&iter, &key, &stream_class)) {
- ret = bt_ctf_trace_add_stream_class(ctx->trace,
- stream_class);
- if (ret) {
- int64_t id = bt_ctf_stream_class_get_id(stream_class);
- BT_LOGE("Cannot add stream class to trace: id=%" PRId64,
- id);
- goto end;
- }
- }
-
- g_hash_table_remove_all(ctx->stream_classes);
-
-end:
- return ret;
-}
-
BT_HIDDEN
struct ctf_visitor_generate_ir *ctf_visitor_generate_ir_create(
const struct ctf_metadata_decoder_config *decoder_config,
const char *name)
{
- int ret;
struct ctx *ctx = NULL;
- struct bt_ctf_trace *trace;
-
- trace = bt_ctf_trace_create();
- if (!trace) {
- BT_LOGE_STR("Cannot create empty trace.");
- goto error;
- }
-
- /* Set packet header to NULL to override the default one */
- ret = bt_ctf_trace_set_packet_header_type(trace, NULL);
- if (ret) {
- BT_LOGE_STR("Cannot reset initial trace's packet header field type.");
- goto error;
- }
/* Create visitor's context */
- ctx = ctx_create(trace, decoder_config, name);
+ ctx = ctx_create(decoder_config, name);
if (!ctx) {
BT_LOGE_STR("Cannot create visitor's context.");
goto error;
}
- trace = NULL;
goto end;
error:
ctx = NULL;
end:
- bt_put(trace);
return (void *) ctx;
}
}
BT_HIDDEN
-struct bt_ctf_trace *ctf_visitor_generate_ir_get_trace(
+struct bt_private_trace *ctf_visitor_generate_ir_get_ir_trace(
struct ctf_visitor_generate_ir *visitor)
{
struct ctx *ctx = (void *) visitor;
- assert(ctx);
- assert(ctx->trace);
- return bt_get(ctx->trace);
+ BT_ASSERT(ctx);
+ BT_ASSERT(ctx->trace);
+ return bt_object_get_ref(ctx->trace);
+}
+
+BT_HIDDEN
+struct ctf_trace_class *ctf_visitor_generate_ir_borrow_ctf_trace_class(
+ struct ctf_visitor_generate_ir *visitor)
+{
+ struct ctx *ctx = (void *) visitor;
+
+ BT_ASSERT(ctx);
+ BT_ASSERT(ctx->ctf_tc);
+ return ctx->ctf_tc;
}
BT_HIDDEN
case NODE_ROOT:
{
struct ctf_node *iter;
- int got_trace_decl = FALSE;
+ bool got_trace_decl = false;
/*
* The first thing we need is the native byte order of
- * the trace block, because early type aliases can have
+ * the trace block, because early class aliases can have
* a `byte_order` attribute set to `native`. If we don't
* have the native byte order yet, and we don't have any
* trace block yet, then fail with EINCOMPLETE.
*/
- if (ctx->trace_bo == BT_CTF_BYTE_ORDER_NATIVE) {
+ if (ctx->ctf_tc->default_byte_order == -1) {
bt_list_for_each_entry(iter, &node->u.root.trace, siblings) {
if (got_trace_decl) {
_BT_LOGE_NODE(node,
goto end;
}
- got_trace_decl = TRUE;
+ got_trace_decl = true;
}
if (!got_trace_decl) {
}
}
- assert(ctx->trace_bo == BT_CTF_BYTE_ORDER_LITTLE_ENDIAN ||
- ctx->trace_bo == BT_CTF_BYTE_ORDER_BIG_ENDIAN);
- assert(ctx->current_scope &&
- ctx->current_scope->parent_scope == NULL);
+ BT_ASSERT(ctx->ctf_tc->default_byte_order == CTF_BYTE_ORDER_LITTLE ||
+ ctx->ctf_tc->default_byte_order == CTF_BYTE_ORDER_BIG);
+ BT_ASSERT(ctx->current_scope &&
+ ctx->current_scope->parent_scope == NULL);
/* Environment */
bt_list_for_each_entry(iter, &node->u.root.env, siblings) {
}
}
- assert(ctx->current_scope &&
+ BT_ASSERT(ctx->current_scope &&
ctx->current_scope->parent_scope == NULL);
/*
}
}
- assert(ctx->current_scope &&
+ BT_ASSERT(ctx->current_scope &&
ctx->current_scope->parent_scope == NULL);
/*
}
}
- assert(ctx->current_scope &&
+ BT_ASSERT(ctx->current_scope &&
ctx->current_scope->parent_scope == NULL);
/* Callsite blocks are not supported */
"\"callsite\" blocks are not supported as of this version.");
}
- assert(ctx->current_scope &&
+ BT_ASSERT(ctx->current_scope &&
ctx->current_scope->parent_scope == NULL);
/* Trace */
}
}
- assert(ctx->current_scope &&
+ BT_ASSERT(ctx->current_scope &&
ctx->current_scope->parent_scope == NULL);
/* Streams */
}
}
- assert(ctx->current_scope &&
+ BT_ASSERT(ctx->current_scope &&
ctx->current_scope->parent_scope == NULL);
/* Events */
}
}
- assert(ctx->current_scope &&
+ BT_ASSERT(ctx->current_scope &&
ctx->current_scope->parent_scope == NULL);
break;
}
goto end;
}
- /* Move decoded stream classes to trace, if any */
- ret = move_ctx_stream_classes_to_trace(ctx);
+ /* Update default clock classes */
+ ret = ctf_trace_class_update_default_clock_classes(ctx->ctf_tc);
+ if (ret) {
+ ret = -EINVAL;
+ goto end;
+ }
+
+ /* Set trace's name, if not already done */
+ ret = try_set_trace_class_name(ctx);
+ if (ret) {
+ ret = -EINVAL;
+ goto end;
+ }
+
+ /* Update trace class meanings */
+ ret = ctf_trace_class_update_meanings(ctx->ctf_tc);
+ if (ret) {
+ ret = -EINVAL;
+ goto end;
+ }
+
+ /* Update text arrays and sequences */
+ ret = ctf_trace_class_update_text_array_sequence(ctx->ctf_tc);
+ if (ret) {
+ ret = -EINVAL;
+ goto end;
+ }
+
+ /* Resolve sequence lengths and variant tags */
+ ret = ctf_trace_class_resolve_field_classes(ctx->ctf_tc);
+ if (ret) {
+ ret = -EINVAL;
+ goto end;
+ }
+
+ /* Update "in IR" for field classes */
+ ret = ctf_trace_class_update_in_ir(ctx->ctf_tc);
+ if (ret) {
+ ret = -EINVAL;
+ goto end;
+ }
+
+ /* Update saved value indexes */
+ ret = ctf_trace_class_update_value_storing_indexes(ctx->ctf_tc);
if (ret) {
- BT_LOGE("Cannot move stream classes to trace: ret=%d", ret);
+ ret = -EINVAL;
+ goto end;
+ }
+
+ /* Validate what we have so far */
+ ret = ctf_trace_class_validate(ctx->ctf_tc);
+ if (ret) {
+ ret = -EINVAL;
+ goto end;
+ }
+
+ /* Copy new CTF metadata -> new IR metadata */
+ ret = ctf_trace_class_translate(ctx->trace, ctx->ctf_tc);
+ if (ret) {
+ ret = -EINVAL;
+ goto end;
}
end: