libpurple/cmds.c

changeset 40884
ca31392953ed
parent 40564
2c5b4dc2e86a
child 41685
ca22b00972d4
--- a/libpurple/cmds.c	Sun May 16 12:29:20 2021 -0500
+++ b/libpurple/cmds.c	Mon May 17 20:32:56 2021 -0500
@@ -41,11 +41,7 @@
 
 static gint cmds_compare_func(const PurpleCmd *a, const PurpleCmd *b)
 {
-	if (a->priority > b->priority)
-		return -1;
-	else if (a->priority < b->priority)
-		return 1;
-	else return 0;
+	return b->priority - a->priority;
 }
 
 PurpleCmdId purple_cmd_register(const gchar *cmd, const gchar *args,
@@ -94,25 +90,33 @@
 	g_free(c);
 }
 
+static gint
+purple_cmd_cmp_id(gconstpointer cmd, gconstpointer id)
+{
+	return ((PurpleCmd *)cmd)->id - GPOINTER_TO_UINT(id);
+}
+
 void purple_cmd_unregister(PurpleCmdId id)
 {
 	PurpleCmd *c;
 	GList *l;
+	PurpleCommandsUiOps *ops;
 
-	for (l = cmds; l; l = l->next) {
-		c = l->data;
+	l = g_list_find_custom(cmds, GUINT_TO_POINTER(id), purple_cmd_cmp_id);
+	if (!l) {
+		return;
+	}
+
+	c = l->data;
 
-		if (c->id == id) {
-			PurpleCommandsUiOps *ops = purple_cmds_get_ui_ops();
-			if (ops && ops->unregister_command)
-				ops->unregister_command(c->cmd, c->protocol_id);
+	ops = purple_cmds_get_ui_ops();
+	if (ops && ops->unregister_command) {
+		ops->unregister_command(c->cmd, c->protocol_id);
+	}
 
-			cmds = g_list_delete_link(cmds, l);
-			purple_signal_emit(purple_cmds_get_handle(), "cmd-removed", c->cmd);
-			purple_cmd_free(c);
-			return;
-		}
-	}
+	cmds = g_list_delete_link(cmds, l);
+	purple_signal_emit(purple_cmds_get_handle(), "cmd-removed", c->cmd);
+	purple_cmd_free(c);
 }
 
 /*
@@ -201,24 +205,31 @@
 	}
 }
 
+static gboolean
+is_right_type(PurpleCmd *cmd, PurpleConversation *conv)
+{
+	return (PURPLE_IS_IM_CONVERSATION(conv) && (cmd->flags & PURPLE_CMD_FLAG_IM))
+	    || (PURPLE_IS_CHAT_CONVERSATION(conv) && (cmd->flags & PURPLE_CMD_FLAG_CHAT));
+}
+
+static gboolean
+is_right_protocol(PurpleCmd *cmd, PurpleConversation *conv)
+{
+	const gchar *protocol_id = purple_account_get_protocol_id(purple_conversation_get_account(conv));
+
+	return !(cmd->flags & PURPLE_CMD_FLAG_PROTOCOL_ONLY)
+	    || purple_strequal(cmd->protocol_id, protocol_id);
+}
+
 PurpleCmdStatus purple_cmd_do_command(PurpleConversation *conv, const gchar *cmdline,
                                   const gchar *markup, gchar **error)
 {
-	PurpleCmd *c;
-	GList *l;
 	gchar *err = NULL;
-	gboolean is_im = TRUE;
 	gboolean found = FALSE, tried_cmd = FALSE, right_type = FALSE, right_protocol = FALSE;
-	const gchar *protocol_id;
-	gchar **args = NULL;
 	gchar *cmd, *rest, *mrest;
 	PurpleCmdRet ret = PURPLE_CMD_RET_CONTINUE;
 
 	*error = NULL;
-	protocol_id = purple_account_get_protocol_id(purple_conversation_get_account(conv));
-
-	if (PURPLE_IS_CHAT_CONVERSATION(conv))
-		is_im = FALSE;
 
 	rest = strchr(cmdline, ' ');
 	if (rest) {
@@ -232,51 +243,45 @@
 	mrest = g_strdup(markup);
 	purple_cmd_strip_cmd_from_markup(mrest);
 
-	for (l = cmds; l; l = l->next) {
-		c = l->data;
+	for (GList *l = cmds; l; l = l->next) {
+		PurpleCmd *c = l->data;
+		gchar **args = NULL;
 
 		if (!purple_strequal(c->cmd, cmd))
 			continue;
 
 		found = TRUE;
 
-		if (is_im)
-			if (!(c->flags & PURPLE_CMD_FLAG_IM))
-				continue;
-		if (!is_im)
-			if (!(c->flags & PURPLE_CMD_FLAG_CHAT))
-				continue;
+		if (!is_right_type(c, conv)) {
+			continue;
+		}
 
 		right_type = TRUE;
 
-		if ((c->flags & PURPLE_CMD_FLAG_PROTOCOL_ONLY) &&
-		    !purple_strequal(c->protocol_id, protocol_id))
+		if (!is_right_protocol(c, conv)) {
 			continue;
+		}
 
 		right_protocol = TRUE;
 
 		/* this checks the allow bad args flag for us */
 		if (!purple_cmd_parse_args(c, rest, mrest, &args)) {
 			g_strfreev(args);
-			args = NULL;
 			continue;
 		}
 
 		tried_cmd = TRUE;
 		ret = c->func(conv, cmd, args, &err, c->data);
+		g_strfreev(args);
 		if (ret == PURPLE_CMD_RET_CONTINUE) {
 			g_free(err);
 			err = NULL;
-			g_strfreev(args);
-			args = NULL;
 			continue;
-		} else {
-			break;
 		}
 
+		break;
 	}
 
-	g_strfreev(args);
 	g_free(cmd);
 	g_free(mrest);
 
@@ -290,9 +295,7 @@
 	if (!tried_cmd)
 		return PURPLE_CMD_STATUS_WRONG_ARGS;
 
-	if (ret == PURPLE_CMD_RET_OK) {
-		return PURPLE_CMD_STATUS_OK;
-	} else {
+	if (ret != PURPLE_CMD_RET_OK) {
 		*error = err;
 		if (ret == PURPLE_CMD_RET_CONTINUE)
 			return PURPLE_CMD_STATUS_NOT_FOUND;
@@ -300,6 +303,7 @@
 			return PURPLE_CMD_STATUS_FAILED;
 	}
 
+	return PURPLE_CMD_STATUS_OK;
 }
 
 gboolean purple_cmd_execute(PurpleCmdId id, PurpleConversation *conv,
@@ -311,28 +315,16 @@
 	gchar *err = NULL;
 	gchar **args = NULL;
 
-	for(l = cmds; l; l = l->next) {
-		cmd = (PurpleCmd*)l->data;
-
-		if(cmd->id == id) {
-			break;
-		}
-		cmd = NULL;
-	}
-	if(cmd == NULL) {
+	l = g_list_find_custom(cmds, GUINT_TO_POINTER(id), purple_cmd_cmp_id);
+	if (!l) {
 		return FALSE;
 	}
 
-	if (PURPLE_IS_IM_CONVERSATION(conv)) {
-		if (!(cmd->flags & PURPLE_CMD_FLAG_IM))
-			return FALSE;
+	cmd = l->data;
+
+	if (!is_right_type(cmd, conv)) {
+		return FALSE;
 	}
-	else if (PURPLE_IS_CHAT_CONVERSATION(conv)) {
-		if (!(cmd->flags & PURPLE_CMD_FLAG_CHAT))
-			return FALSE;
-	}
-	else
-		return FALSE;
 
 	/* XXX: Don't worry much about the markup version of the command
 	   line, there's not a single use case... */
@@ -353,22 +345,13 @@
 GList *purple_cmd_list(PurpleConversation *conv)
 {
 	GList *ret = NULL;
-	PurpleCmd *c;
-	GList *l;
 
-	for (l = cmds; l; l = l->next) {
-		c = l->data;
+	for (GList *l = cmds; l; l = l->next) {
+		PurpleCmd *c = l->data;
 
-		if (conv && PURPLE_IS_IM_CONVERSATION(conv))
-			if (!(c->flags & PURPLE_CMD_FLAG_IM))
-				continue;
-		if (conv && PURPLE_IS_CHAT_CONVERSATION(conv))
-			if (!(c->flags & PURPLE_CMD_FLAG_CHAT))
-				continue;
-
-		if (conv && (c->flags & PURPLE_CMD_FLAG_PROTOCOL_ONLY) &&
-		    !purple_strequal(c->protocol_id, purple_account_get_protocol_id(purple_conversation_get_account(conv))))
+		if (conv && (!is_right_type(c, conv) || !is_right_protocol(c, conv))) {
 			continue;
+		}
 
 		ret = g_list_append(ret, c->cmd);
 	}
@@ -382,25 +365,16 @@
 GList *purple_cmd_help(PurpleConversation *conv, const gchar *cmd)
 {
 	GList *ret = NULL;
-	PurpleCmd *c;
-	GList *l;
 
-	for (l = cmds; l; l = l->next) {
-		c = l->data;
+	for (GList *l = cmds; l; l = l->next) {
+		PurpleCmd *c = l->data;
 
 		if (cmd && !purple_strequal(cmd, c->cmd))
 			continue;
 
-		if (conv && PURPLE_IS_IM_CONVERSATION(conv))
-			if (!(c->flags & PURPLE_CMD_FLAG_IM))
-				continue;
-		if (conv && PURPLE_IS_CHAT_CONVERSATION(conv))
-			if (!(c->flags & PURPLE_CMD_FLAG_CHAT))
-				continue;
-
-		if (conv && (c->flags & PURPLE_CMD_FLAG_PROTOCOL_ONLY) &&
-		    !purple_strequal(c->protocol_id, purple_account_get_protocol_id(purple_conversation_get_account(conv))))
+		if (conv && (!is_right_type(c, conv) || !is_right_protocol(c, conv))) {
 			continue;
+		}
 
 		ret = g_list_append(ret, c->help);
 	}

mercurial