int fr_command_walk(fr_cmd_t *head, void **walk_ctx, void *ctx, fr_cmd_walk_t callback);
int fr_command_tab_expand(TALLOC_CTX *ctx, fr_cmd_t *head, fr_cmd_info_t *info, int max_expansions, char const **expansions);
char const *fr_command_help(fr_cmd_t *head, int argc, char *argv[]);
-int fr_command_run(FILE *fp, FILE *fp_err, fr_cmd_t *head, fr_cmd_info_t *info);
+int fr_command_run(FILE *fp, FILE *fp_err, fr_cmd_info_t *info);
void fr_command_debug(FILE *fp, fr_cmd_t *head);
void fr_command_list(FILE *fp, int max_depth, fr_cmd_t *head, bool is_head);
int fr_command_str_to_argv(fr_cmd_t *head, fr_cmd_info_t *info, char *str);
*
* @param fp where the output is sent
* @param fp_err where the error output is sent
- * @param head the head of the command hierarchy.
* @param info the structure describing the command to expand
* @return
* - <0 on error
* - 0 the command was run successfully
*/
-int fr_command_run(FILE *fp, FILE *fp_err, fr_cmd_t *head, fr_cmd_info_t *info)
+int fr_command_run(FILE *fp, FILE *fp_err, fr_cmd_info_t *info)
{
- int i;
- fr_cmd_t *cmd, *start;
+ int i, rcode;
+ fr_cmd_t *cmd;
+ fr_cmd_info_t my_info;
- start = head;
+ cmd = NULL;
/*
* Asked to do nothing, do nothing.
if (info->argc == 0) return 0;
for (i = 0; i < info->argc; i++) {
- int rcode;
- fr_cmd_info_t my_info;
-
- cmd = fr_command_find(&start, info->argv[i], NULL);
- if (!cmd) {
- no_such_command:
- if (info->argc == 1) {
- fr_strerror_printf("No such command '%s'", info->argv[i]);
- } else {
- fr_strerror_printf("No such command '... %s'", info->argv[i]);
- }
- return -1;
- }
+ cmd = info->cmd[i];
+ rad_assert(cmd != NULL);
- /*
- * Intermediate nodes must have children, and
- * must not have callbacks.
- */
- if (cmd->intermediate) {
- rad_assert(cmd->child != NULL);
- rad_assert(cmd->func == NULL);
- start = cmd->child;
- continue;
- }
+ if (!cmd->live) return 0;
- if (!cmd->live) goto no_such_command;
+ if (cmd->intermediate) continue;
+ break;
+ }
- /*
- * Leaf nodes must have a callback.
- */
- rad_assert(cmd->func != NULL);
+ if (!cmd) return 0;
- // @todo - add cmd->min_argc && cmd->max_argc, to track optional things, varargs, etc.
+ /*
+ * Leaf nodes must have a callback.
+ */
+ rad_assert(cmd->func != NULL);
- /*
- * The arguments have already been verified by
- * fr_command_str_to_argv().
- */
- my_info.argc = info->argc - i - 1;
- my_info.max_argc = info->max_argc - info->argc;
- my_info.runnable = true;
- my_info.argv = &info->argv[i + 1];
- my_info.box = &info->box[i + 1];
- rcode = cmd->func(fp, fp_err, cmd->ctx, &my_info);
- return rcode;
- }
+ // @todo - add cmd->min_argc && cmd->max_argc, to track optional things, varargs, etc.
- return 0;
+ /*
+ * The arguments have already been verified by
+ * fr_command_str_to_argv().
+ */
+ my_info.argc = info->argc - i - 1;
+ my_info.max_argc = info->max_argc - info->argc;
+ my_info.runnable = true;
+ my_info.argv = &info->argv[i + 1];
+ my_info.box = &info->box[i + 1];
+ rcode = cmd->func(fp, fp_err, cmd->ctx, &my_info);
+ return rcode;
}
/*
* Cache the command for later consumption.
*/
- if (info->cmd) info->cmd[i] = cmd;
+ info->cmd[i] = cmd;
/*
* There's a child. Go match it.