void help_command (cli_context_t *ctx, GList *cmdnames, gchar **cmd, gint num_args, cmd_type_t cmdtype) { command_action_t *action; command_trie_match_type_t match; gint i, k; gint padding, max_flag_len = 0; match = cli_context_find_command (ctx, &cmd, &num_args, &action); if (match == COMMAND_TRIE_MATCH_ACTION) { g_printf (_("usage: %s"), action->name); if (action->usage) { g_printf (" %s", action->usage); } g_printf ("\n\n"); print_indented (action->description, COMMAND_HELP_DESCRIPTION_INDENT); g_printf ("\n\n"); if (action->argdefs && action->argdefs[0].long_name) { /* Find length of longest option */ for (i = 0; action->argdefs[i].long_name; ++i) { if (max_flag_len < strlen (action->argdefs[i].long_name)) { max_flag_len = strlen (action->argdefs[i].long_name); } } g_printf (_("Valid options:\n")); for (i = 0; action->argdefs[i].long_name; ++i) { padding = max_flag_len - strlen (action->argdefs[i].long_name) + 2; if (action->argdefs[i].short_name) { g_printf (" -%c, ", action->argdefs[i].short_name); } else { g_printf (" "); } g_printf ("--%s", action->argdefs[i].long_name); for (k = 0; k < padding; ++k) { g_printf (" "); } g_printf ("%s\n", action->argdefs[i].description); /* FIXME: align multi-line */ } } } else if (match == COMMAND_TRIE_MATCH_SUBTRIE) { help_list (cmdnames, action->name, cmdtype); } else { /* FIXME: Better handle help for subcommands! */ g_printf (_("Unknown command: '")); for (i = 0; i < num_args; ++i) { if (i > 0) g_printf (" "); g_printf ("%s", cmd[i]); } g_printf (_("'\n")); g_printf (_("Type 'help' for the list of commands.\n")); } }
static void cli_context_command_dispatch (cli_context_t *ctx, gint in_argc, gchar **in_argv) { command_action_t *action; command_trie_match_type_t match; gint argc; gchar *tmp_argv[in_argc+1]; gchar **argv; /* The arguments will be updated by command_trie_find and * init_context_from_args, so we make a copy. */ memcpy (tmp_argv, in_argv, in_argc * sizeof (gchar *)); tmp_argv[in_argc] = NULL; argc = in_argc; argv = tmp_argv; /* This updates argv and argc so that they start at the first non-command * token. */ match = cli_context_find_command (ctx, &argv, &argc, &action); if (match == COMMAND_TRIE_MATCH_ACTION) { gboolean help; gboolean need_io; command_t *cmd; /* 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. */ cmd = command_new (action->argdefs, argc + 1, argv - 1); if (cmd) { if (command_flag_boolean_get (cmd, "help", &help) && help) { /* Help flag passed, bypass action and show help */ /* FIXME(g): select aliasnames list if it's an alias */ help_command (ctx, cli_context_command_names (ctx), in_argv, in_argc, CMD_TYPE_COMMAND); } else if (cli_context_command_runnable (ctx, action)) { /* All fine, run the command */ command_name_set (cmd, action->name); cli_context_loop_suspend (ctx); need_io = action->callback (ctx, cmd); if (!need_io) { cli_context_loop_resume (ctx); } } command_free (cmd); } } else { /* Call help to print the "no such command" error */ help_command (ctx, cli_context_command_names (ctx), in_argv, in_argc, CMD_TYPE_COMMAND); } }