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);
}
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;
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;
--- /dev/null
+#!/bin/bash
+#
+# Copyright (C) 2019 EfficiOS Inc.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License, version 2 only, as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+SH_TAP=1
+
+if [ "x${BT_TESTS_SRCDIR:-}" != "x" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../utils/utils.sh"
+fi
+
+# shellcheck source=../utils/utils.sh
+source "$UTILSSH"
+
+plan_tests 21
+
+stdout=$(mktemp test_help_stdout.XXXXXX)
+stderr=$(mktemp test_help_stderr.XXXXXX)
+
+# Return 0 if file "$1" exists and is empty, non-0 otherwise.
+
+is_empty()
+{
+ [[ -f "$1" && ! -s "$1" ]]
+}
+
+# Test with a working plugin name.
+bt_cli "${stdout}" "${stderr}" help ctf
+ok $? "help ctf plugin exit status"
+
+grep --silent 'Description: CTF input and output' "${stdout}"
+ok $? "help ctf plugin expected output"
+
+is_empty "${stderr}"
+ok $? "help ctf plugin produces no error"
+
+# Test with a working component class name.
+bt_cli "${stdout}" "${stderr}" help src.ctf.fs
+ok $? "help src.ctf.fs component class exit status"
+
+grep --silent 'Description: Read CTF traces from the file system.' "${stdout}"
+ok $? "help src.ctf.fs component class expected output"
+
+is_empty "${stderr}"
+ok $? "help src.ctf.fs component class produces no error"
+
+# Test without parameter.
+bt_cli "${stdout}" "${stderr}" help
+isnt $? 0 "help without parameter exit status"
+
+grep --silent "Missing plugin name or component class descriptor." "${stderr}"
+ok $? "help without parameter produces expected error"
+
+is_empty "${stdout}"
+ok $? "help without parameter produces no output"
+
+# Test with too many parameters.
+bt_cli "${stdout}" "${stderr}" help ctf fs
+isnt $? 0 "help with too many parameters exit status"
+
+grep --silent "Extraneous command-line argument specified to \`help\` command:" "${stderr}"
+ok $? "help with too many parameters produces expected error"
+
+is_empty "${stdout}"
+ok $? "help with too many parameters produces no output"
+
+# Test with unknown plugin name.
+bt_cli "${stdout}" "${stderr}" help zigotos
+isnt $? 0 "help with unknown plugin name"
+
+grep --silent 'Cannot find plugin: plugin-name="zigotos"' "${stderr}"
+ok $? "help with unknown plugin name produces expected error"
+
+is_empty "${stdout}"
+ok $? "help with unknown plugin name produces no output"
+
+# Test with unknown component class name (but known plugin).
+bt_cli "${stdout}" "${stderr}" help src.ctf.bob
+isnt $? 0 "help with unknown component class name"
+
+grep --silent 'Cannot find component class: plugin-name="ctf", comp-cls-name="bob", comp-cls-type=0' "${stderr}"
+ok $? "help with unknown component class name produces expected error"
+
+grep --silent 'Description: CTF input and output' "${stdout}"
+ok $? "help with unknown component class name prints plugin help"
+
+# Test with unknown component class plugin
+bt_cli "${stdout}" "${stderr}" help src.bob.fs
+isnt $? 0 "help with unknown component class plugin"
+
+grep --silent 'Cannot find plugin: plugin-name="bob"' "${stderr}"
+ok $? "help with unknown component class plugin produces expected error"
+
+is_empty "${stdout}"
+ok $? "help with unknown component class plugin produces no output"