struct command *register_command(struct command_context *context, struct command *parent, const struct command_registration *cr) { if (!context || !cr->name) return NULL; const char *name = cr->name; struct command **head = command_list_for_parent(context, parent); struct command *c = command_find(*head, name); if (NULL != c) { /* TODO: originally we treated attempting to register a cmd twice as an error * Sometimes we need this behaviour, such as with flash banks. * http://www.mail-archive.com/[email protected]/msg11152.html */ LOG_DEBUG("command '%s' is already registered in '%s' context", name, parent ? parent->name : "<global>"); return c; } c = command_new(context, parent, cr); if (NULL == c) return NULL; int retval = ERROR_OK; if (NULL != cr->jim_handler && NULL == parent) { retval = Jim_CreateCommand(context->interp, cr->name, cr->jim_handler, cr->jim_handler_data, NULL); } else if (NULL != cr->handler || NULL != parent) retval = register_command_handler(context, command_root(c)); if (ERROR_OK != retval) { unregister_command(context, parent, name); c = NULL; } return c; }
static struct command *command_new(struct command_context *cmd_ctx, struct command *parent, const struct command_registration *cr) { assert(cr->name); struct command *c = calloc(1, sizeof(struct command)); if (NULL == c) return NULL; c->name = strdup(cr->name); if (cr->help) c->help = strdup(cr->help); if (cr->usage) c->usage = strdup(cr->usage); if (!c->name || (cr->help && !c->help) || (cr->usage && !c->usage)) goto command_new_error; c->parent = parent; c->handler = cr->handler; c->jim_handler = cr->jim_handler; c->jim_handler_data = cr->jim_handler_data; c->mode = cr->mode; command_add_child(command_list_for_parent(cmd_ctx, parent), c); return c; command_new_error: command_free(c); return NULL; }
int unregister_all_commands(struct command_context *context, struct command *parent) { if (context == NULL) return ERROR_OK; struct command **head = command_list_for_parent(context, parent); while (NULL != *head) { struct command *tmp = *head; *head = tmp->next; command_free(tmp); } return ERROR_OK; }
static struct command *command_new(struct command_context *cmd_ctx, struct command *parent, const struct command_registration *cr) { assert(cr->name); /* * If it is a non-jim command with no .usage specified, * log an error. * * strlen(.usage) == 0 means that the command takes no * arguments. */ if ((cr->jim_handler == NULL) && (cr->usage == NULL)) { LOG_DEBUG("BUG: command '%s%s%s' does not have the " "'.usage' field filled out", parent && parent->name ? parent->name : "", parent && parent->name ? " " : "", cr->name); } struct command *c = calloc(1, sizeof(struct command)); if (NULL == c) return NULL; c->name = strdup(cr->name); if (cr->help) c->help = strdup(cr->help); if (cr->usage) c->usage = strdup(cr->usage); if (!c->name || (cr->help && !c->help) || (cr->usage && !c->usage)) goto command_new_error; c->parent = parent; c->handler = cr->handler; c->jim_handler = cr->jim_handler; c->jim_handler_data = cr->jim_handler_data; c->mode = cr->mode; command_add_child(command_list_for_parent(cmd_ctx, parent), c); return c; command_new_error: command_free(c); return NULL; }
int unregister_command(struct command_context *context, struct command *parent, const char *name) { if ((!context) || (!name)) return ERROR_COMMAND_SYNTAX_ERROR; struct command *p = NULL; struct command **head = command_list_for_parent(context, parent); for (struct command *c = *head; NULL != c; p = c, c = c->next) { if (strcmp(name, c->name) != 0) continue; if (p) p->next = c->next; else *head = c->next; command_free(c); return ERROR_OK; } return ERROR_OK; }