#include "babeltrace-cfg.h"
#include "babeltrace-cfg-cli-args.h"
#include "babeltrace-cfg-cli-args-connect.h"
+#include "version.h"
/*
* Error printf() macro which prepends "Error: " the first time it's
* 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_type is set.
+ * 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,
/* 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 name\n");
+ printf_err("Missing plugin or component class name\n");
goto error;
}
static
void print_version(void)
{
- puts("Babeltrace " VERSION);
+ if (GIT_VERSION[0] == '\0') {
+ puts("Babeltrace " VERSION);
+ } else {
+ puts("Babeltrace " VERSION " - " GIT_VERSION);
+ }
}
/*
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:
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:
OPT_COMPONENT,
OPT_CONNECT,
OPT_DEBUG,
+ OPT_DEBUG_INFO,
OPT_DEBUG_INFO_DIR,
OPT_DEBUG_INFO_FULL_PATH,
OPT_DEBUG_INFO_TARGET_PREFIX,
OPT_LIST,
OPT_NAME,
OPT_NAMES,
- OPT_NO_DEBUG_INFO,
OPT_NO_DELTA,
OPT_OMIT_HOME_PLUGIN_PATH,
OPT_OMIT_SYSTEM_PLUGIN_PATH,
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:
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:
void print_help_usage(FILE *fp)
{
fprintf(fp, "Usage: babeltrace [GENERAL OPTIONS] help [OPTIONS] PLUGIN\n");
- fprintf(fp, " babeltrace [GENERAL OPTIONS] help [OPTIONS] --component=TYPE.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, " -c, --component=TYPE.PLUGIN.CLS Get help for the component class CLS of\n");
- fprintf(fp, " type TYPE (`source`, `filter`, or `sink`)\n");
- fprintf(fp, " 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");
static
struct poptOption help_long_options[] = {
/* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
- { "component", 'c', POPT_ARG_STRING, NULL, OPT_COMPONENT, 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 },
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);
case OPT_OMIT_HOME_PLUGIN_PATH:
cfg->omit_home_plugin_path = true;
break;
- case OPT_COMPONENT:
- if (plug_comp_cls_names) {
- printf_err("Cannot specify more than one plugin and component class:\n %s\n",
- arg);
- goto error;
- }
-
- 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;
leftover = poptGetArg(pc);
if (leftover) {
- if (plug_comp_cls_names) {
- printf_err("Cannot specify plugin name and --component component class:\n %s\n",
- leftover);
- goto error;
- }
-
- g_string_assign(cfg->cmd_data.help.cfg_component->plugin_name,
- leftover);
- } else {
- if (!plug_comp_cls_names) {
- print_help_usage(stdout);
- *retcode = -1;
- BT_PUT(cfg);
- goto end;
- }
-
- plugin_comp_cls_names(plug_comp_cls_names, NULL,
+ 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 --component option's argument:\n %s\n",
- plug_comp_cls_names);
- goto error;
+ /* Fall back to plugin help */
+ cfg->cmd_data.help.cfg_component->type =
+ BT_COMPONENT_CLASS_TYPE_UNKNOWN;
+ g_string_assign(
+ cfg->cmd_data.help.cfg_component->plugin_name,
+ leftover);
}
+ } else {
+ print_help_usage(stdout);
+ *retcode = -1;
+ BT_PUT(cfg);
+ goto end;
}
if (append_home_and_system_plugin_paths_cfg(cfg)) {
BT_PUT(cfg);
end:
- free(plug_comp_cls_names);
g_free(plugin_name);
g_free(comp_cls_name);
static
void print_query_usage(FILE *fp)
{
- fprintf(fp, "Usage: babeltrace [GEN OPTS] query [OPTS] OBJECT --component=TYPE.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, " -c, --component=TYPE.PLUGIN.CLS Query the component class CLS of type TYPE\n");
- fprintf(fp, " (`source`, `filter`, or `sink`) found in\n");
- fprintf(fp, " 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");
static
struct poptOption query_long_options[] = {
/* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
- { "component", 'c', POPT_ARG_STRING, NULL, OPT_COMPONENT, 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 },
case OPT_OMIT_HOME_PLUGIN_PATH:
cfg->omit_home_plugin_path = true;
break;
- case OPT_COMPONENT:
- if (cfg->cmd_data.query.cfg_component) {
- printf_err("Cannot specify more than one plugin and component class:\n %s\n",
- arg);
- goto error;
- }
-
- cfg->cmd_data.query.cfg_component =
- bt_config_component_from_arg(arg);
- if (!cfg->cmd_data.query.cfg_component) {
- printf_err("Invalid format for --component 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_put(params);
params = bt_value_from_arg(arg);
if (!params) {
printf_err("Invalid format for --params option's argument:\n %s\n",
arg = NULL;
}
- if (!cfg->cmd_data.query.cfg_component) {
- printf_err("No target component class specified with --component 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",
}
/*
- * 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;
+ }
+
+ assert(params);
+ BT_MOVE(cfg->cmd_data.query.cfg_component->params, params);
+ } else {
+ print_query_usage(stdout);
+ *retcode = -1;
+ BT_PUT(cfg);
+ goto end;
+ }
+
leftover = poptGetArg(pc);
if (leftover) {
if (strlen(leftover) == 0) {
poptFreeContext(pc);
}
- BT_PUT(params);
+ bt_put(params);
free(arg);
return cfg;
}
struct bt_value *connection_args = NULL;
GString *cur_param_key = NULL;
char error_buf[256] = { 0 };
- long long retry_duration = -1;
+ long retry_duration = -1;
struct poptOption run_long_options[] = {
{ "base-params", 'b', POPT_ARG_STRING, NULL, OPT_BASE_PARAMS, NULL, NULL },
{ "component", 'c', POPT_ARG_STRING, NULL, OPT_COMPONENT, NULL, NULL },
{ "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 },
+ { "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 },
};
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;
}
{
struct bt_config *cfg = NULL;
const char **argv;
- size_t i;
+ int64_t i, len;
const size_t argc = bt_value_array_size(run_args) + 1;
argv = calloc(argc, sizeof(*argv));
argv[0] = "run";
- for (i = 0; i < bt_value_array_size(run_args); i++) {
+ len = bt_value_array_size(run_args);
+ if (len < 0) {
+ printf_err("Invalid executable arguments\n");
+ goto end;
+ }
+ for (i = 0; i < len; i++) {
int ret;
struct bt_value *arg_value = bt_value_array_get(run_args, i);
const char *arg;
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, " --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, " --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 `sink.text.pretty` component options:\n");
fprintf(fp, "\n");
fprintf(fp, "\n");
fprintf(fp, "Implicit `filter.lttng-utils.debug-info` component options:\n");
fprintf(fp, "\n");
+ fprintf(fp, " --debug-info Create an implicit\n");
+ fprintf(fp, " `filter.lttng-utils.debug-info` component\n");
fprintf(fp, " --debug-info-dir=DIR Search for debug info in directory DIR\n");
fprintf(fp, " instead of `/usr/lib/debug`\n");
fprintf(fp, " --debug-info-full-path Show full debug info source and\n");
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, " `text`:\n");
fprintf(fp, " Create an implicit `sink.text.pretty`\n");
fprintf(fp, " component\n");
- fprintf(fp, " `text`:\n");
+ fprintf(fp, " `ctf`:\n");
fprintf(fp, " Create an implicit `sink.ctf.fs`\n");
fprintf(fp, " component\n");
fprintf(fp, " `dummy`:\n");
{ "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 },
BT_PUT(impl_args->extra_params);
impl_args->extra_params =
bt_value_copy(base_implicit_ctf_input_args->extra_params);
- if (!impl_args) {
+ if (!impl_args->extra_params) {
print_err_oom();
destroy_implicit_component_args(impl_args);
goto error;
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,
+ bool force_omit_home_plugin_path,
struct bt_value *initial_plugin_paths, char *log_level)
{
poptContext pc = NULL;
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;
}
if (init_implicit_component_args(&implicit_debug_info_args,
- "filter.lttng-utils.debug-info", !force_no_debug_info)) {
+ "filter.lttng-utils.debug-info", false)) {
goto error;
}
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:
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:
case OPT_CLOCK_GMT:
append_implicit_component_param(
&implicit_text_args, "clock-gmt", "yes");
+ append_implicit_component_param(
+ &implicit_trimmer_args, "clock-gmt", "yes");
implicit_text_args.exists = true;
break;
case OPT_CLOCK_OFFSET:
base_implicit_ctf_input_args.exists = true;
append_implicit_component_param(
- &implicit_muxer_args,
+ &base_implicit_ctf_input_args,
"clock-class-offset-s", arg);
- if (ret) {
- goto error;
- }
break;
case OPT_CLOCK_OFFSET_NS:
base_implicit_ctf_input_args.exists = true;
- ret = append_implicit_component_extra_param(
- &base_implicit_ctf_input_args,
- "clock-class-offset-ns", arg);
- if (ret) {
- goto error;
- }
+ append_implicit_component_param(
+ &base_implicit_ctf_input_args,
+ "clock-class-offset-ns", arg);
break;
case OPT_CLOCK_SECONDS:
append_implicit_component_param(
goto error;
}
break;
- case OPT_NO_DEBUG_INFO:
- implicit_debug_info_args.exists = false;
+ case OPT_DEBUG_INFO:
+ implicit_debug_info_args.exists = true;
break;
case OPT_DEBUG_INFO_DIR:
implicit_debug_info_args.exists = true;
ret = append_implicit_component_extra_param(
- &implicit_debug_info_args, "dir", arg);
+ &implicit_debug_info_args, "debug-info-dir", arg);
if (ret) {
goto error;
}
print_run_args_0 = true;
break;
case OPT_STREAM_INTERSECTION:
- append_implicit_component_param(
- &base_implicit_ctf_input_args,
- "stream-intersection", "yes");
- base_implicit_ctf_input_args.exists = true;
+ /*
+ * Applies to all traces implementing the trace-info
+ * query.
+ */
+ stream_intersection_mode = true;
break;
case OPT_VERBOSE:
if (*log_level != 'V' && *log_level != 'D') {
gs_leftover = leftovers->data;
g_string_assign(cfg->cmd_data.print_ctf_metadata.path,
gs_leftover->str);
+
+ if (output) {
+ g_string_assign(
+ cfg->cmd_data.print_ctf_metadata.output_path,
+ output);
+ }
+
goto end;
}
g_string_assign(cfg->cmd_data.print_lttng_live_sessions.url,
gs_leftover->str);
+
+ if (output) {
+ g_string_assign(
+ cfg->cmd_data.print_lttng_live_sessions.output_path,
+ output);
+ }
+
goto end;
}
* here.
*/
if (print_run_args || print_run_args_0) {
+ 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_size(run_args); i++) {
struct bt_value *arg_value =
bt_value_array_get(run_args, i);
goto error;
}
+ cfg->cmd_data.run.stream_intersection_mode = stream_intersection_mode;
goto end;
error:
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,
+ bool force_omit_home_plugin_path,
struct bt_value *initial_plugin_paths)
{
struct bt_config *config = NULL;
}
if (argc <= 1) {
+ print_version();
+ puts("");
print_gen_usage(stdout);
goto end;
}
case COMMAND_TYPE_CONVERT:
config = bt_config_convert_from_args(command_argc, command_argv,
retcode, force_omit_system_plugin_path,
- force_omit_home_plugin_path, force_no_debug_info,
+ force_omit_home_plugin_path,
initial_plugin_paths, &log_level);
break;
case COMMAND_TYPE_LIST_PLUGINS: