* SOFTWARE.
*/
+#define BT_LOG_TAG "CLI-CFG-CLI-ARGS"
+#include "logging.h"
+
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "babeltrace-cfg-cli-args.h"
#include "babeltrace-cfg-cli-args-connect.h"
-#define BT_LOG_TAG "CLI-CFG-ARGS"
-#include "logging.h"
-
/*
* Error printf() macro which prepends "Error: " the first time it's
* called. This gives a nicer feel than having a bunch of error prefixes
const char *envvar;
if (bt_common_is_setuid_setgid()) {
- printf_debug("Skipping non-system plugin paths for setuid/setgid binary\n");
+ BT_LOGI_STR("Skipping non-system plugin paths for setuid/setgid binary.");
goto end;
}
if (!omit_home_plugin_path) {
if (bt_common_is_setuid_setgid()) {
- printf_debug("Skipping non-system plugin paths for setuid/setgid binary\n");
+ BT_LOGI_STR("Skipping non-system plugin paths for setuid/setgid binary.");
} else {
char *home_plugin_dir =
bt_common_get_home_plugin_path();
int ret = 0;
if (bt_common_is_setuid_setgid()) {
- printf_debug("Skipping non-system plugin paths for setuid/setgid binary\n");
+ BT_LOGI_STR("Skipping non-system plugin paths for setuid/setgid binary.");
goto end;
}
fprintf(fp, " --omit-system-plugin-path Omit system plugins from plugin search path\n");
fprintf(fp, " --plugin-path=PATH[:PATH]... Add PATH to the list of paths from which\n");
fprintf(fp, " dynamic plugins can be loaded\n");
- fprintf(fp, " -h --help Show this help and quit\n");
+ fprintf(fp, " -h, --help Show this help and quit\n");
fprintf(fp, "\n");
fprintf(fp, "See `babeltrace --help` for the list of general options.\n");
fprintf(fp, "\n");
leftover = poptGetArg(pc);
if (leftover) {
- if (!plug_comp_cls_names) {
+ if (plug_comp_cls_names) {
printf_err("Cannot specify plugin name and --component component class:\n %s\n",
leftover);
goto error;
fprintf(fp, " (see the expected format of PARAMS below)\n");
fprintf(fp, " --plugin-path=PATH[:PATH]... Add PATH to the list of paths from which\n");
fprintf(fp, " dynamic plugins can be loaded\n");
- fprintf(fp, " -h --help Show this help and quit\n");
+ fprintf(fp, " -h, --help Show this help and quit\n");
fprintf(fp, "\n\n");
print_expected_params_format(fp);
}
fprintf(fp, " --omit-system-plugin-path Omit system plugins from plugin search path\n");
fprintf(fp, " --plugin-path=PATH[:PATH]... Add PATH to the list of paths from which\n");
fprintf(fp, " dynamic plugins can be loaded\n");
- fprintf(fp, " -h --help Show this help and quit\n");
+ fprintf(fp, " -h, --help Show this help and quit\n");
fprintf(fp, "\n");
fprintf(fp, "See `babeltrace --help` for the list of general options.\n");
fprintf(fp, "\n");
fprintf(fp, " the current component with a name given by\n");
fprintf(fp, " the last argument of the --key option and a\n");
fprintf(fp, " value set to VAL\n");
- fprintf(fp, " -h --help Show this help and quit\n");
+ fprintf(fp, " -h, --help Show this help and quit\n");
fprintf(fp, "\n");
fprintf(fp, "See `babeltrace --help` for the list of general options.\n");
fprintf(fp, "\n\n");
{
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, " formatted for `xargs -0`, and quit\n");
fprintf(fp, " -u, --url=URL Set the `url` string parameter of the\n");
fprintf(fp, " current component to URL\n");
- fprintf(fp, " -h --help Show this help and quit\n");
+ fprintf(fp, " -h, --help Show this help and quit\n");
fprintf(fp, "\n");
fprintf(fp, "Implicit `source.ctf.fs` component options:\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");
struct bt_config *bt_config_convert_from_args(int argc, const char *argv[],
int *retcode, bool force_omit_system_plugin_path,
bool force_omit_home_plugin_path, bool force_no_debug_info,
- struct bt_value *initial_plugin_paths)
+ struct bt_value *initial_plugin_paths, char *log_level)
{
poptContext pc = NULL;
char *arg = NULL;
BT_CONFIG_COMPONENT_DEST_UNKNOWN;
int opt, ret = 0;
struct bt_config *cfg = NULL;
- bool got_verbose_opt = false;
- bool got_debug_opt = false;
bool got_input_format_opt = false;
bool got_output_format_opt = false;
bool trimmer_has_begin = false;
bool trimmer_has_end = false;
+ bool stream_intersection_mode = false;
GString *cur_name = NULL;
GString *cur_name_prefix = NULL;
const char *leftover = NULL;
break;
case OPT_CLOCK_FORCE_CORRELATE:
append_implicit_component_param(
- &implicit_muxer_args, "assume-absolute-clock-classes", "yes");
+ &implicit_muxer_args,
+ "assume-absolute-clock-classes", "yes");
break;
case OPT_CLOCK_GMT:
append_implicit_component_param(
&implicit_text_args, "clock-gmt", "yes");
+ append_implicit_component_param(
+ &implicit_trimmer_args, "clock-gmt", "yes");
implicit_text_args.exists = true;
break;
case OPT_CLOCK_OFFSET:
base_implicit_ctf_input_args.exists = true;
- ret = append_implicit_component_extra_param(
- &base_implicit_ctf_input_args, "clock-offset-cycles", arg);
- if (ret) {
- goto error;
- }
+ append_implicit_component_param(
+ &base_implicit_ctf_input_args,
+ "clock-class-offset-s", arg);
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-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(
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 (got_verbose_opt) {
- printf_err("Duplicate -v/--verbose option\n");
- goto error;
+ if (*log_level != 'V' && *log_level != 'D') {
+ *log_level = 'I';
}
-
- append_implicit_component_param(&implicit_text_args,
- "verbose", "yes");
- implicit_text_args.exists = true;
- got_verbose_opt = true;
break;
case OPT_DEBUG:
- got_debug_opt = true;
+ *log_level = 'V';
break;
}
goto error;
}
+ /*
+ * Legacy behaviour: --verbose used to make the `text` output
+ * format print more information. --verbose is now equivalent to
+ * the INFO log level, which is why we compare to 'I' here.
+ */
+ if (*log_level == 'I') {
+ append_implicit_component_param(&implicit_text_args,
+ "verbose", "yes");
+ }
+
/*
* Append home and system plugin paths now that we possibly got
* --plugin-path.
goto error;
}
- cfg->debug = got_debug_opt;
- cfg->verbose = got_verbose_opt;
gs_leftover = leftovers->data;
g_string_assign(cfg->cmd_data.print_ctf_metadata.path,
gs_leftover->str);
goto error;
}
- cfg->debug = got_debug_opt;
- cfg->verbose = got_verbose_opt;
g_string_assign(cfg->cmd_data.print_lttng_live_sessions.url,
gs_leftover->str);
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->debug = got_debug_opt;
- cfg->verbose = got_verbose_opt;
+ cfg->cmd_data.run.stream_intersection_mode = stream_intersection_mode;
goto end;
error:
fprintf(fp, "\n");
fprintf(fp, "General options:\n");
fprintf(fp, "\n");
- fprintf(fp, " -d, --debug Turn on debug mode\n");
- fprintf(fp, " -h --help Show this help and quit\n");
- fprintf(fp, " -v, --verbose Turn on verbose mode\n");
- fprintf(fp, " -V, --version Show version and quit\n");
+ fprintf(fp, " -d, --debug Enable debug mode (same as --log-level=V)\n");
+ fprintf(fp, " -h, --help Show this help and quit\n");
+ fprintf(fp, " --log-level=LVL Set all log levels to LVL (`N`, `V`, `D`,\n");
+ fprintf(fp, " `I`, `W` (default), `E`, or `F`)\n");
+ fprintf(fp, " -v, --verbose Enable verbose mode (same as --log-level=I)\n");
+ fprintf(fp, " -V, --version Show version and quit\n");
fprintf(fp, "\n");
fprintf(fp, "Available commands:\n");
fprintf(fp, "\n");
fprintf(fp, "Use `babeltrace COMMAND --help` to show the help of COMMAND.\n");
}
+static
+char log_level_from_arg(const char *arg)
+{
+ char level = 'U';
+
+ if (strcmp(arg, "VERBOSE") == 0 ||
+ strcmp(arg, "V") == 0) {
+ level = 'V';
+ } else if (strcmp(arg, "DEBUG") == 0 ||
+ strcmp(arg, "D") == 0) {
+ level = 'D';
+ } else if (strcmp(arg, "INFO") == 0 ||
+ strcmp(arg, "I") == 0) {
+ level = 'I';
+ } else if (strcmp(arg, "WARN") == 0 ||
+ strcmp(arg, "WARNING") == 0 ||
+ strcmp(arg, "W") == 0) {
+ level = 'W';
+ } else if (strcmp(arg, "ERROR") == 0 ||
+ strcmp(arg, "E") == 0) {
+ level = 'E';
+ } else if (strcmp(arg, "FATAL") == 0 ||
+ strcmp(arg, "F") == 0) {
+ level = 'F';
+ } else if (strcmp(arg, "NONE") == 0 ||
+ strcmp(arg, "N") == 0) {
+ level = 'N';
+ }
+
+ return level;
+}
+
struct bt_config *bt_config_cli_args_create(int argc, const char *argv[],
int *retcode, bool force_omit_system_plugin_path,
bool force_omit_home_plugin_path, bool force_no_debug_info,
struct bt_value *initial_plugin_paths)
{
struct bt_config *config = NULL;
- bool verbose = false;
- bool debug = false;
int i;
const char **command_argv = NULL;
int command_argc = -1;
const char *command_name = NULL;
+ char log_level = 'U';
enum command_type {
COMMAND_TYPE_NONE = -1,
for (i = 1; i < argc; i++) {
const char *cur_arg = argv[i];
+ const char *next_arg = i == (argc - 1) ? NULL : argv[i + 1];
if (strcmp(cur_arg, "-d") == 0 ||
strcmp(cur_arg, "--debug") == 0) {
- debug = true;
+ log_level = 'V';
} else if (strcmp(cur_arg, "-v") == 0 ||
strcmp(cur_arg, "--verbose") == 0) {
- verbose = true;
+ if (log_level != 'V' && log_level != 'D') {
+ /*
+ * Legacy: do not override a previous
+ * --debug because --verbose and --debug
+ * can be specified together (in this
+ * case we want the lowest log level to
+ * apply, VERBOSE).
+ */
+ log_level = 'I';
+ }
+ } else if (strcmp(cur_arg, "--log-level") == 0) {
+ if (!next_arg) {
+ printf_err("Missing log level value for --log-level option\n");
+ *retcode = 1;
+ goto end;
+ }
+
+ log_level = log_level_from_arg(next_arg);
+ if (log_level == 'U') {
+ printf_err("Invalid argument for --log-level option:\n %s\n",
+ next_arg);
+ *retcode = 1;
+ goto end;
+ }
+
+ i++;
+ } else if (strncmp(cur_arg, "--log-level=", 12) == 0) {
+ const char *arg = &cur_arg[12];
+
+ log_level = log_level_from_arg(arg);
+ if (log_level == 'U') {
+ printf_err("Invalid argument for --log-level option:\n %s\n",
+ arg);
+ *retcode = 1;
+ goto end;
+ }
} else if (strcmp(cur_arg, "-V") == 0 ||
strcmp(cur_arg, "--version") == 0) {
print_version();
print_gen_usage(stdout);
goto end;
} else {
- bool has_command = true;
-
/*
* First unknown argument: is it a known command
* name?
*/
+ command_argv = &argv[i];
+ command_argc = argc - i;
+
if (strcmp(cur_arg, "convert") == 0) {
command_type = COMMAND_TYPE_CONVERT;
} else if (strcmp(cur_arg, "list-plugins") == 0) {
} else {
/*
* Unknown argument, but not a known
- * command name: assume the whole
- * arguments are for the default convert
- * command.
+ * command name: assume the default
+ * `convert` command.
*/
command_type = COMMAND_TYPE_CONVERT;
- command_argv = argv;
- command_argc = argc;
- has_command = false;
- }
-
- if (has_command) {
- command_argv = &argv[i];
- command_argc = argc - i;
- command_name = cur_arg;
+ command_name = "convert";
+ command_argv = &argv[i - 1];
+ command_argc = argc - i + 1;
}
break;
}
config = bt_config_convert_from_args(command_argc, command_argv,
retcode, force_omit_system_plugin_path,
force_omit_home_plugin_path, force_no_debug_info,
- initial_plugin_paths);
+ initial_plugin_paths, &log_level);
break;
case COMMAND_TYPE_LIST_PLUGINS:
config = bt_config_list_plugins_from_args(command_argc,
}
if (config) {
- if (verbose) {
- config->verbose = true;
- }
-
- if (debug) {
- config->debug = true;
+ if (log_level == 'U') {
+ log_level = 'W';
}
+ config->log_level = log_level;
config->command_name = command_name;
}