summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorDiogo Sousa <diogogsousa@gmail.com>2013-11-28 00:59:31 +0000
committerDiogo Sousa <diogogsousa@gmail.com>2013-11-28 02:11:33 +0000
commit40f26429f8e3466fb68af30076d1a297c84f5da6 (patch)
treedcbc904de44ff5284d77e53168fc001c342e218d
parentd38bbb1e2c96314dd61faa84f2908b90ae29b987 (diff)
Print{,_attr} and server{,_attr} hooks were incorrectly handled when both
version existed (regular and attrs).  Specifically, the priority was not
respected, and both versions were run even when EAT_PLUGIN was returned.

Fixes #847.
-rw-r--r--src/common/dcc.c3
-rw-r--r--src/common/plugin.c71
-rw-r--r--src/common/plugin.h8
-rw-r--r--src/common/proto-irc.c20
-rw-r--r--src/common/text.c7
5 files changed, 49 insertions, 60 deletions
diff --git a/src/common/dcc.c b/src/common/dcc.c
index 57354ba9..ca1be140 100644
--- a/src/common/dcc.c
+++ b/src/common/dcc.c
@@ -557,8 +557,7 @@ dcc_chat_line (struct DCC *dcc, char *line)
 	for (i = 5; i < PDIWORDS; i++)
 		word[i] = "\000";
 
-	ret = plugin_emit_print (sess, word) 
-		+ plugin_emit_print_attrs (sess, word, 0);
+	ret = plugin_emit_print (sess, word, 0);
 
 	/* did the plugin close it? */
 	if (!g_slist_find (dcc_list, dcc))
diff --git a/src/common/plugin.c b/src/common/plugin.c
index 45746777..ee3b26c8 100644
--- a/src/common/plugin.c
+++ b/src/common/plugin.c
@@ -102,16 +102,21 @@ enum
 	LIST_USERS
 };
 
+/* We use binary flags here because it makes it possible for plugin_hook_find()
+ * to match several types of hooks.  This is used so that plugin_hook_run()
+ * match both HOOK_SERVER and HOOK_SERVER_ATTRS hooks when plugin_emit_server()
+ * is called.
+ */
 enum
 {
-	HOOK_COMMAND,      /* /command */
-	HOOK_SERVER,       /* PRIVMSG, NOTICE, numerics */
-	HOOK_SERVER_ATTRS, /* same as above, with attributes */
-	HOOK_PRINT,        /* All print events */
-	HOOK_PRINT_ATTRS,  /* same as above, with attributes */
-	HOOK_TIMER,        /* timeouts */
-	HOOK_FD,           /* sockets & fds */
-	HOOK_DELETED       /* marked for deletion */
+	HOOK_COMMAND      = 1 << 0, /* /command */
+	HOOK_SERVER       = 1 << 1, /* PRIVMSG, NOTICE, numerics */
+	HOOK_SERVER_ATTRS = 1 << 2, /* same as above, with attributes */
+	HOOK_PRINT        = 1 << 3, /* All print events */
+	HOOK_PRINT_ATTRS  = 1 << 4, /* same as above, with attributes */
+	HOOK_TIMER        = 1 << 5, /* timeouts */
+	HOOK_FD           = 1 << 6, /* sockets & fds */
+	HOOK_DELETED      = 1 << 7  /* marked for deletion */
 };
 
 GSList *plugin_list = NULL;	/* export for plugingui.c */
@@ -560,16 +565,14 @@ plugin_hook_find (GSList *list, int type, char *name)
 	while (list)
 	{
 		hook = list->data;
-		if (hook && hook->type == type)
+		if (hook && (hook->type & type))
 		{
 			if (g_ascii_strcasecmp (hook->name, name) == 0)
 				return list;
 
-			if (type == HOOK_SERVER)
-			{
-				if (g_ascii_strcasecmp (hook->name, "RAW LINE") == 0)
+			if ((type & HOOK_SERVER)
+				&& g_ascii_strcasecmp (hook->name, "RAW LINE") == 0)
 					return list;
-			}
 		}
 		list = list->next;
 	}
@@ -599,7 +602,7 @@ plugin_hook_run (session *sess, char *name, char *word[], char *word_eol[],
 		hook->pl->context = sess;
 
 		/* run the plugin's callback function */
-		switch (type)
+		switch (hook->type)
 		{
 		case HOOK_COMMAND:
 			ret = ((hexchat_cmd_cb *)hook->callback) (word, word_eol, hook->userdata);
@@ -676,39 +679,30 @@ hexchat_event_attrs_free (hexchat_plugin *ph, hexchat_event_attrs *attrs)
 }
 
 /* got a server PRIVMSG, NOTICE, numeric etc... */
-int
-plugin_emit_server (session *sess, char *name, char *word[], char *word_eol[])
-{
-	return plugin_hook_run (sess, name, word, word_eol, NULL, HOOK_SERVER);
-}
 
 int
-plugin_emit_server_attrs (session *sess, char *name, char *word[], char *word_eol[],
-						  time_t server_time)
+plugin_emit_server (session *sess, char *name, char *word[], char *word_eol[],
+					time_t server_time)
 {
 	hexchat_event_attrs attrs;
 
 	attrs.server_time_utc = server_time;
 
-	return plugin_hook_run (sess, name, word, word_eol, &attrs, HOOK_SERVER_ATTRS);
+	return plugin_hook_run (sess, name, word, word_eol, &attrs, 
+							HOOK_SERVER | HOOK_SERVER_ATTRS);
 }
 
 /* see if any plugins are interested in this print event */
 
 int
-plugin_emit_print (session *sess, char *word[])
-{
-	return plugin_hook_run (sess, word[0], word, NULL, NULL, HOOK_PRINT);
-}
-
-int
-plugin_emit_print_attrs (session *sess, char *word[], time_t server_time)
+plugin_emit_print (session *sess, char *word[], time_t server_time)
 {
 	hexchat_event_attrs attrs;
 
 	attrs.server_time_utc = server_time;
 
-	return plugin_hook_run (sess, word[0], word, NULL, &attrs, HOOK_PRINT_ATTRS);
+	return plugin_hook_run (sess, word[0], word, NULL, &attrs,
+							HOOK_PRINT | HOOK_PRINT_ATTRS);
 }
 
 int
@@ -783,12 +777,27 @@ plugin_insert_hook (hexchat_hook *new_hook)
 {
 	GSList *list;
 	hexchat_hook *hook;
+	int new_hook_type;
+ 
+	switch (new_hook->type)
+	{
+		case HOOK_PRINT:
+		case HOOK_PRINT_ATTRS:
+			new_hook_type = HOOK_PRINT | HOOK_PRINT_ATTRS;
+			break;
+		case HOOK_SERVER:
+		case HOOK_SERVER_ATTRS:
+			new_hook_type = HOOK_SERVER | HOOK_PRINT_ATTRS;
+			break;
+		default:
+			new_hook_type = new_hook->type;
+	}
 
 	list = hook_list;
 	while (list)
 	{
 		hook = list->data;
-		if (hook && hook->type == new_hook->type && hook->pri <= new_hook->pri)
+		if (hook && (hook->type & new_hook_type) && hook->pri <= new_hook->pri)
 		{
 			hook_list = g_slist_insert_before (hook_list, list, new_hook);
 			return;
diff --git a/src/common/plugin.h b/src/common/plugin.h
index ee9da8c1..cd3f70a8 100644
--- a/src/common/plugin.h
+++ b/src/common/plugin.h
@@ -170,11 +170,9 @@ int plugin_kill (char *name, int by_filename);
 void plugin_kill_all (void);
 void plugin_auto_load (session *sess);
 int plugin_emit_command (session *sess, char *name, char *word[], char *word_eol[]);
-int plugin_emit_server (session *sess, char *name, char *word[], char *word_eol[]);
-int plugin_emit_server_attrs (session *sess, char *name, char *word[],
-							  char *word_eol[], time_t server_time);
-int plugin_emit_print (session *sess, char *word[]);
-int plugin_emit_print_attrs (session *sess, char *word[], time_t server_time);
+int plugin_emit_server (session *sess, char *name, char *word[], char *word_eol[],
+						time_t server_time);
+int plugin_emit_print (session *sess, char *word[], time_t server_time);
 int plugin_emit_dummy_print (session *sess, char *name);
 int plugin_emit_keypress (session *sess, unsigned int state, unsigned int keyval, int len, char *string);
 GList* plugin_command_list(GList *tmp_list);
diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c
index eb60a2e6..6d7c7fc1 100644
--- a/src/common/proto-irc.c
+++ b/src/common/proto-irc.c
@@ -1503,9 +1503,6 @@ irc_inline (server *serv, char *buf, int len)
 
 	if (buf[0] == ':')
 	{
-		int eat1;
-		int eat2;
-
 		/* find a context for this message */
 		if (is_channel (serv, word[3]))
 		{
@@ -1520,11 +1517,8 @@ irc_inline (server *serv, char *buf, int len)
 		word[0] = type;
 		word_eol[1] = buf;	/* keep the ":" for plugins */
 
-		eat1 = plugin_emit_server (sess, type, word, word_eol);
-		eat2 = plugin_emit_server_attrs (sess, type, word, word_eol, 
-										 tags_data.timestamp);
-
-		if (eat1 || eat2)
+		if (plugin_emit_server (sess, type, word, word_eol,
+								tags_data.timestamp))
 			goto xit;
 
 		word[1]++;
@@ -1532,16 +1526,10 @@ irc_inline (server *serv, char *buf, int len)
 
 	} else
 	{
-		int eat1;
-		int eat2;
-
 		word[0] = type = word[1];
 
-		eat1 = plugin_emit_server (sess, type, word, word_eol);
-		eat2 = plugin_emit_server_attrs (sess, type, word, word_eol,
-										 tags_data.timestamp);
-
-		if (eat1 || eat2)
+		if (plugin_emit_server (sess, type, word, word_eol,
+								tags_data.timestamp))
 			goto xit;
 	}
 
diff --git a/src/common/text.c b/src/common/text.c
index 58d3b45c..1afb0c18 100644
--- a/src/common/text.c
+++ b/src/common/text.c
@@ -2074,8 +2074,6 @@ text_emit (int index, session *sess, char *a, char *b, char *c, char *d,
 	int i;
 	unsigned int stripcolor_args = (chanopt_is_set (prefs.hex_text_stripcolor_msg, sess->text_strip) ? 0xFFFFFFFF : 0);
 	char tbuf[NICKLEN + 4];
-	int eat1;
-	int eat2;
 
 	if (prefs.hex_text_color_nicks && (index == XP_TE_CHANACTION || index == XP_TE_CHANMSG))
 	{
@@ -2092,10 +2090,7 @@ text_emit (int index, session *sess, char *a, char *b, char *c, char *d,
 	for (i = 5; i < PDIWORDS; i++)
 		word[i] = "\000";
 
-	eat1 = plugin_emit_print (sess, word);
-	eat2 = plugin_emit_print_attrs (sess, word, timestamp);
-
-	if (eat1 || eat2)
+	if (plugin_emit_print (sess, word, timestamp))
 		return;
 
 	/* If a plugin's callback executes "/close", 'sess' may be invalid */