static struct bt_value *bt_attributes_get_field_by_name( struct bt_value *attr_obj, const char *name) { uint64_t i; int64_t attr_size; struct bt_value *value_obj = NULL; struct bt_value *attr_field_name_obj = NULL; attr_size = bt_value_array_size(attr_obj); if (attr_size < 0) { BT_LOGE("Cannot get array value's size: value-addr=%p", attr_obj); goto error; } for (i = 0; i < attr_size; ++i) { int ret; const char *field_name; value_obj = bt_value_array_get(attr_obj, i); if (!value_obj) { BT_LOGE("Cannot get attributes object's array value's element by index: " "value-addr=%p, index=%" PRIu64, attr_obj, i); goto error; } attr_field_name_obj = bt_value_array_get(value_obj, 0); if (!attr_field_name_obj) { BT_LOGE("Cannot get attribute array value's element by index: " "value-addr=%p, index=%" PRIu64, value_obj, (int64_t) 0); goto error; } ret = bt_value_string_get(attr_field_name_obj, &field_name); if (ret) { BT_LOGE("Cannot get raw value from string value: value-addr=%p", attr_field_name_obj); goto error; } if (!strcmp(field_name, name)) { BT_PUT(attr_field_name_obj); break; } BT_PUT(attr_field_name_obj); BT_PUT(value_obj); } return value_obj; error: BT_PUT(attr_field_name_obj); BT_PUT(value_obj); return value_obj; }
static int set_trace_name(bt_trace *trace, const char *name_suffix) { int ret = 0; const bt_trace_class *tc = bt_trace_borrow_class_const(trace); const bt_value *val; GString *name; name = g_string_new(NULL); if (!name) { BT_LOGE_STR("Failed to allocate a GString."); ret = -1; goto end; } /* * Check if we have a trace environment string value named `hostname`. * If so, use it as the trace name's prefix. */ val = bt_trace_class_borrow_environment_entry_value_by_name_const( tc, "hostname"); if (val && bt_value_is_string(val)) { g_string_append(name, bt_value_string_get(val)); if (name_suffix) { g_string_append_c(name, G_DIR_SEPARATOR); } } if (name_suffix) { g_string_append(name, name_suffix); } ret = bt_trace_set_name(trace, name->str); if (ret) { goto end; } goto end; end: if (name) { g_string_free(name, TRUE); } return ret; }
BT_HIDDEN const char *bt_attributes_get_field_name(struct bt_value *attr_obj, uint64_t index) { int rc; const char *ret = NULL; struct bt_value *attr_field_obj = NULL; struct bt_value *attr_field_name_obj = NULL; if (!attr_obj) { BT_LOGW_STR("Invalid parameter: attributes object is NULL."); goto end; } attr_field_obj = bt_value_array_get(attr_obj, index); if (!attr_field_obj) { BT_LOGE("Cannot get attributes object's array value's element by index: " "value-addr=%p, index=%" PRIu64, attr_obj, index); goto end; } attr_field_name_obj = bt_value_array_get(attr_field_obj, BT_ATTR_NAME_INDEX); if (!attr_field_name_obj) { BT_LOGE("Cannot get attribute array value's element by index: " "value-addr=%p, index=%" PRIu64, attr_field_obj, (uint64_t) BT_ATTR_NAME_INDEX); goto end; } rc = bt_value_string_get(attr_field_name_obj, &ret); if (rc) { BT_LOGE("Cannot get raw value from string value: value-addr=%p", attr_field_name_obj); ret = NULL; } end: BT_PUT(attr_field_name_obj); BT_PUT(attr_field_obj); return ret; }
int ctf_fs_component_create_ctf_fs_traces(bt_self_component_source *self_comp, struct ctf_fs_component *ctf_fs, const bt_value *paths_value) { int ret = 0; uint64_t i; for (i = 0; i < bt_value_array_get_size(paths_value); i++) { const bt_value *path_value = bt_value_array_borrow_element_by_index_const(paths_value, i); const char *path = bt_value_string_get(path_value); ret = ctf_fs_component_create_ctf_fs_traces_one_root(self_comp, ctf_fs, path); if (ret) { goto end; } } merge_traces_with_same_uuid(ctf_fs); end: return ret; }
BT_HIDDEN const char *bt_ctf_event_class_get_name(struct bt_ctf_event_class *event_class) { struct bt_value *obj = NULL; const char *name = NULL; if (!event_class) { goto end; } obj = bt_ctf_attributes_get_field_value(event_class->attributes, BT_CTF_EVENT_CLASS_ATTR_NAME_INDEX); if (!obj) { goto end; } if (bt_value_string_get(obj, &name)) { name = NULL; } end: BT_PUT(obj); return name; }
static void append_env_metadata(struct bt_ctf_trace *trace, struct metadata_context *context) { int i; int env_size; env_size = bt_ctf_attributes_get_count(trace->environment); if (env_size <= 0) { return; } g_string_append(context->string, "env {\n"); for (i = 0; i < env_size; ++i) { struct bt_value *env_field_value_obj = NULL; const char *entry_name; entry_name = bt_ctf_attributes_get_field_name( trace->environment, i); env_field_value_obj = bt_ctf_attributes_get_field_value( trace->environment, i); if (!entry_name || !env_field_value_obj) { goto loop_next; } switch (bt_value_get_type(env_field_value_obj)) { case BT_VALUE_TYPE_INTEGER: { int ret; int64_t int_value; ret = bt_value_integer_get(env_field_value_obj, &int_value); if (ret) { goto loop_next; } g_string_append_printf(context->string, "\t%s = %" PRId64 ";\n", entry_name, int_value); break; } case BT_VALUE_TYPE_STRING: { int ret; const char *str_value; char *escaped_str = NULL; ret = bt_value_string_get(env_field_value_obj, &str_value); if (ret) { goto loop_next; } escaped_str = g_strescape(str_value, NULL); if (!escaped_str) { goto loop_next; } g_string_append_printf(context->string, "\t%s = \"%s\";\n", entry_name, escaped_str); free(escaped_str); break; } default: goto loop_next; } loop_next: BT_PUT(env_field_value_obj); } g_string_append(context->string, "};\n\n"); }
BT_HIDDEN int bt_ctf_event_class_serialize(struct bt_ctf_event_class *event_class, struct metadata_context *context) { int i; int count; int ret = 0; struct bt_value *attr_value = NULL; assert(event_class); assert(context); context->current_indentation_level = 1; g_string_assign(context->field_name, ""); g_string_append(context->string, "event {\n"); count = bt_ctf_event_class_get_attribute_count(event_class); if (count < 0) { ret = -1; goto end; } for (i = 0; i < count; ++i) { const char *attr_name = NULL; attr_name = bt_ctf_event_class_get_attribute_name( event_class, i); attr_value = bt_ctf_event_class_get_attribute_value( event_class, i); if (!attr_name || !attr_value) { ret = -1; goto end; } switch (bt_value_get_type(attr_value)) { case BT_VALUE_TYPE_INTEGER: { int64_t value; ret = bt_value_integer_get(attr_value, &value); if (ret) { goto end; } g_string_append_printf(context->string, "\t%s = %" PRId64 ";\n", attr_name, value); break; } case BT_VALUE_TYPE_STRING: { const char *value; ret = bt_value_string_get(attr_value, &value); if (ret) { goto end; } g_string_append_printf(context->string, "\t%s = \"%s\";\n", attr_name, value); break; } default: /* should never happen */ assert(false); break; } BT_PUT(attr_value); } if (event_class->context) { g_string_append(context->string, "\tcontext := "); ret = bt_ctf_field_type_serialize(event_class->context, context); if (ret) { goto end; } g_string_append(context->string, ";\n"); } if (event_class->fields) { g_string_append(context->string, "\tfields := "); ret = bt_ctf_field_type_serialize(event_class->fields, context); if (ret) { goto end; } g_string_append(context->string, ";\n"); } g_string_append(context->string, "};\n\n"); end: context->current_indentation_level = 0; BT_PUT(attr_value); return ret; }
/* * Parses a timestamp, figuring out its format. * * Returns a negative value if anything goes wrong. * * Expected formats: * * YYYY-MM-DD hh:mm:ss.ns * hh:mm:ss.ns * -ss.ns * ss.ns * YYYY-MM-DD hh:mm:ss * hh:mm:ss * -ss * ss */ static int timestamp_from_arg(const char *arg, struct trimmer *trimmer, struct trimmer_bound *result_bound, bt_bool gmt) { int ret; int64_t value; unsigned int year, month, day, hh, mm, ss, ns; /* YYYY-MM-DD hh:mm:ss.ns */ ret = sscanf(arg, "%u-%u-%u %u:%u:%u.%u", &year, &month, &day, &hh, &mm, &ss, &ns); if (ret == 7) { struct tm tm = { .tm_sec = ss, .tm_min = mm, .tm_hour = hh, .tm_mday = day, .tm_mon = month - 1, .tm_year = year - 1900, .tm_isdst = -1, }; time_t result; if (gmt) { result = bt_timegm(&tm); if (result < 0) { return -1; } } else { result = mktime(&tm); if (result < 0) { return -1; } } value = (int64_t) result; value *= NSEC_PER_SEC; value += ns; if (!trimmer->date) { trimmer->year = year; trimmer->month = month; trimmer->day = day; trimmer->date = true; } goto set; } /* hh:mm:ss.ns */ ret = sscanf(arg, "%u:%u:%u.%u", &hh, &mm, &ss, &ns); if (ret == 4) { if (!trimmer->date) { /* We don't know which day until we get an event. */ result_bound->lazy_values.hh = hh; result_bound->lazy_values.mm = mm; result_bound->lazy_values.ss = ss; result_bound->lazy_values.ns = ns; result_bound->lazy_values.gmt = gmt; goto lazy; } else { struct tm tm = { .tm_sec = ss, .tm_min = mm, .tm_hour = hh, .tm_mday = trimmer->day, .tm_mon = trimmer->month - 1, .tm_year = trimmer->year - 1900, .tm_isdst = -1, }; time_t result; if (gmt) { result = bt_timegm(&tm); if (result < 0) { return -1; } } else { result = mktime(&tm); if (result < 0) { return -1; } } value = (int64_t) result; value *= NSEC_PER_SEC; value += ns; goto set; } } /* -ss.ns */ ret = sscanf(arg, "-%u.%u", &ss, &ns); if (ret == 2) { value = -ss * NSEC_PER_SEC; value -= ns; goto set; } /* ss.ns */ ret = sscanf(arg, "%u.%u", &ss, &ns); if (ret == 2) { value = ss * NSEC_PER_SEC; value += ns; goto set; } /* YYYY-MM-DD hh:mm:ss */ ret = sscanf(arg, "%u-%u-%u %u:%u:%u", &year, &month, &day, &hh, &mm, &ss); if (ret == 6) { struct tm tm = { .tm_sec = ss, .tm_min = mm, .tm_hour = hh, .tm_mday = day, .tm_mon = month - 1, .tm_year = year - 1900, .tm_isdst = -1, }; if (gmt) { value = bt_timegm(&tm); if (value < 0) { return -1; } } else { value = mktime(&tm); if (value < 0) { return -1; } } value *= NSEC_PER_SEC; if (!trimmer->date) { trimmer->year = year; trimmer->month = month; trimmer->day = day; trimmer->date = true; } goto set; } /* hh:mm:ss */ ret = sscanf(arg, "%u:%u:%u", &hh, &mm, &ss); if (ret == 3) { if (!trimmer->date) { /* We don't know which day until we get an event. */ result_bound->lazy_values.hh = hh; result_bound->lazy_values.mm = mm; result_bound->lazy_values.ss = ss; result_bound->lazy_values.ns = 0; result_bound->lazy_values.gmt = gmt; goto lazy; } else { struct tm tm = { .tm_sec = ss, .tm_min = mm, .tm_hour = hh, .tm_mday = trimmer->day, .tm_mon = trimmer->month - 1, .tm_year = trimmer->year - 1900, .tm_isdst = -1, }; time_t result; if (gmt) { result = bt_timegm(&tm); if (result < 0) { return -1; } } else { result = mktime(&tm); if (result < 0) { return -1; } } value = (int64_t) result; value *= NSEC_PER_SEC; goto set; } } /* -ss */ ret = sscanf(arg, "-%u", &ss); if (ret == 1) { value = -ss * NSEC_PER_SEC; goto set; } /* ss */ ret = sscanf(arg, "%u", &ss); if (ret == 1) { value = ss * NSEC_PER_SEC; goto set; } /* Not found. */ return -1; set: result_bound->value = value; result_bound->set = true; return 0; lazy: result_bound->lazy = true; return 0; } static enum bt_component_status init_from_params(struct trimmer *trimmer, struct bt_value *params) { struct bt_value *value = NULL; bt_bool gmt = BT_FALSE; enum bt_component_status ret = BT_COMPONENT_STATUS_OK; assert(params); value = bt_value_map_get(params, "clock-gmt"); if (value) { enum bt_value_status value_ret; value_ret = bt_value_bool_get(value, &gmt); if (value_ret) { ret = BT_COMPONENT_STATUS_INVALID; printf_error("Failed to retrieve clock-gmt value. Expecting a boolean"); } } bt_put(value); if (ret != BT_COMPONENT_STATUS_OK) { goto end; } value = bt_value_map_get(params, "begin"); if (value) { enum bt_value_status value_ret; const char *str; value_ret = bt_value_string_get(value, &str); if (value_ret || timestamp_from_arg(str, trimmer, &trimmer->begin, gmt)) { ret = BT_COMPONENT_STATUS_INVALID; printf_error("Failed to retrieve begin value. Expecting a timestamp string"); } } bt_put(value); if (ret != BT_COMPONENT_STATUS_OK) { goto end; } value = bt_value_map_get(params, "end"); if (value) { enum bt_value_status value_ret; const char *str; value_ret = bt_value_string_get(value, &str); if (value_ret || timestamp_from_arg(str, trimmer, &trimmer->end, gmt)) { ret = BT_COMPONENT_STATUS_INVALID; printf_error("Failed to retrieve end value. Expecting a timestamp string"); } } bt_put(value); end: if (trimmer->begin.set && trimmer->end.set) { if (trimmer->begin.value > trimmer->end.value) { printf_error("Unexpected: time range begin value is above end value"); ret = BT_COMPONENT_STATUS_INVALID; } } return ret; } enum bt_component_status trimmer_component_init( struct bt_private_component *component, struct bt_value *params, UNUSED_VAR void *init_method_data) { enum bt_component_status ret; struct trimmer *trimmer = create_trimmer_data(); if (!trimmer) { ret = BT_COMPONENT_STATUS_NOMEM; goto end; } /* Create input and output ports */ ret = bt_private_component_filter_add_input_private_port( component, "in", NULL, NULL); if (ret != BT_COMPONENT_STATUS_OK) { goto error; } ret = bt_private_component_filter_add_output_private_port( component, "out", NULL, NULL); if (ret != BT_COMPONENT_STATUS_OK) { goto error; } ret = bt_private_component_set_user_data(component, trimmer); if (ret != BT_COMPONENT_STATUS_OK) { goto error; } ret = init_from_params(trimmer, params); end: return ret; error: destroy_trimmer_data(trimmer); ret = BT_COMPONENT_STATUS_ERROR; return ret; }