X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=cli%2Fbabeltrace-cfg-cli-args.c;h=06385a35d1e908edfd3b0c9bd0870894ecdf6210;hb=136906ad574dff33d6266173e577e3f2a9518d1f;hp=60e5605df69b8ab25bdbe60e7e2ef961ee3c9991;hpb=8ed0bf1041490e214247a7ad8cb013f0f36c7f2c;p=deliverable%2Fbabeltrace.git diff --git a/cli/babeltrace-cfg-cli-args.c b/cli/babeltrace-cfg-cli-args.c index 60e5605df..06385a35d 100644 --- a/cli/babeltrace-cfg-cli-args.c +++ b/cli/babeltrace-cfg-cli-args.c @@ -28,19 +28,19 @@ #include #include #include -#include +#include #include #include #include #include #include -#include #include #include #include #include "babeltrace-cfg.h" #include "babeltrace-cfg-cli-args.h" #include "babeltrace-cfg-cli-args-connect.h" +#include "version.h" /* * Error printf() macro which prepends "Error: " the first time it's @@ -70,9 +70,6 @@ enum ini_parsing_fsm_state { /* Expect a value */ INI_EXPECT_VALUE, - /* Expect a negative number value */ - INI_EXPECT_VALUE_NUMBER_NEG, - /* Expect a comma character (',') */ INI_EXPECT_COMMA, }; @@ -83,7 +80,7 @@ struct ini_parsing_state { GScanner *scanner; /* Output map value object being filled (owned by this) */ - struct bt_value *params; + bt_value *params; /* Next expected FSM state */ enum ini_parsing_fsm_state expecting; @@ -120,8 +117,8 @@ struct text_legacy_opts { GString *output; GString *dbg_info_dir; GString *dbg_info_target_prefix; - struct bt_value *names; - struct bt_value *fields; + const bt_value *names; + const bt_value *fields; /* Flags */ bool no_delta; @@ -188,12 +185,202 @@ void ini_append_error_expecting(struct ini_parsing_state *state, g_string_append_printf(state->ini_error, "^\n\n"); } +/* Parse the next token as a number and return its negation. */ +static +bt_value *ini_parse_neg_number(struct ini_parsing_state *state) +{ + bt_value *value = NULL; + GTokenType token_type = g_scanner_get_next_token(state->scanner); + + switch (token_type) { + case G_TOKEN_INT: + { + /* Negative integer */ + uint64_t int_val = state->scanner->value.v_int64; + + if (int_val > (((uint64_t) INT64_MAX) + 1)) { + g_string_append_printf(state->ini_error, + "Integer value -%" PRIu64 " is outside the range of a 64-bit signed integer\n", + int_val); + } else { + value = bt_value_integer_create_init(-((int64_t) int_val)); + } + + break; + } + case G_TOKEN_FLOAT: + /* Negative floating point number */ + value = bt_value_real_create_init(-state->scanner->value.v_float); + break; + default: + ini_append_error_expecting(state, state->scanner, "value"); + break; + } + + return value; +} + +static bt_value *ini_parse_value(struct ini_parsing_state *state); + +/* + * Parse the current and following tokens as an array. Arrays are formatted as + * an opening `[`, a list of comma-separated values and a closing `]`. For + * convenience we support an optional trailing comma, after the last value. + * + * The current token of the parser must be the opening square bracket of the + * array. + */ +static +bt_value *ini_parse_array(struct ini_parsing_state *state) +{ + /* The [ character must have already been ingested. */ + BT_ASSERT(g_scanner_cur_token(state->scanner) == G_TOKEN_CHAR); + BT_ASSERT(g_scanner_cur_value(state->scanner).v_char == '['); + + bt_value *array_value; + GTokenType token_type; + + array_value = bt_value_array_create (); + token_type = g_scanner_get_next_token(state->scanner); + + /* While the current token is not a ]... */ + while (!(token_type == G_TOKEN_CHAR && g_scanner_cur_value(state->scanner).v_char == ']')) { + /* Parse the item... */ + bt_value *item_value; + bt_value_status status; + + item_value = ini_parse_value(state); + if (!item_value) { + goto error; + } + + /* ... and add it to the result array. */ + status = bt_value_array_append_element(array_value, item_value); + BT_VALUE_PUT_REF_AND_RESET(item_value); + + if (status != BT_VALUE_STATUS_OK) { + goto error; + } + + /* + * Ingest the token following the value, it should be either a + * comma or closing square brace. + */ + token_type = g_scanner_get_next_token(state->scanner); + + if (token_type == G_TOKEN_CHAR && g_scanner_cur_value(state->scanner).v_char == ',') { + /* + * Ingest the token following the comma. If it happens + * to be a closing square bracket, we'll exit the loop + * and we are done (we allow trailing commas). + * Otherwise, we are ready for the next ini_parse_value call. + */ + token_type = g_scanner_get_next_token(state->scanner); + } else if (token_type != G_TOKEN_CHAR || g_scanner_cur_value(state->scanner).v_char != ']') { + ini_append_error_expecting(state, state->scanner, ", or ]"); + goto error; + } + } + + goto end; + +error: + BT_VALUE_PUT_REF_AND_RESET(array_value); + +end: + return array_value; +} + +/* + * Parse the current token (and the following ones if needed) as a value, return + * it as a bt_value. + */ +static +bt_value *ini_parse_value(struct ini_parsing_state *state) +{ + bt_value *value = NULL; + GTokenType token_type = state->scanner->token; + + switch (token_type) { + case G_TOKEN_CHAR: + if (state->scanner->value.v_char == '-') { + /* Negative number */ + value = ini_parse_neg_number(state); + } else if (state->scanner->value.v_char == '[') { + /* Array */ + value = ini_parse_array(state); + } else { + ini_append_error_expecting(state, state->scanner, "value"); + } + break; + case G_TOKEN_INT: + { + /* Positive integer */ + uint64_t int_val = state->scanner->value.v_int64; + + if (int_val > INT64_MAX) { + g_string_append_printf(state->ini_error, + "Integer value %" PRIu64 " is outside the range of a 64-bit signed integer\n", + int_val); + } else { + value = bt_value_integer_create_init((int64_t)int_val); + } + break; + } + case G_TOKEN_FLOAT: + /* Positive floating point number */ + value = bt_value_real_create_init(state->scanner->value.v_float); + break; + case G_TOKEN_STRING: + /* Quoted string */ + value = bt_value_string_create_init(state->scanner->value.v_string); + break; + case G_TOKEN_IDENTIFIER: + { + /* + * Using symbols would be appropriate here, + * but said symbols are allowed as map key, + * so it's easier to consider everything an + * identifier. + * + * If one of the known symbols is not + * recognized here, then fall back to creating + * a string value. + */ + const char *id = state->scanner->value.v_identifier; + + if (!strcmp(id, "null") || !strcmp(id, "NULL") || + !strcmp(id, "nul")) { + value = bt_value_null; + } else if (!strcmp(id, "true") || !strcmp(id, "TRUE") || + !strcmp(id, "yes") || + !strcmp(id, "YES")) { + value = bt_value_bool_create_init(true); + } else if (!strcmp(id, "false") || + !strcmp(id, "FALSE") || + !strcmp(id, "no") || + !strcmp(id, "NO")) { + value = bt_value_bool_create_init(false); + } else { + value = bt_value_string_create_init(id); + } + break; + } + default: + /* Unset value variable will trigger the error */ + ini_append_error_expecting(state, state->scanner, "value"); + break; + } + + return value; +} + static int ini_handle_state(struct ini_parsing_state *state) { int ret = 0; GTokenType token_type; - struct bt_value *value = NULL; + bt_value *value = NULL; token_type = g_scanner_get_next_token(state->scanner); if (token_type == G_TOKEN_EOF) { @@ -204,7 +391,6 @@ int ini_handle_state(struct ini_parsing_state *state) state->scanner, "'='"); break; case INI_EXPECT_VALUE: - case INI_EXPECT_VALUE_NUMBER_NEG: ini_append_error_expecting(state, state->scanner, "value"); break; @@ -240,7 +426,8 @@ int ini_handle_state(struct ini_parsing_state *state) goto error; } - if (bt_value_map_has_key(state->params, state->last_map_key)) { + if (bt_value_map_has_entry(state->params, + state->last_map_key)) { g_string_append_printf(state->ini_error, "Duplicate parameter key: `%s`\n", state->last_map_key); @@ -266,122 +453,8 @@ int ini_handle_state(struct ini_parsing_state *state) goto success; case INI_EXPECT_VALUE: { - switch (token_type) { - case G_TOKEN_CHAR: - if (state->scanner->value.v_char == '-') { - /* Negative number */ - state->expecting = - INI_EXPECT_VALUE_NUMBER_NEG; - goto success; - } else { - ini_append_error_expecting(state, - state->scanner, "value"); - goto error; - } - break; - case G_TOKEN_INT: - { - /* Positive integer */ - uint64_t int_val = state->scanner->value.v_int64; - - if (int_val > (1ULL << 63) - 1) { - g_string_append_printf(state->ini_error, - "Integer value %" PRIu64 " is outside the range of a 64-bit signed integer\n", - int_val); - goto error; - } - - value = bt_value_integer_create_init( - (int64_t) int_val); - break; - } - case G_TOKEN_FLOAT: - /* Positive floating point number */ - value = bt_value_float_create_init( - state->scanner->value.v_float); - break; - case G_TOKEN_STRING: - /* Quoted string */ - value = bt_value_string_create_init( - state->scanner->value.v_string); - break; - case G_TOKEN_IDENTIFIER: - { - /* - * Using symbols would be appropriate here, - * but said symbols are allowed as map key, - * so it's easier to consider everything an - * identifier. - * - * If one of the known symbols is not - * recognized here, then fall back to creating - * a string value. - */ - const char *id = state->scanner->value.v_identifier; - - if (!strcmp(id, "null") || !strcmp(id, "NULL") || - !strcmp(id, "nul")) { - value = bt_value_null; - } else if (!strcmp(id, "true") || !strcmp(id, "TRUE") || - !strcmp(id, "yes") || - !strcmp(id, "YES")) { - value = bt_value_bool_create_init(true); - } else if (!strcmp(id, "false") || - !strcmp(id, "FALSE") || - !strcmp(id, "no") || - !strcmp(id, "NO")) { - value = bt_value_bool_create_init(false); - } else { - value = bt_value_string_create_init(id); - } - break; - } - default: - /* Unset value variable will trigger the error */ - break; - } - - if (!value) { - ini_append_error_expecting(state, - state->scanner, "value"); - goto error; - } - - state->expecting = INI_EXPECT_COMMA; - goto success; - } - case INI_EXPECT_VALUE_NUMBER_NEG: - { - switch (token_type) { - case G_TOKEN_INT: - { - /* Negative integer */ - uint64_t int_val = state->scanner->value.v_int64; - - if (int_val > (1ULL << 63) - 1) { - g_string_append_printf(state->ini_error, - "Integer value -%" PRIu64 " is outside the range of a 64-bit signed integer\n", - int_val); - goto error; - } - - value = bt_value_integer_create_init( - -((int64_t) int_val)); - break; - } - case G_TOKEN_FLOAT: - /* Negative floating point number */ - value = bt_value_float_create_init( - -state->scanner->value.v_float); - break; - default: - /* Unset value variable will trigger the error */ - break; - } - + value = ini_parse_value(state); if (!value) { - ini_append_error_expecting(state, - state->scanner, "value"); goto error; } @@ -413,7 +486,7 @@ error: success: if (value) { - if (bt_value_map_insert(state->params, + if (bt_value_map_insert_entry(state->params, state->last_map_key, value)) { /* Only override return value on error */ ret = -1; @@ -421,7 +494,7 @@ success: } end: - BT_PUT(value); + BT_VALUE_PUT_REF_AND_RESET(value); return ret; } @@ -431,7 +504,8 @@ end: * Return value is owned by the caller. */ static -struct bt_value *bt_value_from_ini(const char *arg, GString *ini_error) +bt_value *bt_value_from_ini(const char *arg, + GString *ini_error) { /* Lexical scanner configuration */ GScannerConfig scanner_config = { @@ -538,7 +612,7 @@ struct bt_value *bt_value_from_ini(const char *arg, GString *ini_error) goto end; error: - BT_PUT(state.params); + BT_VALUE_PUT_REF_AND_RESET(state.params); end: if (state.scanner) { @@ -556,9 +630,9 @@ end: * Return value is owned by the caller. */ static -struct bt_value *bt_value_from_arg(const char *arg) +bt_value *bt_value_from_arg(const char *arg) { - struct bt_value *params = NULL; + bt_value *params = NULL; GString *ini_error = NULL; ini_error = g_string_new(NULL); @@ -578,6 +652,7 @@ end: if (ini_error) { g_string_free(ini_error, TRUE); } + return params; } @@ -598,7 +673,7 @@ end: */ static void plugin_comp_cls_names(const char *arg, char **name, char **plugin, - char **comp_cls, enum bt_component_class_type *comp_cls_type) + char **comp_cls, bt_component_class_type *comp_cls_type) { const char *at = arg; GString *gs_name = NULL; @@ -607,10 +682,10 @@ void plugin_comp_cls_names(const char *arg, char **name, char **plugin, GString *gs_comp_cls = NULL; size_t end_pos; - assert(arg); - assert(plugin); - assert(comp_cls); - assert(comp_cls_type); + BT_ASSERT(arg); + BT_ASSERT(plugin); + BT_ASSERT(comp_cls); + BT_ASSERT(comp_cls_type); if (!bt_common_string_is_printable(arg)) { printf_err("Argument contains a non-printable character\n"); @@ -729,14 +804,18 @@ end: static void print_version(void) { - puts("Babeltrace " VERSION); + if (GIT_VERSION[0] == '\0') { + puts("Babeltrace " VERSION); + } else { + puts("Babeltrace " VERSION " - " GIT_VERSION); + } } /* * Destroys a component configuration. */ static -void bt_config_component_destroy(struct bt_object *obj) +void bt_config_component_destroy(bt_object *obj) { struct bt_config_component *bt_config_component = container_of(obj, struct bt_config_component, base); @@ -757,7 +836,7 @@ void bt_config_component_destroy(struct bt_object *obj) g_string_free(bt_config_component->instance_name, TRUE); } - BT_PUT(bt_config_component->params); + BT_VALUE_PUT_REF_AND_RESET(bt_config_component->params); g_free(bt_config_component); end: @@ -773,7 +852,7 @@ end: */ static struct bt_config_component *bt_config_component_create( - enum bt_component_class_type type, + bt_component_class_type type, const char *plugin_name, const char *comp_cls_name) { struct bt_config_component *cfg_component = NULL; @@ -784,7 +863,8 @@ struct bt_config_component *bt_config_component_create( goto error; } - bt_object_init(cfg_component, bt_config_component_destroy); + bt_object_init_shared(&cfg_component->base, + bt_config_component_destroy); cfg_component->type = type; cfg_component->plugin_name = g_string_new(plugin_name); if (!cfg_component->plugin_name) { @@ -814,7 +894,7 @@ struct bt_config_component *bt_config_component_create( goto end; error: - BT_PUT(cfg_component); + BT_OBJECT_PUT_REF_AND_RESET(cfg_component); end: return cfg_component; @@ -831,7 +911,7 @@ struct bt_config_component *bt_config_component_from_arg(const char *arg) char *name = NULL; char *plugin_name = NULL; char *comp_cls_name = NULL; - enum bt_component_class_type type; + bt_component_class_type type; plugin_comp_cls_names(arg, &name, &plugin_name, &comp_cls_name, &type); if (!plugin_name || !comp_cls_name) { @@ -850,7 +930,7 @@ struct bt_config_component *bt_config_component_from_arg(const char *arg) goto end; error: - BT_PUT(cfg_comp); + BT_OBJECT_PUT_REF_AND_RESET(cfg_comp); end: g_free(name); @@ -863,7 +943,7 @@ end: * Destroys a configuration. */ static -void bt_config_destroy(struct bt_object *obj) +void bt_config_destroy(bt_object *obj) { struct bt_config *cfg = container_of(obj, struct bt_config, base); @@ -872,7 +952,7 @@ void bt_config_destroy(struct bt_object *obj) goto end; } - BT_PUT(cfg->plugin_paths); + BT_VALUE_PUT_REF_AND_RESET(cfg->plugin_paths); switch (cfg->command) { case BT_CONFIG_COMMAND_RUN: @@ -896,10 +976,10 @@ void bt_config_destroy(struct bt_object *obj) case BT_CONFIG_COMMAND_LIST_PLUGINS: break; case BT_CONFIG_COMMAND_HELP: - BT_PUT(cfg->cmd_data.help.cfg_component); + BT_OBJECT_PUT_REF_AND_RESET(cfg->cmd_data.help.cfg_component); break; case BT_CONFIG_COMMAND_QUERY: - BT_PUT(cfg->cmd_data.query.cfg_component); + BT_OBJECT_PUT_REF_AND_RESET(cfg->cmd_data.query.cfg_component); if (cfg->cmd_data.query.object) { g_string_free(cfg->cmd_data.query.object, TRUE); @@ -909,6 +989,9 @@ void bt_config_destroy(struct bt_object *obj) if (cfg->cmd_data.print_ctf_metadata.path) { g_string_free(cfg->cmd_data.print_ctf_metadata.path, TRUE); + g_string_free( + cfg->cmd_data.print_ctf_metadata.output_path, + TRUE); } break; case BT_CONFIG_COMMAND_PRINT_LTTNG_LIVE_SESSIONS: @@ -916,6 +999,9 @@ void bt_config_destroy(struct bt_object *obj) g_string_free( cfg->cmd_data.print_lttng_live_sessions.url, TRUE); + g_string_free( + cfg->cmd_data.print_lttng_live_sessions.output_path, + TRUE); } break; default: @@ -998,10 +1084,10 @@ GScanner *create_csv_identifiers_scanner(void) * Return value is owned by the caller. */ static -struct bt_value *names_from_arg(const char *arg) +bt_value *names_from_arg(const char *arg) { GScanner *scanner = NULL; - struct bt_value *names = NULL; + bt_value *names = NULL; bool found_all = false, found_none = false, found_item = false; names = bt_value_array_create(); @@ -1029,33 +1115,33 @@ struct bt_value *names_from_arg(const char *arg) !strcmp(identifier, "args") || !strcmp(identifier, "arg")) { found_item = true; - if (bt_value_array_append_string(names, + if (bt_value_array_append_string_element(names, "payload")) { goto error; } } else if (!strcmp(identifier, "context") || !strcmp(identifier, "ctx")) { found_item = true; - if (bt_value_array_append_string(names, + if (bt_value_array_append_string_element(names, "context")) { goto error; } } else if (!strcmp(identifier, "scope") || !strcmp(identifier, "header")) { found_item = true; - if (bt_value_array_append_string(names, + if (bt_value_array_append_string_element(names, identifier)) { goto error; } } else if (!strcmp(identifier, "all")) { found_all = true; - if (bt_value_array_append_string(names, + if (bt_value_array_append_string_element(names, identifier)) { goto error; } } else if (!strcmp(identifier, "none")) { found_none = true; - if (bt_value_array_append_string(names, + if (bt_value_array_append_string_element(names, identifier)) { goto error; } @@ -1085,7 +1171,7 @@ end: * least one item is specified. */ if (found_item && !found_none && !found_all) { - if (bt_value_array_append_string(names, "none")) { + if (bt_value_array_append_string_element(names, "none")) { goto error; } } @@ -1095,7 +1181,7 @@ end: return names; error: - BT_PUT(names); + BT_VALUE_PUT_REF_AND_RESET(names); if (scanner) { g_scanner_destroy(scanner); } @@ -1110,10 +1196,10 @@ error: * Return value is owned by the caller. */ static -struct bt_value *fields_from_arg(const char *arg) +bt_value *fields_from_arg(const char *arg) { GScanner *scanner = NULL; - struct bt_value *fields; + bt_value *fields; fields = bt_value_array_create(); if (!fields) { @@ -1145,7 +1231,7 @@ struct bt_value *fields_from_arg(const char *arg) !strcmp(identifier, "emf") || !strcmp(identifier, "callsite") || !strcmp(identifier, "all")) { - if (bt_value_array_append_string(fields, + if (bt_value_array_append_string_element(fields, identifier)) { goto error; } @@ -1168,7 +1254,7 @@ struct bt_value *fields_from_arg(const char *arg) goto end; error: - BT_PUT(fields); + BT_VALUE_PUT_REF_AND_RESET(fields); end: if (scanner) { @@ -1180,9 +1266,9 @@ end: static void append_param_arg(GString *params_arg, const char *key, const char *value) { - assert(params_arg); - assert(key); - assert(value); + BT_ASSERT(params_arg); + BT_ASSERT(key); + BT_ASSERT(value); if (params_arg->len != 0) { g_string_append_c(params_arg, ','); @@ -1199,7 +1285,7 @@ void append_param_arg(GString *params_arg, const char *key, const char *value) */ static int insert_flat_params_from_array(GString *params_arg, - struct bt_value *names_array, const char *prefix) + const bt_value *names_array, const char *prefix) { int ret = 0; int i; @@ -1228,8 +1314,10 @@ int insert_flat_params_from_array(GString *params_arg, goto end; } - for (i = 0; i < bt_value_array_size(names_array); i++) { - struct bt_value *str_obj = bt_value_array_get(names_array, i); + for (i = 0; i < bt_value_array_get_size(names_array); i++) { + const bt_value *str_obj = + bt_value_array_borrow_element_by_index_const(names_array, + i); const char *suffix; bool is_default = false; @@ -1239,12 +1327,7 @@ int insert_flat_params_from_array(GString *params_arg, goto end; } - ret = bt_value_string_get(str_obj, &suffix); - BT_PUT(str_obj); - if (ret) { - printf_err("Unexpected error\n"); - goto end; - } + suffix = bt_value_string_get(str_obj); g_string_assign(tmpstr, prefix); g_string_append(tmpstr, "-"); @@ -1305,6 +1388,7 @@ enum { OPT_COMPONENT, OPT_CONNECT, OPT_DEBUG, + OPT_DEBUG_INFO, OPT_DEBUG_INFO_DIR, OPT_DEBUG_INFO_FULL_PATH, OPT_DEBUG_INFO_TARGET_PREFIX, @@ -1312,11 +1396,9 @@ enum { OPT_FIELDS, OPT_HELP, OPT_INPUT_FORMAT, - OPT_KEY, OPT_LIST, OPT_NAME, OPT_NAMES, - OPT_NO_DEBUG_INFO, OPT_NO_DELTA, OPT_OMIT_HOME_PLUGIN_PATH, OPT_OMIT_SYSTEM_PLUGIN_PATH, @@ -1332,7 +1414,6 @@ enum { OPT_STREAM_INTERSECTION, OPT_TIMERANGE, OPT_URL, - OPT_VALUE, OPT_VERBOSE, }; @@ -1352,7 +1433,7 @@ void add_run_cfg_comp(struct bt_config *cfg, struct bt_config_component *cfg_comp, enum bt_config_component_dest dest) { - bt_get(cfg_comp); + bt_object_get_ref(cfg_comp); switch (dest) { case BT_CONFIG_COMPONENT_DEST_SOURCE: @@ -1373,7 +1454,7 @@ static int add_run_cfg_comp_check_name(struct bt_config *cfg, struct bt_config_component *cfg_comp, enum bt_config_component_dest dest, - struct bt_value *instance_names) + bt_value *instance_names) { int ret = 0; @@ -1383,14 +1464,15 @@ int add_run_cfg_comp_check_name(struct bt_config *cfg, goto end; } - if (bt_value_map_has_key(instance_names, cfg_comp->instance_name->str)) { + if (bt_value_map_has_entry(instance_names, + cfg_comp->instance_name->str)) { printf_err("Duplicate component instance name:\n %s\n", cfg_comp->instance_name->str); ret = -1; goto end; } - if (bt_value_map_insert(instance_names, + if (bt_value_map_insert_entry(instance_names, cfg_comp->instance_name->str, bt_value_null)) { print_err_oom(); ret = -1; @@ -1404,7 +1486,7 @@ end: } static -int append_env_var_plugin_paths(struct bt_value *plugin_paths) +int append_env_var_plugin_paths(bt_value *plugin_paths) { int ret = 0; const char *envvar; @@ -1430,7 +1512,7 @@ end: } static -int append_home_and_system_plugin_paths(struct bt_value *plugin_paths, +int append_home_and_system_plugin_paths(bt_value *plugin_paths, bool omit_system_plugin_path, bool omit_home_plugin_path) { int ret; @@ -1477,7 +1559,8 @@ int append_home_and_system_plugin_paths_cfg(struct bt_config *cfg) static struct bt_config *bt_config_base_create(enum bt_config_command command, - struct bt_value *initial_plugin_paths, bool needs_plugins) + const bt_value *initial_plugin_paths, + bool needs_plugins) { struct bt_config *cfg; @@ -1488,12 +1571,16 @@ struct bt_config *bt_config_base_create(enum bt_config_command command, goto error; } - bt_object_init(cfg, bt_config_destroy); + bt_object_init_shared(&cfg->base, bt_config_destroy); cfg->command = command; cfg->command_needs_plugins = needs_plugins; if (initial_plugin_paths) { - cfg->plugin_paths = bt_get(initial_plugin_paths); + bt_value *initial_plugin_paths_copy; + + (void) bt_value_copy(initial_plugin_paths, + &initial_plugin_paths_copy); + cfg->plugin_paths = initial_plugin_paths_copy; } else { cfg->plugin_paths = bt_value_array_create(); if (!cfg->plugin_paths) { @@ -1505,7 +1592,7 @@ struct bt_config *bt_config_base_create(enum bt_config_command command, goto end; error: - BT_PUT(cfg); + BT_OBJECT_PUT_REF_AND_RESET(cfg); end: return cfg; @@ -1513,7 +1600,7 @@ end: static struct bt_config *bt_config_run_create( - struct bt_value *initial_plugin_paths) + const bt_value *initial_plugin_paths) { struct bt_config *cfg; @@ -1525,21 +1612,21 @@ struct bt_config *bt_config_run_create( } cfg->cmd_data.run.sources = g_ptr_array_new_with_free_func( - (GDestroyNotify) bt_put); + (GDestroyNotify) bt_object_put_ref); if (!cfg->cmd_data.run.sources) { print_err_oom(); goto error; } cfg->cmd_data.run.filters = g_ptr_array_new_with_free_func( - (GDestroyNotify) bt_put); + (GDestroyNotify) bt_object_put_ref); if (!cfg->cmd_data.run.filters) { print_err_oom(); goto error; } cfg->cmd_data.run.sinks = g_ptr_array_new_with_free_func( - (GDestroyNotify) bt_put); + (GDestroyNotify) bt_object_put_ref); if (!cfg->cmd_data.run.sinks) { print_err_oom(); goto error; @@ -1555,7 +1642,7 @@ struct bt_config *bt_config_run_create( goto end; error: - BT_PUT(cfg); + BT_OBJECT_PUT_REF_AND_RESET(cfg); end: return cfg; @@ -1563,7 +1650,7 @@ end: static struct bt_config *bt_config_list_plugins_create( - struct bt_value *initial_plugin_paths) + const bt_value *initial_plugin_paths) { struct bt_config *cfg; @@ -1577,7 +1664,7 @@ struct bt_config *bt_config_list_plugins_create( goto end; error: - BT_PUT(cfg); + BT_OBJECT_PUT_REF_AND_RESET(cfg); end: return cfg; @@ -1585,7 +1672,7 @@ end: static struct bt_config *bt_config_help_create( - struct bt_value *initial_plugin_paths) + const bt_value *initial_plugin_paths) { struct bt_config *cfg; @@ -1597,8 +1684,7 @@ struct bt_config *bt_config_help_create( } cfg->cmd_data.help.cfg_component = - bt_config_component_create(BT_COMPONENT_CLASS_TYPE_UNKNOWN, - NULL, NULL); + bt_config_component_create(-1, NULL, NULL); if (!cfg->cmd_data.help.cfg_component) { goto error; } @@ -1606,7 +1692,7 @@ struct bt_config *bt_config_help_create( goto end; error: - BT_PUT(cfg); + BT_OBJECT_PUT_REF_AND_RESET(cfg); end: return cfg; @@ -1614,7 +1700,7 @@ end: static struct bt_config *bt_config_query_create( - struct bt_value *initial_plugin_paths) + const bt_value *initial_plugin_paths) { struct bt_config *cfg; @@ -1634,7 +1720,7 @@ struct bt_config *bt_config_query_create( goto end; error: - BT_PUT(cfg); + BT_OBJECT_PUT_REF_AND_RESET(cfg); end: return cfg; @@ -1642,7 +1728,7 @@ end: static struct bt_config *bt_config_print_ctf_metadata_create( - struct bt_value *initial_plugin_paths) + const bt_value *initial_plugin_paths) { struct bt_config *cfg; @@ -1659,10 +1745,16 @@ struct bt_config *bt_config_print_ctf_metadata_create( goto error; } + cfg->cmd_data.print_ctf_metadata.output_path = g_string_new(NULL); + if (!cfg->cmd_data.print_ctf_metadata.output_path) { + print_err_oom(); + goto error; + } + goto end; error: - BT_PUT(cfg); + BT_OBJECT_PUT_REF_AND_RESET(cfg); end: return cfg; @@ -1670,7 +1762,7 @@ end: static struct bt_config *bt_config_print_lttng_live_sessions_create( - struct bt_value *initial_plugin_paths) + const bt_value *initial_plugin_paths) { struct bt_config *cfg; @@ -1687,10 +1779,17 @@ struct bt_config *bt_config_print_lttng_live_sessions_create( goto error; } + cfg->cmd_data.print_lttng_live_sessions.output_path = + g_string_new(NULL); + if (!cfg->cmd_data.print_lttng_live_sessions.output_path) { + print_err_oom(); + goto error; + } + goto end; error: - BT_PUT(cfg); + BT_OBJECT_PUT_REF_AND_RESET(cfg); end: return cfg; @@ -1698,7 +1797,7 @@ end: static int bt_config_append_plugin_paths_check_setuid_setgid( - struct bt_value *plugin_paths, const char *arg) + bt_value *plugin_paths, const char *arg) { int ret = 0; @@ -1742,6 +1841,8 @@ void print_expected_params_format(FILE *fp) fprintf(fp, "* Unquoted string with no special characters, and not matching any of\n"); fprintf(fp, " the null and boolean value symbols above.\n"); fprintf(fp, "* Double-quoted string (accepts escape characters).\n"); + fprintf(fp, "* Array, formatted as an opening `[`, a list of comma-separated values\n"); + fprintf(fp, " (as described by the current list) and a closing `]`.\n"); fprintf(fp, "\n"); fprintf(fp, "You can put whitespaces allowed around individual `=` and `,` symbols.\n"); fprintf(fp, "\n"); @@ -1749,7 +1850,8 @@ void print_expected_params_format(FILE *fp) fprintf(fp, "\n"); fprintf(fp, " many=null, fresh=yes, condition=false, squirrel=-782329,\n"); fprintf(fp, " observe=3.14, simple=beef, needs-quotes=\"some string\",\n"); - fprintf(fp, " escape.chars-are:allowed=\"this is a \\\" double quote\"\n"); + fprintf(fp, " escape.chars-are:allowed=\"this is a \\\" double quote\",\n"); + fprintf(fp, " things=[1, \"2\", 3]\n"); fprintf(fp, "\n"); fprintf(fp, "IMPORTANT: Make sure to single-quote the whole argument when you run\n"); fprintf(fp, "babeltrace from a shell.\n"); @@ -1799,7 +1901,7 @@ static struct bt_config *bt_config_help_from_args(int argc, const char *argv[], int *retcode, bool force_omit_system_plugin_path, bool force_omit_home_plugin_path, - struct bt_value *initial_plugin_paths) + const bt_value *initial_plugin_paths) { poptContext pc = NULL; char *arg = NULL; @@ -1851,7 +1953,7 @@ struct bt_config *bt_config_help_from_args(int argc, const char *argv[], case OPT_HELP: print_help_usage(stdout); *retcode = -1; - BT_PUT(cfg); + BT_OBJECT_PUT_REF_AND_RESET(cfg); goto end; default: printf_err("Unknown command-line option specified (option code %d)\n", @@ -1885,8 +1987,6 @@ struct bt_config *bt_config_help_from_args(int argc, const char *argv[], comp_cls_name); } else { /* Fall back to plugin help */ - cfg->cmd_data.help.cfg_component->type = - BT_COMPONENT_CLASS_TYPE_UNKNOWN; g_string_assign( cfg->cmd_data.help.cfg_component->plugin_name, leftover); @@ -1894,7 +1994,7 @@ struct bt_config *bt_config_help_from_args(int argc, const char *argv[], } else { print_help_usage(stdout); *retcode = -1; - BT_PUT(cfg); + BT_OBJECT_PUT_REF_AND_RESET(cfg); goto end; } @@ -1906,7 +2006,7 @@ struct bt_config *bt_config_help_from_args(int argc, const char *argv[], error: *retcode = 1; - BT_PUT(cfg); + BT_OBJECT_PUT_REF_AND_RESET(cfg); end: g_free(plugin_name); @@ -1963,7 +2063,7 @@ static struct bt_config *bt_config_query_from_args(int argc, const char *argv[], int *retcode, bool force_omit_system_plugin_path, bool force_omit_home_plugin_path, - struct bt_value *initial_plugin_paths) + const bt_value *initial_plugin_paths) { poptContext pc = NULL; char *arg = NULL; @@ -1971,7 +2071,10 @@ struct bt_config *bt_config_query_from_args(int argc, const char *argv[], int ret; struct bt_config *cfg = NULL; const char *leftover; - struct bt_value *params = bt_value_null; + bt_value *params; + + params = bt_value_null; + bt_value_get_ref(bt_value_null); *retcode = 0; cfg = bt_config_query_create(initial_plugin_paths); @@ -2014,7 +2117,7 @@ struct bt_config *bt_config_query_from_args(int argc, const char *argv[], break; case OPT_PARAMS: { - bt_put(params); + bt_value_put_ref(params); params = bt_value_from_arg(arg); if (!params) { printf_err("Invalid format for --params option's argument:\n %s\n", @@ -2026,7 +2129,7 @@ struct bt_config *bt_config_query_from_args(int argc, const char *argv[], case OPT_HELP: print_query_usage(stdout); *retcode = -1; - BT_PUT(cfg); + BT_OBJECT_PUT_REF_AND_RESET(cfg); goto end; default: printf_err("Unknown command-line option specified (option code %d)\n", @@ -2059,12 +2162,13 @@ struct bt_config *bt_config_query_from_args(int argc, const char *argv[], goto error; } - assert(params); - BT_MOVE(cfg->cmd_data.query.cfg_component->params, params); + BT_ASSERT(params); + BT_OBJECT_MOVE_REF(cfg->cmd_data.query.cfg_component->params, + params); } else { print_query_usage(stdout); *retcode = -1; - BT_PUT(cfg); + BT_OBJECT_PUT_REF_AND_RESET(cfg); goto end; } @@ -2079,7 +2183,7 @@ struct bt_config *bt_config_query_from_args(int argc, const char *argv[], } else { print_query_usage(stdout); *retcode = -1; - BT_PUT(cfg); + BT_OBJECT_PUT_REF_AND_RESET(cfg); goto end; } @@ -2097,14 +2201,14 @@ struct bt_config *bt_config_query_from_args(int argc, const char *argv[], error: *retcode = 1; - BT_PUT(cfg); + BT_OBJECT_PUT_REF_AND_RESET(cfg); end: if (pc) { poptFreeContext(pc); } - bt_put(params); + bt_value_put_ref(params); free(arg); return cfg; } @@ -2151,7 +2255,7 @@ static struct bt_config *bt_config_list_plugins_from_args(int argc, const char *argv[], int *retcode, bool force_omit_system_plugin_path, bool force_omit_home_plugin_path, - struct bt_value *initial_plugin_paths) + const bt_value *initial_plugin_paths) { poptContext pc = NULL; char *arg = NULL; @@ -2202,7 +2306,7 @@ struct bt_config *bt_config_list_plugins_from_args(int argc, const char *argv[], case OPT_HELP: print_list_plugins_usage(stdout); *retcode = -1; - BT_PUT(cfg); + BT_OBJECT_PUT_REF_AND_RESET(cfg); goto end; default: printf_err("Unknown command-line option specified (option code %d)\n", @@ -2235,7 +2339,7 @@ struct bt_config *bt_config_list_plugins_from_args(int argc, const char *argv[], error: *retcode = 1; - BT_PUT(cfg); + BT_OBJECT_PUT_REF_AND_RESET(cfg); end: if (pc) { @@ -2266,10 +2370,8 @@ void print_run_usage(FILE *fp) fprintf(fp, " in the plugin PLUGIN, add it to the graph,\n"); fprintf(fp, " and optionally name it NAME (you can also\n"); fprintf(fp, " specify the name with --name)\n"); - fprintf(fp, " -C, --connect=CONNECTION Connect two created components (see the\n"); + fprintf(fp, " -x, --connect=CONNECTION Connect two created components (see the\n"); fprintf(fp, " expected format of CONNECTION below)\n"); - fprintf(fp, " --key=KEY Set the current initialization string\n"); - fprintf(fp, " parameter key to KEY (see --value)\n"); fprintf(fp, " -n, --name=NAME Set the name of the current component\n"); fprintf(fp, " to NAME (must be unique amongst all the\n"); fprintf(fp, " names of the created components)\n"); @@ -2286,10 +2388,6 @@ void print_run_usage(FILE *fp) fprintf(fp, " --retry-duration=DUR When babeltrace(1) needs to retry to run\n"); fprintf(fp, " the graph later, retry in DUR µs\n"); fprintf(fp, " (default: 100000)\n"); - fprintf(fp, " --value=VAL Add a string initialization parameter to\n"); - fprintf(fp, " the current component with a name given by\n"); - fprintf(fp, " the last argument of the --key option and a\n"); - fprintf(fp, " value set to VAL\n"); fprintf(fp, " -h, --help Show this help and quit\n"); fprintf(fp, "\n"); fprintf(fp, "See `babeltrace --help` for the list of general options.\n"); @@ -2341,44 +2439,37 @@ static struct bt_config *bt_config_run_from_args(int argc, const char *argv[], int *retcode, bool force_omit_system_plugin_path, bool force_omit_home_plugin_path, - struct bt_value *initial_plugin_paths) + const bt_value *initial_plugin_paths) { poptContext pc = NULL; char *arg = NULL; struct bt_config_component *cur_cfg_comp = NULL; enum bt_config_component_dest cur_cfg_comp_dest = BT_CONFIG_COMPONENT_DEST_UNKNOWN; - struct bt_value *cur_base_params = NULL; + bt_value *cur_base_params = NULL; int opt, ret = 0; struct bt_config *cfg = NULL; - struct bt_value *instance_names = NULL; - struct bt_value *connection_args = NULL; - GString *cur_param_key = NULL; + bt_value *instance_names = NULL; + bt_value *connection_args = NULL; char error_buf[256] = { 0 }; - long long retry_duration = -1; + long retry_duration = -1; + bt_value_status status; struct poptOption run_long_options[] = { { "base-params", 'b', POPT_ARG_STRING, NULL, OPT_BASE_PARAMS, NULL, NULL }, { "component", 'c', POPT_ARG_STRING, NULL, OPT_COMPONENT, NULL, NULL }, - { "connect", 'C', POPT_ARG_STRING, NULL, OPT_CONNECT, NULL, NULL }, + { "connect", 'x', POPT_ARG_STRING, NULL, OPT_CONNECT, NULL, NULL }, { "help", 'h', POPT_ARG_NONE, NULL, OPT_HELP, NULL, NULL }, - { "key", '\0', POPT_ARG_STRING, NULL, OPT_KEY, NULL, NULL }, { "name", 'n', POPT_ARG_STRING, NULL, OPT_NAME, NULL, NULL }, { "omit-home-plugin-path", '\0', POPT_ARG_NONE, NULL, OPT_OMIT_HOME_PLUGIN_PATH, NULL, NULL }, { "omit-system-plugin-path", '\0', POPT_ARG_NONE, NULL, OPT_OMIT_SYSTEM_PLUGIN_PATH, NULL, NULL }, { "params", 'p', POPT_ARG_STRING, NULL, OPT_PARAMS, NULL, NULL }, { "plugin-path", '\0', POPT_ARG_STRING, NULL, OPT_PLUGIN_PATH, NULL, NULL }, { "reset-base-params", 'r', POPT_ARG_NONE, NULL, OPT_RESET_BASE_PARAMS, NULL, NULL }, - { "retry-duration", '\0', POPT_ARG_LONGLONG, &retry_duration, OPT_RETRY_DURATION, NULL, NULL }, - { "value", '\0', POPT_ARG_STRING, NULL, OPT_VALUE, NULL, NULL }, + { "retry-duration", '\0', POPT_ARG_LONG, &retry_duration, OPT_RETRY_DURATION, NULL, NULL }, { NULL, 0, '\0', NULL, 0, NULL, NULL }, }; *retcode = 0; - cur_param_key = g_string_new(NULL); - if (!cur_param_key) { - print_err_oom(); - goto error; - } if (argc <= 1) { print_run_usage(stdout); @@ -2451,7 +2542,7 @@ struct bt_config *bt_config_run_from_args(int argc, const char *argv[], ret = add_run_cfg_comp_check_name(cfg, cur_cfg_comp, cur_cfg_comp_dest, instance_names); - BT_PUT(cur_cfg_comp); + BT_OBJECT_PUT_REF_AND_RESET(cur_cfg_comp); if (ret) { goto error; } @@ -2478,10 +2569,11 @@ struct bt_config *bt_config_run_from_args(int argc, const char *argv[], abort(); } - assert(cur_base_params); - bt_put(cur_cfg_comp->params); - cur_cfg_comp->params = bt_value_copy(cur_base_params); - if (!cur_cfg_comp->params) { + BT_ASSERT(cur_base_params); + bt_value_put_ref(cur_cfg_comp->params); + status = bt_value_copy(cur_base_params, + &cur_cfg_comp->params); + if (status != BT_VALUE_STATUS_OK) { print_err_oom(); goto error; } @@ -2491,8 +2583,8 @@ struct bt_config *bt_config_run_from_args(int argc, const char *argv[], } case OPT_PARAMS: { - struct bt_value *params; - struct bt_value *params_to_set; + bt_value *params; + bt_value *params_to_set; if (!cur_cfg_comp) { printf_err("Cannot add parameters to unavailable component:\n %s\n", @@ -2507,45 +2599,18 @@ struct bt_config *bt_config_run_from_args(int argc, const char *argv[], goto error; } - params_to_set = bt_value_map_extend(cur_cfg_comp->params, - params); - BT_PUT(params); - if (!params_to_set) { + status = bt_value_map_extend(cur_cfg_comp->params, + params, ¶ms_to_set); + BT_VALUE_PUT_REF_AND_RESET(params); + if (status != BT_VALUE_STATUS_OK) { printf_err("Cannot extend current component parameters with --params option's argument:\n %s\n", arg); goto error; } - BT_MOVE(cur_cfg_comp->params, params_to_set); + BT_OBJECT_MOVE_REF(cur_cfg_comp->params, params_to_set); break; } - case OPT_KEY: - if (strlen(arg) == 0) { - printf_err("Cannot set an empty string as the current parameter key\n"); - goto error; - } - - g_string_assign(cur_param_key, arg); - break; - case OPT_VALUE: - if (!cur_cfg_comp) { - printf_err("Cannot set a parameter's value of unavailable component:\n %s\n", - arg); - goto error; - } - - if (cur_param_key->len == 0) { - printf_err("--value option specified without preceding --key option:\n %s\n", - arg); - goto error; - } - - if (bt_value_map_insert_string(cur_cfg_comp->params, - cur_param_key->str, arg)) { - print_err_oom(); - goto error; - } - break; case OPT_NAME: if (!cur_cfg_comp) { printf_err("Cannot set the name of unavailable component:\n %s\n", @@ -2557,7 +2622,8 @@ struct bt_config *bt_config_run_from_args(int argc, const char *argv[], break; case OPT_BASE_PARAMS: { - struct bt_value *params = bt_value_from_arg(arg); + bt_value *params = + bt_value_from_arg(arg); if (!params) { printf_err("Invalid format for --base-params option's argument:\n %s\n", @@ -2565,11 +2631,11 @@ struct bt_config *bt_config_run_from_args(int argc, const char *argv[], goto error; } - BT_MOVE(cur_base_params, params); + BT_OBJECT_MOVE_REF(cur_base_params, params); break; } case OPT_RESET_BASE_PARAMS: - BT_PUT(cur_base_params); + BT_VALUE_PUT_REF_AND_RESET(cur_base_params); cur_base_params = bt_value_map_create(); if (!cur_base_params) { print_err_oom(); @@ -2577,15 +2643,15 @@ struct bt_config *bt_config_run_from_args(int argc, const char *argv[], } break; case OPT_CONNECT: - if (bt_value_array_append_string(connection_args, - arg)) { + if (bt_value_array_append_string_element( + connection_args, arg)) { print_err_oom(); goto error; } break; case OPT_RETRY_DURATION: if (retry_duration < 0) { - printf_err("--retry-duration option's argument must be positive or 0: %lld\n", + printf_err("--retry-duration option's argument must be positive or 0: %ld\n", retry_duration); goto error; } @@ -2596,7 +2662,7 @@ struct bt_config *bt_config_run_from_args(int argc, const char *argv[], case OPT_HELP: print_run_usage(stdout); *retcode = -1; - BT_PUT(cfg); + BT_OBJECT_PUT_REF_AND_RESET(cfg); goto end; default: printf_err("Unknown command-line option specified (option code %d)\n", @@ -2625,7 +2691,7 @@ struct bt_config *bt_config_run_from_args(int argc, const char *argv[], if (cur_cfg_comp) { ret = add_run_cfg_comp_check_name(cfg, cur_cfg_comp, cur_cfg_comp_dest, instance_names); - BT_PUT(cur_cfg_comp); + BT_OBJECT_PUT_REF_AND_RESET(cur_cfg_comp); if (ret) { goto error; } @@ -2645,7 +2711,8 @@ struct bt_config *bt_config_run_from_args(int argc, const char *argv[], goto error; } - ret = bt_config_cli_args_create_connections(cfg, connection_args, + ret = bt_config_cli_args_create_connections(cfg, + connection_args, error_buf, 256); if (ret) { printf_err("Cannot creation connections:\n%s", error_buf); @@ -2656,35 +2723,31 @@ struct bt_config *bt_config_run_from_args(int argc, const char *argv[], error: *retcode = 1; - BT_PUT(cfg); + BT_OBJECT_PUT_REF_AND_RESET(cfg); end: if (pc) { poptFreeContext(pc); } - if (cur_param_key) { - g_string_free(cur_param_key, TRUE); - } - free(arg); - BT_PUT(cur_cfg_comp); - BT_PUT(cur_base_params); - BT_PUT(instance_names); - BT_PUT(connection_args); + BT_OBJECT_PUT_REF_AND_RESET(cur_cfg_comp); + BT_VALUE_PUT_REF_AND_RESET(cur_base_params); + BT_VALUE_PUT_REF_AND_RESET(instance_names); + BT_VALUE_PUT_REF_AND_RESET(connection_args); return cfg; } static -struct bt_config *bt_config_run_from_args_array(struct bt_value *run_args, +struct bt_config *bt_config_run_from_args_array(const bt_value *run_args, int *retcode, bool force_omit_system_plugin_path, bool force_omit_home_plugin_path, - struct bt_value *initial_plugin_paths) + const bt_value *initial_plugin_paths) { struct bt_config *cfg = NULL; const char **argv; int64_t i, len; - const size_t argc = bt_value_array_size(run_args) + 1; + const size_t argc = bt_value_array_get_size(run_args) + 1; argv = calloc(argc, sizeof(*argv)); if (!argv) { @@ -2694,22 +2757,21 @@ struct bt_config *bt_config_run_from_args_array(struct bt_value *run_args, argv[0] = "run"; - len = bt_value_array_size(run_args); + len = bt_value_array_get_size(run_args); if (len < 0) { printf_err("Invalid executable arguments\n"); goto end; } for (i = 0; i < len; i++) { - int ret; - struct bt_value *arg_value = bt_value_array_get(run_args, i); + const bt_value *arg_value = + bt_value_array_borrow_element_by_index_const(run_args, + i); const char *arg; - assert(arg_value); - ret = bt_value_string_get(arg_value, &arg); - assert(ret == 0); - assert(arg); + BT_ASSERT(arg_value); + arg = bt_value_string_get(arg_value); + BT_ASSERT(arg); argv[i + 1] = arg; - bt_put(arg_value); } cfg = bt_config_run_from_args(argc, argv, retcode, @@ -2813,6 +2875,8 @@ void print_convert_usage(FILE *fp) fprintf(fp, "\n"); fprintf(fp, "Implicit `filter.lttng-utils.debug-info` component options:\n"); fprintf(fp, "\n"); + fprintf(fp, " --debug-info Create an implicit\n"); + fprintf(fp, " `filter.lttng-utils.debug-info` component\n"); fprintf(fp, " --debug-info-dir=DIR Search for debug info in directory DIR\n"); fprintf(fp, " instead of `/usr/lib/debug`\n"); fprintf(fp, " --debug-info-full-path Show full debug info source and\n"); @@ -2821,8 +2885,6 @@ void print_convert_usage(FILE *fp) fprintf(fp, " Use directory DIR as a prefix when\n"); fprintf(fp, " looking up executables during debug\n"); fprintf(fp, " info analysis\n"); - fprintf(fp, " --no-debug-info Do not create an implicit\n"); - fprintf(fp, " `lttng-utils.debug-info` filter component\n"); fprintf(fp, "\n"); fprintf(fp, "Legacy options that still work:\n"); fprintf(fp, "\n"); @@ -2880,7 +2942,7 @@ struct poptOption convert_long_options[] = { { "input-format", 'i', POPT_ARG_STRING, NULL, OPT_INPUT_FORMAT, NULL, NULL }, { "name", '\0', POPT_ARG_STRING, NULL, OPT_NAME, NULL, NULL }, { "names", 'n', POPT_ARG_STRING, NULL, OPT_NAMES, NULL, NULL }, - { "no-debug-info", '\0', POPT_ARG_NONE, NULL, OPT_NO_DEBUG_INFO, NULL, NULL }, + { "debug-info", '\0', POPT_ARG_NONE, NULL, OPT_DEBUG_INFO, NULL, NULL }, { "no-delta", '\0', POPT_ARG_NONE, NULL, OPT_NO_DELTA, NULL, NULL }, { "omit-home-plugin-path", '\0', POPT_ARG_NONE, NULL, OPT_OMIT_HOME_PLUGIN_PATH, NULL, NULL }, { "omit-system-plugin-path", '\0', POPT_ARG_NONE, NULL, OPT_OMIT_SYSTEM_PLUGIN_PATH, NULL, NULL }, @@ -2901,7 +2963,7 @@ struct poptOption convert_long_options[] = { static GString *get_component_auto_name(const char *prefix, - struct bt_value *existing_names) + const bt_value *existing_names) { unsigned int i = 0; GString *auto_name = g_string_new(NULL); @@ -2911,7 +2973,7 @@ GString *get_component_auto_name(const char *prefix, goto end; } - if (!bt_value_map_has_key(existing_names, prefix)) { + if (!bt_value_map_has_entry(existing_names, prefix)) { g_string_assign(auto_name, prefix); goto end; } @@ -2919,7 +2981,7 @@ GString *get_component_auto_name(const char *prefix, do { g_string_printf(auto_name, "%s-%d", prefix, i); i++; - } while (bt_value_map_has_key(existing_names, auto_name->str)); + } while (bt_value_map_has_entry(existing_names, auto_name->str)); end: return auto_name; @@ -2930,12 +2992,12 @@ struct implicit_component_args { GString *comp_arg; GString *name_arg; GString *params_arg; - struct bt_value *extra_params; + bt_value *extra_params; }; static int assign_name_to_implicit_component(struct implicit_component_args *args, - const char *prefix, struct bt_value *existing_names, + const char *prefix, bt_value *existing_names, GList **comp_names, bool append_to_comp_names) { int ret = 0; @@ -2945,7 +3007,8 @@ int assign_name_to_implicit_component(struct implicit_component_args *args, goto end; } - name = get_component_auto_name(prefix, existing_names); + name = get_component_auto_name(prefix, + existing_names); if (!name) { ret = -1; @@ -2954,7 +3017,7 @@ int assign_name_to_implicit_component(struct implicit_component_args *args, g_string_assign(args->name_arg, name->str); - if (bt_value_map_insert(existing_names, name->str, + if (bt_value_map_insert_entry(existing_names, name->str, bt_value_null)) { print_err_oom(); ret = -1; @@ -2977,7 +3040,7 @@ end: static int append_run_args_for_implicit_component( struct implicit_component_args *impl_args, - struct bt_value *run_args) + bt_value *run_args) { int ret = 0; size_t i; @@ -2986,55 +3049,53 @@ int append_run_args_for_implicit_component( goto end; } - if (bt_value_array_append_string(run_args, "--component")) { + if (bt_value_array_append_string_element(run_args, "--component")) { print_err_oom(); goto error; } - if (bt_value_array_append_string(run_args, impl_args->comp_arg->str)) { + if (bt_value_array_append_string_element(run_args, impl_args->comp_arg->str)) { print_err_oom(); goto error; } - if (bt_value_array_append_string(run_args, "--name")) { + if (bt_value_array_append_string_element(run_args, "--name")) { print_err_oom(); goto error; } - if (bt_value_array_append_string(run_args, impl_args->name_arg->str)) { + if (bt_value_array_append_string_element(run_args, impl_args->name_arg->str)) { print_err_oom(); goto error; } if (impl_args->params_arg->len > 0) { - if (bt_value_array_append_string(run_args, "--params")) { + if (bt_value_array_append_string_element(run_args, "--params")) { print_err_oom(); goto error; } - if (bt_value_array_append_string(run_args, + if (bt_value_array_append_string_element(run_args, impl_args->params_arg->str)) { print_err_oom(); goto error; } } - for (i = 0; i < bt_value_array_size(impl_args->extra_params); i++) { - struct bt_value *elem; + for (i = 0; i < bt_value_array_get_size(impl_args->extra_params); + i++) { + const bt_value *elem; const char *arg; - elem = bt_value_array_get(impl_args->extra_params, i); + elem = bt_value_array_borrow_element_by_index(impl_args->extra_params, + i); if (!elem) { goto error; } - assert(bt_value_is_string(elem)); - if (bt_value_string_get(elem, &arg)) { - goto error; - } - - ret = bt_value_array_append_string(run_args, arg); - bt_put(elem); + BT_ASSERT(bt_value_is_string(elem)); + arg = bt_value_string_get(elem); + ret = bt_value_array_append_string_element(run_args, arg); if (ret) { print_err_oom(); goto error; @@ -3053,7 +3114,7 @@ end: static void finalize_implicit_component_args(struct implicit_component_args *args) { - assert(args); + BT_ASSERT(args); if (args->comp_arg) { g_string_free(args->comp_arg, TRUE); @@ -3067,18 +3128,7 @@ void finalize_implicit_component_args(struct implicit_component_args *args) g_string_free(args->params_arg, TRUE); } - bt_put(args->extra_params); -} - -static -void destroy_implicit_component_args(void *args) -{ - if (!args) { - return; - } - - finalize_implicit_component_args(args); - g_free(args); + bt_value_put_ref(args->extra_params); } static @@ -3109,54 +3159,213 @@ static void append_implicit_component_param(struct implicit_component_args *args, const char *key, const char *value) { - assert(args); - assert(key); - assert(value); + BT_ASSERT(args); + BT_ASSERT(key); + BT_ASSERT(value); append_param_arg(args->params_arg, key, value); } +/* Escape value to make it suitable to use as a string parameter value. */ static -int append_implicit_component_extra_param(struct implicit_component_args *args, - const char *key, const char *value) +gchar *escape_string_value(const char *value) { - int ret = 0; + GString *ret; + const char *in; + + ret = g_string_new(NULL); + if (!ret) { + print_err_oom(); + goto end; + } + + in = value; + while (*in) { + switch (*in) { + case '"': + case '\\': + g_string_append_c(ret, '\\'); + break; + } + + g_string_append_c(ret, *in); + + in++; + } + +end: + return g_string_free(ret, FALSE); +} + +static +int bt_value_to_cli_param_value_append(const bt_value *value, GString *buf) +{ + BT_ASSERT(buf); + + int ret = -1; + + switch (bt_value_get_type(value)) { + case BT_VALUE_TYPE_STRING: + { + const char *str_value = bt_value_string_get(value); + gchar *escaped_str_value; + + escaped_str_value = escape_string_value(str_value); + if (!escaped_str_value) { + goto end; + } + + g_string_append_printf(buf, "\"%s\"", escaped_str_value); + + g_free(escaped_str_value); + break; + } + case BT_VALUE_TYPE_ARRAY: { + g_string_append_c(buf, '['); + uint64_t sz = bt_value_array_get_size(value); + for (uint64_t i = 0; i < sz; i++) { + if (i > 0) { + g_string_append_c(buf, ','); + } + const bt_value *item = bt_value_array_borrow_element_by_index_const(value, i); + int ret = bt_value_to_cli_param_value_append(item, buf); + if (ret) { + goto end; + } + } + g_string_append_c(buf, ']'); + break; + } + default: + abort(); + } - assert(args); - assert(key); - assert(value); + ret = 0; - if (bt_value_array_append_string(args->extra_params, "--key")) { +end: + return ret; +} + +/* + * Convert `value` to its equivalent representation as a command line parameter + * value. + */ + +static +gchar *bt_value_to_cli_param_value(bt_value *value) +{ + GString *buf; + gchar *result = NULL; + + buf = g_string_new(NULL); + if (!buf) { + print_err_oom(); + goto error; + } + + if (bt_value_to_cli_param_value_append(value, buf)) { + goto error; + } + + result = g_string_free(buf, FALSE); + buf = NULL; + + goto end; + +error: + if (buf) { + g_string_free(buf, TRUE); + } + +end: + return result; +} + +static +int append_parameter_to_args(bt_value *args, const char *key, bt_value *value) +{ + BT_ASSERT(args); + BT_ASSERT(bt_value_get_type(args) == BT_VALUE_TYPE_ARRAY); + BT_ASSERT(key); + BT_ASSERT(value); + + int ret = 0; + gchar *str_value = NULL; + GString *parameter = NULL; + + if (bt_value_array_append_string_element(args, "--params")) { print_err_oom(); ret = -1; goto end; } - if (bt_value_array_append_string(args->extra_params, key)) { + str_value = bt_value_to_cli_param_value(value); + if (!str_value) { + ret = -1; + goto end; + } + + parameter = g_string_new(NULL); + if (!parameter) { print_err_oom(); ret = -1; goto end; } - if (bt_value_array_append_string(args->extra_params, "--value")) { + g_string_printf(parameter, "%s=%s", key, str_value); + + if (bt_value_array_append_string_element(args, parameter->str)) { print_err_oom(); ret = -1; goto end; } - if (bt_value_array_append_string(args->extra_params, value)) { +end: + if (parameter) { + g_string_free(parameter, TRUE); + parameter = NULL; + } + + if (str_value) { + g_free(str_value); + str_value = NULL; + } + + return ret; +} + +static +int append_string_parameter_to_args(bt_value *args, const char *key, const char *value) +{ + bt_value *str_value; + int ret; + + str_value = bt_value_string_create_init(value); + + if (!str_value) { print_err_oom(); ret = -1; goto end; } + ret = append_parameter_to_args(args, key, str_value); + end: + BT_VALUE_PUT_REF_AND_RESET(str_value); return ret; } +static +int append_implicit_component_extra_param(struct implicit_component_args *args, + const char *key, const char *value) +{ + return append_string_parameter_to_args(args->extra_params, key, value); +} + static int convert_append_name_param(enum bt_config_component_dest dest, GString *cur_name, GString *cur_name_prefix, - struct bt_value *run_args, struct bt_value *all_names, + bt_value *run_args, + bt_value *all_names, GList **source_names, GList **filter_names, GList **sink_names) { @@ -3180,8 +3389,8 @@ int convert_append_name_param(enum bt_config_component_dest dest, * An explicit name was provided for the user * component. */ - if (bt_value_map_has_key(all_names, - cur_name->str)) { + if (bt_value_map_has_entry(all_names, + cur_name->str)) { printf_err("Duplicate component instance name:\n %s\n", cur_name->str); goto error; @@ -3199,7 +3408,7 @@ int convert_append_name_param(enum bt_config_component_dest dest, * Remember this name globally, for the uniqueness of * all component names. */ - if (bt_value_map_insert(all_names, name->str, bt_value_null)) { + if (bt_value_map_insert_entry(all_names, name->str, bt_value_null)) { print_err_oom(); goto error; } @@ -3208,12 +3417,12 @@ int convert_append_name_param(enum bt_config_component_dest dest, * Append the --name option if necessary. */ if (append_name_opt) { - if (bt_value_array_append_string(run_args, "--name")) { + if (bt_value_array_append_string_element(run_args, "--name")) { print_err_oom(); goto error; } - if (bt_value_array_append_string(run_args, name->str)) { + if (bt_value_array_append_string_element(run_args, name->str)) { print_err_oom(); goto error; } @@ -3281,7 +3490,7 @@ end: * function. */ static -int append_connect_arg(struct bt_value *run_args, +int append_connect_arg(bt_value *run_args, const char *upstream_name, const char *downstream_name) { int ret = 0; @@ -3295,7 +3504,7 @@ int append_connect_arg(struct bt_value *run_args, goto end; } - ret = bt_value_array_append_string(run_args, "--connect"); + ret = bt_value_array_append_string_element(run_args, "--connect"); if (ret) { print_err_oom(); ret = -1; @@ -3305,7 +3514,7 @@ int append_connect_arg(struct bt_value *run_args, g_string_append(arg, e_upstream_name->str); g_string_append_c(arg, ':'); g_string_append(arg, e_downstream_name->str); - ret = bt_value_array_append_string(run_args, arg->str); + ret = bt_value_array_append_string_element(run_args, arg->str); if (ret) { print_err_oom(); ret = -1; @@ -3332,7 +3541,7 @@ end: * Appends the run command's --connect options for the convert command. */ static -int convert_auto_connect(struct bt_value *run_args, +int convert_auto_connect(bt_value *run_args, GList *source_names, GList *filter_names, GList *sink_names) { @@ -3342,9 +3551,9 @@ int convert_auto_connect(struct bt_value *run_args, GList *filter_prev; GList *sink_at = sink_names; - assert(source_names); - assert(filter_names); - assert(sink_names); + BT_ASSERT(source_names); + BT_ASSERT(filter_names); + BT_ASSERT(sink_names); /* Connect all sources to the first filter */ for (source_at = source_names; source_at != NULL; source_at = g_list_next(source_at)) { @@ -3403,7 +3612,7 @@ int split_timerange(const char *arg, char **begin, char **end) GString *g_begin = NULL; GString *g_end = NULL; - assert(arg); + BT_ASSERT(arg); if (*ch == '[') { ch++; @@ -3421,8 +3630,8 @@ int split_timerange(const char *arg, char **begin, char **end) goto error; } - assert(begin); - assert(end); + BT_ASSERT(begin); + BT_ASSERT(end); *begin = g_begin->str; *end = g_end->str; g_string_free(g_begin, FALSE); @@ -3452,7 +3661,7 @@ int g_list_prepend_gstring(GList **list, const char *string) int ret = 0; GString *gs = g_string_new(string); - assert(list); + BT_ASSERT(list); if (!gs) { print_err_oom(); @@ -3465,84 +3674,6 @@ end: return ret; } -static -struct implicit_component_args *create_implicit_component_args(void) -{ - struct implicit_component_args *impl_args = - g_new0(struct implicit_component_args, 1); - - if (!impl_args) { - goto end; - } - - if (init_implicit_component_args(impl_args, NULL, true)) { - destroy_implicit_component_args(impl_args); - impl_args = NULL; - goto end; - } - -end: - return impl_args; -} - -static -int fill_implicit_ctf_inputs_args(GPtrArray *implicit_ctf_inputs_args, - struct implicit_component_args *base_implicit_ctf_input_args, - GList *leftovers) -{ - int ret = 0; - GList *leftover; - - for (leftover = leftovers; leftover != NULL; - leftover = g_list_next(leftover)) { - GString *gs_leftover = leftover->data; - struct implicit_component_args *impl_args = - create_implicit_component_args(); - - if (!impl_args) { - print_err_oom(); - goto error; - } - - impl_args->exists = true; - g_string_assign(impl_args->comp_arg, - base_implicit_ctf_input_args->comp_arg->str); - g_string_assign(impl_args->params_arg, - base_implicit_ctf_input_args->params_arg->str); - - /* - * We need our own copy of the extra parameters because - * this is where the unique path goes. - */ - BT_PUT(impl_args->extra_params); - impl_args->extra_params = - bt_value_copy(base_implicit_ctf_input_args->extra_params); - if (!impl_args->extra_params) { - print_err_oom(); - destroy_implicit_component_args(impl_args); - goto error; - } - - /* Append unique path parameter */ - ret = append_implicit_component_extra_param(impl_args, - "path", gs_leftover->str); - if (ret) { - destroy_implicit_component_args(impl_args); - goto error; - } - - g_ptr_array_add(implicit_ctf_inputs_args, impl_args); - } - - goto end; - -error: - ret = -1; - -end: - return ret; -} - /* * Creates a Babeltrace config object from the arguments of a convert * command. @@ -3552,8 +3683,8 @@ end: static struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], int *retcode, bool force_omit_system_plugin_path, - bool force_omit_home_plugin_path, bool force_no_debug_info, - struct bt_value *initial_plugin_paths, char *log_level) + bool force_omit_home_plugin_path, + const bt_value *initial_plugin_paths, char *log_level) { poptContext pc = NULL; char *arg = NULL; @@ -3572,14 +3703,13 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], bool print_run_args = false; bool print_run_args_0 = false; bool print_ctf_metadata = false; - struct bt_value *run_args = NULL; - struct bt_value *all_names = NULL; + bt_value *run_args = NULL; + bt_value *all_names = NULL; GList *source_names = NULL; GList *filter_names = NULL; GList *sink_names = NULL; - GList *leftovers = NULL; - GPtrArray *implicit_ctf_inputs_args = NULL; - struct implicit_component_args base_implicit_ctf_input_args = { 0 }; + bt_value *leftovers = NULL; + struct implicit_component_args implicit_ctf_input_args = { 0 }; struct implicit_component_args implicit_ctf_output_args = { 0 }; struct implicit_component_args implicit_lttng_live_args = { 0 }; struct implicit_component_args implicit_dummy_args = { 0 }; @@ -3587,12 +3717,14 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], struct implicit_component_args implicit_debug_info_args = { 0 }; struct implicit_component_args implicit_muxer_args = { 0 }; struct implicit_component_args implicit_trimmer_args = { 0 }; - struct bt_value *plugin_paths = bt_get(initial_plugin_paths); + bt_value *plugin_paths; char error_buf[256] = { 0 }; size_t i; struct bt_common_lttng_live_url_parts lttng_live_url_parts = { 0 }; char *output = NULL; + (void) bt_value_copy(initial_plugin_paths, &plugin_paths); + *retcode = 0; if (argc <= 1) { @@ -3601,7 +3733,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto end; } - if (init_implicit_component_args(&base_implicit_ctf_input_args, + if (init_implicit_component_args(&implicit_ctf_input_args, "source.ctf.fs", false)) { goto error; } @@ -3627,7 +3759,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], } if (init_implicit_component_args(&implicit_debug_info_args, - "filter.lttng-utils.debug-info", !force_no_debug_info)) { + "filter.lttng-utils.debug-info", false)) { goto error; } @@ -3641,13 +3773,6 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto error; } - implicit_ctf_inputs_args = g_ptr_array_new_with_free_func( - (GDestroyNotify) destroy_implicit_component_args); - if (!implicit_ctf_inputs_args) { - print_err_oom(); - goto error; - } - all_names = bt_value_map_create(); if (!all_names) { print_err_oom(); @@ -3677,14 +3802,20 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto error; } + leftovers = bt_value_array_create(); + if (!leftovers) { + print_err_oom(); + goto error; + } + /* * First pass: collect all arguments which need to be passed * as is to the run command. This pass can also add --name * arguments if needed to automatically name unnamed component * instances. Also it does the following transformations: * - * --path=PATH -> --key path --value PATH - * --url=URL -> --key url --value URL + * --path=PATH -> --params=path="PATH" + * --url=URL -> --params=url="URL" * * Also it appends the plugin paths of --plugin-path to * `plugin_paths`. @@ -3708,7 +3839,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], switch (opt) { case OPT_COMPONENT: { - enum bt_component_class_type type; + bt_component_class_type type; const char *type_prefix; /* Append current component's name if needed */ @@ -3751,13 +3882,13 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], abort(); } - if (bt_value_array_append_string(run_args, + if (bt_value_array_append_string_element(run_args, "--component")) { print_err_oom(); goto error; } - if (bt_value_array_append_string(run_args, arg)) { + if (bt_value_array_append_string_element(run_args, arg)) { print_err_oom(); goto error; } @@ -3780,13 +3911,13 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto error; } - if (bt_value_array_append_string(run_args, + if (bt_value_array_append_string_element(run_args, "--params")) { print_err_oom(); goto error; } - if (bt_value_array_append_string(run_args, arg)) { + if (bt_value_array_append_string_element(run_args, arg)) { print_err_oom(); goto error; } @@ -3798,23 +3929,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto error; } - if (bt_value_array_append_string(run_args, "--key")) { - print_err_oom(); - goto error; - } - - if (bt_value_array_append_string(run_args, "path")) { - print_err_oom(); - goto error; - } - - if (bt_value_array_append_string(run_args, "--value")) { - print_err_oom(); - goto error; - } - - if (bt_value_array_append_string(run_args, arg)) { - print_err_oom(); + if (append_string_parameter_to_args(run_args, "path", arg)) { goto error; } break; @@ -3825,23 +3940,8 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto error; } - if (bt_value_array_append_string(run_args, "--key")) { - print_err_oom(); - goto error; - } - if (bt_value_array_append_string(run_args, "url")) { - print_err_oom(); - goto error; - } - - if (bt_value_array_append_string(run_args, "--value")) { - print_err_oom(); - goto error; - } - - if (bt_value_array_append_string(run_args, arg)) { - print_err_oom(); + if (append_string_parameter_to_args(run_args, "url", arg)) { goto error; } break; @@ -3852,12 +3952,12 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto error; } - if (bt_value_array_append_string(run_args, "--name")) { + if (bt_value_array_append_string_element(run_args, "--name")) { print_err_oom(); goto error; } - if (bt_value_array_append_string(run_args, arg)) { + if (bt_value_array_append_string_element(run_args, arg)) { print_err_oom(); goto error; } @@ -3867,20 +3967,20 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], case OPT_OMIT_HOME_PLUGIN_PATH: force_omit_home_plugin_path = true; - if (bt_value_array_append_string(run_args, + if (bt_value_array_append_string_element(run_args, "--omit-home-plugin-path")) { print_err_oom(); goto error; } break; case OPT_RETRY_DURATION: - if (bt_value_array_append_string(run_args, + if (bt_value_array_append_string_element(run_args, "--retry-duration")) { print_err_oom(); goto error; } - if (bt_value_array_append_string(run_args, arg)) { + if (bt_value_array_append_string_element(run_args, arg)) { print_err_oom(); goto error; } @@ -3888,7 +3988,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], case OPT_OMIT_SYSTEM_PLUGIN_PATH: force_omit_system_plugin_path = true; - if (bt_value_array_append_string(run_args, + if (bt_value_array_append_string_element(run_args, "--omit-system-plugin-path")) { print_err_oom(); goto error; @@ -3900,13 +4000,13 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto error; } - if (bt_value_array_append_string(run_args, + if (bt_value_array_append_string_element(run_args, "--plugin-path")) { print_err_oom(); goto error; } - if (bt_value_array_append_string(run_args, arg)) { + if (bt_value_array_append_string_element(run_args, arg)) { print_err_oom(); goto error; } @@ -3914,7 +4014,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], case OPT_HELP: print_convert_usage(stdout); *retcode = -1; - BT_PUT(cfg); + BT_OBJECT_PUT_REF_AND_RESET(cfg); goto end; case OPT_BEGIN: case OPT_CLOCK_CYCLES: @@ -3926,6 +4026,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], case OPT_CLOCK_SECONDS: case OPT_COLOR: case OPT_DEBUG: + case OPT_DEBUG_INFO: case OPT_DEBUG_INFO_DIR: case OPT_DEBUG_INFO_FULL_PATH: case OPT_DEBUG_INFO_TARGET_PREFIX: @@ -3933,7 +4034,6 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], case OPT_FIELDS: case OPT_INPUT_FORMAT: case OPT_NAMES: - case OPT_NO_DEBUG_INFO: case OPT_NO_DELTA: case OPT_OUTPUT_FORMAT: case OPT_OUTPUT: @@ -4070,19 +4170,19 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], append_implicit_component_param( &implicit_text_args, "clock-gmt", "yes"); append_implicit_component_param( - &implicit_trimmer_args, "clock-gmt", "yes"); + &implicit_trimmer_args, "gmt", "yes"); implicit_text_args.exists = true; break; case OPT_CLOCK_OFFSET: - base_implicit_ctf_input_args.exists = true; + implicit_ctf_input_args.exists = true; append_implicit_component_param( - &base_implicit_ctf_input_args, + &implicit_ctf_input_args, "clock-class-offset-s", arg); break; case OPT_CLOCK_OFFSET_NS: - base_implicit_ctf_input_args.exists = true; + implicit_ctf_input_args.exists = true; append_implicit_component_param( - &base_implicit_ctf_input_args, + &implicit_ctf_input_args, "clock-class-offset-ns", arg); break; case OPT_CLOCK_SECONDS: @@ -4098,13 +4198,13 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto error; } break; - case OPT_NO_DEBUG_INFO: - implicit_debug_info_args.exists = false; + case OPT_DEBUG_INFO: + implicit_debug_info_args.exists = true; break; case OPT_DEBUG_INFO_DIR: implicit_debug_info_args.exists = true; ret = append_implicit_component_extra_param( - &implicit_debug_info_args, "dir", arg); + &implicit_debug_info_args, "debug-info-dir", arg); if (ret) { goto error; } @@ -4125,7 +4225,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], break; case OPT_FIELDS: { - struct bt_value *fields = fields_from_arg(arg); + bt_value *fields = fields_from_arg(arg); if (!fields) { goto error; @@ -4135,7 +4235,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], ret = insert_flat_params_from_array( implicit_text_args.params_arg, fields, "field"); - bt_put(fields); + bt_value_put_ref(fields); if (ret) { goto error; } @@ -4143,7 +4243,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], } case OPT_NAMES: { - struct bt_value *names = names_from_arg(arg); + bt_value *names = names_from_arg(arg); if (!names) { goto error; @@ -4153,7 +4253,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], ret = insert_flat_params_from_array( implicit_text_args.params_arg, names, "name"); - bt_put(names); + bt_value_put_ref(names); if (ret) { goto error; } @@ -4173,7 +4273,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], got_input_format_opt = true; if (strcmp(arg, "ctf") == 0) { - base_implicit_ctf_input_args.exists = true; + implicit_ctf_input_args.exists = true; } else if (strcmp(arg, "lttng-live") == 0) { implicit_lttng_live_args.exists = true; } else { @@ -4282,16 +4382,8 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], /* Consume and keep leftover arguments */ while ((leftover = poptGetArg(pc))) { - GString *gs_leftover = g_string_new(leftover); - - if (!gs_leftover) { - print_err_oom(); - goto error; - } - - leftovers = g_list_append(leftovers, gs_leftover); - if (!leftovers) { - g_string_free(gs_leftover, TRUE); + bt_value_status status = bt_value_array_append_string_element(leftovers, leftover); + if (status != BT_VALUE_STATUS_OK) { print_err_oom(); goto error; } @@ -4299,14 +4391,14 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], /* Print CTF metadata or print LTTng live sessions */ if (print_ctf_metadata) { - GString *gs_leftover; + const bt_value *bt_val_leftover; - if (g_list_length(leftovers) == 0) { + if (bt_value_array_is_empty(leftovers)) { printf_err("--output-format=ctf-metadata specified without a path\n"); goto error; } - if (g_list_length(leftovers) > 1) { + if (bt_value_array_get_size(leftovers) > 1) { printf_err("Too many paths specified for --output-format=ctf-metadata\n"); goto error; } @@ -4316,9 +4408,16 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto error; } - gs_leftover = leftovers->data; + bt_val_leftover = bt_value_array_borrow_element_by_index_const(leftovers, 0); g_string_assign(cfg->cmd_data.print_ctf_metadata.path, - gs_leftover->str); + bt_value_string_get(bt_val_leftover)); + + if (output) { + g_string_assign( + cfg->cmd_data.print_ctf_metadata.output_path, + output); + } + goto end; } @@ -4377,18 +4476,18 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], } /* Decide where the leftover argument(s) go */ - if (g_list_length(leftovers) > 0) { + if (bt_value_array_get_size(leftovers) > 0) { if (implicit_lttng_live_args.exists) { - GString *gs_leftover; + const bt_value *bt_val_leftover; - if (g_list_length(leftovers) > 1) { + if (bt_value_array_get_size(leftovers) > 1) { printf_err("Too many URLs specified for --output-format=lttng-live\n"); goto error; } - gs_leftover = leftovers->data; + bt_val_leftover = bt_value_array_borrow_element_by_index_const(leftovers, 0); lttng_live_url_parts = - bt_common_parse_lttng_live_url(gs_leftover->str, + bt_common_parse_lttng_live_url(bt_value_string_get(bt_val_leftover), error_buf, sizeof(error_buf)); if (!lttng_live_url_parts.proto) { printf_err("Invalid LTTng live URL format: %s\n", @@ -4405,26 +4504,39 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], } g_string_assign(cfg->cmd_data.print_lttng_live_sessions.url, - gs_leftover->str); + bt_value_string_get(bt_val_leftover)); + + if (output) { + g_string_assign( + cfg->cmd_data.print_lttng_live_sessions.output_path, + output); + } + goto end; } ret = append_implicit_component_extra_param( &implicit_lttng_live_args, "url", - gs_leftover->str); + bt_value_string_get(bt_val_leftover)); + if (ret) { + goto error; + } + + ret = append_implicit_component_extra_param( + &implicit_lttng_live_args, + "session-not-found-action", "end"); if (ret) { goto error; } } else { /* - * Append one implicit component argument set - * for each leftover (souce.ctf.fs paths). Copy - * the base implicit component arguments. - * Note that they still have to be named later. + * Create one source.ctf.fs component, pass it an array + * with the leftovers. + * Note that it still has to be named later. */ - ret = fill_implicit_ctf_inputs_args( - implicit_ctf_inputs_args, - &base_implicit_ctf_input_args, leftovers); + implicit_ctf_input_args.exists = true; + ret = append_parameter_to_args(implicit_ctf_input_args.extra_params, + "paths", leftovers); if (ret) { goto error; } @@ -4435,10 +4547,9 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], * Ensure mutual exclusion between implicit `source.ctf.fs` and * `source.ctf.lttng-live` components. */ - if (base_implicit_ctf_input_args.exists && - implicit_lttng_live_args.exists) { + if (implicit_ctf_input_args.exists && implicit_lttng_live_args.exists) { printf_err("Cannot create both implicit `%s` and `%s` components\n", - base_implicit_ctf_input_args.comp_arg->str, + implicit_ctf_input_args.comp_arg->str, implicit_lttng_live_args.comp_arg->str); goto error; } @@ -4448,29 +4559,23 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], * components exists, make sure there's at least one leftover * (which is the path or URL). */ - if (base_implicit_ctf_input_args.exists && - g_list_length(leftovers) == 0) { + if (implicit_ctf_input_args.exists && bt_value_array_is_empty(leftovers)) { printf_err("Missing path for implicit `%s` component\n", - base_implicit_ctf_input_args.comp_arg->str); + implicit_ctf_input_args.comp_arg->str); goto error; } - if (implicit_lttng_live_args.exists && g_list_length(leftovers) == 0) { + if (implicit_lttng_live_args.exists && bt_value_array_is_empty(leftovers)) { printf_err("Missing URL for implicit `%s` component\n", implicit_lttng_live_args.comp_arg->str); goto error; } /* Assign names to implicit components */ - for (i = 0; i < implicit_ctf_inputs_args->len; i++) { - struct implicit_component_args *impl_args = - g_ptr_array_index(implicit_ctf_inputs_args, i); - - ret = assign_name_to_implicit_component(impl_args, - "source-ctf-fs", all_names, &source_names, true); - if (ret) { - goto error; - } + ret = assign_name_to_implicit_component(&implicit_ctf_input_args, + "source-ctf-fs", all_names, &source_names, true); + if (ret) { + goto error; } ret = assign_name_to_implicit_component(&implicit_lttng_live_args, @@ -4556,15 +4661,9 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], * Append the equivalent run arguments for the implicit * components. */ - for (i = 0; i < implicit_ctf_inputs_args->len; i++) { - struct implicit_component_args *impl_args = - g_ptr_array_index(implicit_ctf_inputs_args, i); - - ret = append_run_args_for_implicit_component(impl_args, - run_args); - if (ret) { - goto error; - } + ret = append_run_args_for_implicit_component(&implicit_ctf_input_args, run_args); + if (ret) { + goto error; } ret = append_run_args_for_implicit_component(&implicit_lttng_live_args, @@ -4628,17 +4727,16 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto error; } - for (i = 0; i < bt_value_array_size(run_args); i++) { - struct bt_value *arg_value = - bt_value_array_get(run_args, i); + for (i = 0; i < bt_value_array_get_size(run_args); i++) { + const bt_value *arg_value = + bt_value_array_borrow_element_by_index(run_args, + i); const char *arg; GString *quoted = NULL; const char *arg_to_print; - assert(arg_value); - ret = bt_value_string_get(arg_value, &arg); - assert(ret == 0); - BT_PUT(arg_value); + BT_ASSERT(arg_value); + arg = bt_value_string_get(arg_value); if (print_run_args) { quoted = bt_common_shell_quote(arg, true); @@ -4657,7 +4755,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], g_string_free(quoted, TRUE); } - if (i < bt_value_array_size(run_args) - 1) { + if (i < bt_value_array_get_size(run_args) - 1) { if (print_run_args) { putchar(' '); } else { @@ -4667,13 +4765,14 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], } *retcode = -1; - BT_PUT(cfg); + BT_OBJECT_PUT_REF_AND_RESET(cfg); goto end; } cfg = bt_config_run_from_args_array(run_args, retcode, - force_omit_system_plugin_path, force_omit_home_plugin_path, - initial_plugin_paths); + force_omit_system_plugin_path, + force_omit_home_plugin_path, + initial_plugin_paths); if (!cfg) { goto error; } @@ -4683,7 +4782,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], error: *retcode = 1; - BT_PUT(cfg); + BT_OBJECT_PUT_REF_AND_RESET(cfg); end: if (pc) { @@ -4701,17 +4800,13 @@ end: g_string_free(cur_name_prefix, TRUE); } - if (implicit_ctf_inputs_args) { - g_ptr_array_free(implicit_ctf_inputs_args, TRUE); - } - - bt_put(run_args); - bt_put(all_names); + bt_value_put_ref(run_args); + bt_value_put_ref(all_names); destroy_glist_of_gstring(source_names); destroy_glist_of_gstring(filter_names); destroy_glist_of_gstring(sink_names); - destroy_glist_of_gstring(leftovers); - finalize_implicit_component_args(&base_implicit_ctf_input_args); + bt_value_put_ref(leftovers); + finalize_implicit_component_args(&implicit_ctf_input_args); finalize_implicit_component_args(&implicit_ctf_output_args); finalize_implicit_component_args(&implicit_lttng_live_args); finalize_implicit_component_args(&implicit_dummy_args); @@ -4719,7 +4814,7 @@ end: finalize_implicit_component_args(&implicit_debug_info_args); finalize_implicit_component_args(&implicit_muxer_args); finalize_implicit_component_args(&implicit_trimmer_args); - bt_put(plugin_paths); + bt_value_put_ref(plugin_paths); bt_common_destroy_lttng_live_url_parts(<tng_live_url_parts); return cfg; } @@ -4736,7 +4831,7 @@ void print_gen_usage(FILE *fp) fprintf(fp, "\n"); fprintf(fp, " -d, --debug Enable debug mode (same as --log-level=V)\n"); fprintf(fp, " -h, --help Show this help and quit\n"); - fprintf(fp, " --log-level=LVL Set all log levels to LVL (`N`, `V`, `D`,\n"); + fprintf(fp, " -l, --log-level=LVL Set all log levels to LVL (`N`, `V`, `D`,\n"); fprintf(fp, " `I`, `W` (default), `E`, or `F`)\n"); fprintf(fp, " -v, --verbose Enable verbose mode (same as --log-level=I)\n"); fprintf(fp, " -V, --version Show version and quit\n"); @@ -4786,8 +4881,8 @@ char log_level_from_arg(const char *arg) struct bt_config *bt_config_cli_args_create(int argc, const char *argv[], int *retcode, bool force_omit_system_plugin_path, - bool force_omit_home_plugin_path, bool force_no_debug_info, - struct bt_value *initial_plugin_paths) + bool force_omit_home_plugin_path, + const bt_value *initial_plugin_paths) { struct bt_config *config = NULL; int i; @@ -4814,7 +4909,7 @@ struct bt_config *bt_config_cli_args_create(int argc, const char *argv[], goto end; } } else { - bt_get(initial_plugin_paths); + bt_value_get_ref(initial_plugin_paths); } if (argc <= 1) { @@ -4843,7 +4938,8 @@ struct bt_config *bt_config_cli_args_create(int argc, const char *argv[], */ log_level = 'I'; } - } else if (strcmp(cur_arg, "--log-level") == 0) { + } else if (strcmp(cur_arg, "--log-level") == 0 || + strcmp(cur_arg, "-l") == 0) { if (!next_arg) { printf_err("Missing log level value for --log-level option\n"); *retcode = 1; @@ -4862,6 +4958,16 @@ struct bt_config *bt_config_cli_args_create(int argc, const char *argv[], } else if (strncmp(cur_arg, "--log-level=", 12) == 0) { const char *arg = &cur_arg[12]; + log_level = log_level_from_arg(arg); + if (log_level == 'U') { + printf_err("Invalid argument for --log-level option:\n %s\n", + arg); + *retcode = 1; + goto end; + } + } else if (strncmp(cur_arg, "-l", 2) == 0) { + const char *arg = &cur_arg[2]; + log_level = log_level_from_arg(arg); if (log_level == 'U') { printf_err("Invalid argument for --log-level option:\n %s\n", @@ -4921,8 +5027,8 @@ struct bt_config *bt_config_cli_args_create(int argc, const char *argv[], goto end; } - assert(command_argv); - assert(command_argc >= 0); + BT_ASSERT(command_argv); + BT_ASSERT(command_argc >= 0); switch (command_type) { case COMMAND_TYPE_RUN: @@ -4933,7 +5039,7 @@ struct bt_config *bt_config_cli_args_create(int argc, const char *argv[], case COMMAND_TYPE_CONVERT: config = bt_config_convert_from_args(command_argc, command_argv, retcode, force_omit_system_plugin_path, - force_omit_home_plugin_path, force_no_debug_info, + force_omit_home_plugin_path, initial_plugin_paths, &log_level); break; case COMMAND_TYPE_LIST_PLUGINS: @@ -4965,6 +5071,6 @@ struct bt_config *bt_config_cli_args_create(int argc, const char *argv[], } end: - bt_put(initial_plugin_paths); + bt_value_put_ref(initial_plugin_paths); return config; }