/soc/2013/ankitkv/gobjectification: c61b6dbc1f03: Make protocols...

Ankit Vani a at nevitus.org
Tue Sep 3 14:55:13 EDT 2013


Changeset: c61b6dbc1f03e3b11c4bfdb0f27e59ffd8e1fd2f
Author:	 Ankit Vani <a at nevitus.org>
Date:	 2013-09-04 00:25 +0530
Branch:	 soc.2013.gobjectification.plugins
URL: https://hg.pidgin.im/soc/2013/ankitkv/gobjectification/rev/c61b6dbc1f03

Description:

Make protocols unregister their commands when being removed

diffstat:

 libpurple/protocols/irc/irc.c           |    7 +-
 libpurple/protocols/irc/irc.h           |    1 +
 libpurple/protocols/irc/parse.c         |   15 +++-
 libpurple/protocols/msn/msn.c           |   11 ++-
 libpurple/protocols/null/nullprotocol.c |   29 ++++++-
 libpurple/protocols/silc/silc.c         |  132 ++++++++++++++++++++++++-------
 libpurple/protocols/yahoo/libyahoo.c    |   31 ++++++-
 libpurple/protocols/yahoo/libyahoojp.c  |   38 +++++++-
 libpurple/protocols/zephyr/zephyr.c     |   83 +++++++++++++-------
 9 files changed, 267 insertions(+), 80 deletions(-)

diffs (truncated from 787 to 300 lines):

diff --git a/libpurple/protocols/irc/irc.c b/libpurple/protocols/irc/irc.c
--- a/libpurple/protocols/irc/irc.c
+++ b/libpurple/protocols/irc/irc.c
@@ -977,6 +977,11 @@ irc_protocol_base_init(IRCProtocolClass 
 	irc_register_commands();
 }
 
+static void irc_protocol_base_finalize(IRCProtocolClass *klass)
+{
+	irc_unregister_commands();
+}
+
 static void
 irc_protocol_interface_init(PurpleProtocolInterface *iface)
 {
@@ -1008,8 +1013,6 @@ irc_protocol_interface_init(PurpleProtoc
 	iface->get_max_message_size = irc_get_max_message_size;
 }
 
-static void irc_protocol_base_finalize(IRCProtocolClass *klass) { }
-
 static PurplePluginInfo *
 plugin_query(GError **error)
 {
diff --git a/libpurple/protocols/irc/irc.h b/libpurple/protocols/irc/irc.h
--- a/libpurple/protocols/irc/irc.h
+++ b/libpurple/protocols/irc/irc.h
@@ -150,6 +150,7 @@ const char *irc_nick_skip_mode(struct ir
 gboolean irc_ischannel(const char *string);
 
 void irc_register_commands(void);
+void irc_unregister_commands(void);
 void irc_msg_table_build(struct irc_conn *irc);
 void irc_parse_msg(struct irc_conn *irc, char *input);
 char *irc_parse_ctcp(struct irc_conn *irc, const char *from, const char *to, const char *msg, int notice);
diff --git a/libpurple/protocols/irc/parse.c b/libpurple/protocols/irc/parse.c
--- a/libpurple/protocols/irc/parse.c
+++ b/libpurple/protocols/irc/parse.c
@@ -34,6 +34,8 @@
 #include <stdlib.h>
 #include <ctype.h>
 
+static GSList *cmds = NULL;
+
 static char *irc_send_convert(struct irc_conn *irc, const char *string);
 static char *irc_recv_convert(struct irc_conn *irc, const char *string);
 
@@ -195,6 +197,7 @@ static PurpleCmdRet irc_parse_purple_cmd
 
 static void irc_register_command(struct _irc_user_cmd *c)
 {
+	PurpleCmdId id;
 	PurpleCmdFlag f;
 	char args[10];
 	char *format;
@@ -221,8 +224,9 @@ static void irc_register_command(struct 
 
 	args[i] = '\0';
 
-	purple_cmd_register(c->name, args, PURPLE_CMD_P_PROTOCOL, f, "irc",
+	id = purple_cmd_register(c->name, args, PURPLE_CMD_P_PROTOCOL, f, "irc",
 	                  irc_parse_purple_cmd, _(c->help), NULL);
+	cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
 }
 
 void irc_register_commands(void)
@@ -233,6 +237,15 @@ void irc_register_commands(void)
 		irc_register_command(c);
 }
 
+void irc_unregister_commands(void)
+{
+	while (cmds) {
+		PurpleCmdId id = GPOINTER_TO_UINT(cmds->data);
+		purple_cmd_unregister(id);
+		cmds = g_slist_delete_link(cmds, cmds);
+	}
+}
+
 static char *irc_send_convert(struct irc_conn *irc, const char *string)
 {
 	char *utf8;
diff --git a/libpurple/protocols/msn/msn.c b/libpurple/protocols/msn/msn.c
--- a/libpurple/protocols/msn/msn.c
+++ b/libpurple/protocols/msn/msn.c
@@ -97,6 +97,7 @@ typedef struct
 } MsnEmoticon;
 
 static PurpleProtocol *my_protocol = NULL;
+static GSList *cmds = NULL;
 
 static const char *
 msn_normalize(const PurpleAccount *account, const char *str)
@@ -2879,6 +2880,7 @@ msn_protocol_base_init(MsnProtocolClass 
 {
 	PurpleProtocolClass *proto_class = PURPLE_PROTOCOL_CLASS(klass);
 	PurpleAccountOption *option;
+	PurpleCmdId id;
 
 	proto_class->id        = "msn";
 	proto_class->name      = "MSN";
@@ -2921,10 +2923,11 @@ msn_protocol_base_init(MsnProtocolClass 
 	proto_class->protocol_options = g_list_append(proto_class->protocol_options,
 											   option);
 
-	purple_cmd_register("nudge", "", PURPLE_CMD_P_PROTOCOL,
+	id = purple_cmd_register("nudge", "", PURPLE_CMD_P_PROTOCOL,
 	                  PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_PROTOCOL_ONLY,
 	                 "msn", msn_cmd_nudge,
 	                  _("nudge: nudge a user to get their attention"), NULL);
+	cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
 
 	purple_prefs_remove("/protocols/msn");
 
@@ -2935,6 +2938,12 @@ msn_protocol_base_init(MsnProtocolClass 
 static void
 msn_protocol_base_finalize(MsnProtocolClass *klass)
 {
+	while (cmds) {
+		PurpleCmdId id = GPOINTER_TO_UINT(cmds->data);
+		purple_cmd_unregister(id);
+		cmds = g_slist_delete_link(cmds, cmds);
+	}
+
 	msn_notification_end();
 	msn_switchboard_end();
 }
diff --git a/libpurple/protocols/null/nullprotocol.c b/libpurple/protocols/null/nullprotocol.c
--- a/libpurple/protocols/null/nullprotocol.c
+++ b/libpurple/protocols/null/nullprotocol.c
@@ -68,8 +68,19 @@
 #include "util.h"
 #include "version.h"
 
+/*
+ * reference to the protocol instance, used for registering signals, prefs,
+ * etc. it is set when the protocol is added in plugin_load and is required
+ * for removing the protocol in plugin_unload.
+ */
 static PurpleProtocol *my_protocol = NULL;
 
+/*
+ * list of commands registered by the protocol, used to unregister the commands
+ * when the protocol is removed.
+ */
+static GSList *cmds = NULL;
+
 #define NULL_STATUS_ONLINE   "online"
 #define NULL_STATUS_AWAY     "away"
 #define NULL_STATUS_OFFLINE  "offline"
@@ -86,7 +97,8 @@ typedef struct {
 
 /*
  * stores offline messages that haven't been delivered yet. maps username
- * (char *) to GList * of GOfflineMessages. initialized in plugin_load.
+ * (char *) to GList * of GOfflineMessages. initialized in
+ * null_protocol_base_init.
  */
 GHashTable* goffline_messages = NULL;
 
@@ -1057,6 +1069,7 @@ null_protocol_base_init(NullProtocolClas
   PurpleProtocolClass *proto_class = PURPLE_PROTOCOL_CLASS(klass);
   PurpleAccountUserSplit *split;
   PurpleAccountOption *option;
+  PurpleCmdId id;
 
   proto_class->id        = "null";
   proto_class->name      = "Null - Testing Protocol";
@@ -1068,7 +1081,7 @@ null_protocol_base_init(NullProtocolClas
       128,                             /* max_width */
       128,                             /* max_height */
       10000,                           /* max_filesize */
-      PURPLE_ICON_SCALE_DISPLAY,       /* scale_rules */
+      PURPLE_ICON_SCALE_DISPLAY        /* scale_rules */
   );
 
   /* see accountopt.h for information about user splits and protocol options */
@@ -1087,7 +1100,7 @@ null_protocol_base_init(NullProtocolClas
   proto_class->protocol_options = g_list_append(NULL, option);
 
   /* register whisper chat command, /msg */
-  purple_cmd_register("msg",
+  id = purple_cmd_register("msg",
                     "ws",                  /* args: recipient and message */
                     PURPLE_CMD_P_DEFAULT,  /* priority */
                     PURPLE_CMD_FLAG_CHAT,
@@ -1096,6 +1109,9 @@ null_protocol_base_init(NullProtocolClas
                     "msg <username> <message>: send a private message, aka a whisper",
                     NULL);                 /* userdata */
 
+  /* add /msg command to the commands list */
+  cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
+
   /* get ready to store offline messages */
   goffline_messages = g_hash_table_new_full(g_str_hash,  /* hash fn */
                                             g_str_equal, /* key comparison fn */
@@ -1107,6 +1123,13 @@ static void
 null_protocol_base_finalize(NullProtocolClass *klass)
 {
   purple_debug_info("nullprotocol", "shutting down\n");
+
+  /* unregister the commands */
+  while (cmds) {
+    PurpleCmdId id = GPOINTER_TO_UINT(cmds->data);
+    purple_cmd_unregister(id);
+    cmds = g_slist_delete_link(cmds, cmds);
+  }
 }
 
 /*
diff --git a/libpurple/protocols/silc/silc.c b/libpurple/protocols/silc/silc.c
--- a/libpurple/protocols/silc/silc.c
+++ b/libpurple/protocols/silc/silc.c
@@ -27,7 +27,9 @@
 #include "core.h"
 
 extern SilcClientOperations ops;
+
 static PurpleProtocol *my_protocol = NULL;
+static GSList *cmds = NULL;
 
 /* Error log message callback */
 
@@ -1915,125 +1917,192 @@ static PurpleCmdRet silcpurple_cmd_call(
 static void
 silcpurple_register_commands(void)
 {
-	purple_cmd_register("part", "w", PURPLE_CMD_P_PROTOCOL,
+	PurpleCmdId id;
+
+	id = purple_cmd_register("part", "w", PURPLE_CMD_P_PROTOCOL,
 			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT |
 			PURPLE_CMD_FLAG_PROTOCOL_ONLY | PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS,
 			"silc", silcpurple_cmd_chat_part, _("part [channel]:  Leave the chat"), NULL);
-	purple_cmd_register("leave", "w", PURPLE_CMD_P_PROTOCOL,
+	cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
+
+	id = purple_cmd_register("leave", "w", PURPLE_CMD_P_PROTOCOL,
 			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT |
 			PURPLE_CMD_FLAG_PROTOCOL_ONLY | PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS,
 			"silc", silcpurple_cmd_chat_part, _("leave [channel]:  Leave the chat"), NULL);
-	purple_cmd_register("topic", "s", PURPLE_CMD_P_PROTOCOL,
+	cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
+
+	id = purple_cmd_register("topic", "s", PURPLE_CMD_P_PROTOCOL,
 			PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PROTOCOL_ONLY |
 			PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "silc",
 			silcpurple_cmd_chat_topic, _("topic [<new topic>]:  View or change the topic"), NULL);
-	purple_cmd_register("join", "ws", PURPLE_CMD_P_PROTOCOL,
+	cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
+
+	id = purple_cmd_register("join", "ws", PURPLE_CMD_P_PROTOCOL,
 			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT |
 			PURPLE_CMD_FLAG_PROTOCOL_ONLY | PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS,
 			"silc", silcpurple_cmd_chat_join,
 			_("join <channel> [<password>]:  Join a chat on this network"), NULL);
-	purple_cmd_register("list", "", PURPLE_CMD_P_PROTOCOL,
+	cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
+
+	id = purple_cmd_register("list", "", PURPLE_CMD_P_PROTOCOL,
 			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PROTOCOL_ONLY |
 			PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "silc",
 			silcpurple_cmd_chat_list, _("list:  List channels on this network"), NULL);
-	purple_cmd_register("whois", "w", PURPLE_CMD_P_PROTOCOL,
+	cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
+
+	id = purple_cmd_register("whois", "w", PURPLE_CMD_P_PROTOCOL,
 			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PROTOCOL_ONLY,
 			"silc",
 			silcpurple_cmd_whois, _("whois <nick>:  View nick's information"), NULL);
-	purple_cmd_register("msg", "ws", PURPLE_CMD_P_PROTOCOL,
+	cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
+
+	id = purple_cmd_register("msg", "ws", PURPLE_CMD_P_PROTOCOL,
 			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PROTOCOL_ONLY,
 			"silc", silcpurple_cmd_msg,
 			_("msg <nick> <message>:  Send a private message to a user"), NULL);
-	purple_cmd_register("query", "ws", PURPLE_CMD_P_PROTOCOL,
+	cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
+
+	id = purple_cmd_register("query", "ws", PURPLE_CMD_P_PROTOCOL,
 			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PROTOCOL_ONLY |
 			PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "silc", silcpurple_cmd_query,
 			_("query <nick> [<message>]:  Send a private message to a user"), NULL);
-	purple_cmd_register("motd", "", PURPLE_CMD_P_PROTOCOL,
+	cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
+
+	id = purple_cmd_register("motd", "", PURPLE_CMD_P_PROTOCOL,
 			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PROTOCOL_ONLY |
 			PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "silc", silcpurple_cmd_motd,
 			_("motd:  View the server's Message Of The Day"), NULL);
-	purple_cmd_register("detach", "", PURPLE_CMD_P_PROTOCOL,
+	cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));
+
+	id = purple_cmd_register("detach", "", PURPLE_CMD_P_PROTOCOL,
 			PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PROTOCOL_ONLY,
 			"silc", silcpurple_cmd_detach,
 			_("detach:  Detach this session"), NULL);
-	purple_cmd_register("quit", "s", PURPLE_CMD_P_PROTOCOL,
+	cmds = g_slist_prepend(cmds, GUINT_TO_POINTER(id));



More information about the Commits mailing list