X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=cli%2Fbabeltrace-cfg-cli-args.c;h=27f9a981208b75d4a8a3092bc51cd4d26974073e;hb=480c0b45f1ed901b29a7c8761d8fb3c424ec7c20;hp=a1eb78b5f00de03d5b0dd474e082ca97217418d5;hpb=c3acd5f3f82ef06a3d04dc180c901a4597514d13;p=babeltrace.git diff --git a/cli/babeltrace-cfg-cli-args.c b/cli/babeltrace-cfg-cli-args.c index a1eb78b5..27f9a981 100644 --- a/cli/babeltrace-cfg-cli-args.c +++ b/cli/babeltrace-cfg-cli-args.c @@ -22,26 +22,25 @@ * SOFTWARE. */ +#define BT_LOG_TAG "CLI-CFG-CLI-ARGS" +#include "logging.h" + #include #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" - -#define BT_LOG_TAG "CLI-CFG-ARGS" -#include "logging.h" +#include "version.h" /* * Error printf() macro which prepends "Error: " the first time it's @@ -84,7 +83,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; @@ -121,8 +120,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; @@ -194,7 +193,7 @@ 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) { @@ -241,7 +240,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); @@ -292,19 +292,16 @@ int ini_handle_state(struct ini_parsing_state *state) goto error; } - value = bt_value_integer_create_init( - (int64_t) int_val); + 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); + 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); + value = bt_value_string_create_init(state->scanner->value.v_string); break; case G_TOKEN_IDENTIFIER: { @@ -366,14 +363,12 @@ int ini_handle_state(struct ini_parsing_state *state) goto error; } - value = bt_value_integer_create_init( - -((int64_t) int_val)); + 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); + value = bt_value_real_create_init(-state->scanner->value.v_float); break; default: /* Unset value variable will trigger the error */ @@ -414,7 +409,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; @@ -422,7 +417,7 @@ success: } end: - BT_PUT(value); + BT_VALUE_PUT_REF_AND_RESET(value); return ret; } @@ -432,7 +427,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 = { @@ -539,7 +535,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) { @@ -557,9 +553,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); @@ -579,36 +575,40 @@ end: if (ini_error) { g_string_free(ini_error, TRUE); } + return params; } /* - * Returns the plugin and component class names, and the instance name, - * from a command-line source/filter/sink option's argument. arg must - * have the following format: + * Returns the plugin name, component class name, component class type, + * and component name from a command-line --component option's argument. + * arg must have the following format: * - * [NAME:]PLUGIN.CLS + * [NAME:]TYPE.PLUGIN.CLS * - * where NAME is the optional component name, PLUGIN is the plugin name, - * and CLS is the component class name. + * where NAME is the optional component name, TYPE is either `source`, + * `filter`, or `sink`, PLUGIN is the plugin name, and CLS is the + * component class name. * * On success, both *plugin and *component are not NULL. *plugin - * and *component are owned by the caller. On success, *name can be NULL - * if no component name was found. + * and *comp_cls are owned by the caller. On success, *name can be NULL + * if no component class name was found, and *comp_cls_type is set. */ static void plugin_comp_cls_names(const char *arg, char **name, char **plugin, - char **comp_cls) + char **comp_cls, bt_component_class_type *comp_cls_type) { const char *at = arg; GString *gs_name = NULL; + GString *gs_comp_cls_type = NULL; GString *gs_plugin = NULL; GString *gs_comp_cls = NULL; size_t end_pos; - assert(arg); - assert(plugin); - assert(comp_cls); + 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"); @@ -628,9 +628,33 @@ void plugin_comp_cls_names(const char *arg, char **name, char **plugin, g_string_assign(gs_name, ""); } + /* Parse the component class type */ + gs_comp_cls_type = bt_common_string_until(at, ".:\\", ".", &end_pos); + if (!gs_comp_cls_type || at[end_pos] == '\0') { + printf_err("Missing component class type (`source`, `filter`, or `sink`)\n"); + goto error; + } + + if (strcmp(gs_comp_cls_type->str, "source") == 0 || + strcmp(gs_comp_cls_type->str, "src") == 0) { + *comp_cls_type = BT_COMPONENT_CLASS_TYPE_SOURCE; + } else if (strcmp(gs_comp_cls_type->str, "filter") == 0 || + strcmp(gs_comp_cls_type->str, "flt") == 0) { + *comp_cls_type = BT_COMPONENT_CLASS_TYPE_FILTER; + } else if (strcmp(gs_comp_cls_type->str, "sink") == 0) { + *comp_cls_type = BT_COMPONENT_CLASS_TYPE_SINK; + } else { + printf_err("Unknown component class type: `%s`\n", + gs_comp_cls_type->str); + goto error; + } + + at += end_pos + 1; + /* Parse the plugin name */ gs_plugin = bt_common_string_until(at, ".:\\", ".", &end_pos); if (!gs_plugin || gs_plugin->len == 0 || at[end_pos] == '\0') { + printf_err("Missing plugin or component class name\n"); goto error; } @@ -639,6 +663,7 @@ void plugin_comp_cls_names(const char *arg, char **name, char **plugin, /* Parse the component class name */ gs_comp_cls = bt_common_string_until(at, ".:\\", ".", &end_pos); if (!gs_comp_cls || gs_comp_cls->len == 0) { + printf_err("Missing component class name\n"); goto error; } @@ -669,6 +694,14 @@ void plugin_comp_cls_names(const char *arg, char **name, char **plugin, goto end; error: + if (name) { + *name = NULL; + } + + *plugin = NULL; + *comp_cls = NULL; + +end: if (gs_name) { g_string_free(gs_name, TRUE); } @@ -681,14 +714,10 @@ error: g_string_free(gs_comp_cls, TRUE); } - if (name) { - *name = NULL; + if (gs_comp_cls_type) { + g_string_free(gs_comp_cls_type, TRUE); } - *plugin = NULL; - *comp_cls = NULL; - -end: return; } @@ -698,14 +727,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); @@ -726,7 +759,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: @@ -742,7 +775,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; @@ -753,7 +786,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) { @@ -783,28 +817,27 @@ 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; } /* - * Creates a component configuration from a command-line source/sink + * Creates a component configuration from a command-line --component * option's argument. */ static -struct bt_config_component *bt_config_component_from_arg( - enum bt_component_class_type type, const char *arg) +struct bt_config_component *bt_config_component_from_arg(const char *arg) { struct bt_config_component *cfg_comp = NULL; char *name = NULL; char *plugin_name = NULL; char *comp_cls_name = NULL; + bt_component_class_type type; - plugin_comp_cls_names(arg, &name, &plugin_name, &comp_cls_name); + plugin_comp_cls_names(arg, &name, &plugin_name, &comp_cls_name, &type); if (!plugin_name || !comp_cls_name) { - printf_err("Cannot get plugin or component class name\n"); goto error; } @@ -820,7 +853,7 @@ struct bt_config_component *bt_config_component_from_arg( goto end; error: - BT_PUT(cfg_comp); + BT_OBJECT_PUT_REF_AND_RESET(cfg_comp); end: g_free(name); @@ -833,7 +866,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); @@ -842,7 +875,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: @@ -866,10 +899,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); @@ -879,6 +912,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: @@ -886,6 +922,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: @@ -901,12 +940,12 @@ end: static void destroy_glist_of_gstring(GList *list) { + GList *at; + if (!list) { return; } - GList *at; - for (at = list; at != NULL; at = g_list_next(at)) { g_string_free(at->data, TRUE); } @@ -968,10 +1007,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(); @@ -999,33 +1038,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; } @@ -1055,7 +1094,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; } } @@ -1065,7 +1104,7 @@ end: return names; error: - BT_PUT(names); + BT_VALUE_PUT_REF_AND_RESET(names); if (scanner) { g_scanner_destroy(scanner); } @@ -1080,10 +1119,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) { @@ -1115,7 +1154,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; } @@ -1138,7 +1177,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) { @@ -1150,9 +1189,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, ','); @@ -1169,7 +1208,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; @@ -1198,8 +1237,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; @@ -1209,12 +1250,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, "-"); @@ -1272,26 +1308,26 @@ enum { OPT_CLOCK_OFFSET_NS, OPT_CLOCK_SECONDS, OPT_COLOR, + OPT_COMPONENT, OPT_CONNECT, OPT_DEBUG, + OPT_DEBUG_INFO, OPT_DEBUG_INFO_DIR, OPT_DEBUG_INFO_FULL_PATH, OPT_DEBUG_INFO_TARGET_PREFIX, OPT_END, OPT_FIELDS, - OPT_FILTER, 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, - OPT_OUTPUT_FORMAT, OPT_OUTPUT, + OPT_OUTPUT_FORMAT, OPT_PARAMS, OPT_PATH, OPT_PLUGIN_PATH, @@ -1299,8 +1335,6 @@ enum { OPT_RETRY_DURATION, OPT_RUN_ARGS, OPT_RUN_ARGS_0, - OPT_SINK, - OPT_SOURCE, OPT_STREAM_INTERSECTION, OPT_TIMERANGE, OPT_URL, @@ -1324,7 +1358,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: @@ -1345,7 +1379,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; @@ -1355,14 +1389,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; @@ -1376,13 +1411,13 @@ 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; if (bt_common_is_setuid_setgid()) { - printf_debug("Skipping non-system plugin paths for setuid/setgid binary\n"); + BT_LOGI_STR("Skipping non-system plugin paths for setuid/setgid binary."); goto end; } @@ -1402,14 +1437,14 @@ 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; if (!omit_home_plugin_path) { if (bt_common_is_setuid_setgid()) { - printf_debug("Skipping non-system plugin paths for setuid/setgid binary\n"); + BT_LOGI_STR("Skipping non-system plugin paths for setuid/setgid binary."); } else { char *home_plugin_dir = bt_common_get_home_plugin_path(); @@ -1449,7 +1484,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; @@ -1460,12 +1496,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) { @@ -1477,7 +1517,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; @@ -1485,7 +1525,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; @@ -1497,21 +1537,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; @@ -1527,7 +1567,7 @@ struct bt_config *bt_config_run_create( goto end; error: - BT_PUT(cfg); + BT_OBJECT_PUT_REF_AND_RESET(cfg); end: return cfg; @@ -1535,7 +1575,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; @@ -1549,7 +1589,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; @@ -1557,7 +1597,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; @@ -1569,8 +1609,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; } @@ -1578,7 +1617,7 @@ struct bt_config *bt_config_help_create( goto end; error: - BT_PUT(cfg); + BT_OBJECT_PUT_REF_AND_RESET(cfg); end: return cfg; @@ -1586,7 +1625,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; @@ -1606,7 +1645,7 @@ struct bt_config *bt_config_query_create( goto end; error: - BT_PUT(cfg); + BT_OBJECT_PUT_REF_AND_RESET(cfg); end: return cfg; @@ -1614,7 +1653,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; @@ -1631,10 +1670,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; @@ -1642,7 +1687,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; @@ -1659,10 +1704,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; @@ -1670,12 +1722,12 @@ 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; if (bt_common_is_setuid_setgid()) { - printf_debug("Skipping non-system plugin paths for setuid/setgid binary\n"); + BT_LOGI_STR("Skipping non-system plugin paths for setuid/setgid binary."); goto end; } @@ -1735,24 +1787,16 @@ static void print_help_usage(FILE *fp) { fprintf(fp, "Usage: babeltrace [GENERAL OPTIONS] help [OPTIONS] PLUGIN\n"); - fprintf(fp, " babeltrace [GENERAL OPTIONS] help [OPTIONS] --source=PLUGIN.CLS\n"); - fprintf(fp, " babeltrace [GENERAL OPTIONS] help [OPTIONS] --filter=PLUGIN.CLS\n"); - fprintf(fp, " babeltrace [GENERAL OPTIONS] help [OPTIONS] --sink=PLUGIN.CLS\n"); + fprintf(fp, " babeltrace [GENERAL OPTIONS] help [OPTIONS] TYPE.PLUGIN.CLS\n"); fprintf(fp, "\n"); fprintf(fp, "Options:\n"); fprintf(fp, "\n"); - fprintf(fp, " -f, --filter=PLUGIN.CLS Get help for the filter component class\n"); - fprintf(fp, " CLS found in the plugin PLUGIN\n"); fprintf(fp, " --omit-home-plugin-path Omit home plugins from plugin search path\n"); fprintf(fp, " (~/.local/lib/babeltrace/plugins)\n"); fprintf(fp, " --omit-system-plugin-path Omit system plugins from plugin search path\n"); fprintf(fp, " --plugin-path=PATH[:PATH]... Add PATH to the list of paths from which\n"); fprintf(fp, " dynamic plugins can be loaded\n"); - fprintf(fp, " -S, --sink=PLUGIN.CLS Get help for the sink component class\n"); - fprintf(fp, " CLS found in the plugin PLUGIN\n"); - fprintf(fp, " -s, --source=PLUGIN.CLS Get help for the source component class\n"); - fprintf(fp, " CLS found in the plugin PLUGIN\n"); - fprintf(fp, " -h --help Show this help and quit\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"); fprintf(fp, "\n"); @@ -1762,13 +1806,10 @@ void print_help_usage(FILE *fp) static struct poptOption help_long_options[] = { /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ - { "filter", 'f', POPT_ARG_STRING, NULL, OPT_FILTER, NULL, NULL }, { "help", 'h', POPT_ARG_NONE, NULL, OPT_HELP, 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 }, { "plugin-path", '\0', POPT_ARG_STRING, NULL, OPT_PLUGIN_PATH, NULL, NULL }, - { "sink", 'S', POPT_ARG_STRING, NULL, OPT_SINK, NULL, NULL }, - { "source", 's', POPT_ARG_STRING, NULL, OPT_SOURCE, NULL, NULL }, { NULL, 0, '\0', NULL, 0, NULL, NULL }, }; @@ -1782,7 +1823,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; @@ -1791,7 +1832,6 @@ struct bt_config *bt_config_help_from_args(int argc, const char *argv[], struct bt_config *cfg = NULL; const char *leftover; char *plugin_name = NULL, *comp_cls_name = NULL; - char *plug_comp_cls_names = NULL; *retcode = 0; cfg = bt_config_help_create(initial_plugin_paths); @@ -1832,42 +1872,10 @@ struct bt_config *bt_config_help_from_args(int argc, const char *argv[], case OPT_OMIT_HOME_PLUGIN_PATH: cfg->omit_home_plugin_path = true; break; - case OPT_SOURCE: - case OPT_FILTER: - case OPT_SINK: - if (cfg->cmd_data.help.cfg_component->type != - BT_COMPONENT_CLASS_TYPE_UNKNOWN) { - printf_err("Cannot specify more than one plugin and component class:\n %s\n", - arg); - goto error; - } - - switch (opt) { - case OPT_SOURCE: - cfg->cmd_data.help.cfg_component->type = - BT_COMPONENT_CLASS_TYPE_SOURCE; - break; - case OPT_FILTER: - cfg->cmd_data.help.cfg_component->type = - BT_COMPONENT_CLASS_TYPE_FILTER; - break; - case OPT_SINK: - cfg->cmd_data.help.cfg_component->type = - BT_COMPONENT_CLASS_TYPE_SINK; - break; - default: - abort(); - } - plug_comp_cls_names = strdup(arg); - if (!plug_comp_cls_names) { - print_err_oom(); - goto error; - } - break; 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", @@ -1888,36 +1896,28 @@ struct bt_config *bt_config_help_from_args(int argc, const char *argv[], leftover = poptGetArg(pc); if (leftover) { - if (cfg->cmd_data.help.cfg_component->type != - BT_COMPONENT_CLASS_TYPE_UNKNOWN) { - printf_err("Cannot specify plugin name and --source/--filter/--sink component class:\n %s\n", - leftover); - goto error; - } - - g_string_assign(cfg->cmd_data.help.cfg_component->plugin_name, - leftover); - } else { - if (cfg->cmd_data.help.cfg_component->type == - BT_COMPONENT_CLASS_TYPE_UNKNOWN) { - print_help_usage(stdout); - *retcode = -1; - BT_PUT(cfg); - goto end; - } - - plugin_comp_cls_names(plug_comp_cls_names, NULL, - &plugin_name, &comp_cls_name); + plugin_comp_cls_names(leftover, NULL, + &plugin_name, &comp_cls_name, + &cfg->cmd_data.help.cfg_component->type); if (plugin_name && comp_cls_name) { - g_string_assign(cfg->cmd_data.help.cfg_component->plugin_name, + /* Component class help */ + g_string_assign( + cfg->cmd_data.help.cfg_component->plugin_name, plugin_name); - g_string_assign(cfg->cmd_data.help.cfg_component->comp_cls_name, + g_string_assign( + cfg->cmd_data.help.cfg_component->comp_cls_name, comp_cls_name); } else { - printf_err("Invalid --source/--filter/--sink option's argument:\n %s\n", - plug_comp_cls_names); - goto error; + /* Fall back to plugin help */ + g_string_assign( + cfg->cmd_data.help.cfg_component->plugin_name, + leftover); } + } else { + print_help_usage(stdout); + *retcode = -1; + BT_OBJECT_PUT_REF_AND_RESET(cfg); + goto end; } if (append_home_and_system_plugin_paths_cfg(cfg)) { @@ -1928,10 +1928,9 @@ 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: - free(plug_comp_cls_names); g_free(plugin_name); g_free(comp_cls_name); @@ -1949,14 +1948,10 @@ end: static void print_query_usage(FILE *fp) { - fprintf(fp, "Usage: babeltrace [GEN OPTS] query [OPTS] OBJECT --source=PLUGIN.CLS\n"); - fprintf(fp, " babeltrace [GEN OPTS] query [OPTS] OBJECT --filter=PLUGIN.CLS\n"); - fprintf(fp, " babeltrace [GEN OPTS] query [OPTS] OBJECT --sink=PLUGIN.CLS\n"); + fprintf(fp, "Usage: babeltrace [GEN OPTS] query [OPTS] TYPE.PLUGIN.CLS OBJECT\n"); fprintf(fp, "\n"); fprintf(fp, "Options:\n"); fprintf(fp, "\n"); - fprintf(fp, " -f. --filter=PLUGIN.CLS Query object from the filter component\n"); - fprintf(fp, " class CLS found in the plugin PLUGIN\n"); fprintf(fp, " --omit-home-plugin-path Omit home plugins from plugin search path\n"); fprintf(fp, " (~/.local/lib/babeltrace/plugins)\n"); fprintf(fp, " --omit-system-plugin-path Omit system plugins from plugin search path\n"); @@ -1964,11 +1959,7 @@ void print_query_usage(FILE *fp) fprintf(fp, " (see the expected format of PARAMS below)\n"); fprintf(fp, " --plugin-path=PATH[:PATH]... Add PATH to the list of paths from which\n"); fprintf(fp, " dynamic plugins can be loaded\n"); - fprintf(fp, " -S, --sink=PLUGIN.CLS Query object from the sink component class\n"); - fprintf(fp, " CLS found in the plugin PLUGIN\n"); - fprintf(fp, " -s, --source=PLUGIN.CLS Query object from the source component\n"); - fprintf(fp, " class CLS found in the plugin PLUGIN\n"); - fprintf(fp, " -h --help Show this help and quit\n"); + fprintf(fp, " -h, --help Show this help and quit\n"); fprintf(fp, "\n\n"); print_expected_params_format(fp); } @@ -1976,14 +1967,11 @@ void print_query_usage(FILE *fp) static struct poptOption query_long_options[] = { /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ - { "filter", 'f', POPT_ARG_STRING, NULL, OPT_FILTER, NULL, NULL }, { "help", 'h', POPT_ARG_NONE, NULL, OPT_HELP, 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 }, - { "sink", 'S', POPT_ARG_STRING, NULL, OPT_SINK, NULL, NULL }, - { "source", 's', POPT_ARG_STRING, NULL, OPT_SOURCE, NULL, NULL }, { NULL, 0, '\0', NULL, 0, NULL, NULL }, }; @@ -1997,7 +1985,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; @@ -2005,7 +1993,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); @@ -2046,48 +2037,9 @@ struct bt_config *bt_config_query_from_args(int argc, const char *argv[], case OPT_OMIT_HOME_PLUGIN_PATH: cfg->omit_home_plugin_path = true; break; - case OPT_SOURCE: - case OPT_FILTER: - case OPT_SINK: - { - enum bt_component_class_type type; - - if (cfg->cmd_data.query.cfg_component) { - printf_err("Cannot specify more than one plugin and component class:\n %s\n", - arg); - goto error; - } - - switch (opt) { - case OPT_SOURCE: - type = BT_COMPONENT_CLASS_TYPE_SOURCE; - break; - case OPT_FILTER: - type = BT_COMPONENT_CLASS_TYPE_FILTER; - break; - case OPT_SINK: - type = BT_COMPONENT_CLASS_TYPE_SINK; - break; - default: - abort(); - } - - cfg->cmd_data.query.cfg_component = - bt_config_component_from_arg(type, arg); - if (!cfg->cmd_data.query.cfg_component) { - printf_err("Invalid format for --source/--filter/--sink option's argument:\n %s\n", - arg); - goto error; - } - - /* Default parameters: null */ - bt_put(cfg->cmd_data.query.cfg_component->params); - cfg->cmd_data.query.cfg_component->params = - bt_value_null; - break; - } case OPT_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", @@ -2099,7 +2051,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", @@ -2111,14 +2063,6 @@ struct bt_config *bt_config_query_from_args(int argc, const char *argv[], arg = NULL; } - if (!cfg->cmd_data.query.cfg_component) { - printf_err("No target component class specified with --source/--filter/--sink option\n"); - goto error; - } - - assert(params); - BT_MOVE(cfg->cmd_data.query.cfg_component->params, params); - /* Check for option parsing error */ if (opt < -1) { printf_err("While parsing command-line options, at option %s: %s\n", @@ -2127,9 +2071,29 @@ struct bt_config *bt_config_query_from_args(int argc, const char *argv[], } /* - * We need exactly one leftover argument which is the - * mandatory object. + * We need exactly two leftover arguments which are the + * mandatory component class specification and query object. */ + leftover = poptGetArg(pc); + if (leftover) { + cfg->cmd_data.query.cfg_component = + bt_config_component_from_arg(leftover); + if (!cfg->cmd_data.query.cfg_component) { + printf_err("Invalid format for component class specification:\n %s\n", + leftover); + goto error; + } + + BT_ASSERT(params); + BT_OBJECT_MOVE_REF(cfg->cmd_data.query.cfg_component->params, + params); + } else { + print_query_usage(stdout); + *retcode = -1; + BT_OBJECT_PUT_REF_AND_RESET(cfg); + goto end; + } + leftover = poptGetArg(pc); if (leftover) { if (strlen(leftover) == 0) { @@ -2141,7 +2105,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; } @@ -2159,14 +2123,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; } @@ -2186,7 +2150,7 @@ void print_list_plugins_usage(FILE *fp) fprintf(fp, " --omit-system-plugin-path Omit system plugins from plugin search path\n"); fprintf(fp, " --plugin-path=PATH[:PATH]... Add PATH to the list of paths from which\n"); fprintf(fp, " dynamic plugins can be loaded\n"); - fprintf(fp, " -h --help Show this help and quit\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"); fprintf(fp, "\n"); @@ -2213,7 +2177,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; @@ -2264,7 +2228,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", @@ -2297,7 +2261,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) { @@ -2322,12 +2286,14 @@ void print_run_usage(FILE *fp) fprintf(fp, " for all the following components until\n"); fprintf(fp, " --reset-base-params is encountered\n"); fprintf(fp, " (see the expected format of PARAMS below)\n"); - fprintf(fp, " -c, --connect=CONNECTION Connect two created components (see the\n"); + fprintf(fp, " -c, --component=[NAME:]TYPE.PLUGIN.CLS\n"); + fprintf(fp, " Instantiate the component class CLS of type\n"); + fprintf(fp, " TYPE (`source`, `filter`, or `sink`) found\n"); + 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, " -x, --connect=CONNECTION Connect two created components (see the\n"); fprintf(fp, " expected format of CONNECTION below)\n"); - fprintf(fp, " -f, --filter=[NAME:]PLUGIN.CLS Instantiate a filter component from plugin\n"); - fprintf(fp, " PLUGIN and component class CLS, set it as\n"); - fprintf(fp, " the current component, and if NAME is\n"); - fprintf(fp, " given, set its instance name to NAME\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"); @@ -2346,19 +2312,11 @@ 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, " -S, --sink=[NAME:]PLUGIN.CLS Instantiate a sink component from plugin\n"); - fprintf(fp, " PLUGIN and component class CLS, set it as\n"); - fprintf(fp, " the current component, and if NAME is\n"); - fprintf(fp, " given, set its instance name to NAME\n"); - fprintf(fp, " -s, --source=[NAME:]PLUGIN.CLS Instantiate a source component from plugin\n"); - fprintf(fp, " PLUGIN and component class CLS, set it as\n"); - fprintf(fp, " the current component, and if NAME is\n"); - fprintf(fp, " given, set its instance name to NAME\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, " -h, --help Show this help and quit\n"); fprintf(fp, "\n"); fprintf(fp, "See `babeltrace --help` for the list of general options.\n"); fprintf(fp, "\n\n"); @@ -2409,25 +2367,26 @@ 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; + bt_value *instance_names = NULL; + bt_value *connection_args = NULL; GString *cur_param_key = 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 }, - { "connect", 'c', POPT_ARG_STRING, NULL, OPT_CONNECT, NULL, NULL }, - { "filter", 'f', POPT_ARG_STRING, NULL, OPT_FILTER, NULL, NULL }, + { "component", 'c', POPT_ARG_STRING, NULL, OPT_COMPONENT, 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 }, @@ -2436,9 +2395,7 @@ struct bt_config *bt_config_run_from_args(int argc, const char *argv[], { "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 }, - { "sink", 'S', POPT_ARG_STRING, NULL, OPT_SINK, NULL, NULL }, - { "source", 's', POPT_ARG_STRING, NULL, OPT_SOURCE, NULL, NULL }, + { "retry-duration", '\0', POPT_ARG_LONG, &retry_duration, OPT_RETRY_DURATION, NULL, NULL }, { "value", '\0', POPT_ARG_STRING, NULL, OPT_VALUE, NULL, NULL }, { NULL, 0, '\0', NULL, 0, NULL, NULL }, }; @@ -2513,56 +2470,46 @@ struct bt_config *bt_config_run_from_args(int argc, const char *argv[], case OPT_OMIT_HOME_PLUGIN_PATH: cfg->omit_home_plugin_path = true; break; - case OPT_SOURCE: - case OPT_FILTER: - case OPT_SINK: + case OPT_COMPONENT: { - enum bt_component_class_type new_comp_type; enum bt_config_component_dest new_dest; - const char *opt_name; - - switch (opt) { - case OPT_SOURCE: - new_comp_type = BT_COMPONENT_CLASS_TYPE_SOURCE; - new_dest = BT_CONFIG_COMPONENT_DEST_SOURCE; - opt_name = "--source"; - break; - case OPT_FILTER: - new_comp_type = BT_COMPONENT_CLASS_TYPE_FILTER; - new_dest = BT_CONFIG_COMPONENT_DEST_FILTER; - opt_name = "--filter"; - break; - case OPT_SINK: - new_comp_type = BT_COMPONENT_CLASS_TYPE_SINK; - new_dest = BT_CONFIG_COMPONENT_DEST_SINK; - opt_name = "--sink"; - break; - default: - abort(); - } 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; } } - cur_cfg_comp = bt_config_component_from_arg( - new_comp_type, arg); + cur_cfg_comp = bt_config_component_from_arg(arg); if (!cur_cfg_comp) { - printf_err("Invalid format for %s option's argument:\n %s\n", - opt_name, arg); + printf_err("Invalid format for --component option's argument:\n %s\n", + arg); goto error; } - 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) { + switch (cur_cfg_comp->type) { + case BT_COMPONENT_CLASS_TYPE_SOURCE: + new_dest = BT_CONFIG_COMPONENT_DEST_SOURCE; + break; + case BT_COMPONENT_CLASS_TYPE_FILTER: + new_dest = BT_CONFIG_COMPONENT_DEST_FILTER; + break; + case BT_COMPONENT_CLASS_TYPE_SINK: + new_dest = BT_CONFIG_COMPONENT_DEST_SINK; + break; + default: + abort(); + } + + 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; } @@ -2572,8 +2519,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", @@ -2588,16 +2535,16 @@ 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: @@ -2621,7 +2568,7 @@ struct bt_config *bt_config_run_from_args(int argc, const char *argv[], goto error; } - if (bt_value_map_insert_string(cur_cfg_comp->params, + if (bt_value_map_insert_string_entry(cur_cfg_comp->params, cur_param_key->str, arg)) { print_err_oom(); goto error; @@ -2638,7 +2585,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", @@ -2646,11 +2594,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(); @@ -2658,15 +2606,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; } @@ -2677,7 +2625,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", @@ -2706,7 +2654,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; } @@ -2726,7 +2674,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); @@ -2737,7 +2686,7 @@ 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) { @@ -2749,23 +2698,23 @@ end: } 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; - size_t i; - const size_t argc = bt_value_array_size(run_args) + 1; + int64_t i, len; + const size_t argc = bt_value_array_get_size(run_args) + 1; argv = calloc(argc, sizeof(*argv)); if (!argv) { @@ -2775,17 +2724,21 @@ struct bt_config *bt_config_run_from_args_array(struct bt_value *run_args, argv[0] = "run"; - for (i = 0; i < bt_value_array_size(run_args); i++) { - int ret; - struct bt_value *arg_value = bt_value_array_get(run_args, i); + 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++) { + 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, @@ -2807,10 +2760,13 @@ void print_convert_usage(FILE *fp) fprintf(fp, "\n"); fprintf(fp, "Options:\n"); fprintf(fp, "\n"); - fprintf(fp, " --filter=[NAME:]PLUGIN.CLS Instantiate a filter component from plugin\n"); - fprintf(fp, " PLUGIN and component class CLS, set it as\n"); - fprintf(fp, " the current component, and if NAME is\n"); - fprintf(fp, " given, set its instance name to NAME\n"); + fprintf(fp, " -c, --component=[NAME:]TYPE.PLUGIN.CLS\n"); + fprintf(fp, " Instantiate the component class CLS of type\n"); + fprintf(fp, " TYPE (`source`, `filter`, or `sink`) found\n"); + fprintf(fp, " in the plugin PLUGIN, add it to the\n"); + fprintf(fp, " conversion graph, and optionally name it\n"); + fprintf(fp, " NAME (you can also specify the name with\n"); + fprintf(fp, " --name)\n"); fprintf(fp, " --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"); @@ -2833,26 +2789,18 @@ void print_convert_usage(FILE *fp) fprintf(fp, " --run-args-0 Print the equivalent arguments for the\n"); fprintf(fp, " `run` command to the standard output,\n"); fprintf(fp, " formatted for `xargs -0`, and quit\n"); - fprintf(fp, " --sink=[NAME:]PLUGIN.CLS Instantiate a sink component from plugin\n"); - fprintf(fp, " PLUGIN and component class CLS, set it as\n"); - fprintf(fp, " the current component, and if NAME is\n"); - fprintf(fp, " given, set its instance name to NAME\n"); - fprintf(fp, " --source=[NAME:]PLUGIN.CLS Instantiate a source component from plugin\n"); - fprintf(fp, " PLUGIN and component class CLS, set it as\n"); - fprintf(fp, " the current component, and if NAME is\n"); - fprintf(fp, " given, set its instance name to NAME\n"); + fprintf(fp, " --stream-intersection Only process events when all streams\n"); + fprintf(fp, " are active\n"); fprintf(fp, " -u, --url=URL Set the `url` string parameter of the\n"); fprintf(fp, " current component to URL\n"); - fprintf(fp, " -h --help Show this help and quit\n"); + fprintf(fp, " -h, --help Show this help and quit\n"); fprintf(fp, "\n"); - fprintf(fp, "Implicit `ctf.fs` source component options:\n"); + fprintf(fp, "Implicit `source.ctf.fs` component options:\n"); fprintf(fp, "\n"); fprintf(fp, " --clock-offset=SEC Set clock offset to SEC seconds\n"); fprintf(fp, " --clock-offset-ns=NS Set clock offset to NS ns\n"); - fprintf(fp, " --stream-intersection Only process events when all streams\n"); - fprintf(fp, " are active\n"); fprintf(fp, "\n"); - fprintf(fp, "Implicit `text.text` sink component options:\n"); + fprintf(fp, "Implicit `sink.text.pretty` component options:\n"); fprintf(fp, "\n"); fprintf(fp, " --clock-cycles Print timestamps in clock cycles\n"); fprintf(fp, " --clock-date Print timestamp dates\n"); @@ -2876,12 +2824,12 @@ void print_convert_usage(FILE *fp) fprintf(fp, " -w, --output=PATH Write output text to PATH instead of\n"); fprintf(fp, " the standard output\n"); fprintf(fp, "\n"); - fprintf(fp, "Implicit `utils.muxer` filter component options:\n"); + fprintf(fp, "Implicit `filter.utils.muxer` component options:\n"); fprintf(fp, "\n"); fprintf(fp, " --clock-force-correlate Assume that clocks are inherently\n"); fprintf(fp, " correlated across traces\n"); fprintf(fp, "\n"); - fprintf(fp, "Implicit `utils.trimmer` filter component options:\n"); + fprintf(fp, "Implicit `filter.utils.trimmer` component options:\n"); fprintf(fp, "\n"); fprintf(fp, " -b, --begin=BEGIN Set the beginning time of the conversion\n"); fprintf(fp, " time range to BEGIN (see the format of\n"); @@ -2892,8 +2840,10 @@ void print_convert_usage(FILE *fp) fprintf(fp, " BEGIN,END or [BEGIN,END] (literally `[` and\n"); fprintf(fp, " `]`) (see the format of BEGIN/END below)\n"); fprintf(fp, "\n"); - fprintf(fp, "Implicit `lttng-utils.debug-info` filter component options:\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"); @@ -2902,28 +2852,29 @@ 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"); fprintf(fp, " -i, --input-format=(ctf | lttng-live)\n"); fprintf(fp, " `ctf`:\n"); - fprintf(fp, " Create an implicit `ctf.fs` source\n"); + fprintf(fp, " Create an implicit `source.ctf.fs`\n"); fprintf(fp, " component\n"); fprintf(fp, " `lttng-live`:\n"); - fprintf(fp, " Create an implicit `ctf.lttng-live`\n"); - fprintf(fp, " source component\n"); - fprintf(fp, " -o, --output-format=(text | dummy | ctf-metadata)\n"); + fprintf(fp, " Create an implicit `source.ctf.lttng-live`\n"); + fprintf(fp, " component\n"); + fprintf(fp, " -o, --output-format=(text | ctf | dummy | ctf-metadata)\n"); fprintf(fp, " `text`:\n"); - fprintf(fp, " Create an implicit `text.text` sink\n"); + fprintf(fp, " Create an implicit `sink.text.pretty`\n"); + fprintf(fp, " component\n"); + fprintf(fp, " `ctf`:\n"); + fprintf(fp, " Create an implicit `sink.ctf.fs`\n"); fprintf(fp, " component\n"); fprintf(fp, " `dummy`:\n"); - fprintf(fp, " Create an implicit `utils.dummy` sink\n"); + fprintf(fp, " Create an implicit `sink.utils.dummy`\n"); fprintf(fp, " component\n"); fprintf(fp, " `ctf-metadata`:\n"); - fprintf(fp, " Query the `ctf.fs` component class for\n"); - fprintf(fp, " metadata text and quit\n"); + fprintf(fp, " Query the `source.ctf.fs` component class\n"); + fprintf(fp, " for metadata text and quit\n"); fprintf(fp, "\n"); fprintf(fp, "See `babeltrace --help` for the list of general options.\n"); fprintf(fp, "\n\n"); @@ -2947,18 +2898,18 @@ struct poptOption convert_long_options[] = { { "clock-offset-ns", '\0', POPT_ARG_STRING, NULL, OPT_CLOCK_OFFSET_NS, NULL, NULL }, { "clock-seconds", '\0', POPT_ARG_NONE, NULL, OPT_CLOCK_SECONDS, NULL, NULL }, { "color", '\0', POPT_ARG_STRING, NULL, OPT_COLOR, NULL, NULL }, + { "component", 'c', POPT_ARG_STRING, NULL, OPT_COMPONENT, NULL, NULL }, { "debug", 'd', POPT_ARG_NONE, NULL, OPT_DEBUG, NULL, NULL }, { "debug-info-dir", 0, POPT_ARG_STRING, NULL, OPT_DEBUG_INFO_DIR, NULL, NULL }, { "debug-info-full-path", 0, POPT_ARG_NONE, NULL, OPT_DEBUG_INFO_FULL_PATH, NULL, NULL }, { "debug-info-target-prefix", 0, POPT_ARG_STRING, NULL, OPT_DEBUG_INFO_TARGET_PREFIX, NULL, NULL }, { "end", 'e', POPT_ARG_STRING, NULL, OPT_END, NULL, NULL }, { "fields", 'f', POPT_ARG_STRING, NULL, OPT_FIELDS, NULL, NULL }, - { "filter", '\0', POPT_ARG_STRING, NULL, OPT_FILTER, NULL, NULL }, { "help", 'h', POPT_ARG_NONE, NULL, OPT_HELP, NULL, NULL }, { "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 }, @@ -2970,8 +2921,6 @@ struct poptOption convert_long_options[] = { { "retry-duration", '\0', POPT_ARG_STRING, NULL, OPT_RETRY_DURATION, NULL, NULL }, { "run-args", '\0', POPT_ARG_NONE, NULL, OPT_RUN_ARGS, NULL, NULL }, { "run-args-0", '\0', POPT_ARG_NONE, NULL, OPT_RUN_ARGS_0, NULL, NULL }, - { "sink", '\0', POPT_ARG_STRING, NULL, OPT_SINK, NULL, NULL }, - { "source", '\0', POPT_ARG_STRING, NULL, OPT_SOURCE, NULL, NULL }, { "stream-intersection", '\0', POPT_ARG_NONE, NULL, OPT_STREAM_INTERSECTION, NULL, NULL }, { "timerange", '\0', POPT_ARG_STRING, NULL, OPT_TIMERANGE, NULL, NULL }, { "url", 'u', POPT_ARG_STRING, NULL, OPT_URL, NULL, NULL }, @@ -2981,7 +2930,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); @@ -2991,7 +2940,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; } @@ -2999,7 +2948,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; @@ -3007,15 +2956,15 @@ end: struct implicit_component_args { bool exists; - GString *plugin_comp_cls_arg; + GString *comp_arg; GString *name_arg; GString *params_arg; - struct bt_value *extra_args; + 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; @@ -3025,7 +2974,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; @@ -3034,7 +2984,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; @@ -3056,9 +3006,8 @@ end: static int append_run_args_for_implicit_component( - enum bt_component_class_type type, struct implicit_component_args *impl_args, - struct bt_value *run_args) + bt_value *run_args) { int ret = 0; size_t i; @@ -3067,74 +3016,53 @@ int append_run_args_for_implicit_component( goto end; } - switch (type) { - case BT_COMPONENT_CLASS_TYPE_SOURCE: - if (bt_value_array_append_string(run_args, "--source")) { - print_err_oom(); - goto error; - } - break; - case BT_COMPONENT_CLASS_TYPE_FILTER: - if (bt_value_array_append_string(run_args, "--filter")) { - print_err_oom(); - goto error; - } - break; - case BT_COMPONENT_CLASS_TYPE_SINK: - if (bt_value_array_append_string(run_args, "--sink")) { - print_err_oom(); - goto error; - } - break; - default: - abort(); + 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->plugin_comp_cls_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_args); 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_args, 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; @@ -3151,12 +3079,12 @@ end: } static -void destroy_implicit_component_args(struct implicit_component_args *args) +void finalize_implicit_component_args(struct implicit_component_args *args) { - assert(args); + BT_ASSERT(args); - if (args->plugin_comp_cls_arg) { - g_string_free(args->plugin_comp_cls_arg, TRUE); + if (args->comp_arg) { + g_string_free(args->comp_arg, TRUE); } if (args->name_arg) { @@ -3167,25 +3095,36 @@ void destroy_implicit_component_args(struct implicit_component_args *args) g_string_free(args->params_arg, TRUE); } - bt_put(args->extra_args); + bt_value_put_ref(args->extra_params); +} + +static +void destroy_implicit_component_args(void *args) +{ + if (!args) { + return; + } + + finalize_implicit_component_args(args); + g_free(args); } static int init_implicit_component_args(struct implicit_component_args *args, - const char *plugin_comp_cls_arg, bool exists) + const char *comp_arg, bool exists) { int ret = 0; args->exists = exists; - args->plugin_comp_cls_arg = g_string_new(plugin_comp_cls_arg); + args->comp_arg = g_string_new(comp_arg); args->name_arg = g_string_new(NULL); args->params_arg = g_string_new(NULL); - args->extra_args = bt_value_array_create(); + args->extra_params = bt_value_array_create(); - if (!args->plugin_comp_cls_arg || !args->name_arg || - !args->params_arg || !args->extra_args) { + if (!args->comp_arg || !args->name_arg || + !args->params_arg || !args->extra_params) { ret = -1; - destroy_implicit_component_args(args); + finalize_implicit_component_args(args); print_err_oom(); goto end; } @@ -3198,41 +3137,41 @@ 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); } static -int append_implicit_component_extra_arg(struct implicit_component_args *args, +int append_implicit_component_extra_param(struct implicit_component_args *args, const char *key, const char *value) { int ret = 0; - assert(args); - assert(key); - assert(value); + BT_ASSERT(args); + BT_ASSERT(key); + BT_ASSERT(value); - if (bt_value_array_append_string(args->extra_args, "--key")) { + if (bt_value_array_append_string_element(args->extra_params, "--key")) { print_err_oom(); ret = -1; goto end; } - if (bt_value_array_append_string(args->extra_args, key)) { + if (bt_value_array_append_string_element(args->extra_params, key)) { print_err_oom(); ret = -1; goto end; } - if (bt_value_array_append_string(args->extra_args, "--value")) { + if (bt_value_array_append_string_element(args->extra_params, "--value")) { print_err_oom(); ret = -1; goto end; } - if (bt_value_array_append_string(args->extra_args, value)) { + if (bt_value_array_append_string_element(args->extra_params, value)) { print_err_oom(); ret = -1; goto end; @@ -3245,14 +3184,15 @@ end: 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) { int ret = 0; if (cur_name_prefix->len > 0) { - /* We're after a --source/--filter/--sink */ + /* We're after a --component option */ GString *name = NULL; bool append_name_opt = false; @@ -3261,8 +3201,7 @@ int convert_append_name_param(enum bt_config_component_dest dest, * No explicit name was provided for the user * component. */ - name = get_component_auto_name( - cur_name_prefix->str, + name = get_component_auto_name(cur_name_prefix->str, all_names); append_name_opt = true; } else { @@ -3270,8 +3209,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; @@ -3289,7 +3228,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; } @@ -3298,12 +3237,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; } @@ -3371,7 +3310,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; @@ -3385,7 +3324,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; @@ -3395,7 +3334,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; @@ -3422,7 +3361,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) { @@ -3432,9 +3371,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)) { @@ -3493,7 +3432,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++; @@ -3511,8 +3450,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); @@ -3542,7 +3481,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(); @@ -3555,6 +3494,85 @@ 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; + bt_value_status status; + + 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_VALUE_PUT_REF_AND_RESET(impl_args->extra_params); + status = bt_value_copy(base_implicit_ctf_input_args->extra_params, + &impl_args->extra_params); + if (status != BT_VALUE_STATUS_OK) { + 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. @@ -3564,8 +3582,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) + bool force_omit_home_plugin_path, + const bt_value *initial_plugin_paths, char *log_level) { poptContext pc = NULL; char *arg = NULL; @@ -3573,34 +3591,39 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], BT_CONFIG_COMPONENT_DEST_UNKNOWN; int opt, ret = 0; struct bt_config *cfg = NULL; - bool got_verbose_opt = false; - bool got_debug_opt = false; bool got_input_format_opt = false; bool got_output_format_opt = false; bool trimmer_has_begin = false; bool trimmer_has_end = false; + bool stream_intersection_mode = false; GString *cur_name = NULL; GString *cur_name_prefix = NULL; const char *leftover = NULL; 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; - struct implicit_component_args implicit_ctf_args = { 0 }; + GList *leftovers = NULL; + GPtrArray *implicit_ctf_inputs_args = NULL; + struct implicit_component_args base_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 }; struct implicit_component_args implicit_text_args = { 0 }; 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; @@ -3610,37 +3633,50 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto end; } - if (init_implicit_component_args(&implicit_ctf_args, "ctf.fs", false)) { + if (init_implicit_component_args(&base_implicit_ctf_input_args, + "source.ctf.fs", false)) { + goto error; + } + + if (init_implicit_component_args(&implicit_ctf_output_args, + "sink.ctf.fs", false)) { goto error; } if (init_implicit_component_args(&implicit_lttng_live_args, - "ctf.lttng-live", false)) { + "source.ctf.lttng-live", false)) { goto error; } - if (init_implicit_component_args(&implicit_text_args, "text.pretty", - false)) { + if (init_implicit_component_args(&implicit_text_args, + "sink.text.pretty", false)) { goto error; } - if (init_implicit_component_args(&implicit_dummy_args, "utils.dummy", - false)) { + if (init_implicit_component_args(&implicit_dummy_args, + "sink.utils.dummy", false)) { goto error; } if (init_implicit_component_args(&implicit_debug_info_args, - "lttng-utils.debug-info", !force_no_debug_info)) { + "filter.lttng-utils.debug-info", false)) { goto error; } - if (init_implicit_component_args(&implicit_muxer_args, "utils.muxer", - true)) { + if (init_implicit_component_args(&implicit_muxer_args, + "filter.utils.muxer", true)) { goto error; } if (init_implicit_component_args(&implicit_trimmer_args, - "utils.trimmer", false)) { + "filter.utils.trimmer", false)) { + 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; } @@ -3702,9 +3738,11 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], arg = poptGetOptArg(pc); switch (opt) { - case OPT_SOURCE: - case OPT_FILTER: - case OPT_SINK: + case OPT_COMPONENT: + { + bt_component_class_type type; + const char *type_prefix; + /* Append current component's name if needed */ ret = convert_append_name_param(cur_comp_dest, cur_name, cur_name_prefix, run_args, all_names, @@ -3715,9 +3753,9 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], /* Parse the argument */ plugin_comp_cls_names(arg, &name, &plugin_name, - &comp_cls_name); + &comp_cls_name, &type); if (!plugin_name || !comp_cls_name) { - printf_err("Invalid format for --source/--filter/--sink option's argument:\n %s\n", + printf_err("Invalid format for --component option's argument:\n %s\n", arg); goto error; } @@ -3728,47 +3766,37 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], g_string_assign(cur_name, ""); } - switch (opt) { - case OPT_SOURCE: - cur_comp_dest = - BT_CONFIG_COMPONENT_DEST_SOURCE; - if (bt_value_array_append_string(run_args, - "--source")) { - print_err_oom(); - goto error; - } + switch (type) { + case BT_COMPONENT_CLASS_TYPE_SOURCE: + cur_comp_dest = BT_CONFIG_COMPONENT_DEST_SOURCE; + type_prefix = "source"; break; - case OPT_FILTER: - cur_comp_dest = - BT_CONFIG_COMPONENT_DEST_FILTER; - if (bt_value_array_append_string(run_args, - "--filter")) { - print_err_oom(); - goto error; - } + case BT_COMPONENT_CLASS_TYPE_FILTER: + cur_comp_dest = BT_CONFIG_COMPONENT_DEST_FILTER; + type_prefix = "filter"; break; - case OPT_SINK: - cur_comp_dest = - BT_CONFIG_COMPONENT_DEST_SINK; - if (bt_value_array_append_string(run_args, - "--sink")) { - print_err_oom(); - goto error; - } + case BT_COMPONENT_CLASS_TYPE_SINK: + cur_comp_dest = BT_CONFIG_COMPONENT_DEST_SINK; + type_prefix = "sink"; break; default: abort(); } - if (bt_value_array_append_string(run_args, arg)) { + if (bt_value_array_append_string_element(run_args, + "--component")) { + print_err_oom(); + goto error; + } + + if (bt_value_array_append_string_element(run_args, arg)) { print_err_oom(); goto error; } g_string_assign(cur_name_prefix, ""); - g_string_append(cur_name_prefix, plugin_name); - g_string_append_c(cur_name_prefix, '.'); - g_string_append(cur_name_prefix, comp_cls_name); + g_string_append_printf(cur_name_prefix, "%s.%s.%s", + type_prefix, plugin_name, comp_cls_name); free(name); free(plugin_name); free(comp_cls_name); @@ -3776,6 +3804,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], plugin_name = NULL; comp_cls_name = NULL; break; + } case OPT_PARAMS: if (cur_name_prefix->len == 0) { printf_err("No current component of which to set parameters:\n %s\n", @@ -3783,13 +3812,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; } @@ -3801,22 +3830,22 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto error; } - if (bt_value_array_append_string(run_args, "--key")) { + if (bt_value_array_append_string_element(run_args, "--key")) { print_err_oom(); goto error; } - if (bt_value_array_append_string(run_args, "path")) { + if (bt_value_array_append_string_element(run_args, "path")) { print_err_oom(); goto error; } - if (bt_value_array_append_string(run_args, "--value")) { + if (bt_value_array_append_string_element(run_args, "--value")) { 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; } @@ -3828,22 +3857,22 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto error; } - if (bt_value_array_append_string(run_args, "--key")) { + if (bt_value_array_append_string_element(run_args, "--key")) { print_err_oom(); goto error; } - if (bt_value_array_append_string(run_args, "url")) { + if (bt_value_array_append_string_element(run_args, "url")) { print_err_oom(); goto error; } - if (bt_value_array_append_string(run_args, "--value")) { + if (bt_value_array_append_string_element(run_args, "--value")) { 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; } @@ -3855,12 +3884,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; } @@ -3870,20 +3899,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; } @@ -3891,7 +3920,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; @@ -3903,13 +3932,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; } @@ -3917,7 +3946,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: @@ -3929,6 +3958,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: @@ -3936,7 +3966,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: @@ -4002,7 +4031,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], } trimmer_has_begin = true; - ret = append_implicit_component_extra_arg( + ret = append_implicit_component_extra_param( &implicit_trimmer_args, "begin", arg); implicit_trimmer_args.exists = true; if (ret) { @@ -4017,7 +4046,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], } trimmer_has_end = true; - ret = append_implicit_component_extra_arg( + ret = append_implicit_component_extra_param( &implicit_trimmer_args, "end", arg); implicit_trimmer_args.exists = true; if (ret) { @@ -4042,9 +4071,9 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto error; } - ret = append_implicit_component_extra_arg( + ret = append_implicit_component_extra_param( &implicit_trimmer_args, "begin", begin); - ret |= append_implicit_component_extra_arg( + ret |= append_implicit_component_extra_param( &implicit_trimmer_args, "end", end); implicit_trimmer_args.exists = true; free(begin); @@ -4066,28 +4095,27 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], break; case OPT_CLOCK_FORCE_CORRELATE: append_implicit_component_param( - &implicit_muxer_args, "assume-absolute-clock-classes", "yes"); + &implicit_muxer_args, + "assume-absolute-clock-classes", "yes"); break; case OPT_CLOCK_GMT: append_implicit_component_param( &implicit_text_args, "clock-gmt", "yes"); + append_implicit_component_param( + &implicit_trimmer_args, "gmt", "yes"); implicit_text_args.exists = true; break; case OPT_CLOCK_OFFSET: - ret = append_implicit_component_extra_arg( - &implicit_ctf_args, "clock-offset-cycles", arg); - implicit_ctf_args.exists = true; - if (ret) { - goto error; - } + base_implicit_ctf_input_args.exists = true; + append_implicit_component_param( + &base_implicit_ctf_input_args, + "clock-class-offset-s", arg); break; case OPT_CLOCK_OFFSET_NS: - ret = append_implicit_component_extra_arg( - &implicit_ctf_args, "clock-offset-ns", arg); - implicit_ctf_args.exists = true; - if (ret) { - goto error; - } + base_implicit_ctf_input_args.exists = true; + append_implicit_component_param( + &base_implicit_ctf_input_args, + "clock-class-offset-ns", arg); break; case OPT_CLOCK_SECONDS: append_implicit_component_param( @@ -4095,29 +4123,32 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], implicit_text_args.exists = true; break; case OPT_COLOR: - ret = append_implicit_component_extra_arg( - &implicit_text_args, "color", arg); implicit_text_args.exists = true; + ret = append_implicit_component_extra_param( + &implicit_text_args, "color", arg); if (ret) { 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: - ret = append_implicit_component_extra_arg( - &implicit_debug_info_args, "dir", arg); + implicit_debug_info_args.exists = true; + ret = append_implicit_component_extra_param( + &implicit_debug_info_args, "debug-info-dir", arg); if (ret) { goto error; } break; case OPT_DEBUG_INFO_FULL_PATH: + implicit_debug_info_args.exists = true; append_implicit_component_param( &implicit_debug_info_args, "full-path", "yes"); break; case OPT_DEBUG_INFO_TARGET_PREFIX: - ret = append_implicit_component_extra_arg( + implicit_debug_info_args.exists = true; + ret = append_implicit_component_extra_param( &implicit_debug_info_args, "target-prefix", arg); if (ret) { @@ -4126,16 +4157,17 @@ 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; } + implicit_text_args.exists = true; 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,16 +4175,17 @@ 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; } + implicit_text_args.exists = true; 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; } @@ -4172,7 +4205,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], got_input_format_opt = true; if (strcmp(arg, "ctf") == 0) { - implicit_ctf_args.exists = true; + base_implicit_ctf_input_args.exists = true; } else if (strcmp(arg, "lttng-live") == 0) { implicit_lttng_live_args.exists = true; } else { @@ -4191,6 +4224,8 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], if (strcmp(arg, "text") == 0) { implicit_text_args.exists = true; + } else if (strcmp(arg, "ctf") == 0) { + implicit_ctf_output_args.exists = true; } else if (strcmp(arg, "dummy") == 0) { implicit_dummy_args.exists = true; } else if (strcmp(arg, "ctf-metadata") == 0) { @@ -4202,10 +4237,14 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], } break; case OPT_OUTPUT: - ret = append_implicit_component_extra_arg( - &implicit_text_args, "path", arg); - implicit_text_args.exists = true; - if (ret) { + if (output) { + printf_err("Duplicate --output option\n"); + goto error; + } + + output = strdup(arg); + if (!output) { + print_err_oom(); goto error; } break; @@ -4226,23 +4265,19 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], print_run_args_0 = true; break; case OPT_STREAM_INTERSECTION: - append_implicit_component_param(&implicit_ctf_args, - "stream-intersection", "yes"); - implicit_ctf_args.exists = true; + /* + * Applies to all traces implementing the trace-info + * query. + */ + stream_intersection_mode = true; break; case OPT_VERBOSE: - if (got_verbose_opt) { - printf_err("Duplicate -v/--verbose option\n"); - goto error; + if (*log_level != 'V' && *log_level != 'D') { + *log_level = 'I'; } - - append_implicit_component_param(&implicit_text_args, - "verbose", "yes"); - implicit_text_args.exists = true; - got_verbose_opt = true; break; case OPT_DEBUG: - got_debug_opt = true; + *log_level = 'V'; break; } @@ -4257,6 +4292,16 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto error; } + /* + * Legacy behaviour: --verbose used to make the `text` output + * format print more information. --verbose is now equivalent to + * the INFO log level, which is why we compare to 'I' here. + */ + if (*log_level == 'I') { + append_implicit_component_param(&implicit_text_args, + "verbose", "yes"); + } + /* * Append home and system plugin paths now that we possibly got * --plugin-path. @@ -4267,47 +4312,122 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto error; } - /* Consume leftover argument */ - leftover = poptGetArg(pc); + /* Consume and keep leftover arguments */ + while ((leftover = poptGetArg(pc))) { + GString *gs_leftover = g_string_new(leftover); - if (poptPeekArg(pc)) { - printf_err("Unexpected argument:\n %s\n", - poptPeekArg(pc)); - goto error; + if (!gs_leftover) { + print_err_oom(); + goto error; + } + + leftovers = g_list_append(leftovers, gs_leftover); + if (!leftovers) { + g_string_free(gs_leftover, TRUE); + print_err_oom(); + goto error; + } } /* Print CTF metadata or print LTTng live sessions */ if (print_ctf_metadata) { - if (!leftover) { + GString *gs_leftover; + + if (g_list_length(leftovers) == 0) { printf_err("--output-format=ctf-metadata specified without a path\n"); goto error; } + if (g_list_length(leftovers) > 1) { + printf_err("Too many paths specified for --output-format=ctf-metadata\n"); + goto error; + } + cfg = bt_config_print_ctf_metadata_create(plugin_paths); if (!cfg) { goto error; } - cfg->debug = got_debug_opt; - cfg->verbose = got_verbose_opt; + gs_leftover = leftovers->data; g_string_assign(cfg->cmd_data.print_ctf_metadata.path, - leftover); + gs_leftover->str); + + if (output) { + g_string_assign( + cfg->cmd_data.print_ctf_metadata.output_path, + output); + } + goto end; } /* - * If -o dummy was not specified, and if there are no explicit - * sink components, then use an implicit `text.text` sink. + * If -o ctf was specified, make sure an output path (--output) + * was also specified. --output does not imply -o ctf because + * it's also used for the default, implicit -o text if -o ctf + * is not specified. */ - if (!implicit_dummy_args.exists && !sink_names) { + if (implicit_ctf_output_args.exists) { + if (!output) { + printf_err("--output-format=ctf specified without --output (trace output path)\n"); + goto error; + } + + /* + * At this point we know that -o ctf AND --output were + * specified. Make sure that no options were specified + * which would imply -o text because --output would be + * ambiguous in this case. For example, this is wrong: + * + * babeltrace --names=all -o ctf --output=/tmp/path my-trace + * + * because --names=all implies -o text, and --output + * could apply to both the sink.text.pretty and + * sink.ctf.fs implicit components. + */ + if (implicit_text_args.exists) { + printf_err("Ambiguous --output option: --output-format=ctf specified but another option implies --output-format=text\n"); + goto error; + } + } + + /* + * If -o dummy and -o ctf were not specified, and if there are + * no explicit sink components, then use an implicit + * `sink.text.pretty` component. + */ + if (!implicit_dummy_args.exists && !implicit_ctf_output_args.exists && + !sink_names) { implicit_text_args.exists = true; } - /* Decide where the leftover argument goes */ - if (leftover) { + /* + * Set implicit `sink.text.pretty` or `sink.ctf.fs` component's + * `path` parameter if --output was specified. + */ + if (output) { + if (implicit_text_args.exists) { + append_implicit_component_extra_param(&implicit_text_args, + "path", output); + } else if (implicit_ctf_output_args.exists) { + append_implicit_component_extra_param(&implicit_ctf_output_args, + "path", output); + } + } + + /* Decide where the leftover argument(s) go */ + if (g_list_length(leftovers) > 0) { if (implicit_lttng_live_args.exists) { + GString *gs_leftover; + + if (g_list_length(leftovers) > 1) { + printf_err("Too many URLs specified for --output-format=lttng-live\n"); + goto error; + } + + gs_leftover = leftovers->data; lttng_live_url_parts = - bt_common_parse_lttng_live_url(leftover, + bt_common_parse_lttng_live_url(gs_leftover->str, error_buf, sizeof(error_buf)); if (!lttng_live_url_parts.proto) { printf_err("Invalid LTTng live URL format: %s\n", @@ -4323,22 +4443,34 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto error; } - cfg->debug = got_debug_opt; - cfg->verbose = got_verbose_opt; g_string_assign(cfg->cmd_data.print_lttng_live_sessions.url, - leftover); + gs_leftover->str); + + if (output) { + g_string_assign( + cfg->cmd_data.print_lttng_live_sessions.output_path, + output); + } + goto end; } - ret = append_implicit_component_extra_arg( - &implicit_lttng_live_args, "url", leftover); + ret = append_implicit_component_extra_param( + &implicit_lttng_live_args, "url", + gs_leftover->str); if (ret) { goto error; } } else { - ret = append_implicit_component_extra_arg( - &implicit_ctf_args, "path", leftover); - implicit_ctf_args.exists = true; + /* + * 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. + */ + ret = fill_implicit_ctf_inputs_args( + implicit_ctf_inputs_args, + &base_implicit_ctf_input_args, leftovers); if (ret) { goto error; } @@ -4346,37 +4478,45 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], } /* - * Ensure mutual exclusion between implicit `ctf.fs` and - * `ctf.lttng-live` sources. + * Ensure mutual exclusion between implicit `source.ctf.fs` and + * `source.ctf.lttng-live` components. */ - if (implicit_ctf_args.exists && implicit_lttng_live_args.exists) { - printf_err("Cannot create both implicit `%s` and `%s` source components\n", - implicit_ctf_args.plugin_comp_cls_arg->str, - implicit_lttng_live_args.plugin_comp_cls_arg->str); + if (base_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_lttng_live_args.comp_arg->str); goto error; } /* - * If the implicit `ctf.fs` or `ctf.lttng-live` source exists, - * make sure there's a leftover (which is the path or URL). + * If the implicit `source.ctf.fs` or `source.ctf.lttng-live` + * components exists, make sure there's at least one leftover + * (which is the path or URL). */ - if (implicit_ctf_args.exists && !leftover) { - printf_err("Missing path for implicit `%s` source component\n", - implicit_ctf_args.plugin_comp_cls_arg->str); + if (base_implicit_ctf_input_args.exists && + g_list_length(leftovers) == 0) { + printf_err("Missing path for implicit `%s` component\n", + base_implicit_ctf_input_args.comp_arg->str); goto error; } - if (implicit_lttng_live_args.exists && !leftover) { - printf_err("Missing URL for implicit `%s` source component\n", - implicit_lttng_live_args.plugin_comp_cls_arg->str); + if (implicit_lttng_live_args.exists && g_list_length(leftovers) == 0) { + printf_err("Missing URL for implicit `%s` component\n", + implicit_lttng_live_args.comp_arg->str); goto error; } /* Assign names to implicit components */ - ret = assign_name_to_implicit_component(&implicit_ctf_args, - "ctf-fs", all_names, &source_names, true); - if (ret) { - goto error; + 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_lttng_live_args, @@ -4391,6 +4531,12 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], goto error; } + ret = assign_name_to_implicit_component(&implicit_ctf_output_args, + "sink-ctf-fs", all_names, &sink_names, true); + if (ret) { + goto error; + } + ret = assign_name_to_implicit_component(&implicit_dummy_args, "dummy", all_names, &sink_names, true); if (ret) { @@ -4456,46 +4602,54 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], * Append the equivalent run arguments for the implicit * components. */ - ret = append_run_args_for_implicit_component( - BT_COMPONENT_CLASS_TYPE_SOURCE, &implicit_ctf_args, run_args); + 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_lttng_live_args, + run_args); if (ret) { goto error; } - ret = append_run_args_for_implicit_component( - BT_COMPONENT_CLASS_TYPE_SOURCE, &implicit_lttng_live_args, + ret = append_run_args_for_implicit_component(&implicit_text_args, run_args); if (ret) { goto error; } - ret = append_run_args_for_implicit_component( - BT_COMPONENT_CLASS_TYPE_SINK, &implicit_text_args, run_args); + ret = append_run_args_for_implicit_component(&implicit_ctf_output_args, + run_args); if (ret) { goto error; } - ret = append_run_args_for_implicit_component( - BT_COMPONENT_CLASS_TYPE_SINK, &implicit_dummy_args, run_args); + ret = append_run_args_for_implicit_component(&implicit_dummy_args, + run_args); if (ret) { goto error; } - ret = append_run_args_for_implicit_component( - BT_COMPONENT_CLASS_TYPE_FILTER, &implicit_muxer_args, run_args); + ret = append_run_args_for_implicit_component(&implicit_muxer_args, + run_args); if (ret) { goto error; } - ret = append_run_args_for_implicit_component( - BT_COMPONENT_CLASS_TYPE_FILTER, &implicit_trimmer_args, + ret = append_run_args_for_implicit_component(&implicit_trimmer_args, run_args); if (ret) { goto error; } - ret = append_run_args_for_implicit_component( - BT_COMPONENT_CLASS_TYPE_FILTER, &implicit_debug_info_args, + ret = append_run_args_for_implicit_component(&implicit_debug_info_args, run_args); if (ret) { goto error; @@ -4515,17 +4669,21 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], * here. */ if (print_run_args || print_run_args_0) { - for (i = 0; i < bt_value_array_size(run_args); i++) { - struct bt_value *arg_value = - bt_value_array_get(run_args, i); + if (stream_intersection_mode) { + printf_err("Cannot specify --stream-intersection with --run-args or --run-args-0\n"); + goto error; + } + + 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); @@ -4544,7 +4702,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 { @@ -4554,18 +4712,24 @@ 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; + } + + cfg->cmd_data.run.stream_intersection_mode = stream_intersection_mode; goto end; error: *retcode = 1; - BT_PUT(cfg); + BT_OBJECT_PUT_REF_AND_RESET(cfg); end: if (pc) { @@ -4573,6 +4737,7 @@ end: } free(arg); + free(output); if (cur_name) { g_string_free(cur_name, TRUE); @@ -4582,19 +4747,25 @@ end: g_string_free(cur_name_prefix, TRUE); } - bt_put(run_args); - bt_put(all_names); + if (implicit_ctf_inputs_args) { + g_ptr_array_free(implicit_ctf_inputs_args, TRUE); + } + + 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_implicit_component_args(&implicit_ctf_args); - destroy_implicit_component_args(&implicit_lttng_live_args); - destroy_implicit_component_args(&implicit_dummy_args); - destroy_implicit_component_args(&implicit_text_args); - destroy_implicit_component_args(&implicit_debug_info_args); - destroy_implicit_component_args(&implicit_muxer_args); - destroy_implicit_component_args(&implicit_trimmer_args); - bt_put(plugin_paths); + destroy_glist_of_gstring(leftovers); + finalize_implicit_component_args(&base_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); + finalize_implicit_component_args(&implicit_text_args); + finalize_implicit_component_args(&implicit_debug_info_args); + finalize_implicit_component_args(&implicit_muxer_args); + finalize_implicit_component_args(&implicit_trimmer_args); + bt_value_put_ref(plugin_paths); bt_common_destroy_lttng_live_url_parts(<tng_live_url_parts); return cfg; } @@ -4609,10 +4780,12 @@ void print_gen_usage(FILE *fp) fprintf(fp, "\n"); fprintf(fp, "General options:\n"); fprintf(fp, "\n"); - fprintf(fp, " -d, --debug Turn on debug mode\n"); - fprintf(fp, " -h --help Show this help and quit\n"); - fprintf(fp, " -v, --verbose Turn on verbose mode\n"); - fprintf(fp, " -V, --version Show version and quit\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, " -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"); fprintf(fp, "\n"); fprintf(fp, "Available commands:\n"); fprintf(fp, "\n"); @@ -4625,18 +4798,49 @@ void print_gen_usage(FILE *fp) fprintf(fp, "Use `babeltrace COMMAND --help` to show the help of COMMAND.\n"); } +static +char log_level_from_arg(const char *arg) +{ + char level = 'U'; + + if (strcmp(arg, "VERBOSE") == 0 || + strcmp(arg, "V") == 0) { + level = 'V'; + } else if (strcmp(arg, "DEBUG") == 0 || + strcmp(arg, "D") == 0) { + level = 'D'; + } else if (strcmp(arg, "INFO") == 0 || + strcmp(arg, "I") == 0) { + level = 'I'; + } else if (strcmp(arg, "WARN") == 0 || + strcmp(arg, "WARNING") == 0 || + strcmp(arg, "W") == 0) { + level = 'W'; + } else if (strcmp(arg, "ERROR") == 0 || + strcmp(arg, "E") == 0) { + level = 'E'; + } else if (strcmp(arg, "FATAL") == 0 || + strcmp(arg, "F") == 0) { + level = 'F'; + } else if (strcmp(arg, "NONE") == 0 || + strcmp(arg, "N") == 0) { + level = 'N'; + } + + return level; +} + 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; - bool verbose = false; - bool debug = false; int i; const char **command_argv = NULL; int command_argc = -1; const char *command_name = NULL; + char log_level = 'U'; enum command_type { COMMAND_TYPE_NONE = -1, @@ -4656,23 +4860,72 @@ 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) { + print_version(); + puts(""); print_gen_usage(stdout); goto end; } for (i = 1; i < argc; i++) { const char *cur_arg = argv[i]; + const char *next_arg = i == (argc - 1) ? NULL : argv[i + 1]; if (strcmp(cur_arg, "-d") == 0 || strcmp(cur_arg, "--debug") == 0) { - debug = true; + log_level = 'V'; } else if (strcmp(cur_arg, "-v") == 0 || strcmp(cur_arg, "--verbose") == 0) { - verbose = true; + if (log_level != 'V' && log_level != 'D') { + /* + * Legacy: do not override a previous + * --debug because --verbose and --debug + * can be specified together (in this + * case we want the lowest log level to + * apply, VERBOSE). + */ + log_level = 'I'; + } + } 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; + goto end; + } + + log_level = log_level_from_arg(next_arg); + if (log_level == 'U') { + printf_err("Invalid argument for --log-level option:\n %s\n", + next_arg); + *retcode = 1; + goto end; + } + + i++; + } 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", + arg); + *retcode = 1; + goto end; + } } else if (strcmp(cur_arg, "-V") == 0 || strcmp(cur_arg, "--version") == 0) { print_version(); @@ -4682,12 +4935,13 @@ struct bt_config *bt_config_cli_args_create(int argc, const char *argv[], print_gen_usage(stdout); goto end; } else { - bool has_command = true; - /* * First unknown argument: is it a known command * name? */ + command_argv = &argv[i]; + command_argc = argc - i; + if (strcmp(cur_arg, "convert") == 0) { command_type = COMMAND_TYPE_CONVERT; } else if (strcmp(cur_arg, "list-plugins") == 0) { @@ -4701,20 +4955,13 @@ struct bt_config *bt_config_cli_args_create(int argc, const char *argv[], } else { /* * Unknown argument, but not a known - * command name: assume the whole - * arguments are for the default convert - * command. + * command name: assume the default + * `convert` command. */ command_type = COMMAND_TYPE_CONVERT; - command_argv = argv; - command_argc = argc; - has_command = false; - } - - if (has_command) { - command_argv = &argv[i]; - command_argc = argc - i; - command_name = cur_arg; + command_name = "convert"; + command_argv = &argv[i - 1]; + command_argc = argc - i + 1; } break; } @@ -4731,8 +4978,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: @@ -4743,8 +4990,8 @@ 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, - initial_plugin_paths); + force_omit_home_plugin_path, + initial_plugin_paths, &log_level); break; case COMMAND_TYPE_LIST_PLUGINS: config = bt_config_list_plugins_from_args(command_argc, @@ -4766,18 +5013,15 @@ struct bt_config *bt_config_cli_args_create(int argc, const char *argv[], } if (config) { - if (verbose) { - config->verbose = true; - } - - if (debug) { - config->debug = true; + if (log_level == 'U') { + log_level = 'W'; } + config->log_level = log_level; config->command_name = command_name; } end: - bt_put(initial_plugin_paths); + bt_value_put_ref(initial_plugin_paths); return config; }