+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;
+}
+
+static int command_unknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
+
+static int register_command_handler(struct command_context *cmd_ctx,
+ struct command *c)