#include "common/list.h"
#include <babeltrace2/babeltrace.h>
#include "common/macros.h"
+#include "common/assert.h"
#include "decoder.h"
#include "ctf-meta.h"
int ctf_visitor_parent_links(int depth, struct ctf_node *node,
struct meta_log_config *log_cfg);
+static inline
+char *ctf_ast_concatenate_unary_strings(struct bt_list_head *head)
+{
+ int i = 0;
+ GString *str;
+ struct ctf_node *node;
+
+ str = g_string_new(NULL);
+ BT_ASSERT(str);
+
+ bt_list_for_each_entry(node, head, siblings) {
+ char *src_string;
+
+ if (
+ node->type != NODE_UNARY_EXPRESSION ||
+ node->u.unary_expression.type != UNARY_STRING ||
+ !(
+ (
+ node->u.unary_expression.link !=
+ UNARY_LINK_UNKNOWN
+ ) ^ (i == 0)
+ )
+ ) {
+ goto error;
+ }
+
+ switch (node->u.unary_expression.link) {
+ case UNARY_DOTLINK:
+ g_string_append(str, ".");
+ break;
+ case UNARY_ARROWLINK:
+ g_string_append(str, "->");
+ break;
+ case UNARY_DOTDOTDOT:
+ g_string_append(str, "...");
+ break;
+ default:
+ break;
+ }
+
+ src_string = node->u.unary_expression.u.string;
+ g_string_append(str, src_string);
+ i++;
+ }
+
+ /* Destroys the container, returns the underlying string */
+ return g_string_free(str, FALSE);
+
+error:
+ /* This always returns NULL */
+ return g_string_free(str, TRUE);
+}
+
+static inline
+int ctf_ast_get_unary_uuid(struct bt_list_head *head,
+ bt_uuid_t uuid, int log_level, bt_self_component *self_comp)
+{
+ int i = 0;
+ int ret = 0;
+ struct ctf_node *node;
+
+ bt_list_for_each_entry(node, head, siblings) {
+ int uexpr_type = node->u.unary_expression.type;
+ int uexpr_link = node->u.unary_expression.link;
+ const char *src_string;
+
+ if (node->type != NODE_UNARY_EXPRESSION ||
+ uexpr_type != UNARY_STRING ||
+ uexpr_link != UNARY_LINK_UNKNOWN ||
+ i != 0) {
+ ret = -EINVAL;
+ goto end;
+ }
+
+ src_string = node->u.unary_expression.u.string;
+ ret = bt_uuid_from_str(src_string, uuid);
+ if (ret) {
+#ifdef BT_COMP_LOG_CUR_LVL
+ BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, log_level,
+ self_comp,
+ "Cannot parse UUID: uuid=\"%s\"", src_string);
+#endif
+ goto end;
+ }
+ }
+
+end:
+ return ret;
+}
+
#endif /* _CTF_AST_H */
end:
return ret;
}
+
+static
+enum ctf_metadata_decoder_status find_uuid_in_trace_decl(
+ struct ctf_metadata_decoder *mdec, struct ctf_node *trace_node,
+ bt_uuid_t uuid)
+{
+ enum ctf_metadata_decoder_status status =
+ CTF_METADATA_DECODER_STATUS_OK;
+ struct ctf_node *entry_node;
+ struct bt_list_head *decl_list = &trace_node->u.trace.declaration_list;
+ char *left = NULL;
+
+ bt_list_for_each_entry(entry_node, decl_list, siblings) {
+ if (entry_node->type == NODE_CTF_EXPRESSION) {
+ int ret;
+
+ left = ctf_ast_concatenate_unary_strings(
+ &entry_node->u.ctf_expression.left);
+ if (!left) {
+ BT_COMP_LOGE("Cannot concatenate unary strings.");
+ status = CTF_METADATA_DECODER_STATUS_ERROR;
+ goto end;
+ }
+
+ if (strcmp(left, "uuid") == 0) {
+ ret = ctf_ast_get_unary_uuid(
+ &entry_node->u.ctf_expression.right,
+ uuid, mdec->config.log_level,
+ mdec->config.self_comp);
+ if (ret) {
+ BT_COMP_LOGE("Invalid trace's `uuid` attribute.");
+ status = CTF_METADATA_DECODER_STATUS_ERROR;
+ goto end;
+ }
+
+ goto end;
+ }
+
+ g_free(left);
+ left = NULL;
+ }
+ }
+
+ status = CTF_METADATA_DECODER_STATUS_NONE;
+
+end:
+ g_free(left);
+ return status;
+}
+
+BT_HIDDEN
+enum ctf_metadata_decoder_status ctf_metadata_decoder_get_trace_class_uuid(
+ struct ctf_metadata_decoder *mdec, bt_uuid_t uuid)
+{
+ enum ctf_metadata_decoder_status status =
+ CTF_METADATA_DECODER_STATUS_INCOMPLETE;
+ struct ctf_node *root_node = &mdec->scanner->ast->root;
+ struct ctf_node *trace_node;
+
+ if (!root_node) {
+ status = CTF_METADATA_DECODER_STATUS_INCOMPLETE;
+ goto end;
+ }
+
+ trace_node =
+ bt_list_entry(root_node->u.root.trace.next,
+ struct ctf_node, siblings);
+ if (!trace_node) {
+ status = CTF_METADATA_DECODER_STATUS_INCOMPLETE;
+ goto end;
+ }
+
+ status = find_uuid_in_trace_decl(mdec, trace_node, uuid);
+
+end:
+ return status;
+}
/* CTF metadata decoder status */
enum ctf_metadata_decoder_status {
CTF_METADATA_DECODER_STATUS_OK = 0,
+ CTF_METADATA_DECODER_STATUS_NONE = 1,
CTF_METADATA_DECODER_STATUS_ERROR = -1,
CTF_METADATA_DECODER_STATUS_INCOMPLETE = -2,
CTF_METADATA_DECODER_STATUS_INVAL_VERSION = -3,
/*
* Returns the UUID of the decoder's metadata stream as set by the last
* call to ctf_metadata_decoder_append_content().
+ */
+BT_HIDDEN
+int ctf_metadata_decoder_get_uuid(
+ struct ctf_metadata_decoder *mdec, bt_uuid_t uuid);
+
+/*
+ * Returns the UUID of the decoder's trace class, if available.
*
- * Returns -1 if unknown (plain text content).
+ * Returns:
+ *
+ * * `CTF_METADATA_DECODER_STATUS_OK`: success.
+ * * `CTF_METADATA_DECODER_STATUS_NONE`: no UUID.
+ * * `CTF_METADATA_DECODER_STATUS_INCOMPLETE`: missing metadata content.
*/
BT_HIDDEN
-int ctf_metadata_decoder_get_uuid(struct ctf_metadata_decoder *mdec,
- bt_uuid_t uuid);
+enum ctf_metadata_decoder_status ctf_metadata_decoder_get_trace_class_uuid(
+ struct ctf_metadata_decoder *mdec, bt_uuid_t uuid);
/*
* Returns the metadata decoder's current metadata text.
return ret;
}
-static
-char *concatenate_unary_strings(struct bt_list_head *head)
-{
- int i = 0;
- GString *str;
- struct ctf_node *node;
-
- str = g_string_new(NULL);
- BT_ASSERT(str);
-
- bt_list_for_each_entry(node, head, siblings) {
- char *src_string;
-
- if (
- node->type != NODE_UNARY_EXPRESSION ||
- node->u.unary_expression.type != UNARY_STRING ||
- !(
- (
- node->u.unary_expression.link !=
- UNARY_LINK_UNKNOWN
- ) ^ (i == 0)
- )
- ) {
- goto error;
- }
-
- switch (node->u.unary_expression.link) {
- case UNARY_DOTLINK:
- g_string_append(str, ".");
- break;
- case UNARY_ARROWLINK:
- g_string_append(str, "->");
- break;
- case UNARY_DOTDOTDOT:
- g_string_append(str, "...");
- break;
- default:
- break;
- }
-
- src_string = node->u.unary_expression.u.string;
- g_string_append(str, src_string);
- i++;
- }
-
- /* Destroys the container, returns the underlying string */
- return g_string_free(str, FALSE);
-
-error:
- /* This always returns NULL */
- return g_string_free(str, TRUE);
-}
-
static
const char *get_map_clock_name_value(struct bt_list_head *head)
{
return ret;
}
-static
int get_unary_uuid(struct ctx *ctx, struct bt_list_head *head,
- uint8_t *uuid)
+ bt_uuid_t uuid)
{
- int i = 0;
- int ret = 0;
- struct ctf_node *node;
-
- bt_list_for_each_entry(node, head, siblings) {
- int uexpr_type = node->u.unary_expression.type;
- int uexpr_link = node->u.unary_expression.link;
- const char *src_string;
-
- if (node->type != NODE_UNARY_EXPRESSION ||
- uexpr_type != UNARY_STRING ||
- uexpr_link != UNARY_LINK_UNKNOWN ||
- i != 0) {
- ret = -EINVAL;
- goto end;
- }
-
- src_string = node->u.unary_expression.u.string;
- ret = bt_uuid_from_str(src_string, uuid);
- if (ret) {
- _BT_COMP_LOGE_NODE(node,
- "Cannot parse UUID: uuid=\"%s\"", src_string);
- goto end;
- }
- }
-
-end:
- return ret;
+ return ctf_ast_get_unary_uuid(head, uuid, ctx->log_cfg.log_level,
+ ctx->log_cfg.self_comp);
}
static
{
/* Lookup unsigned integer definition, create seq. */
struct ctf_field_class_sequence *seq_decl = NULL;
- char *length_name = concatenate_unary_strings(length);
+ char *length_name = ctf_ast_concatenate_unary_strings(length);
if (!length_name) {
_BT_COMP_LOGE_NODE(node_field_class_declarator,
}
case UNARY_STRING:
{
- char *s_right = concatenate_unary_strings(
+ char *s_right = ctf_ast_concatenate_unary_strings(
&expression->u.ctf_expression.right);
if (!s_right) {
_BT_COMP_LOGE_NODE(right,
goto error;
}
- s_right = concatenate_unary_strings(
+ s_right = ctf_ast_concatenate_unary_strings(
&expression->u.ctf_expression.right);
if (!s_right) {
_BT_COMP_LOGE_NODE(right,
get_map_clock_name_value(
&expression->u.ctf_expression.right);
if (!clock_name) {
- char *s_right = concatenate_unary_strings(
+ char *s_right = ctf_ast_concatenate_unary_strings(
&expression->u.ctf_expression.right);
if (!s_right) {
goto error;
}
- s_right = concatenate_unary_strings(
+ s_right = ctf_ast_concatenate_unary_strings(
&expression->u.ctf_expression.right);
if (!s_right) {
_BT_COMP_LOGE_NODE(right,
break;
case NODE_CTF_EXPRESSION:
{
- left = concatenate_unary_strings(&node->u.ctf_expression.left);
+ left = ctf_ast_concatenate_unary_strings(&node->u.ctf_expression.left);
if (!left) {
_BT_COMP_LOGE_NODE(node, "Cannot concatenate unary strings.");
ret = -EINVAL;
goto error;
}
- right = concatenate_unary_strings(
+ right = ctf_ast_concatenate_unary_strings(
&node->u.ctf_expression.right);
if (!right) {
_BT_COMP_LOGE_NODE(node,
continue;
}
- left = concatenate_unary_strings(&iter->u.ctf_expression.left);
+ left = ctf_ast_concatenate_unary_strings(&iter->u.ctf_expression.left);
if (!left) {
_BT_COMP_LOGE_NODE(iter,
"Cannot concatenate unary strings.");
}
if (strcmp(left, "name") == 0) {
- name = concatenate_unary_strings(
+ name = ctf_ast_concatenate_unary_strings(
&iter->u.ctf_expression.right);
if (!name) {
_BT_COMP_LOGE_NODE(iter,
break;
case NODE_CTF_EXPRESSION:
{
- left = concatenate_unary_strings(&node->u.ctf_expression.left);
+ left = ctf_ast_concatenate_unary_strings(&node->u.ctf_expression.left);
if (!left) {
_BT_COMP_LOGE_NODE(node, "Cannot concatenate unary strings.");
ret = -EINVAL;
break;
case NODE_CTF_EXPRESSION:
{
- left = concatenate_unary_strings(&node->u.ctf_expression.left);
+ left = ctf_ast_concatenate_unary_strings(&node->u.ctf_expression.left);
if (!left) {
_BT_COMP_LOGE_NODE(node, "Cannot concatenate unary strings.");
ret = -EINVAL;
goto error;
}
- left = concatenate_unary_strings(
+ left = ctf_ast_concatenate_unary_strings(
&entry_node->u.ctf_expression.left);
if (!left) {
_BT_COMP_LOGE_NODE(entry_node,
}
if (is_unary_string(right_head)) {
- char *right = concatenate_unary_strings(right_head);
+ char *right = ctf_ast_concatenate_unary_strings(right_head);
if (!right) {
_BT_COMP_LOGE_NODE(entry_node,
if (node->type == NODE_CTF_EXPRESSION) {
struct ctf_node *right_node;
- left = concatenate_unary_strings(
+ left = ctf_ast_concatenate_unary_strings(
&node->u.ctf_expression.left);
if (!left) {
_BT_COMP_LOGE_NODE(node,
goto error;
}
- left = concatenate_unary_strings(&entry_node->u.ctf_expression.left);
+ left = ctf_ast_concatenate_unary_strings(&entry_node->u.ctf_expression.left);
if (!left) {
_BT_COMP_LOGE_NODE(entry_node, "Cannot concatenate unary strings.");
ret = -EINVAL;
goto error;
}
- right = concatenate_unary_strings(
+ right = ctf_ast_concatenate_unary_strings(
&entry_node->u.ctf_expression.right);
if (!right) {
_BT_COMP_LOGE_NODE(entry_node,
goto error;
}
- right = concatenate_unary_strings(
+ right = ctf_ast_concatenate_unary_strings(
&entry_node->u.ctf_expression.right);
if (!right) {
_BT_COMP_LOGE_NODE(entry_node,