From 158698e3331b446243b863ab8b58ebee2c56f0cc Mon Sep 17 00:00:00 2001
From: Zachary T Welch <zw@superlucidity.net>
Date: Wed, 11 Nov 2009 10:20:55 -0800
Subject: improve command registration

Eliminate duplicate code for linking commands into a list.

Adds a check to ensure the command does not already exist;
if it does, return that one instead of creating a duplicate.
---
 src/helper/command.c | 74 ++++++++++++++++++++++++++++++----------------------
 1 file changed, 43 insertions(+), 31 deletions(-)

(limited to 'src/helper')

diff --git a/src/helper/command.c b/src/helper/command.c
index 5ac5c301..f960127d 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -191,13 +191,53 @@ static void command_helptext_add(Jim_Obj *cmd_list, const char *help)
 /* nice short description of source file */
 #define __THIS__FILE__ "command.c"
 
-command_t* register_command(command_context_t *context, command_t *parent, char *name, int (*handler)(struct command_context_s *context, char* name, char** args, int argc), enum command_mode mode, char *help)
+/**
+ * Find a command by name from a list of commands.
+ * @returns The named command if found, or NULL.
+ */
+static struct command_s *command_find(struct command_s **head, const char *name)
+{
+	assert(head);
+	for (struct command_s *cc = *head; cc; cc = cc->next)
+	{
+		if (strcmp(cc->name, name) == 0)
+			return cc;
+	}
+	return NULL;
+}
+
+/**
+ * Add the command to the end of linked list.
+ * @returns Returns false if the named command already exists in the list.
+ * Returns true otherwise.
+ */
+static void command_add_child(struct command_s **head, struct command_s *c)
 {
-	command_t *c, *p;
+	assert(head);
+	if (NULL == *head)
+	{
+		*head = c;
+		return;
+	}
+	struct command_s *cc = *head;
+	while (cc->next) cc = cc->next;
+	cc->next = c;
+}
 
+command_t* register_command(command_context_t *context,
+		command_t *parent, char *name,
+		int (*handler)(struct command_context_s *context,
+				char* name, char** args, int argc),
+		enum command_mode mode, char *help)
+{
 	if (!context || !name)
 		return NULL;
 
+	struct command_s **head = parent ? &parent->children : &context->commands;
+	struct command_s *c = command_find(head, name);
+	if (NULL != c)
+		return c;
+
 	c = malloc(sizeof(command_t));
 
 	c->name = strdup(name);
@@ -207,35 +247,7 @@ command_t* register_command(command_context_t *context, command_t *parent, char
 	c->mode = mode;
 	c->next = NULL;
 
-	/* place command in tree */
-	if (parent)
-	{
-		if (parent->children)
-		{
-			/* find last child */
-			for (p = parent->children; p && p->next; p = p->next);
-			if (p)
-				p->next = c;
-		}
-		else
-		{
-			parent->children = c;
-		}
-	}
-	else
-	{
-		if (context->commands)
-		{
-			/* find last command */
-			for (p = context->commands; p && p->next; p = p->next);
-			if (p)
-				p->next = c;
-		}
-		else
-		{
-			context->commands = c;
-		}
-	}
+	command_add_child(head, c);
 
 	command_helptext_add(command_name_list(c), help);
 
-- 
cgit v1.2.3