X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=src%2Fcli%2Fbabeltrace2-cfg-cli-args.c;h=5df6ce3a4a3ce813d30ca6fe0f1f682bc9750357;hb=f956eb2d2b08c13e4f105fce5de566b9f2346693;hp=8a9c1bf6d6e705ca3295bdfc454794daa6ea9fc5;hpb=d98f6ad1a757060bd4da0a3accae03dd5c5fd57f;p=babeltrace.git diff --git a/src/cli/babeltrace2-cfg-cli-args.c b/src/cli/babeltrace2-cfg-cli-args.c index 8a9c1bf6..5df6ce3a 100644 --- a/src/cli/babeltrace2-cfg-cli-args.c +++ b/src/cli/babeltrace2-cfg-cli-args.c @@ -40,49 +40,13 @@ #include "babeltrace2-cfg.h" #include "babeltrace2-cfg-cli-args.h" #include "babeltrace2-cfg-cli-args-connect.h" -#include "babeltrace2-cfg-cli-params-arg.h" +#include "param-parse/param-parse.h" #include "babeltrace2-log-level.h" #include "babeltrace2-plugins.h" #include "babeltrace2-query.h" #include "autodisc/autodisc.h" #include "common/version.h" -/* INI-style parsing FSM states */ -enum ini_parsing_fsm_state { - /* Expect a map key (identifier) */ - INI_EXPECT_MAP_KEY, - - /* Expect an equal character ('=') */ - INI_EXPECT_EQUAL, - - /* Expect a value */ - INI_EXPECT_VALUE, - - /* Expect a comma character (',') */ - INI_EXPECT_COMMA, -}; - -/* INI-style parsing state variables */ -struct ini_parsing_state { - /* Lexical scanner (owned by this) */ - GScanner *scanner; - - /* Output map value object being filled (owned by this) */ - bt_value *params; - - /* Next expected FSM state */ - enum ini_parsing_fsm_state expecting; - - /* Last decoded map key (owned by this) */ - char *last_map_key; - - /* Complete INI-style string to parse (not owned by this) */ - const char *arg; - - /* Error buffer (not owned by this) */ - GString *ini_error; -}; - /* Offset option with "is set" boolean */ struct offset_opt { int64_t value; @@ -1382,6 +1346,8 @@ struct bt_config *bt_config_help_from_args(int argc, const char *argv[], char *plugin_name = NULL, *comp_cls_name = NULL; struct bt_argpar_parse_ret argpar_parse_ret = { 0 }; struct bt_argpar_item_non_opt *non_opt; + GString *substring = NULL; + size_t end_pos; *retcode = 0; cfg = bt_config_help_create(plugin_paths, default_log_level); @@ -1423,18 +1389,36 @@ struct bt_config *bt_config_help_from_args(int argc, const char *argv[], } non_opt = argpar_parse_ret.items->pdata[0]; - plugin_comp_cls_names(non_opt->arg, NULL, &plugin_name, &comp_cls_name, - &cfg->cmd_data.help.cfg_component->type); - if (plugin_name && comp_cls_name) { - /* Component class help */ + + /* Look for unescaped dots in the argument. */ + substring = bt_common_string_until(non_opt->arg, ".\\", ".", &end_pos); + if (!substring) { + BT_CLI_LOGE_APPEND_CAUSE("Could not consume argument: arg=%s", + non_opt->arg); + goto error; + } + + if (end_pos == strlen(non_opt->arg)) { + /* Didn't find an unescaped dot, treat it as a plugin name. */ + g_string_assign(cfg->cmd_data.help.cfg_component->plugin_name, + non_opt->arg); + } else { + /* + * Found an unescaped dot, treat it as a component class name. + */ + plugin_comp_cls_names(non_opt->arg, NULL, &plugin_name, &comp_cls_name, + &cfg->cmd_data.help.cfg_component->type); + if (!plugin_name || !comp_cls_name) { + BT_CLI_LOGE_APPEND_CAUSE( + "Could not parse argument as a component class name: arg=%s", + non_opt->arg); + goto error; + } + 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, comp_cls_name); - } else { - /* Fall back to plugin help */ - g_string_assign(cfg->cmd_data.help.cfg_component->plugin_name, - non_opt->arg); } goto end; @@ -1447,6 +1431,10 @@ end: g_free(plugin_name); g_free(comp_cls_name); + if (substring) { + g_string_free(substring, TRUE); + } + bt_argpar_parse_ret_fini(&argpar_parse_ret); return cfg; @@ -1540,7 +1528,7 @@ struct bt_config *bt_config_query_from_args(int argc, const char *argv[], case OPT_PARAMS: { bt_value_put_ref(params); - params = cli_value_from_arg(arg, error_str); + params = bt_param_parse(arg, error_str); if (!params) { BT_CLI_LOGE_APPEND_CAUSE("Invalid format for --params option's argument:\n %s", error_str->str); @@ -1939,7 +1927,7 @@ struct bt_config *bt_config_run_from_args(int argc, const char *argv[], goto error; } - params = cli_value_from_arg(arg, error_str); + params = bt_param_parse(arg, error_str); if (!params) { BT_CLI_LOGE_APPEND_CAUSE("Invalid format for --params option's argument:\n %s", error_str->str); @@ -1975,7 +1963,7 @@ struct bt_config *bt_config_run_from_args(int argc, const char *argv[], break; case OPT_BASE_PARAMS: { - bt_value *params = cli_value_from_arg(arg, error_str); + bt_value *params = bt_param_parse(arg, error_str); if (!params) { BT_CLI_LOGE_APPEND_CAUSE("Invalid format for --base-params option's argument:\n %s", @@ -2148,6 +2136,8 @@ void print_convert_usage(FILE *fp) fprintf(fp, "\n"); fprintf(fp, "Implicit `source.ctf.fs` component options:\n"); fprintf(fp, "\n"); + fprintf(fp, " --clock-force-correlate Force the origin of all clocks\n"); + fprintf(fp, " to the Unix epoch\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, "\n"); @@ -2175,11 +2165,6 @@ void print_convert_usage(FILE *fp) fprintf(fp, " -w, --output=PATH Write output text to PATH instead of\n"); fprintf(fp, " the standard output\n"); fprintf(fp, "\n"); - fprintf(fp, "Implicit `filter.utils.muxer` component options:\n"); - fprintf(fp, "\n"); - fprintf(fp, " --clock-force-correlate Assume that clocks are inherently\n"); - fprintf(fp, " correlated across traces\n"); - fprintf(fp, "\n"); fprintf(fp, "Implicit `filter.utils.trimmer` component options:\n"); fprintf(fp, "\n"); fprintf(fp, " -b, --begin=BEGIN Set the beginning time of the conversion\n"); @@ -2981,6 +2966,9 @@ end: * Create `struct implicit_component_args` structures for each of the * source components we identified. Add them to `component_args`. * + * `non_opts` is an array of the non-option arguments passed on the command + * line. + * * `non_opt_params` is an array where each element is an array of * strings containing all the arguments to `--params` that apply to the * non-option argument at the same index. For example, if, for a @@ -2996,6 +2984,7 @@ end: static int create_implicit_component_args_from_auto_discovered_sources( const struct auto_source_discovery *auto_disc, + const bt_value *non_opts, const bt_value *non_opt_params, const bt_value *non_opt_loglevels, GPtrArray *component_args) @@ -3086,6 +3075,42 @@ int create_implicit_component_args_from_auto_discovered_sources( } } + /* + * If single input and a src.ctf.fs component, provide the + * relative path from the path passed on the command line to the + * found trace. + */ + if (bt_value_array_get_length(res->inputs) == 1 && + strcmp(res->plugin_name, "ctf") == 0 && + strcmp(res->source_cc_name, "fs") == 0) { + const bt_value *orig_idx_value = + bt_value_array_borrow_element_by_index( + res->original_input_indices, 0); + uint64_t orig_idx = bt_value_integer_unsigned_get(orig_idx_value); + const bt_value *non_opt_value = + bt_value_array_borrow_element_by_index_const( + non_opts, orig_idx); + const char *non_opt = bt_value_string_get(non_opt_value); + const bt_value *input_value = + bt_value_array_borrow_element_by_index_const( + res->inputs, 0); + const char *input = bt_value_string_get(input_value); + + BT_ASSERT(orig_indices_count == 1); + BT_ASSERT(g_str_has_prefix(input, non_opt)); + + input += strlen(non_opt); + + while (G_IS_DIR_SEPARATOR(*input)) { + input++; + } + + if (strlen(input) > 0) { + append_string_parameter_to_args(comp->extra_params, + "trace-name", input); + } + } + status = append_parameter_to_args(comp->extra_params, "inputs", res->inputs); if (status != 0) { goto error; @@ -3136,7 +3161,7 @@ enum convert_current_item_type { static struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], int *retcode, const bt_value *plugin_paths, - int *default_log_level) + int *default_log_level, const bt_interrupter *interrupter) { enum convert_current_item_type current_item_type = CONVERT_CURRENT_ITEM_TYPE_NONE; @@ -3189,6 +3214,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], const char *auto_source_discovery_restrict_plugin_name = NULL; const char *auto_source_discovery_restrict_component_class_name = NULL; + bool ctf_fs_source_force_clock_class_unix_epoch_origin = false; gchar *ctf_fs_source_clock_class_offset_arg = NULL; gchar *ctf_fs_source_clock_class_offset_ns_arg = NULL; *retcode = 0; @@ -3661,9 +3687,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], implicit_text_args.exists = true; break; case OPT_CLOCK_FORCE_CORRELATE: - append_implicit_component_param( - &implicit_muxer_args, - "assume-absolute-clock-classes", "yes"); + ctf_fs_source_force_clock_class_unix_epoch_origin = true; break; case OPT_CLOCK_GMT: append_implicit_component_param( @@ -3849,7 +3873,7 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], case OPT_STREAM_INTERSECTION: /* * Applies to all traces implementing the - * babeltrace.trace-info query. + * babeltrace.trace-infos query. */ stream_intersection_mode = true; break; @@ -4053,14 +4077,18 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], status = auto_discover_source_components(non_opts, plugins, plugin_count, auto_source_discovery_restrict_component_class_name, - *default_log_level, &auto_disc); + *default_log_level, &auto_disc, interrupter); if (status != 0) { + if (status == AUTO_SOURCE_DISCOVERY_STATUS_INTERRUPTED) { + BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN( + "Babeltrace CLI", "Automatic source discovery interrupted by the user"); + } goto error; } status = create_implicit_component_args_from_auto_discovered_sources( - &auto_disc, non_opt_params, non_opt_loglevels, + &auto_disc, non_opts, non_opt_params, non_opt_loglevels, discovered_source_args); if (status != 0) { goto error; @@ -4068,6 +4096,23 @@ struct bt_config *bt_config_convert_from_args(int argc, const char *argv[], } } + + /* + * If --clock-force-correlated was given, apply it to any src.ctf.fs + * component. + */ + if (ctf_fs_source_force_clock_class_unix_epoch_origin) { + int n; + + n = append_multiple_implicit_components_param( + discovered_source_args, "source.ctf.fs", "force-clock-class-origin-unix-epoch", + "yes"); + if (n == 0) { + BT_CLI_LOGE_APPEND_CAUSE("--clock-force-correlate specified, but no source.ctf.fs component instantiated."); + goto error; + } + } + /* If --clock-offset was given, apply it to any src.ctf.fs component. */ if (ctf_fs_source_clock_class_offset_arg) { int n; @@ -4428,7 +4473,8 @@ void print_gen_usage(FILE *fp) struct bt_config *bt_config_cli_args_create(int argc, const char *argv[], int *retcode, bool omit_system_plugin_path, bool omit_home_plugin_path, - const bt_value *initial_plugin_paths) + const bt_value *initial_plugin_paths, + const bt_interrupter *interrupter) { struct bt_config *config = NULL; int i; @@ -4658,7 +4704,7 @@ struct bt_config *bt_config_cli_args_create(int argc, const char *argv[], break; case COMMAND_TYPE_CONVERT: config = bt_config_convert_from_args(command_argc, command_argv, - retcode, plugin_paths, &default_log_level); + retcode, plugin_paths, &default_log_level, interrupter); break; case COMMAND_TYPE_LIST_PLUGINS: config = bt_config_list_plugins_from_args(command_argc,