Пример #1
0
command_trie_match_type_t
cli_context_complete_command (cli_context_t *ctx, gchar ***argv, gint *argc,
                            command_action_t **action, GList **suffixes)
{
	gboolean auto_complete = configuration_get_boolean (ctx->config, "AUTO_UNIQUE_COMPLETE");
	return command_trie_find (ctx->commands, argv, argc, auto_complete, action, suffixes);
}
Пример #2
0
/* Given a command trie, look up the action that matches the input
 * passed as an array of input strings (typically argv).  The input
 * array and number of items in the array (num) are passed as
 * pointers, such that they are updated to the position of the
 * matched action.
 * The matching action (if any) is stored in the action pointer, and
 * the state of the matching is returned by the function:
 * NONE    - command mismatch
 * ACTION  - matched an action, arguments might remain in input
 * SUBTRIE - matched a "parent command", with available subcommands
 *
 * If auto_complete is TRUE, unambiguous prefixes of commands are
 * automatically matched.
 *
 * If completions is not NULL, a list of possible completions is
 * stored in it.
 */
command_trie_match_type_t
command_trie_find (command_trie_t *trie, gchar ***input, gint *num,
                   gboolean auto_complete, command_action_t **action,
                   GList **completions)
{
	command_trie_t *node;
	command_trie_match_type_t retval = COMMAND_TRIE_MATCH_NONE;

	if ((node = command_trie_find_node (trie, **input, auto_complete, completions))) {
		(*input) ++;
		(*num) --;
		if (node->match.type == COMMAND_TRIE_MATCH_ACTION) {
			*action = node->match.action;
			retval = COMMAND_TRIE_MATCH_ACTION;
		} else if (node->match.type == COMMAND_TRIE_MATCH_SUBTRIE) {
			if (*num == 0) {
				*action = node->match.action;
				retval = COMMAND_TRIE_MATCH_SUBTRIE;
			} else {
				retval = command_trie_find (node->match.subtrie, input, num,
				                            auto_complete, action, completions);
			}
		}
	}

	return retval;
}
Пример #3
0
void
command_dispatch (cli_infos_t *infos, gint in_argc, gchar **in_argv)
{
	command_action_t *action;
	command_trie_match_type_t match;
	gint argc;
	gchar **argv;

	gboolean auto_complete;

	/* The arguments will be updated by command_trie_find. */
	argc = in_argc;
	argv = in_argv;
	auto_complete = configuration_get_boolean (infos->config,
	                                           "AUTO_UNIQUE_COMPLETE");
	match = command_trie_find (infos->commands, &argv, &argc,
	                            auto_complete, &action);

	if (match == COMMAND_TRIE_MATCH_ACTION) {

		gboolean help;
		gboolean need_io;
		command_context_t *ctx;

		/* Include one command token as a workaround for the bug that
		 * the option parser does not parse commands starting with a
		 * flag properly (e.g. "-p foo arg1"). Will be skipped by the
		 * command utils. */
		ctx = init_context_from_args (action->argdefs, argc + 1, argv - 1);
		ctx->name = g_strdup (action->name);

		if (command_flag_boolean_get (ctx, "help", &help) && help) {
			/* Help flag passed, bypass action and show help */
			/* FIXME(g): select aliasnames list if it's an alias */
			help_command (infos, infos->cmdnames, in_argv, in_argc, CMD_TYPE_COMMAND);
		} else if (command_runnable (infos, action)) {
			/* All fine, run the command */
			cli_infos_loop_suspend (infos);
			need_io = action->callback (infos, ctx);
			if (!need_io) {
				cli_infos_loop_resume (infos);
			}
		}

		command_context_free (ctx);
	} else {
		/* Call help to print the "no such command" error */
		help_command (infos, infos->cmdnames, in_argv, in_argc, CMD_TYPE_COMMAND);
	}
}