puts("Babeltrace " VERSION);
}
-/*
- * Prints the legacy, Babeltrace 1.x command usage. Those options are
- * still compatible in Babeltrace 2.x, but it is recommended to use
- * the more generic plugin/component parameters instead of those
- * hard-coded option names.
- */
-static
-void print_legacy_usage(FILE *fp)
-{
- fprintf(fp, "Usage: babeltrace [OPTIONS] INPUT...\n");
- fprintf(fp, "\n");
- fprintf(fp, "The following options are compatible with the Babeltrace 1.x options:\n");
- fprintf(fp, "\n");
- fprintf(fp, " --help-legacy Show this help\n");
- fprintf(fp, " -V, --version Show version\n");
- fprintf(fp, " --clock-force-correlate Assume that clocks are inherently correlated\n");
- fprintf(fp, " across traces\n");
- fprintf(fp, " -d, --debug Enable debug mode\n");
- fprintf(fp, " -i, --input-format=FORMAT Input trace format (default: ctf)\n");
- fprintf(fp, " -l, --list List available formats\n");
- fprintf(fp, " -o, --output-format=FORMAT Output trace format (default: text)\n");
- fprintf(fp, " -v, --verbose Enable verbose output\n");
- fprintf(fp, "\n");
- fprintf(fp, " Available input formats: ctf, lttng-live, ctf-metadata\n");
- fprintf(fp, " Available output formats: text, dummy\n");
- fprintf(fp, "\n");
- fprintf(fp, "Input formats specific options:\n");
- fprintf(fp, "\n");
- fprintf(fp, " INPUT... Input trace file(s), directory(ies), or URLs\n");
- fprintf(fp, " --clock-offset=SEC Set clock offset to SEC seconds\n");
- fprintf(fp, " --clock-offset-ns=NS Set clock offset to NS nanoseconds\n");
- fprintf(fp, " --stream-intersection Only process events when all streams are active\n");
- fprintf(fp, "\n");
- fprintf(fp, "text output format specific options:\n");
- fprintf(fp, " \n");
- fprintf(fp, " --clock-cycles Print timestamps in clock cycles\n");
- fprintf(fp, " --clock-date Print timestamp dates\n");
- fprintf(fp, " --clock-gmt Print and parse timestamps in GMT time zone\n");
- fprintf(fp, " (default: local time zone)\n");
- fprintf(fp, " --clock-seconds Print the timestamps as [SEC.NS]\n");
- fprintf(fp, " (default format: [HH:MM:SS.NS])\n");
- fprintf(fp, " --debug-info-dir=DIR Search for debug info in directory DIR\n");
- fprintf(fp, " (default: `/usr/lib/debug`)\n");
- fprintf(fp, " --debug-info-full-path Show full debug info source and binary paths\n");
- fprintf(fp, " --debug-info-target-prefix=DIR Use directory DIR as a prefix when looking\n");
- fprintf(fp, " up executables during debug info analysis\n");
- fprintf(fp, " (default: `/usr/lib/debug`)\n");
- fprintf(fp, " -f, --fields=NAME[,NAME]... Print additional fields:\n");
- fprintf(fp, " all, trace, trace:hostname, trace:domain,\n");
- fprintf(fp, " trace:procname, trace:vpid, loglevel, emf\n");
- fprintf(fp, " (default: trace:hostname, trace:procname,\n");
- fprintf(fp, " trace:vpid)\n");
- fprintf(fp, " -n, --names=NAME[,NAME]... Print field names:\n");
- fprintf(fp, " payload (or arg or args)\n");
- fprintf(fp, " none, all, scope, header, context (or ctx)\n");
- fprintf(fp, " (default: payload, context)\n");
- fprintf(fp, " --no-delta Do not print time delta between consecutive\n");
- fprintf(fp, " events\n");
- fprintf(fp, " -w, --output=PATH Write output to PATH (default: standard output)\n");
-}
-
-/*
- * Prints the Babeltrace 2.x usage.
- */
-static
-void print_usage(FILE *fp)
-{
- fprintf(fp, "Usage: babeltrace [OPTIONS]\n");
- fprintf(fp, "\n");
- fprintf(fp, " -b, --base-params=PARAMS Set PARAMS as the current base parameters\n");
- fprintf(fp, " of the following source and sink component\n");
- fprintf(fp, " instances (see the exact format of PARAMS\n");
- fprintf(fp, " below)\n");
- fprintf(fp, " --begin=BEGIN Set beginning time to BEGIN\n");
- fprintf(fp, " (format: [YYYY-MM-DD [hh:mm:]]ss[.nnnnnnnnn])\n");
- fprintf(fp, " -d, --debug Enable debug mode\n");
- fprintf(fp, " --end=END Set end time to END\n");
- fprintf(fp, " (format: [YYYY-MM-DD [hh:mm:]]ss[.nnnnnnnnn])\n");
- fprintf(fp, " -l, --list List available plugins and their components\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, " -p, --params=PARAMS Set the parameters of the latest source or\n");
- fprintf(fp, " sink component instance (in command-line \n");
- fprintf(fp, " order) to PARAMS (see the exact format of\n");
- fprintf(fp, " PARAMS below)\n");
- fprintf(fp, " -P, --path=PATH Set the `path` parameter of the latest source\n");
- fprintf(fp, " or sink component to PATH\n");
- fprintf(fp, " --plugin-path=PATH[:PATH]... Add PATH to the list of paths from which dynamic\n");
- fprintf(fp, " plugins can be loaded\n");
- fprintf(fp, " -r, --reset-base-params Reset the current base parameters of the\n");
- fprintf(fp, " following source and sink component\n");
- fprintf(fp, " instances to an empty map\n");
- fprintf(fp, " -o, --sink=PLUGIN.COMPCLS Instantiate a sink component from plugin\n");
- fprintf(fp, " PLUGIN and component class COMPCLS (may be\n");
- fprintf(fp, " repeated)\n");
- fprintf(fp, " -i, --source=PLUGIN.COMPCLS Instantiate a source component from plugin\n");
- fprintf(fp, " PLUGIN and component class COMPCLS (may be\n");
- fprintf(fp, " repeated)\n");
- fprintf(fp, " --timerange=TIMERANGE Set time range to TIMERANGE: BEGIN,END or\n");
- fprintf(fp, " [BEGIN,END] (where [ and ] are actual brackets)\n");
- fprintf(fp, " -h --help Show this help\n");
- fprintf(fp, " --help-legacy Show Babeltrace 1.x legacy options\n");
- fprintf(fp, " -v, --verbose Enable verbose output\n");
- fprintf(fp, " -V, --version Show version\n");
- fprintf(fp, "\n\n");
- fprintf(fp, "Format of PARAMS\n");
- fprintf(fp, "----------------\n");
- fprintf(fp, "\n");
- fprintf(fp, " PARAM=VALUE[,PARAM=VALUE]...\n");
- fprintf(fp, "\n");
- fprintf(fp, "The parameter string is a comma-separated list of PARAM=VALUE assignments,\n");
- fprintf(fp, "where PARAM is the parameter name (C identifier plus [:.-] characters), and\n");
- fprintf(fp, "VALUE can be one of:\n");
- fprintf(fp, "\n");
- fprintf(fp, "* `null`, `nul`, `NULL`: null value (no backticks).\n");
- fprintf(fp, "* `true`, `TRUE`, `yes`, `YES`: true boolean value (no backticks).\n");
- fprintf(fp, "* `false`, `FALSE`, `no`, `NO`: false boolean value (no backticks).\n");
- fprintf(fp, "* Binary (`0b` prefix), octal (`0` prefix), decimal, or hexadecimal\n");
- fprintf(fp, " (`0x` prefix) signed 64-bit integer.\n");
- fprintf(fp, "* Double precision floating point number (scientific notation is accepted).\n");
- fprintf(fp, "* Unquoted string with no special characters, and not matching any of\n");
- fprintf(fp, " the null and boolean value symbols above.\n");
- fprintf(fp, "* Double-quoted string (accepts escape characters).\n");
- fprintf(fp, "\n");
- fprintf(fp, "Whitespaces are allowed around individual `=` and `,` tokens.\n");
- fprintf(fp, "\n");
- fprintf(fp, "Example:\n");
- fprintf(fp, "\n");
- fprintf(fp, " many=null, fresh=yes, condition=false, squirrel=-782329,\n");
- fprintf(fp, " observe=3.14, simple=beef, needs-quotes=\"some string\",\n");
- fprintf(fp, " escape.chars-are:allowed=\"this is a \\\" double quote\"\n");
- fprintf(fp, "\n");
- fprintf(fp, "IMPORTANT: Make sure to single-quote the whole argument when you run babeltrace\n");
- fprintf(fp, "from a shell.\n");
-}
-
/*
* Destroys a component configuration.
*/
static
void bt_config_destroy(struct bt_object *obj)
{
- struct bt_config *bt_config =
+ struct bt_config *cfg =
container_of(obj, struct bt_config, base);
if (!obj) {
goto end;
}
- if (bt_config->sources) {
- g_ptr_array_free(bt_config->sources, TRUE);
- }
+ switch (cfg->command) {
+ case BT_CONFIG_COMMAND_CONVERT:
+ if (cfg->cmd_data.convert.sources) {
+ g_ptr_array_free(cfg->cmd_data.convert.sources, TRUE);
+ }
- if (bt_config->sinks) {
- g_ptr_array_free(bt_config->sinks, TRUE);
+ if (cfg->cmd_data.convert.sinks) {
+ g_ptr_array_free(cfg->cmd_data.convert.sinks, TRUE);
+ }
+
+ BT_PUT(cfg->cmd_data.convert.plugin_paths);
+ break;
+
+ case BT_CONFIG_COMMAND_LIST_PLUGINS:
+ BT_PUT(cfg->cmd_data.list_plugins.plugin_paths);
+ break;
+
+ default:
+ assert(false);
}
- BT_PUT(bt_config->plugin_paths);
- g_free(bt_config);
+ g_free(cfg);
end:
return;
}
/* Make sure no non-legacy sources are specified */
- if (cfg->sources->len != 0) {
+ if (cfg->cmd_data.convert.sources->len != 0) {
print_input_legacy_to_sources(*legacy_input_format,
legacy_input_paths, ctf_legacy_opts);
goto error;
}
/* Make sure no non-legacy sinks are specified */
- if (cfg->sinks->len != 0) {
+ if (cfg->cmd_data.convert.sinks->len != 0) {
print_output_legacy_to_sinks(*legacy_output_format,
text_legacy_opts);
goto error;
OPT_END,
OPT_FIELDS,
OPT_HELP,
- OPT_HELP_LEGACY,
OPT_INPUT_FORMAT,
OPT_LIST,
OPT_NAMES,
OPT_NO_DELTA,
+ OPT_OMIT_HOME_PLUGIN_PATH,
+ OPT_OMIT_SYSTEM_PLUGIN_PATH,
OPT_OUTPUT_FORMAT,
OPT_OUTPUT_PATH,
- OPT_PATH,
OPT_PARAMS,
+ OPT_PATH,
OPT_PLUGIN_PATH,
OPT_RESET_BASE_PARAMS,
OPT_SINK,
OPT_STREAM_INTERSECTION,
OPT_TIMERANGE,
OPT_VERBOSE,
- OPT_VERSION,
- OPT_OMIT_SYSTEM_PLUGIN_PATH,
- OPT_OMIT_HOME_PLUGIN_PATH,
-};
-
-/* popt long option descriptions */
-static struct poptOption long_options[] = {
- /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
- { "base-params", 'b', POPT_ARG_STRING, NULL, OPT_BASE_PARAMS, NULL, NULL },
- { "begin", '\0', POPT_ARG_STRING, NULL, OPT_BEGIN, NULL, NULL },
- { "clock-cycles", '\0', POPT_ARG_NONE, NULL, OPT_CLOCK_CYCLES, NULL, NULL },
- { "clock-date", '\0', POPT_ARG_NONE, NULL, OPT_CLOCK_DATE, NULL, NULL },
- { "clock-force-correlate", '\0', POPT_ARG_NONE, NULL, OPT_CLOCK_FORCE_CORRELATE, NULL, NULL },
- { "clock-gmt", '\0', POPT_ARG_NONE, NULL, OPT_CLOCK_GMT, NULL, NULL },
- { "clock-offset", '\0', POPT_ARG_STRING, NULL, OPT_CLOCK_OFFSET, NULL, NULL },
- { "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 },
- { "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", '\0', POPT_ARG_STRING, NULL, OPT_END, NULL, NULL },
- { "fields", 'f', POPT_ARG_STRING, NULL, OPT_FIELDS, NULL, NULL },
- { "help", 'h', POPT_ARG_NONE, NULL, OPT_HELP, NULL, NULL },
- { "help-legacy", '\0', POPT_ARG_NONE, NULL, OPT_HELP_LEGACY, NULL, NULL },
- { "input-format", 'i', POPT_ARG_STRING, NULL, OPT_INPUT_FORMAT, NULL, NULL },
- { "list", 'l', POPT_ARG_NONE, NULL, OPT_LIST, NULL, NULL },
- { "names", 'n', POPT_ARG_STRING, NULL, OPT_NAMES, NULL, NULL },
- { "no-delta", '\0', POPT_ARG_NONE, NULL, OPT_NO_DELTA, NULL, NULL },
- { "output", 'w', POPT_ARG_STRING, NULL, OPT_OUTPUT_PATH, NULL, NULL },
- { "output-format", 'o', POPT_ARG_STRING, NULL, OPT_OUTPUT_FORMAT, NULL, NULL },
- { "path", 'P', POPT_ARG_STRING, NULL, OPT_PATH, NULL, NULL },
- { "params", 'p', POPT_ARG_STRING, NULL, OPT_PARAMS, NULL, NULL },
- { "plugin-path", '\0', POPT_ARG_STRING, NULL, OPT_PLUGIN_PATH, NULL, NULL },
- { "reset-base-params", 'r', POPT_ARG_NONE, NULL, OPT_RESET_BASE_PARAMS, NULL, NULL },
- { "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 },
- { "verbose", 'v', POPT_ARG_NONE, NULL, OPT_VERBOSE, NULL, NULL },
- { "version", 'V', POPT_ARG_NONE, NULL, OPT_VERSION, NULL, NULL },
- { "omit-system-plugin-path", '\0', POPT_ARG_NONE, NULL, OPT_OMIT_SYSTEM_PLUGIN_PATH, NULL, NULL },
- { "omit-home-plugin-path", '\0', POPT_ARG_NONE, NULL, OPT_OMIT_HOME_PLUGIN_PATH, NULL, NULL },
- { NULL, 0, 0, NULL, 0, NULL, NULL },
};
/*
enum bt_config_component_dest dest)
{
if (dest == BT_CONFIG_COMPONENT_DEST_SOURCE) {
- g_ptr_array_add(cfg->sources, cfg_comp);
+ g_ptr_array_add(cfg->cmd_data.convert.sources, cfg_comp);
} else {
- g_ptr_array_add(cfg->sinks, cfg_comp);
+ g_ptr_array_add(cfg->cmd_data.convert.sinks, cfg_comp);
}
}
return -1;
}
-static int add_env_var_plugin_paths(struct bt_config *cfg)
+static int append_env_var_plugin_paths(struct bt_value *plugin_paths)
{
int ret = 0;
const char *envvar;
goto end;
}
- ret = bt_config_append_plugin_paths(cfg->plugin_paths, envvar);
+ ret = bt_config_append_plugin_paths(plugin_paths, envvar);
end:
return ret;
}
-static int append_home_and_system_plugin_paths(struct bt_config *cfg)
+static int append_home_and_system_plugin_paths(struct bt_value *plugin_paths,
+ bool omit_system_plugin_path, bool omit_home_plugin_path)
{
int ret;
- if (!cfg->omit_home_plugin_path) {
+ if (!omit_home_plugin_path) {
if (bt_common_is_setuid_setgid()) {
printf_debug("Skipping non-system plugin paths for setuid/setgid binary\n");
} else {
bt_common_get_home_plugin_path();
if (home_plugin_dir) {
- ret = bt_config_append_plugin_paths(cfg->plugin_paths,
+ ret = bt_config_append_plugin_paths(
+ plugin_paths,
home_plugin_dir);
free(home_plugin_dir);
}
}
- if (!cfg->omit_system_plugin_path) {
- if (bt_config_append_plugin_paths(cfg->plugin_paths,
+ if (!omit_system_plugin_path) {
+ if (bt_config_append_plugin_paths(plugin_paths,
bt_common_get_system_plugin_path())) {
printf_err("Invalid system plugin path\n");
goto error;
return -1;
}
-struct bt_config *bt_config_create(void)
+static struct bt_config *bt_config_base_create(enum bt_config_command command)
{
struct bt_config *cfg;
}
bt_object_init(cfg, bt_config_destroy);
- cfg->sources = g_ptr_array_new_with_free_func((GDestroyNotify) bt_put);
- if (!cfg->sources) {
- print_err_oom();
- goto error;
- }
+ cfg->command = command;
+ goto end;
- cfg->sinks = g_ptr_array_new_with_free_func((GDestroyNotify) bt_put);
- if (!cfg->sinks) {
- print_err_oom();
- goto error;
- }
+error:
+ BT_PUT(cfg);
- cfg->plugin_paths = bt_value_array_create();
- if (!cfg->plugin_paths) {
- print_err_oom();
- goto error;
- }
end:
return cfg;
-error:
- BT_PUT(cfg);
- goto end;
}
-/*
- * Initializes a created Babeltrace config object according to the
- * command-line arguments found in argv.
- *
- * Return value is set to the appropriate exit code to use.
- */
-int bt_config_init_from_args(struct bt_config *cfg, int argc, const char *argv[])
+static struct bt_config *bt_config_convert_create(
+ struct bt_value *initial_plugin_paths)
{
- poptContext pc = NULL;
- char *arg = NULL;
- struct ctf_legacy_opts ctf_legacy_opts;
- struct text_legacy_opts text_legacy_opts;
- enum legacy_input_format legacy_input_format = LEGACY_INPUT_FORMAT_NONE;
- enum legacy_output_format legacy_output_format =
- LEGACY_OUTPUT_FORMAT_NONE;
- struct bt_value *legacy_input_paths = NULL;
- struct bt_config_component *implicit_source_comp = NULL;
- struct bt_config_component *cur_cfg_comp = NULL;
- bool cur_is_implicit_source = false;
- bool use_implicit_source = false;
- enum bt_config_component_dest cur_cfg_comp_dest =
- BT_CONFIG_COMPONENT_DEST_SOURCE;
- struct bt_value *cur_base_params = NULL;
- int opt, ret = 0;
-
- memset(&ctf_legacy_opts, 0, sizeof(ctf_legacy_opts));
- memset(&text_legacy_opts, 0, sizeof(text_legacy_opts));
+ struct bt_config *cfg;
- text_legacy_opts.output = g_string_new(NULL);
- if (!text_legacy_opts.output) {
+ /* Create config */
+ cfg = bt_config_base_create(BT_CONFIG_COMMAND_CONVERT);
+ if (!cfg) {
print_err_oom();
goto error;
}
- text_legacy_opts.dbg_info_dir = g_string_new(NULL);
- if (!text_legacy_opts.dbg_info_dir) {
+ cfg->cmd_data.convert.sources = g_ptr_array_new_with_free_func(
+ (GDestroyNotify) bt_put);
+ if (!cfg->cmd_data.convert.sources) {
print_err_oom();
goto error;
}
- text_legacy_opts.dbg_info_target_prefix = g_string_new(NULL);
- if (!text_legacy_opts.dbg_info_target_prefix) {
+ cfg->cmd_data.convert.sinks = g_ptr_array_new_with_free_func(
+ (GDestroyNotify) bt_put);
+ if (!cfg->cmd_data.convert.sinks) {
print_err_oom();
goto error;
}
- cur_base_params = bt_value_map_create();
- if (!cur_base_params) {
- print_err_oom();
- goto error;
+ if (initial_plugin_paths) {
+ cfg->cmd_data.convert.plugin_paths =
+ bt_get(initial_plugin_paths);
+ } else {
+ cfg->cmd_data.convert.plugin_paths = bt_value_array_create();
+ if (!cfg->cmd_data.convert.plugin_paths) {
+ print_err_oom();
+ goto error;
+ }
}
- legacy_input_paths = bt_value_array_create();
- if (!legacy_input_paths) {
- print_err_oom();
- goto error;
- }
+ goto end;
- ret = add_env_var_plugin_paths(cfg);
- if (ret) {
- printf_err("Cannot append plugin paths from BABELTRACE_PLUGIN_PATH\n");
+error:
+ BT_PUT(cfg);
+
+end:
+ return cfg;
+}
+
+static struct bt_config *bt_config_list_plugins_create(
+ struct bt_value *initial_plugin_paths)
+{
+ struct bt_config *cfg;
+
+ /* Create config */
+ cfg = bt_config_base_create(BT_CONFIG_COMMAND_LIST_PLUGINS);
+ if (!cfg) {
+ print_err_oom();
goto error;
}
- /* Note: implicit source never gets positional base params. */
- implicit_source_comp = bt_config_component_from_arg(DEFAULT_SOURCE_COMPONENT_NAME);
- if (implicit_source_comp) {
- cur_cfg_comp = implicit_source_comp;
- cur_is_implicit_source = true;
- use_implicit_source = true;
+ if (initial_plugin_paths) {
+ cfg->cmd_data.list_plugins.plugin_paths =
+ bt_get(initial_plugin_paths);
} else {
- printf_debug("Cannot find implicit source plugin \"%s\"",
- DEFAULT_SOURCE_COMPONENT_NAME);
- }
-
- /* Parse options */
- pc = poptGetContext(NULL, argc, (const char **) argv, long_options, 0);
- if (!pc) {
- printf_err("Cannot get popt context\n");
- goto error;
+ cfg->cmd_data.list_plugins.plugin_paths =
+ bt_value_array_create();
+ if (!cfg->cmd_data.list_plugins.plugin_paths) {
+ print_err_oom();
+ goto error;
+ }
}
- poptReadDefaultConfig(pc, 0);
+ goto end;
+
+error:
+ BT_PUT(cfg);
+
+end:
+ return cfg;
+}
+
+/*
+ * Prints the list-plugins command usage.
+ */
+static
+void print_list_plugins_usage(FILE *fp)
+{
+ fprintf(fp, "Usage: babeltrace [GENERAL OPTIONS] list-plugins [OPTIONS]\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "Options:\n");
+ fprintf(fp, "\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, " -h --help Show this help and quit\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "See `babeltrace --help` for the list of general options.\n");
+}
+
+static struct poptOption list_plugins_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 },
+ { "plugin-path", '\0', POPT_ARG_STRING, NULL, OPT_PLUGIN_PATH, NULL, NULL },
+ { NULL, 0, 0, NULL, 0, NULL, NULL },
+};
+
+/*
+ * Creates a Babeltrace config object from the arguments of a
+ * list-plugins command.
+ *
+ * *retcode is set to the appropriate exit code to use.
+ */
+struct bt_config *bt_config_list_plugins_from_args(int argc, const char *argv[],
+ int *retcode, bool omit_system_plugin_path,
+ bool omit_home_plugin_path,
+ struct bt_value *initial_plugin_paths)
+{
+ poptContext pc = NULL;
+ char *arg = NULL;
+ int opt;
+ int ret;
+ struct bt_config *cfg = NULL;
+ const char *leftover;
+
+ *retcode = 0;
+ cfg = bt_config_list_plugins_create(initial_plugin_paths);
+ if (!cfg) {
+ print_err_oom();
+ goto error;
+ }
+
+ cfg->cmd_data.list_plugins.omit_system_plugin_path = omit_system_plugin_path;
+ cfg->cmd_data.list_plugins.omit_home_plugin_path = omit_home_plugin_path;
+ ret = append_env_var_plugin_paths(
+ cfg->cmd_data.list_plugins.plugin_paths);
+ if (ret) {
+ printf_err("Cannot append plugin paths from BABELTRACE_PLUGIN_PATH\n");
+ goto error;
+ }
+
+ /* Parse options */
+ pc = poptGetContext(NULL, argc, (const char **) argv,
+ list_plugins_long_options, 0);
+ if (!pc) {
+ printf_err("Cannot get popt context\n");
+ goto error;
+ }
+
+ poptReadDefaultConfig(pc, 0);
while ((opt = poptGetNextOpt(pc)) > 0) {
arg = poptGetOptArg(pc);
if (bt_common_is_setuid_setgid()) {
printf_debug("Skipping non-system plugin paths for setuid/setgid binary\n");
} else {
- if (bt_config_append_plugin_paths(cfg->plugin_paths, arg)) {
+ if (bt_config_append_plugin_paths(
+ cfg->cmd_data.list_plugins.plugin_paths,
+ arg)) {
printf_err("Invalid --plugin-path option's argument\n");
goto error;
}
}
break;
case OPT_OMIT_SYSTEM_PLUGIN_PATH:
- cfg->omit_system_plugin_path = true;
+ cfg->cmd_data.list_plugins.omit_system_plugin_path = true;
break;
case OPT_OMIT_HOME_PLUGIN_PATH:
- cfg->omit_home_plugin_path = true;
+ cfg->cmd_data.list_plugins.omit_home_plugin_path = true;
+ break;
+ case OPT_HELP:
+ print_list_plugins_usage(stdout);
+ *retcode = -1;
+ BT_PUT(cfg);
+ goto end;
+ default:
+ printf_err("Unknown command-line option specified (option code %d)\n",
+ opt);
+ goto error;
+ }
+
+ free(arg);
+ arg = NULL;
+ }
+
+ /* Check for option parsing error */
+ if (opt < -1) {
+ printf_err("While parsing command-line options, at option %s: %s\n",
+ poptBadOption(pc, 0), poptStrerror(opt));
+ goto error;
+ }
+
+ leftover = poptGetArg(pc);
+ if (leftover) {
+ printf_err("Invalid argument: %s\n", leftover);
+ goto error;
+ }
+
+ if (append_home_and_system_plugin_paths(
+ cfg->cmd_data.list_plugins.plugin_paths,
+ cfg->cmd_data.list_plugins.omit_system_plugin_path,
+ cfg->cmd_data.list_plugins.omit_home_plugin_path)) {
+ printf_err("Cannot append home and system plugin paths\n");
+ goto error;
+ }
+
+ goto end;
+
+error:
+ *retcode = 1;
+ BT_PUT(cfg);
+
+end:
+ if (pc) {
+ poptFreeContext(pc);
+ }
+
+ free(arg);
+ return cfg;
+}
+
+
+/*
+ * Prints the legacy, Babeltrace 1.x command usage. Those options are
+ * still compatible in Babeltrace 2.x, but it is recommended to use
+ * the more generic plugin/component parameters instead of those
+ * hard-coded option names.
+ */
+static
+void print_legacy_usage(FILE *fp)
+{
+ fprintf(fp, "Usage: babeltrace [OPTIONS] INPUT...\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "The following options are compatible with the Babeltrace 1.x options:\n");
+ fprintf(fp, "\n");
+ fprintf(fp, " --clock-force-correlate Assume that clocks are inherently correlated\n");
+ fprintf(fp, " across traces\n");
+ fprintf(fp, " -d, --debug Enable debug mode\n");
+ fprintf(fp, " -i, --input-format=FORMAT Input trace format (default: ctf)\n");
+ fprintf(fp, " -l, --list List available formats\n");
+ fprintf(fp, " -o, --output-format=FORMAT Output trace format (default: text)\n");
+ fprintf(fp, " -v, --verbose Enable verbose output\n");
+ fprintf(fp, " --help-legacy Show this help and quit\n");
+ fprintf(fp, " -V, --version Show version and quit\n");
+ fprintf(fp, "\n");
+ fprintf(fp, " Available input formats: ctf, lttng-live, ctf-metadata\n");
+ fprintf(fp, " Available output formats: text, dummy\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "Input formats specific options:\n");
+ fprintf(fp, "\n");
+ fprintf(fp, " INPUT... Input trace file(s), directory(ies), or URLs\n");
+ fprintf(fp, " --clock-offset=SEC Set clock offset to SEC seconds\n");
+ fprintf(fp, " --clock-offset-ns=NS Set clock offset to NS nanoseconds\n");
+ fprintf(fp, " --stream-intersection Only process events when all streams are active\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "text output format specific options:\n");
+ fprintf(fp, " \n");
+ fprintf(fp, " --clock-cycles Print timestamps in clock cycles\n");
+ fprintf(fp, " --clock-date Print timestamp dates\n");
+ fprintf(fp, " --clock-gmt Print and parse timestamps in GMT time zone\n");
+ fprintf(fp, " (default: local time zone)\n");
+ fprintf(fp, " --clock-seconds Print the timestamps as [SEC.NS]\n");
+ fprintf(fp, " (default format: [HH:MM:SS.NS])\n");
+ fprintf(fp, " --debug-info-dir=DIR Search for debug info in directory DIR\n");
+ fprintf(fp, " (default: `/usr/lib/debug`)\n");
+ fprintf(fp, " --debug-info-full-path Show full debug info source and binary paths\n");
+ fprintf(fp, " --debug-info-target-prefix=DIR Use directory DIR as a prefix when looking\n");
+ fprintf(fp, " up executables during debug info analysis\n");
+ fprintf(fp, " (default: `/usr/lib/debug`)\n");
+ fprintf(fp, " -f, --fields=NAME[,NAME]... Print additional fields:\n");
+ fprintf(fp, " all, trace, trace:hostname, trace:domain,\n");
+ fprintf(fp, " trace:procname, trace:vpid, loglevel, emf\n");
+ fprintf(fp, " (default: trace:hostname, trace:procname,\n");
+ fprintf(fp, " trace:vpid)\n");
+ fprintf(fp, " -n, --names=NAME[,NAME]... Print field names:\n");
+ fprintf(fp, " payload (or arg or args)\n");
+ fprintf(fp, " none, all, scope, header, context (or ctx)\n");
+ fprintf(fp, " (default: payload, context)\n");
+ fprintf(fp, " --no-delta Do not print time delta between consecutive\n");
+ fprintf(fp, " events\n");
+ fprintf(fp, " -w, --output=PATH Write output to PATH (default: standard output)\n");
+}
+
+/*
+ * Prints the convert command usage.
+ */
+static
+void print_convert_usage(FILE *fp)
+{
+ fprintf(fp, "Usage: babeltrace [GENERAL OPTIONS] convert [OPTIONS]\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "Options:\n");
+ fprintf(fp, "\n");
+ fprintf(fp, " -b, --base-params=PARAMS Set PARAMS as the current base parameters\n");
+ fprintf(fp, " for the following component instances\n");
+ fprintf(fp, " (see the expected format of PARAMS below)\n");
+ fprintf(fp, " --begin=BEGIN Set the `begin` parameter of the latest\n");
+ fprintf(fp, " source component instance to BEGIN\n");
+ fprintf(fp, " (see the suggested format of BEGIN below)\n");
+ fprintf(fp, " -d, --debug Enable debug mode\n");
+ fprintf(fp, " --end=END Set the `end` parameter of the latest\n");
+ fprintf(fp, " source component instance to END\n");
+ fprintf(fp, " (see the suggested format of BEGIN below)\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, " -p, --params=PARAMS Set the parameters of the latest component\n");
+ fprintf(fp, " instance (in command-line order) to PARAMS\n");
+ fprintf(fp, " (see the expected format of PARAMS below)\n");
+ fprintf(fp, " -P, --path=PATH Set the `path` parameter of the latest\n");
+ fprintf(fp, " component instance 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, " -r, --reset-base-params Reset the current base parameters of the\n");
+ fprintf(fp, " following source and sink component\n");
+ fprintf(fp, " instances to an empty map\n");
+ fprintf(fp, " -o, --sink=PLUGIN.COMPCLS Instantiate a sink component from plugin\n");
+ fprintf(fp, " PLUGIN and component class COMPCLS (may be\n");
+ fprintf(fp, " repeated)\n");
+ fprintf(fp, " -i, --source=PLUGIN.COMPCLS Instantiate a source component from plugin\n");
+ fprintf(fp, " PLUGIN and component class COMPCLS (may be\n");
+ fprintf(fp, " repeated)\n");
+ fprintf(fp, " --timerange=TIMERANGE Set time range to TIMERANGE: BEGIN,END or\n");
+ fprintf(fp, " [BEGIN,END] (literally `[` and `]`)\n");
+ fprintf(fp, " (suggested format of BEGIN/END below)\n");
+ fprintf(fp, " -v, --verbose Enable verbose output\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");
+ fprintf(fp, "Suggested format of BEGIN and END\n");
+ fprintf(fp, "---------------------------------\n");
+ fprintf(fp, "\n");
+ fprintf(fp, " [YYYY-MM-DD [hh:mm:]]ss[.nnnnnnnnn]\n");
+ fprintf(fp, "\n\n");
+ fprintf(fp, "Expected format of PARAMS\n");
+ fprintf(fp, "-------------------------\n");
+ fprintf(fp, "\n");
+ fprintf(fp, " PARAM=VALUE[,PARAM=VALUE]...\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "The parameter string is a comma-separated list of PARAM=VALUE assignments,\n");
+ fprintf(fp, "where PARAM is the parameter name (C identifier plus [:.-] characters), and\n");
+ fprintf(fp, "VALUE can be one of:\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "* `null`, `nul`, `NULL`: null value (no backticks).\n");
+ fprintf(fp, "* `true`, `TRUE`, `yes`, `YES`: true boolean value (no backticks).\n");
+ fprintf(fp, "* `false`, `FALSE`, `no`, `NO`: false boolean value (no backticks).\n");
+ fprintf(fp, "* Binary (`0b` prefix), octal (`0` prefix), decimal, or hexadecimal\n");
+ fprintf(fp, " (`0x` prefix) signed 64-bit integer.\n");
+ fprintf(fp, "* Double precision floating point number (scientific notation is accepted).\n");
+ fprintf(fp, "* Unquoted string with no special characters, and not matching any of\n");
+ fprintf(fp, " the null and boolean value symbols above.\n");
+ fprintf(fp, "* Double-quoted string (accepts escape characters).\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "Whitespaces are allowed around individual `=` and `,` tokens.\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "Example:\n");
+ fprintf(fp, "\n");
+ fprintf(fp, " many=null, fresh=yes, condition=false, squirrel=-782329,\n");
+ fprintf(fp, " observe=3.14, simple=beef, needs-quotes=\"some string\",\n");
+ fprintf(fp, " escape.chars-are:allowed=\"this is a \\\" double quote\"\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "IMPORTANT: Make sure to single-quote the whole argument when you run babeltrace\n");
+ fprintf(fp, "from a shell.\n");
+}
+
+static struct poptOption convert_long_options[] = {
+ /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
+ { "base-params", 'b', POPT_ARG_STRING, NULL, OPT_BASE_PARAMS, NULL, NULL },
+ { "begin", '\0', POPT_ARG_STRING, NULL, OPT_BEGIN, NULL, NULL },
+ { "clock-cycles", '\0', POPT_ARG_NONE, NULL, OPT_CLOCK_CYCLES, NULL, NULL },
+ { "clock-date", '\0', POPT_ARG_NONE, NULL, OPT_CLOCK_DATE, NULL, NULL },
+ { "clock-force-correlate", '\0', POPT_ARG_NONE, NULL, OPT_CLOCK_FORCE_CORRELATE, NULL, NULL },
+ { "clock-gmt", '\0', POPT_ARG_NONE, NULL, OPT_CLOCK_GMT, NULL, NULL },
+ { "clock-offset", '\0', POPT_ARG_STRING, NULL, OPT_CLOCK_OFFSET, NULL, NULL },
+ { "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 },
+ { "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", '\0', POPT_ARG_STRING, NULL, OPT_END, NULL, NULL },
+ { "fields", 'f', POPT_ARG_STRING, NULL, OPT_FIELDS, NULL, NULL },
+ { "help", 'h', POPT_ARG_NONE, NULL, OPT_HELP, NULL, NULL },
+ { "input-format", 'i', POPT_ARG_STRING, NULL, OPT_INPUT_FORMAT, NULL, NULL },
+ { "names", 'n', POPT_ARG_STRING, NULL, OPT_NAMES, 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 },
+ { "output", 'w', POPT_ARG_STRING, NULL, OPT_OUTPUT_PATH, NULL, NULL },
+ { "output-format", 'o', POPT_ARG_STRING, NULL, OPT_OUTPUT_FORMAT, NULL, NULL },
+ { "params", 'p', POPT_ARG_STRING, NULL, OPT_PARAMS, NULL, NULL },
+ { "path", 'P', POPT_ARG_STRING, NULL, OPT_PATH, 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 },
+ { "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 },
+ { "verbose", 'v', POPT_ARG_NONE, NULL, OPT_VERBOSE, NULL, NULL },
+ { NULL, 0, 0, NULL, 0, NULL, NULL },
+};
+
+/*
+ * Creates a Babeltrace config object from the arguments of a convert
+ * command.
+ *
+ * *retcode is set to the appropriate exit code to use.
+ */
+struct bt_config *bt_config_convert_from_args(int argc, const char *argv[],
+ int *retcode, bool omit_system_plugin_path,
+ bool omit_home_plugin_path,
+ struct bt_value *initial_plugin_paths)
+{
+ poptContext pc = NULL;
+ char *arg = NULL;
+ struct ctf_legacy_opts ctf_legacy_opts;
+ struct text_legacy_opts text_legacy_opts;
+ enum legacy_input_format legacy_input_format = LEGACY_INPUT_FORMAT_NONE;
+ enum legacy_output_format legacy_output_format =
+ LEGACY_OUTPUT_FORMAT_NONE;
+ struct bt_value *legacy_input_paths = NULL;
+ struct bt_config_component *implicit_source_comp = NULL;
+ struct bt_config_component *cur_cfg_comp = NULL;
+ bool cur_is_implicit_source = false;
+ bool use_implicit_source = false;
+ enum bt_config_component_dest cur_cfg_comp_dest =
+ BT_CONFIG_COMPONENT_DEST_SOURCE;
+ struct bt_value *cur_base_params = NULL;
+ int opt, ret = 0;
+ struct bt_config *cfg = NULL;
+
+ *retcode = 0;
+ memset(&ctf_legacy_opts, 0, sizeof(ctf_legacy_opts));
+ memset(&text_legacy_opts, 0, sizeof(text_legacy_opts));
+
+ if (argc <= 1) {
+ print_convert_usage(stdout);
+ *retcode = -1;
+ goto end;
+ }
+
+ cfg = bt_config_convert_create(initial_plugin_paths);
+ if (!cfg) {
+ print_err_oom();
+ goto error;
+ }
+
+ cfg->cmd_data.convert.omit_system_plugin_path = omit_system_plugin_path;
+ cfg->cmd_data.convert.omit_home_plugin_path = omit_home_plugin_path;
+ text_legacy_opts.output = g_string_new(NULL);
+ if (!text_legacy_opts.output) {
+ print_err_oom();
+ goto error;
+ }
+
+ text_legacy_opts.dbg_info_dir = g_string_new(NULL);
+ if (!text_legacy_opts.dbg_info_dir) {
+ print_err_oom();
+ goto error;
+ }
+
+ text_legacy_opts.dbg_info_target_prefix = g_string_new(NULL);
+ if (!text_legacy_opts.dbg_info_target_prefix) {
+ print_err_oom();
+ goto error;
+ }
+
+ cur_base_params = bt_value_map_create();
+ if (!cur_base_params) {
+ print_err_oom();
+ goto error;
+ }
+
+ legacy_input_paths = bt_value_array_create();
+ if (!legacy_input_paths) {
+ print_err_oom();
+ goto error;
+ }
+
+ ret = append_env_var_plugin_paths(cfg->cmd_data.convert.plugin_paths);
+ if (ret) {
+ printf_err("Cannot append plugin paths from BABELTRACE_PLUGIN_PATH\n");
+ goto error;
+ }
+
+ /* Note: implicit source never gets positional base params. */
+ implicit_source_comp = bt_config_component_from_arg(DEFAULT_SOURCE_COMPONENT_NAME);
+ if (implicit_source_comp) {
+ cur_cfg_comp = implicit_source_comp;
+ cur_is_implicit_source = true;
+ use_implicit_source = true;
+ } else {
+ printf_debug("Cannot find implicit source plugin \"%s\"",
+ DEFAULT_SOURCE_COMPONENT_NAME);
+ }
+
+ /* Parse options */
+ pc = poptGetContext(NULL, argc, (const char **) argv,
+ convert_long_options, 0);
+ if (!pc) {
+ printf_err("Cannot get popt context\n");
+ goto error;
+ }
+
+ poptReadDefaultConfig(pc, 0);
+
+ while ((opt = poptGetNextOpt(pc)) > 0) {
+ arg = poptGetOptArg(pc);
+
+ switch (opt) {
+ case OPT_PLUGIN_PATH:
+ if (bt_common_is_setuid_setgid()) {
+ printf_debug("Skipping non-system plugin paths for setuid/setgid binary\n");
+ } else {
+ if (bt_config_append_plugin_paths(
+ cfg->cmd_data.convert.plugin_paths,
+ arg)) {
+ printf_err("Invalid --plugin-path option's argument\n");
+ goto error;
+ }
+ }
+ break;
+ case OPT_OMIT_SYSTEM_PLUGIN_PATH:
+ cfg->cmd_data.convert.omit_system_plugin_path = true;
+ break;
+ case OPT_OMIT_HOME_PLUGIN_PATH:
+ cfg->cmd_data.convert.omit_home_plugin_path = true;
break;
case OPT_OUTPUT_PATH:
if (text_legacy_opts.output->len > 0) {
cur_cfg_comp->params = bt_value_copy(cur_base_params);
if (!cur_cfg_comp->params) {
print_err_oom();
- goto end;
+ goto error;
}
cur_cfg_comp_dest = BT_CONFIG_COMPONENT_DEST_SOURCE;
cur_cfg_comp->params = bt_value_copy(cur_base_params);
if (!cur_cfg_comp->params) {
print_err_oom();
- goto end;
+ goto error;
}
cur_cfg_comp_dest = BT_CONFIG_COMPONENT_DEST_SINK;
ctf_legacy_opts.stream_intersection = true;
break;
case OPT_CLOCK_FORCE_CORRELATE:
- cfg->force_correlate = true;
+ cfg->cmd_data.convert.force_correlate = true;
break;
case OPT_BEGIN:
if (!cur_cfg_comp) {
break;
}
case OPT_HELP:
- print_usage(stdout);
- goto end;
- case OPT_HELP_LEGACY:
- print_legacy_usage(stdout);
- goto end;
- case OPT_VERSION:
- print_version();
- goto end;
- case OPT_LIST:
- cfg->do_list = true;
+ print_convert_usage(stdout);
+ *retcode = -1;
+ BT_PUT(cfg);
goto end;
case OPT_VERBOSE:
cfg->verbose = true;
arg = NULL;
}
- if (argc <= 1) {
- print_usage(stdout);
- goto end;
- }
-
/* Check for option parsing error */
if (opt < -1) {
printf_err("While parsing command-line options, at option %s: %s\n",
}
}
- if (append_home_and_system_plugin_paths(cfg)) {
+ if (append_home_and_system_plugin_paths(
+ cfg->cmd_data.convert.plugin_paths,
+ cfg->cmd_data.convert.omit_system_plugin_path,
+ cfg->cmd_data.convert.omit_home_plugin_path)) {
+ printf_err("Cannot append home and system plugin paths\n");
goto error;
}
* component configurations.
*/
if (legacy_input_format) {
- if (append_sources_from_legacy_opts(cfg->sources,
+ if (append_sources_from_legacy_opts(
+ cfg->cmd_data.convert.sources,
legacy_input_format, &ctf_legacy_opts,
legacy_input_paths)) {
printf_err("Cannot convert legacy input format options to source component instance(s)\n");
goto error;
}
- if (append_sources_from_implicit_params(cfg->sources,
+ if (append_sources_from_implicit_params(
+ cfg->cmd_data.convert.sources,
implicit_source_comp)) {
printf_err("Cannot initialize legacy component parameters\n");
goto error;
* component configurations.
*/
if (legacy_output_format) {
- if (append_sinks_from_legacy_opts(cfg->sinks,
+ if (append_sinks_from_legacy_opts(cfg->cmd_data.convert.sinks,
legacy_output_format, &text_legacy_opts)) {
printf_err("Cannot convert legacy output format options to sink component instance(s)\n");
goto error;
}
}
- if (cfg->sinks->len == 0) {
+ if (cfg->cmd_data.convert.sinks->len == 0) {
/* Use implicit sink as default. */
cur_cfg_comp = bt_config_component_from_arg(DEFAULT_SINK_COMPONENT_NAME);
if (!cur_cfg_comp) {
goto end;
error:
- ret = 1;
+ *retcode = 1;
+ BT_PUT(cfg);
+
end:
if (pc) {
poptFreeContext(pc);
BT_PUT(text_legacy_opts.names);
BT_PUT(text_legacy_opts.fields);
BT_PUT(legacy_input_paths);
- return ret;
+ return cfg;
+}
+
+/*
+ * Prints the Babeltrace 2.x general usage.
+ */
+static
+void print_gen_usage(FILE *fp)
+{
+ fprintf(fp, "Usage: babeltrace [GENERAL OPTIONS] [COMMAND] [COMMAND OPTIONS]\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "General options:\n");
+ fprintf(fp, "\n");
+ fprintf(fp, " -d, --debug Enable debug mode\n");
+ fprintf(fp, " -h --help Show this help and quit\n");
+ fprintf(fp, " --help-legacy Show Babeltrace 1.x legacy help and quit\n");
+ fprintf(fp, " -v, --verbose Enable verbose output\n");
+ fprintf(fp, " -V, --version Show version and quit\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "Available commands:\n");
+ fprintf(fp, "\n");
+ fprintf(fp, " convert Build a trace conversion graph and run it (default)\n");
+ fprintf(fp, " list-plugins List available plugins and their content\n");
+ fprintf(fp, "\n");
+ fprintf(fp, "Use `babeltrace COMMAND --help` to show the help of COMMAND.\n");
+}
+
+struct bt_config *bt_config_from_args(int argc, const char *argv[],
+ int *retcode, bool omit_system_plugin_path,
+ bool omit_home_plugin_path,
+ struct bt_value *initial_plugin_paths)
+{
+ struct bt_config *config = NULL;
+ bool verbose = false;
+ bool debug = false;
+ int i;
+ enum bt_config_command command = -1;
+ const char **command_argv = NULL;
+ int command_argc = -1;
+ const char *command_name = NULL;
+
+ *retcode = -1;
+
+ if (argc <= 1) {
+ print_gen_usage(stdout);
+ goto end;
+ }
+
+ for (i = 1; i < argc; i++) {
+ const char *cur_arg = argv[i];
+
+ if (strcmp(cur_arg, "-d") == 0 ||
+ strcmp(cur_arg, "--debug") == 0) {
+ debug = true;
+ } else if (strcmp(cur_arg, "-v") == 0 ||
+ strcmp(cur_arg, "--verbose") == 0) {
+ verbose = true;
+ } else if (strcmp(cur_arg, "-V") == 0 ||
+ strcmp(cur_arg, "--version") == 0) {
+ print_version();
+ goto end;
+ } else if (strcmp(cur_arg, "-h") == 0 ||
+ strcmp(cur_arg, "--help") == 0) {
+ print_gen_usage(stdout);
+ goto end;
+ } else if (strcmp(cur_arg, "--help-legacy") == 0) {
+ print_legacy_usage(stdout);
+ goto end;
+ } else {
+ /*
+ * First unknown argument: is it a known command
+ * name?
+ */
+ if (strcmp(cur_arg, "convert") == 0) {
+ command = BT_CONFIG_COMMAND_CONVERT;
+ command_argv = &argv[i];
+ command_argc = argc - i;
+ command_name = cur_arg;
+ } else if (strcmp(cur_arg, "list-plugins") == 0) {
+ command = BT_CONFIG_COMMAND_LIST_PLUGINS;
+ command_argv = &argv[i];
+ command_argc = argc - i;
+ command_name = cur_arg;
+ } else {
+ /*
+ * Unknown argument, but not a known
+ * command name: assume the whole
+ * arguments are for the default convert
+ * command.
+ */
+ command = BT_CONFIG_COMMAND_CONVERT;
+ command_argv = argv;
+ command_argc = argc;
+ }
+ break;
+ }
+ }
+
+ if ((int) command < 0) {
+ /*
+ * We only got non-help, non-version general options
+ * like --verbose and --debug, without any other
+ * arguments, so we can't do anything useful: print the
+ * usage and quit.
+ */
+ print_gen_usage(stdout);
+ goto end;
+ }
+
+ assert(command_argv);
+ assert(command_argc >= 0);
+
+ switch (command) {
+ case BT_CONFIG_COMMAND_CONVERT:
+ config = bt_config_convert_from_args(command_argc, command_argv,
+ retcode, omit_system_plugin_path,
+ omit_home_plugin_path, initial_plugin_paths);
+ break;
+ case BT_CONFIG_COMMAND_LIST_PLUGINS:
+ config = bt_config_list_plugins_from_args(command_argc,
+ command_argv, retcode, omit_system_plugin_path,
+ omit_home_plugin_path, initial_plugin_paths);
+ break;
+ default:
+ assert(false);
+ }
+
+ if (config) {
+ if (verbose) {
+ config->verbose = true;
+ }
+
+ if (debug) {
+ config->debug = true;
+ }
+
+ config->command_name = command_name;
+ }
+
+end:
+ return config;
}
#include <babeltrace/babeltrace.h>
#include <babeltrace/plugin/plugin.h>
+#include <babeltrace/common-internal.h>
#include <babeltrace/component/component.h>
#include <babeltrace/component/component-source.h>
#include <babeltrace/component/component-sink.h>
return comp_class;
}
-static
-const char *component_type_str(enum bt_component_class_type type)
-{
- switch (type) {
- case BT_COMPONENT_CLASS_TYPE_SOURCE:
- return "source";
- case BT_COMPONENT_CLASS_TYPE_SINK:
- return "sink";
- case BT_COMPONENT_CLASS_TYPE_FILTER:
- return "filter";
- case BT_COMPONENT_CLASS_TYPE_UNKNOWN:
- default:
- return "unknown";
- }
-}
-
-static
-void print_component_classes_found(void)
-{
- int plugins_count, component_classes_count = 0, i;
-
- if (!babeltrace_verbose) {
- return;
- }
-
- plugins_count = loaded_plugins->len;
- if (plugins_count == 0) {
- fprintf(stderr, "No plugins found. Please make sure your plug-in search path is set correctly.\n");
- return;
- }
-
- for (i = 0; i < plugins_count; i++) {
- struct bt_plugin *plugin = g_ptr_array_index(loaded_plugins, i);
-
- component_classes_count += bt_plugin_get_component_class_count(plugin);
- }
-
- printf("Found %d component classes in %d plugins.\n",
- component_classes_count, plugins_count);
-
- for (i = 0; i < plugins_count; i++) {
- int j;
- struct bt_plugin *plugin = g_ptr_array_index(loaded_plugins, i);
- unsigned int major, minor, patch;
- const char *extra;
- enum bt_plugin_status version_status;
-
- component_classes_count =
- bt_plugin_get_component_class_count(plugin);
- version_status = bt_plugin_get_version(plugin, &major, &minor,
- &patch, &extra);
-
- for (j = 0; j < component_classes_count; j++) {
- struct bt_component_class *comp_class =
- bt_plugin_get_component_class(plugin, j);
- const char *plugin_name = bt_plugin_get_name(plugin);
- const char *comp_class_name =
- bt_component_class_get_name(comp_class);
- const char *path = bt_plugin_get_path(plugin);
- const char *author = bt_plugin_get_author(plugin);
- const char *license = bt_plugin_get_license(plugin);
- const char *plugin_description =
- bt_plugin_get_description(plugin);
- const char *comp_class_description =
- bt_component_class_get_description(comp_class);
- enum bt_component_class_type type =
- bt_component_class_get_type(comp_class);
-
- printf("[%s - %s (%s)]\n", plugin_name,
- comp_class_name, component_type_str(type));
- printf("\tpath: %s\n", path ? path : "None");
- printf("\tauthor: %s\n",
- author ? author : "Unknown");
- printf("\tlicense: %s\n",
- license ? license : "Unknown");
- printf("\tplugin description: %s\n",
- plugin_description ? plugin_description : "None");
-
- if (version_status == BT_PLUGIN_STATUS_OK) {
- printf("\tplugin version: %u.%u.%u",
- major, minor, patch);
-
- if (extra) {
- printf("%s", extra);
- }
-
- printf("\n");
- }
-
- printf("\tcomponent description: %s\n",
- comp_class_description ? comp_class_description : "None");
- bt_put(comp_class);
- }
- }
-}
-
static
void print_indent(size_t indent)
{
}
static
-void print_value(struct bt_value *, size_t, bool);
+void print_value(struct bt_value *, size_t);
static
bool print_map_value(const char *key, struct bt_value *object, void *data)
{
- size_t indent = (size_t) data;
+ size_t *indent = data;
+
+ print_indent(*indent);
+ printf("%s: ", key);
+
+ if (bt_value_is_array(object) &&
+ bt_value_array_is_empty(object)) {
+ printf("[ ]\n");
+ return true;
+ }
+
+ if (bt_value_is_map(object) &&
+ bt_value_map_is_empty(object)) {
+ printf("{ }\n");
+ return true;
+ }
- print_indent(indent);
- printf("\"%s\": ", key);
- print_value(object, indent, false);
+ if (bt_value_is_array(object) ||
+ bt_value_is_map(object)) {
+ printf("\n");
+ }
+ print_value(object, *indent + 2);
return true;
}
static
-void print_value(struct bt_value *value, size_t indent, bool do_indent)
+void print_value(struct bt_value *value, size_t indent)
{
bool bool_val;
int64_t int_val;
return;
}
- if (do_indent) {
- print_indent(indent);
- }
-
switch (bt_value_get_type(value)) {
case BT_VALUE_TYPE_NULL:
printf("null\n");
break;
case BT_VALUE_TYPE_BOOL:
bt_value_bool_get(value, &bool_val);
- printf("%s\n", bool_val ? "true" : "false");
+ printf("%s\n", bool_val ? "yes" : "no");
break;
case BT_VALUE_TYPE_INTEGER:
bt_value_integer_get(value, &int_val);
break;
case BT_VALUE_TYPE_STRING:
bt_value_string_get(value, &str_val);
- printf("\"%s\"\n", str_val);
+ printf("%s\n", str_val);
break;
case BT_VALUE_TYPE_ARRAY:
size = bt_value_array_size(value);
- printf("[\n");
+ assert(size >= 0);
+
+ if (size == 0) {
+ print_indent(indent);
+ printf("[ ]\n");
+ break;
+ }
for (i = 0; i < size; i++) {
struct bt_value *element =
bt_value_array_get(value, i);
- print_value(element, indent + 2, true);
+ assert(element);
+ print_indent(indent);
+ printf("- ");
+
+ if (bt_value_is_array(element) &&
+ bt_value_array_is_empty(element)) {
+ printf("[ ]\n");
+ continue;
+ }
+
+ if (bt_value_is_map(element) &&
+ bt_value_map_is_empty(element)) {
+ printf("{ }\n");
+ continue;
+ }
+
+ if (bt_value_is_array(element) ||
+ bt_value_is_map(element)) {
+ printf("\n");
+ }
+
+ print_value(element, indent + 2);
BT_PUT(element);
}
-
- print_indent(indent);
- printf("]\n");
break;
case BT_VALUE_TYPE_MAP:
if (bt_value_map_is_empty(value)) {
- printf("{}\n");
- return;
+ print_indent(indent);
+ printf("{ }\n");
+ break;
}
- printf("{\n");
- bt_value_map_foreach(value, print_map_value,
- (void *) (indent + 2));
- print_indent(indent);
- printf("}\n");
+ bt_value_map_foreach(value, print_map_value, &indent);
break;
default:
assert(false);
static
void print_bt_config_component(struct bt_config_component *bt_config_component)
{
- printf(" %s.%s\n", bt_config_component->plugin_name->str,
+ printf(" %s.%s:\n", bt_config_component->plugin_name->str,
bt_config_component->component_name->str);
- printf(" params:\n");
- print_value(bt_config_component->params, 6, true);
+ printf(" Parameters:\n");
+ print_value(bt_config_component->params, 8);
}
static
}
}
+static
+void print_plugin_paths(struct bt_value *plugin_paths)
+{
+ printf(" Plugin paths:\n");
+ print_value(plugin_paths, 4);
+}
+
+static
+void print_cfg_convert(struct bt_config *cfg)
+{
+ printf(" Force correlate: %s\n",
+ cfg->cmd_data.convert.force_correlate ? "yes" : "no");
+ print_plugin_paths(cfg->cmd_data.convert.plugin_paths);
+ printf(" Source component instances:\n");
+ print_bt_config_components(cfg->cmd_data.convert.sources);
+ printf(" Sink component instances:\n");
+ print_bt_config_components(cfg->cmd_data.convert.sinks);
+}
+
+static
+void print_cfg_list_plugins(struct bt_config *cfg)
+{
+ print_plugin_paths(cfg->cmd_data.list_plugins.plugin_paths);
+}
+
static
void print_cfg(struct bt_config *cfg)
{
return;
}
- printf("debug: %d\n", cfg->debug);
- printf("verbose: %d\n", cfg->verbose);
- printf("do list: %d\n", cfg->do_list);
- printf("force correlate: %d\n", cfg->force_correlate);
- printf("plugin paths:\n");
- print_value(cfg->plugin_paths, 2, true);
- printf("sources:\n");
- print_bt_config_components(cfg->sources);
- printf("sinks:\n");
- print_bt_config_components(cfg->sinks);
+ printf("Configuration:\n");
+ printf(" Debug mode: %s\n", cfg->debug ? "yes" : "no");
+ printf(" Verbose mode: %s\n", cfg->verbose ? "yes" : "no");
+
+ switch (cfg->command) {
+ case BT_CONFIG_COMMAND_CONVERT:
+ print_cfg_convert(cfg);
+ break;
+ case BT_CONFIG_COMMAND_LIST_PLUGINS:
+ print_cfg_list_plugins(cfg);
+ break;
+ default:
+ assert(false);
+ }
}
static
}
static
-int load_dynamic_plugins(struct bt_config *cfg)
+int load_dynamic_plugins(struct bt_value *plugin_paths)
{
int nr_paths, i, ret = 0;
- nr_paths = bt_value_array_size(cfg->plugin_paths);
+ nr_paths = bt_value_array_size(plugin_paths);
if (nr_paths < 0) {
ret = -1;
goto end;
const char *plugin_path;
struct bt_plugin **plugins;
- plugin_path_value = bt_value_array_get(cfg->plugin_paths, i);
+ plugin_path_value = bt_value_array_get(plugin_paths, i);
if (bt_value_string_get(plugin_path_value,
&plugin_path)) {
BT_PUT(plugin_path_value);
return ret;
}
-int main(int argc, const char **argv)
+static
+const char *component_type_str(enum bt_component_class_type type)
{
- int ret;
- struct bt_component_class *source_class = NULL;
- struct bt_component_class *sink_class = NULL;
- struct bt_component *source = NULL, *sink = NULL;
- struct bt_value *source_params = NULL, *sink_params = NULL;
- struct bt_config *cfg;
- enum bt_component_status sink_status;
- struct bt_config_component *source_cfg = NULL, *sink_cfg = NULL;
+ switch (type) {
+ case BT_COMPONENT_CLASS_TYPE_SOURCE:
+ return "source";
+ case BT_COMPONENT_CLASS_TYPE_SINK:
+ return "sink";
+ case BT_COMPONENT_CLASS_TYPE_FILTER:
+ return "filter";
+ case BT_COMPONENT_CLASS_TYPE_UNKNOWN:
+ default:
+ return "unknown";
+ }
+}
- init_loaded_plugins_array();
+static int load_all_plugins(struct bt_value *plugin_paths)
+{
+ int ret = 0;
- cfg = bt_config_create();
- if (!cfg) {
- fprintf(stderr, "Failed to create Babeltrace configuration\n");
- ret = 1;
+ if (load_dynamic_plugins(plugin_paths)) {
+ fprintf(stderr, "Failed to load dynamic plugins.\n");
+ ret = -1;
goto end;
}
- ret = set_default_config(cfg);
- if (ret) {
+ if (load_static_plugins()) {
+ fprintf(stderr, "Failed to load static plugins.\n");
+ ret = -1;
goto end;
}
- ret = bt_config_init_from_args(cfg, argc, argv);
- if (ret == 0) {
- babeltrace_verbose = cfg->verbose;
- babeltrace_debug = cfg->debug;
- print_cfg(cfg);
- } else {
+end:
+ return ret;
+}
+
+static int cmd_list_plugins(struct bt_config *cfg)
+{
+ int ret;
+ int plugins_count, component_classes_count = 0, i;
+
+ ret = load_all_plugins(cfg->cmd_data.list_plugins.plugin_paths);
+ if (ret) {
goto end;
}
- /* TODO handle more than 1 source and 1 sink. */
- if (cfg->sources->len != 1 || cfg->sinks->len != 1) {
+ plugins_count = loaded_plugins->len;
+ if (plugins_count == 0) {
+ fprintf(stderr, "%s%sNo plugins found.%s\n",
+ bt_common_color_bold(), bt_common_color_fg_red(),
+ bt_common_color_reset());
+ fprintf(stderr, "\n");
+ fprintf(stderr, "Please make sure your plugin search path is set correctly. You can use\n");
+ fprintf(stderr, "the --plugin-path command-line option or the BABELTRACE_PLUGIN_PATH\n");
+ fprintf(stderr, "environment variable.\n");
ret = -1;
goto end;
}
- printf_verbose("Verbose mode active.\n");
- printf_debug("Debug mode active.\n");
+ for (i = 0; i < plugins_count; i++) {
+ struct bt_plugin *plugin = g_ptr_array_index(loaded_plugins, i);
+
+ component_classes_count += bt_plugin_get_component_class_count(plugin);
+ }
- if (load_dynamic_plugins(cfg)) {
- fprintf(stderr, "Failed to load dynamic plugins.\n");
+ printf("Found %s%d%s component classes in %s%d%s plugins.\n",
+ bt_common_color_bold(),
+ component_classes_count,
+ bt_common_color_reset(),
+ bt_common_color_bold(),
+ plugins_count,
+ bt_common_color_reset());
+
+ for (i = 0; i < plugins_count; i++) {
+ int j;
+ struct bt_plugin *plugin = g_ptr_array_index(loaded_plugins, i);
+ unsigned int major, minor, patch;
+ const char *extra;
+ enum bt_plugin_status version_status;
+ const char *plugin_name = bt_plugin_get_name(plugin);
+ const char *path = bt_plugin_get_path(plugin);
+ const char *author = bt_plugin_get_author(plugin);
+ const char *license = bt_plugin_get_license(plugin);
+ const char *plugin_description =
+ bt_plugin_get_description(plugin);
+
+ component_classes_count =
+ bt_plugin_get_component_class_count(plugin);
+ version_status = bt_plugin_get_version(plugin, &major, &minor,
+ &patch, &extra);
+
+ printf("\n%s%s%s%s:\n", bt_common_color_bold(),
+ bt_common_color_fg_blue(), plugin_name,
+ bt_common_color_reset());
+ printf(" %sPath%s: %s\n", bt_common_color_bold(),
+ bt_common_color_reset(), path ? path : "(None)");
+
+ if (version_status == BT_PLUGIN_STATUS_OK) {
+ printf(" %sVersion%s: %u.%u.%u",
+ bt_common_color_bold(), bt_common_color_reset(),
+ major, minor, patch);
+
+ if (extra) {
+ printf("%s", extra);
+ }
+
+ printf("\n");
+ }
+
+ printf(" %sDescription%s: %s\n", bt_common_color_bold(),
+ bt_common_color_reset(),
+ plugin_description ? plugin_description : "(None)");
+ printf(" %sAuthor%s: %s\n", bt_common_color_bold(),
+ bt_common_color_reset(), author ? author : "(Unknown)");
+ printf(" %sLicense%s: %s\n", bt_common_color_bold(),
+ bt_common_color_reset(),
+ license ? license : "(Unknown)");
+
+ if (component_classes_count == 0) {
+ printf(" %sComponent classes%s: (None)\n",
+ bt_common_color_bold(),
+ bt_common_color_reset());
+ } else {
+ printf(" %sComponent classes%s:\n",
+ bt_common_color_bold(),
+ bt_common_color_reset());
+ }
+
+ for (j = 0; j < component_classes_count; j++) {
+ struct bt_component_class *comp_class =
+ bt_plugin_get_component_class(plugin, j);
+ const char *comp_class_name =
+ bt_component_class_get_name(comp_class);
+ const char *comp_class_description =
+ bt_component_class_get_description(comp_class);
+ enum bt_component_class_type type =
+ bt_component_class_get_type(comp_class);
+
+ printf(" %s%s--%s%s %s%s%s.%s%s%s",
+ bt_common_color_bold(),
+ bt_common_color_fg_cyan(),
+ component_type_str(type),
+ bt_common_color_fg_default(),
+ bt_common_color_fg_blue(),
+ plugin_name,
+ bt_common_color_fg_default(),
+ bt_common_color_fg_yellow(),
+ comp_class_name,
+ bt_common_color_reset());
+
+ if (comp_class_description) {
+ printf(": %s", comp_class_description);
+ }
+
+ printf("\n");
+ bt_put(comp_class);
+ }
+ }
+
+end:
+ return ret;
+}
+
+static int cmd_convert(struct bt_config *cfg)
+{
+ int ret = 0;
+ struct bt_component_class *source_class = NULL;
+ struct bt_component_class *sink_class = NULL;
+ struct bt_component *source = NULL, *sink = NULL;
+ struct bt_value *source_params = NULL, *sink_params = NULL;
+ enum bt_component_status sink_status;
+ struct bt_config_component *source_cfg = NULL, *sink_cfg = NULL;
+
+ /* TODO handle more than 1 source and 1 sink. */
+ if (cfg->cmd_data.convert.sources->len != 1 ||
+ cfg->cmd_data.convert.sinks->len != 1) {
ret = -1;
goto end;
}
- if (load_static_plugins()) {
- fprintf(stderr, "Failed to load static plugins.\n");
+ ret = load_all_plugins(cfg->cmd_data.convert.plugin_paths);
+ if (ret) {
goto end;
}
- print_component_classes_found();
- source_cfg = bt_config_get_component(cfg->sources, 0);
+ source_cfg = bt_config_get_component(cfg->cmd_data.convert.sources, 0);
source_params = bt_get(source_cfg->params);
source_class = find_component_class(source_cfg->plugin_name->str,
source_cfg->component_name->str,
goto end;
}
- sink_cfg = bt_config_get_component(cfg->sinks, 0);
+ sink_cfg = bt_config_get_component(cfg->cmd_data.convert.sinks, 0);
sink_params = bt_get(sink_cfg->params);
sink_class = find_component_class(sink_cfg->plugin_name->str,
sink_cfg->component_name->str,
ret = connect_source_sink(source, source_cfg, sink);
if (ret) {
+ ret = -1;
goto end;
}
goto end;
}
}
+
end:
BT_PUT(sink_class);
BT_PUT(source_class);
BT_PUT(sink);
BT_PUT(source_params);
BT_PUT(sink_params);
- BT_PUT(cfg);
BT_PUT(sink_cfg);
BT_PUT(source_cfg);
+ return ret;
+}
+
+static void warn_command_name_and_directory_clash(struct bt_config *cfg)
+{
+ if (!cfg->command_name) {
+ return;
+ }
+
+ if (g_file_test(cfg->command_name,
+ G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) {
+ fprintf(stderr, "\nNOTE: The `%s` command was executed. If you meant to convert a\n",
+ cfg->command_name);
+ fprintf(stderr, "trace located in the local `%s` directory, please use:\n",
+ cfg->command_name);
+ fprintf(stderr, "\n");
+ fprintf(stderr, " babeltrace convert %s [OPTIONS]\n",
+ cfg->command_name);
+ }
+}
+
+int main(int argc, const char **argv)
+{
+ int ret;
+ int retcode;
+ struct bt_config *cfg;
+
+ init_loaded_plugins_array();
+ cfg = bt_config_from_args_with_defaults(argc, argv, &retcode);
+
+ if (retcode < 0) {
+ /* Quit without errors; typically usage/version */
+ retcode = 0;
+ goto end;
+ }
+
+ if (retcode > 0) {
+ goto end;
+ }
+
+ if (!cfg) {
+ fprintf(stderr, "Failed to create Babeltrace configuration\n");
+ goto end;
+ }
+
+ babeltrace_debug = cfg->debug;
+ babeltrace_verbose = cfg->verbose;
+ print_cfg(cfg);
+
+ switch (cfg->command) {
+ case BT_CONFIG_COMMAND_CONVERT:
+ ret = cmd_convert(cfg);
+ break;
+ case BT_CONFIG_COMMAND_LIST_PLUGINS:
+ ret = cmd_list_plugins(cfg);
+ break;
+ default:
+ assert(false);
+ }
+
+ warn_command_name_and_directory_clash(cfg);
+ retcode = ret ? 1 : 0;
+
+end:
+ BT_PUT(cfg);
fini_loaded_plugins_array();
- return ret ? 1 : 0;
+ return retcode;
}