#include <inttypes.h>
#include <babeltrace2/babeltrace.h>
#include "common/common.h"
-#include <popt.h>
#include <glib.h>
#include <sys/types.h>
#include "argpar/argpar.h"
return ret;
}
-/* popt options */
+/* argpar options */
enum {
OPT_NONE = 0,
OPT_BASE_PARAMS,
OPT_INPUT_FORMAT,
OPT_LIST,
OPT_LOG_LEVEL,
- OPT_NAME,
OPT_NAMES,
OPT_NO_DELTA,
OPT_OMIT_HOME_PLUGIN_PATH,
OPT_OUTPUT,
OPT_OUTPUT_FORMAT,
OPT_PARAMS,
- OPT_PATH,
OPT_PLUGIN_PATH,
OPT_RESET_BASE_PARAMS,
OPT_RETRY_DURATION,
OPT_RUN_ARGS_0,
OPT_STREAM_INTERSECTION,
OPT_TIMERANGE,
- OPT_URL,
OPT_VERBOSE,
OPT_VERSION,
};
}
static
-struct poptOption query_long_options[] = {
- /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
- { "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 },
- { NULL, 0, '\0', NULL, 0, NULL, NULL },
+const struct bt_argpar_opt_descr query_options[] = {
+ /* id, short_name, long_name, with_arg */
+ { OPT_HELP, 'h', "help", false },
+ { OPT_OMIT_HOME_PLUGIN_PATH, '\0', "omit-home-plugin-path", false },
+ { OPT_OMIT_SYSTEM_PLUGIN_PATH, '\0', "omit-system-plugin-path", false },
+ { OPT_PARAMS, 'p', "params", true },
+ { OPT_PLUGIN_PATH, '\0', "plugin-path", true },
+ BT_ARGPAR_OPT_DESCR_SENTINEL
};
/*
const bt_value *initial_plugin_paths,
int default_log_level)
{
- poptContext pc = NULL;
- char *arg = NULL;
- int opt;
- int ret;
+ int ret, i;
struct bt_config *cfg = NULL;
- const char *leftover;
+ const char *component_class_spec = NULL;
+ const char *query_object = NULL;
bt_value *params;
GString *error_str = NULL;
+ struct bt_argpar_parse_ret argpar_parse_ret;
params = bt_value_null;
bt_value_get_ref(bt_value_null);
}
/* Parse options */
- pc = poptGetContext(NULL, argc, (const char **) argv,
- query_long_options, POPT_CONTEXT_KEEP_FIRST);
- if (!pc) {
- BT_CLI_LOGE_APPEND_CAUSE("Cannot get popt context.");
+ argpar_parse_ret = bt_argpar_parse(argc, argv, query_options, true);
+ if (argpar_parse_ret.error) {
+ BT_CLI_LOGE_APPEND_CAUSE(
+ "While parsing `query` command's command-line arguments: %s",
+ argpar_parse_ret.error->str);
goto error;
}
- poptReadDefaultConfig(pc, 0);
+ if (help_option_is_specified(&argpar_parse_ret)) {
+ print_query_usage(stdout);
+ *retcode = -1;
+ BT_OBJECT_PUT_REF_AND_RESET(cfg);
+ goto end;
+ }
- while ((opt = poptGetNextOpt(pc)) > 0) {
- arg = poptGetOptArg(pc);
+ for (i = 0; i < argpar_parse_ret.items->len; i++) {
+ struct bt_argpar_item *argpar_item =
+ g_ptr_array_index(argpar_parse_ret.items, i);
- switch (opt) {
- case OPT_PLUGIN_PATH:
- if (bt_config_append_plugin_paths_check_setuid_setgid(
- cfg->plugin_paths, arg)) {
+ if (argpar_item->type == BT_ARGPAR_ITEM_TYPE_OPT) {
+ struct bt_argpar_item_opt *argpar_item_opt =
+ (struct bt_argpar_item_opt *) argpar_item;
+ const char *arg = argpar_item_opt->arg;
+
+ switch (argpar_item_opt->descr->id) {
+ case OPT_PLUGIN_PATH:
+ if (bt_config_append_plugin_paths_check_setuid_setgid(
+ cfg->plugin_paths, arg)) {
+ goto error;
+ }
+ break;
+ case OPT_OMIT_SYSTEM_PLUGIN_PATH:
+ cfg->omit_system_plugin_path = true;
+ break;
+ case OPT_OMIT_HOME_PLUGIN_PATH:
+ cfg->omit_home_plugin_path = true;
+ break;
+ case OPT_PARAMS:
+ {
+ bt_value_put_ref(params);
+ params = cli_value_from_arg(arg, error_str);
+ if (!params) {
+ BT_CLI_LOGE_APPEND_CAUSE("Invalid format for --params option's argument:\n %s",
+ error_str->str);
+ goto error;
+ }
+ break;
+ }
+ default:
+ BT_CLI_LOGE_APPEND_CAUSE("Unknown command-line option specified (option code %d).",
+ argpar_item_opt->descr->id);
goto error;
}
- break;
- case OPT_OMIT_SYSTEM_PLUGIN_PATH:
- cfg->omit_system_plugin_path = true;
- break;
- case OPT_OMIT_HOME_PLUGIN_PATH:
- cfg->omit_home_plugin_path = true;
- break;
- case OPT_PARAMS:
- {
- bt_value_put_ref(params);
- params = cli_value_from_arg(arg, error_str);
- if (!params) {
- BT_CLI_LOGE_APPEND_CAUSE("Invalid format for --params option's argument:\n %s",
- error_str->str);
+ } else {
+ struct bt_argpar_item_non_opt *argpar_item_non_opt
+ = (struct bt_argpar_item_non_opt *) argpar_item;
+
+ /*
+ * We need exactly two leftover arguments which are the
+ * mandatory component class specification and query object.
+ */
+ if (!component_class_spec) {
+ component_class_spec = argpar_item_non_opt->arg;
+ } else if (!query_object) {
+ query_object = argpar_item_non_opt->arg;
+ } else {
+ BT_CLI_LOGE_APPEND_CAUSE("Extraneous command-line argument specified to `query` command: `%s`.",
+ argpar_item_non_opt->arg);
goto error;
}
- break;
}
- case OPT_HELP:
- print_query_usage(stdout);
- *retcode = -1;
- BT_OBJECT_PUT_REF_AND_RESET(cfg);
- goto end;
- default:
- BT_CLI_LOGE_APPEND_CAUSE("Unknown command-line option specified (option code %d).",
- opt);
- goto error;
- }
-
- free(arg);
- arg = NULL;
- }
-
- /* Check for option parsing error */
- if (opt < -1) {
- BT_CLI_LOGE_APPEND_CAUSE("While parsing command-line options, at option %s: `%s`.",
- poptBadOption(pc, 0), poptStrerror(opt));
- goto error;
}
- /*
- * 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,
- default_log_level);
- if (!cfg->cmd_data.query.cfg_component) {
- BT_CLI_LOGE_APPEND_CAUSE("Invalid format for component class specification:\n %s",
- leftover);
- goto error;
- }
-
- BT_ASSERT(params);
- BT_OBJECT_MOVE_REF(cfg->cmd_data.query.cfg_component->params,
- params);
- } else {
+ if (!component_class_spec || !query_object) {
print_query_usage(stdout);
*retcode = -1;
BT_OBJECT_PUT_REF_AND_RESET(cfg);
goto end;
}
- leftover = poptGetArg(pc);
- if (leftover) {
- if (strlen(leftover) == 0) {
- BT_CLI_LOGE_APPEND_CAUSE("Invalid empty object.");
- goto error;
- }
-
- g_string_assign(cfg->cmd_data.query.object, leftover);
- } else {
- print_query_usage(stdout);
- *retcode = -1;
- BT_OBJECT_PUT_REF_AND_RESET(cfg);
- goto end;
+ cfg->cmd_data.query.cfg_component =
+ bt_config_component_from_arg(component_class_spec,
+ default_log_level);
+ if (!cfg->cmd_data.query.cfg_component) {
+ BT_CLI_LOGE_APPEND_CAUSE("Invalid format for component class specification:\n %s",
+ component_class_spec);
+ goto error;
}
- leftover = poptGetArg(pc);
- if (leftover) {
- BT_CLI_LOGE_APPEND_CAUSE("Unexpected argument: `%s`.", leftover);
+ BT_ASSERT(params);
+ BT_OBJECT_MOVE_REF(cfg->cmd_data.query.cfg_component->params, params);
+
+ if (strlen(query_object) == 0) {
+ BT_CLI_LOGE_APPEND_CAUSE("Invalid empty object.");
goto error;
}
+ g_string_assign(cfg->cmd_data.query.object, query_object);
+
if (append_home_and_system_plugin_paths_cfg(cfg)) {
goto error;
}
BT_OBJECT_PUT_REF_AND_RESET(cfg);
end:
- if (pc) {
- poptFreeContext(pc);
- }
+ bt_argpar_parse_ret_fini(&argpar_parse_ret);
if (error_str) {
g_string_free(error_str, TRUE);
}
bt_value_put_ref(params);
- free(arg);
return cfg;
}
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, --component=[NAME:]TYPE.PLUGIN.CLS\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, " and name it NAME");
fprintf(fp, " -x, --connect=CONNECTION Connect two created components (see the\n");
fprintf(fp, " expected format of CONNECTION below)\n");
fprintf(fp, " -l, --log-level=LVL Set the log level of the current component to LVL\n");
fprintf(fp, " (`N`, `V`, `D`, `I`, `W`, `E`, or `F`)\n");
- fprintf(fp, " -n, --name=NAME Set the name of the current component\n");
- fprintf(fp, " to NAME (must be unique amongst all the\n");
- fprintf(fp, " names of the created components)\n");
fprintf(fp, " --omit-home-plugin-path Omit home plugins from plugin search path\n");
fprintf(fp, " (~/.local/lib/babeltrace2/plugins)\n");
fprintf(fp, " --omit-system-plugin-path Omit system plugins from plugin search path\n");
fprintf(fp, "\n");
fprintf(fp, "UPSTREAM and DOWNSTREAM are names of the upstream and downstream\n");
fprintf(fp, "components to connect together. You must escape the following characters\n\n");
- fprintf(fp, "with `\\`: `\\`, `.`, and `:`. You can set the name of the current\n");
- fprintf(fp, "component with the --name option.\n");
+ fprintf(fp, "with `\\`: `\\`, `.`, and `:`. You must set the name of the current\n");
+ fprintf(fp, "component using the NAME prefix of the --component option.\n");
fprintf(fp, "\n");
fprintf(fp, "UPSTREAM-PORT and DOWNSTREAM-PORT are optional globbing patterns to\n");
fprintf(fp, "identify the upstream and downstream ports to use for the connection.\n");
const bt_value *initial_plugin_paths, int default_log_level)
{
struct bt_config_component *cur_cfg_comp = NULL;
- enum bt_config_component_dest cur_cfg_comp_dest =
- BT_CONFIG_COMPONENT_DEST_UNKNOWN;
bt_value *cur_base_params = NULL;
int ret = 0;
struct bt_config *cfg = NULL;
{ OPT_CONNECT, 'x', "connect", true },
{ OPT_HELP, 'h', "help", false },
{ OPT_LOG_LEVEL, 'l', "log-level", true },
- { OPT_NAME, 'n', "name", true },
{ OPT_OMIT_HOME_PLUGIN_PATH, '\0', "omit-home-plugin-path", false },
{ OPT_OMIT_SYSTEM_PLUGIN_PATH, '\0', "omit-system-plugin-path", false },
{ OPT_PARAMS, 'p', "params", true },
break;
case OPT_COMPONENT:
{
- enum bt_config_component_dest new_dest;
-
- if (cur_cfg_comp) {
- ret = add_run_cfg_comp_check_name(cfg,
- cur_cfg_comp, cur_cfg_comp_dest,
- instance_names);
- BT_OBJECT_PUT_REF_AND_RESET(cur_cfg_comp);
- if (ret) {
- goto error;
- }
- }
+ enum bt_config_component_dest dest;
+ BT_OBJECT_PUT_REF_AND_RESET(cur_cfg_comp);
cur_cfg_comp = bt_config_component_from_arg(arg,
default_log_level);
if (!cur_cfg_comp) {
switch (cur_cfg_comp->type) {
case BT_COMPONENT_CLASS_TYPE_SOURCE:
- new_dest = BT_CONFIG_COMPONENT_DEST_SOURCE;
+ dest = BT_CONFIG_COMPONENT_DEST_SOURCE;
break;
case BT_COMPONENT_CLASS_TYPE_FILTER:
- new_dest = BT_CONFIG_COMPONENT_DEST_FILTER;
+ dest = BT_CONFIG_COMPONENT_DEST_FILTER;
break;
case BT_COMPONENT_CLASS_TYPE_SINK:
- new_dest = BT_CONFIG_COMPONENT_DEST_SINK;
+ dest = BT_CONFIG_COMPONENT_DEST_SINK;
break;
default:
abort();
goto error;
}
- cur_cfg_comp_dest = new_dest;
+ ret = add_run_cfg_comp_check_name(cfg,
+ cur_cfg_comp, dest,
+ instance_names);
+ if (ret) {
+ goto error;
+ }
+
break;
}
case OPT_PARAMS:
BT_OBJECT_MOVE_REF(cur_cfg_comp->params, params_to_set);
break;
}
- case OPT_NAME:
- if (!cur_cfg_comp) {
- BT_CLI_LOGE_APPEND_CAUSE("Cannot set the name of unavailable component:\n %s",
- arg);
- goto error;
- }
-
- g_string_assign(cur_cfg_comp->instance_name, arg);
- break;
case OPT_LOG_LEVEL:
if (!cur_cfg_comp) {
BT_CLI_LOGE_APPEND_CAUSE("Cannot set the log level of unavailable component:\n %s",
}
}
- /* Add current component */
- if (cur_cfg_comp) {
- ret = add_run_cfg_comp_check_name(cfg, cur_cfg_comp,
- cur_cfg_comp_dest, instance_names);
- BT_OBJECT_PUT_REF_AND_RESET(cur_cfg_comp);
- if (ret) {
- goto error;
- }
- }
+ BT_OBJECT_PUT_REF_AND_RESET(cur_cfg_comp);
if (cfg->cmd_data.run.sources->len == 0) {
BT_CLI_LOGE_APPEND_CAUSE("Incomplete graph: no source component.");
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\n");
fprintf(fp, " -l, --log-level=LVL Set the log level of the current component to LVL\n");
fprintf(fp, " (`N`, `V`, `D`, `I`, `W`, `E`, or `F`)\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");
fprintf(fp, " --omit-home-plugin-path Omit home plugins from plugin search path\n");
fprintf(fp, " (~/.local/lib/babeltrace2/plugins)\n");
fprintf(fp, " --omit-system-plugin-path Omit system plugins from plugin search path\n");
fprintf(fp, " -p, --params=PARAMS Add initialization parameters PARAMS to the\n");
fprintf(fp, " current component (see the expected format\n");
fprintf(fp, " of PARAMS below)\n");
- fprintf(fp, " -P, --path=PATH Set the `path` string parameter of the\n");
- fprintf(fp, " current component to 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, " --retry-duration=DUR When babeltrace2(1) needs to retry to run\n");
fprintf(fp, " formatted for `xargs -0`, and quit\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, "\n");
fprintf(fp, "Implicit `source.ctf.fs` component options:\n");
{ OPT_HELP, 'h', "help", false },
{ OPT_INPUT_FORMAT, 'i', "input-format", true },
{ OPT_LOG_LEVEL, 'l', "log-level", true },
- { OPT_NAME, '\0', "name", true },
{ OPT_NAMES, 'n', "names", true },
{ OPT_DEBUG_INFO, '\0', "debug-info", false },
{ OPT_NO_DELTA, '\0', "no-delta", false },
{ OPT_OUTPUT, 'w', "output", true },
{ OPT_OUTPUT_FORMAT, 'o', "output-format", true },
{ OPT_PARAMS, 'p', "params", true },
- { OPT_PATH, 'P', "path", true },
{ OPT_PLUGIN_PATH, '\0', "plugin-path", true },
{ OPT_RETRY_DURATION, '\0', "retry-duration", true },
{ OPT_RUN_ARGS, '\0', "run-args", false },
{ OPT_RUN_ARGS_0, '\0', "run-args-0", false },
{ OPT_STREAM_INTERSECTION, '\0', "stream-intersection", false },
{ OPT_TIMERANGE, '\0', "timerange", true },
- { OPT_URL, 'u', "url", true },
{ OPT_VERBOSE, 'v', "verbose", false },
BT_ARGPAR_OPT_DESCR_SENTINEL
};
{
int ret = 0;
size_t i;
+ GString *component_arg_for_run = NULL;
if (!impl_args->exists) {
goto end;
}
- if (bt_value_array_append_string_element(run_args, "--component")) {
+ component_arg_for_run = g_string_new(NULL);
+ if (!component_arg_for_run) {
BT_CLI_LOGE_APPEND_CAUSE_OOM();
goto error;
}
- if (bt_value_array_append_string_element(run_args, impl_args->comp_arg->str)) {
- BT_CLI_LOGE_APPEND_CAUSE_OOM();
- goto error;
- }
+ /* Build the full `name:type.plugin.cls`. */
+ BT_ASSERT(!strchr(impl_args->name_arg->str, '\\'));
+ BT_ASSERT(!strchr(impl_args->name_arg->str, ':'));
+ g_string_printf(component_arg_for_run, "%s:%s",
+ impl_args->name_arg->str, impl_args->comp_arg->str);
- if (bt_value_array_append_string_element(run_args, "--name")) {
+ if (bt_value_array_append_string_element(run_args, "--component")) {
BT_CLI_LOGE_APPEND_CAUSE_OOM();
goto error;
}
- if (bt_value_array_append_string_element(run_args, impl_args->name_arg->str)) {
+ if (bt_value_array_append_string_element(run_args,
+ component_arg_for_run->str)) {
BT_CLI_LOGE_APPEND_CAUSE_OOM();
goto error;
}
ret = -1;
end:
+ if (component_arg_for_run) {
+ g_string_free(component_arg_for_run, TRUE);
+ }
+
return ret;
}
return append_string_parameter_to_args(args->extra_params, key, value);
}
-static
-int convert_append_name_param(enum bt_config_component_dest dest,
- GString *cur_name, GString *cur_name_prefix,
- 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 --component option */
- GString *name = NULL;
- bool append_name_opt = false;
-
- if (cur_name->len == 0) {
- /*
- * No explicit name was provided for the user
- * component.
- */
- name = get_component_auto_name(cur_name_prefix->str,
- all_names);
- append_name_opt = true;
- } else {
- /*
- * An explicit name was provided for the user
- * component.
- */
- if (bt_value_map_has_entry(all_names,
- cur_name->str)) {
- BT_CLI_LOGE_APPEND_CAUSE("Duplicate component instance name:\n %s",
- cur_name->str);
- goto error;
- }
-
- name = g_string_new(cur_name->str);
- }
-
- if (!name) {
- BT_CLI_LOGE_APPEND_CAUSE_OOM();
- goto error;
- }
-
- /*
- * Remember this name globally, for the uniqueness of
- * all component names.
- */
- if (bt_value_map_insert_entry(all_names, name->str, bt_value_null)) {
- BT_CLI_LOGE_APPEND_CAUSE_OOM();
- goto error;
- }
-
- /*
- * Append the --name option if necessary.
- */
- if (append_name_opt) {
- if (bt_value_array_append_string_element(run_args, "--name")) {
- BT_CLI_LOGE_APPEND_CAUSE_OOM();
- goto error;
- }
-
- if (bt_value_array_append_string_element(run_args, name->str)) {
- BT_CLI_LOGE_APPEND_CAUSE_OOM();
- goto error;
- }
- }
-
- /*
- * Remember this name specifically for the type of the
- * component. This is to create connection arguments.
- */
- switch (dest) {
- case BT_CONFIG_COMPONENT_DEST_SOURCE:
- *source_names = g_list_append(*source_names, name);
- break;
- case BT_CONFIG_COMPONENT_DEST_FILTER:
- *filter_names = g_list_append(*filter_names, name);
- break;
- case BT_CONFIG_COMPONENT_DEST_SINK:
- *sink_names = g_list_append(*sink_names, name);
- break;
- default:
- abort();
- }
-
- g_string_assign(cur_name_prefix, "");
- }
-
- goto end;
-
-error:
- ret = -1;
-
-end:
- return ret;
-}
-
/*
* Escapes `.`, `:`, and `\` of `input` with `\`.
*/
}
}
+/*
+ * As we iterate the arguments to the convert command, this tracks what is the
+ * type of the current item, to which some contextual options (e.g. --params)
+ * apply to.
+ */
+enum convert_current_item_type {
+ /* There is no current item. */
+ CONVERT_CURRENT_ITEM_TYPE_NONE,
+
+ /* Current item is a component. */
+ CONVERT_CURRENT_ITEM_TYPE_COMPONENT,
+};
+
/*
* Creates a Babeltrace config object from the arguments of a convert
* command.
bool force_omit_home_plugin_path,
const bt_value *initial_plugin_paths, int *default_log_level)
{
- enum bt_config_component_dest cur_comp_dest =
- BT_CONFIG_COMPONENT_DEST_UNKNOWN;
+ enum convert_current_item_type current_item_type =
+ CONVERT_CURRENT_ITEM_TYPE_NONE;
int ret = 0;
struct bt_config *cfg = NULL;
bool got_input_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;
bool print_run_args = false;
bool print_run_args_0 = false;
bool print_ctf_metadata = false;
struct auto_source_discovery auto_disc = { NULL };
GString *auto_disc_comp_name = NULL;
struct bt_argpar_parse_ret argpar_parse_ret = { 0 };
+ GString *name_gstr = NULL;
+ GString *component_arg_for_run = NULL;
/*
* Array of `struct implicit_component_args *` created for the sources
goto error;
}
- cur_name = g_string_new(NULL);
- if (!cur_name) {
- BT_CLI_LOGE_APPEND_CAUSE_OOM();
- goto error;
- }
-
- cur_name_prefix = g_string_new(NULL);
- if (!cur_name_prefix) {
+ component_arg_for_run = g_string_new(NULL);
+ if (!component_arg_for_run) {
BT_CLI_LOGE_APPEND_CAUSE_OOM();
goto error;
}
* First pass: collect all arguments which need to be passed
* as is to the run command. This pass can also add --name
* arguments if needed to automatically name unnamed component
- * instances. Also it does the following transformations:
- *
- * --path=PATH -> --params=path="PATH"
- * --url=URL -> --params=url="URL"
+ * instances.
*
* Also it appends the plugin paths of --plugin-path to
* `plugin_paths`.
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,
- &source_names, &filter_names, &sink_names);
- if (ret) {
- goto error;
- }
+ current_item_type = CONVERT_CURRENT_ITEM_TYPE_COMPONENT;
/* Parse the argument */
plugin_comp_cls_names(arg, &name, &plugin_name,
}
if (name) {
- g_string_assign(cur_name, name);
+ /*
+ * Name was given by the user, verify it isn't
+ * taken.
+ */
+ if (bt_value_map_has_entry(all_names, name)) {
+ BT_CLI_LOGE_APPEND_CAUSE(
+ "Duplicate component instance name:\n %s",
+ name);
+ goto error;
+ }
+
+ name_gstr = g_string_new(name);
+ if (!name_gstr) {
+ BT_CLI_LOGE_APPEND_CAUSE_OOM();
+ goto error;
+ }
+
+ g_string_assign(component_arg_for_run, arg);
} else {
- g_string_assign(cur_name, "");
- }
+ /* Name not given by user, generate one. */
+ name_gstr = get_component_auto_name(arg, all_names);
+ if (!name_gstr) {
+ goto error;
+ }
- switch (type) {
- case BT_COMPONENT_CLASS_TYPE_SOURCE:
- cur_comp_dest = BT_CONFIG_COMPONENT_DEST_SOURCE;
- type_prefix = "source";
- break;
- case BT_COMPONENT_CLASS_TYPE_FILTER:
- cur_comp_dest = BT_CONFIG_COMPONENT_DEST_FILTER;
- type_prefix = "filter";
- break;
- case BT_COMPONENT_CLASS_TYPE_SINK:
- cur_comp_dest = BT_CONFIG_COMPONENT_DEST_SINK;
- type_prefix = "sink";
- break;
- default:
- abort();
+ g_string_printf(component_arg_for_run, "%s:%s",
+ name_gstr->str, arg);
}
if (bt_value_array_append_string_element(run_args,
goto error;
}
- if (bt_value_array_append_string_element(run_args, arg)) {
+ if (bt_value_array_append_string_element(run_args,
+ component_arg_for_run->str)) {
+ BT_CLI_LOGE_APPEND_CAUSE_OOM();
+ goto error;
+ }
+
+ /*
+ * Remember this name globally, for the uniqueness of
+ * all component names.
+ */
+ if (bt_value_map_insert_entry(all_names,
+ name_gstr->str, bt_value_null)) {
BT_CLI_LOGE_APPEND_CAUSE_OOM();
goto error;
}
- g_string_assign(cur_name_prefix, "");
- g_string_append_printf(cur_name_prefix, "%s.%s.%s",
- type_prefix, plugin_name, comp_cls_name);
+ /*
+ * Remember this name specifically for the type of the
+ * component. This is to create connection arguments.
+ *
+ * The list takes ownership of `name_gstr`.
+ */
+ switch (type) {
+ case BT_COMPONENT_CLASS_TYPE_SOURCE:
+ source_names = g_list_append(source_names, name_gstr);
+ break;
+ case BT_COMPONENT_CLASS_TYPE_FILTER:
+ filter_names = g_list_append(filter_names, name_gstr);
+ break;
+ case BT_COMPONENT_CLASS_TYPE_SINK:
+ sink_names = g_list_append(sink_names, name_gstr);
+ break;
+ default:
+ abort();
+ }
+ name_gstr = NULL;
+
free(name);
free(plugin_name);
free(comp_cls_name);
break;
}
case OPT_PARAMS:
- if (cur_name_prefix->len == 0) {
+ if (current_item_type != CONVERT_CURRENT_ITEM_TYPE_COMPONENT) {
BT_CLI_LOGE_APPEND_CAUSE("No current component of which to set parameters:\n %s",
arg);
goto error;
goto error;
}
break;
- case OPT_PATH:
- if (cur_name_prefix->len == 0) {
- BT_CLI_LOGE_APPEND_CAUSE("No current component of which to set `path` parameter:\n %s",
- arg);
- goto error;
- }
-
- if (append_string_parameter_to_args(run_args, "path", arg)) {
- goto error;
- }
- break;
- case OPT_URL:
- if (cur_name_prefix->len == 0) {
- BT_CLI_LOGE_APPEND_CAUSE("No current component of which to set `url` parameter:\n %s",
- arg);
- goto error;
- }
-
-
- if (append_string_parameter_to_args(run_args, "url", arg)) {
- goto error;
- }
- break;
- case OPT_NAME:
- if (cur_name_prefix->len == 0) {
- BT_CLI_LOGE_APPEND_CAUSE("No current component to name:\n %s",
- arg);
- goto error;
- }
-
- if (bt_value_array_append_string_element(run_args, "--name")) {
- BT_CLI_LOGE_APPEND_CAUSE_OOM();
- goto error;
- }
-
- if (bt_value_array_append_string_element(run_args, arg)) {
- BT_CLI_LOGE_APPEND_CAUSE_OOM();
- goto error;
- }
-
- g_string_assign(cur_name, arg);
- break;
case OPT_LOG_LEVEL:
- if (cur_name_prefix->len == 0) {
+ if (current_item_type != CONVERT_CURRENT_ITEM_TYPE_COMPONENT) {
BT_CLI_LOGE_APPEND_CAUSE("No current component to assign a log level to:\n %s",
arg);
goto error;
}
}
- /* Append current component's name if needed */
- ret = convert_append_name_param(cur_comp_dest, cur_name,
- cur_name_prefix, run_args, all_names, &source_names,
- &filter_names, &sink_names);
- if (ret) {
- goto error;
- }
-
/*
* Second pass: transform the convert-specific options and
* arguments into implicit component instances for the run
free(output);
- if (cur_name) {
- g_string_free(cur_name, TRUE);
+ if (component_arg_for_run) {
+ g_string_free(component_arg_for_run, TRUE);
}
- if (cur_name_prefix) {
- g_string_free(cur_name_prefix, TRUE);
+ if (name_gstr) {
+ g_string_free(name_gstr, TRUE);
}
bt_value_put_ref(run_args);