changeset 2511:a83b4a5ffcd6

[gaim-migrate @ 2524] malsyned's patch for args in perl. committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Mon, 15 Oct 2001 19:52:44 +0000
parents 1950afffd107
children bf7ec3874810
files ChangeLog plugins/PERL-HOWTO plugins/gaim.pl src/aim.c src/core.h src/module.c src/perl.c
diffstat 7 files changed, 152 insertions(+), 102 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Mon Oct 15 19:18:19 2001 +0000
+++ b/ChangeLog	Mon Oct 15 19:52:44 2001 +0000
@@ -10,6 +10,9 @@
 	* Ability to stop animation on buddy icons, hide certain
 	  buddy icons, and save people's buddy icons, all through
 	  a right-click menu
+	* Event handlers in perl passed arguments as elements of
+	  an array rather than all concatenated as a string, making
+	  perl much easier to use (thanks Dennis Lambe Jr.)
 
 version 0.45 (10/04/2001):
 	* New plugin event: event_chat_send_invite
--- a/plugins/PERL-HOWTO	Mon Oct 15 19:18:19 2001 +0000
+++ b/plugins/PERL-HOWTO	Mon Oct 15 19:52:44 2001 +0000
@@ -122,10 +122,11 @@
 	(a string with the same name as the events for plugins, see SIGNALS), and a
 	string with the name of the function you want called. Simple enough?
 
-	When this is triggered, the arguments will be passed in @_ and are not
-	broken into a list, but left as one long string. You'll have to parse those
-	yourself with split. (Sounding exactly like X-Chat yet?) The arguments are
-	the exact same as those passed to the plugins, and are passed after the
+	When this is triggered, the arguments will be passed in @_ and are broken
+	into a list. This is different from all previous versions of Gaim, where you
+	had to parse the arguments yourself. The arguments are quite different from
+	what's passed to the plugins, though they are very similar, and you should
+	read perl.c to figure out what they are. The arguments are passed after the
 	plugins have had their way with them. Perl scripts cannot modify the values
 	so that gaim knows what the changes are.
 
@@ -135,10 +136,6 @@
 	and the event itself to never happen (i.e. the user won't see it happen,
 	and _send events won't actually send).
 
-	Names of buddies and chat rooms will be in quotes, and all other
-	values (like text messages) will not be. (Watch the debug window to get a
-	better feel for this, or better yet, look at the bottom of plugins.c.)
-
 GAIM::add_timeout_handler(integer, function)
 	This calls function after integer number of seconds. It only calls function
 	once, so if you want to keep calling function, keep readding the handler.
--- a/plugins/gaim.pl	Mon Oct 15 19:18:19 2001 +0000
+++ b/plugins/gaim.pl	Mon Oct 15 19:52:44 2001 +0000
@@ -18,9 +18,9 @@
 GAIM::add_timeout_handler(60, "notify");
 
 sub echo_reply {
-	$args = $_[0];
-	$args =~ s/(.+) \"(.+)\"//;
-	GAIM::print_to_conv($1, $2, "Hello", 0);
+	$index = $_[0];
+	$who = $_[1];
+	GAIM::print_to_conv($index, $who, "Hello", 0);
 }
 
 sub notify {
--- a/src/aim.c	Mon Oct 15 19:18:19 2001 +0000
+++ b/src/aim.c	Mon Oct 15 19:52:44 2001 +0000
@@ -569,6 +569,7 @@
 	signal(SIGHUP, sighandler);
 	signal(SIGINT, sighandler);
 	signal(SIGTERM, sighandler);
+	signal(SIGQUIT, sighandler);
 	signal(SIGPIPE, SIG_IGN);
 #endif
 
--- a/src/core.h	Mon Oct 15 19:18:19 2001 +0000
+++ b/src/core.h	Mon Oct 15 19:52:44 2001 +0000
@@ -169,7 +169,7 @@
 #ifdef USE_PERL
 extern void perl_autoload();
 extern void perl_end();
-extern int perl_event(char *, char *);
+extern int perl_event(enum gaim_event, void *, void *, void *, void *);
 extern int perl_load_file(char *);
 extern void unload_perl_scripts();
 extern void list_perl_scripts();
@@ -186,6 +186,7 @@
 extern void remove_all_plugins();
 #endif
 extern int plugin_event(enum gaim_event, void *, void *, void *, void *);
+extern char *event_name(enum gaim_event);
 
 /* Functions in server.c */
 extern void serv_got_update(struct gaim_connection *, char *, int, int, time_t, time_t, int, gushort);
--- a/src/module.c	Mon Oct 15 19:18:19 2001 +0000
+++ b/src/module.c	Mon Oct 15 19:52:44 2001 +0000
@@ -175,7 +175,7 @@
 void gaim_plugin_unload(GModule *handle)
 {
 	GList *pl = plugins;
-	struct gaim_plugin *p;
+	struct gaim_plugin *p = NULL;
 	void (*gaim_plugin_remove)();
 
 	while (pl) {
@@ -269,7 +269,7 @@
 
 #endif /* GAIM_PLUGINS */
 
-static char *event_name(enum gaim_event event)
+char *event_name(enum gaim_event event)
 {
 	static char buf[128];
 	switch (event) {
@@ -468,9 +468,6 @@
 
 int plugin_event(enum gaim_event event, void *arg1, void *arg2, void *arg3, void *arg4)
 {
-#ifdef USE_PERL
-	char buf[BUF_LONG];
-#endif
 #ifdef GAIM_PLUGINS
 	GList *c = callbacks;
 	struct gaim_callback *g;
@@ -487,7 +484,7 @@
 		void (*four)(void *, void *, void *, void *, void *);
 
 		g = (struct gaim_callback *)c->data;
-		if (g->event == event && g->function !=NULL) {
+		if (g->event == event && g->function != NULL) {
 			switch (event) {
 
 				/* no args */
@@ -553,81 +550,7 @@
 	}
 #endif /* GAIM_PLUGINS */
 #ifdef USE_PERL
-	switch (event) {
-	case event_signon:
-	case event_signoff:
-		g_snprintf(buf, sizeof buf, "%lu", (unsigned long)arg1);
-		break;
-	case event_away:
-		g_snprintf(buf, sizeof buf, "%lu %s", (unsigned long)arg1,
-				((struct gaim_connection *)arg1)->away ?
-					((struct gaim_connection *)arg1)->away : "");
-		break;
-	case event_im_recv:
-		g_snprintf(buf, sizeof buf, "%lu \"%s\" %s", (unsigned long)arg1,
-			   *(char **)arg2 ? *(char **)arg2 : "(null)",
-			   *(char **)arg3 ? *(char **)arg3 : "(null)");
-		break;
-	case event_im_send:
-		g_snprintf(buf, sizeof buf, "%lu \"%s\" %s", (unsigned long)arg1,
-			   (char *)arg2, *(char **)arg3 ? *(char **)arg3 : "(null)");
-		break;
-	case event_buddy_signon:
-	case event_buddy_signoff:
-	case event_set_info:
-	case event_buddy_away:
-	case event_buddy_back:
-	case event_buddy_idle:
-	case event_buddy_unidle:
-		g_snprintf(buf, sizeof buf, "%lu \"%s\"", (unsigned long)arg1, (char *)arg2);
-		break;
-	case event_chat_invited:
-		g_snprintf(buf, sizeof buf, "%lu \"%s\" \"%s\" %s", (unsigned long)arg1,
-				(char *)arg2, (char *)arg3, arg4 ? (char *)arg4 : "");
-		break;
-	case event_chat_join:
-	case event_chat_buddy_join:
-	case event_chat_buddy_leave:
-		g_snprintf(buf, sizeof buf, "%lu %d \"%s\"", (unsigned long)arg1,
-				(int)arg2, (char *)arg3);
-		break;
-	case event_chat_leave:
-		g_snprintf(buf, sizeof buf, "%lu %d", (unsigned long)arg1, (int)arg2);
-		break;
-	case event_chat_recv:
-		g_snprintf(buf, sizeof buf, "%lu %d \"%s\" %s", (unsigned long)arg1,
-				(int)arg2, (char *)arg3, (char *)arg4 ? (char *)arg4 : "(null)");
-		break;
-	case event_chat_send_invite:
-		g_snprintf(buf, sizeof buf, "%lu %d \"%s\" %s", (unsigned long)arg1,
-				(int)arg2, (char *)arg3, *(char **)arg4 ? *(char **)arg4 : "(null)");
-		break;
-	case event_chat_send:
-		g_snprintf(buf, sizeof buf, "%lu %d %s", (unsigned long)arg1, (int)arg2,
-				*(char **)arg3 ? *(char **)arg3 : "(null)");
-		break;
-	case event_warned:
-		g_snprintf(buf, sizeof buf, "%lu \"%s\" %d", (unsigned long)arg1,
-				arg2 ? (char *)arg2 : "", (int)arg3);
-		break;
-	case event_quit:
-		buf[0] = 0;
-		break;
-	case event_new_conversation:
-		g_snprintf(buf, sizeof buf, "\"%s\"", (char *)arg1);
-		break;
-	case event_im_displayed_sent:
-		g_snprintf(buf, sizeof buf, "%lu \"%s\" %s", (unsigned long)arg1,
-				(char *)arg2, *(char **)arg3 ? *(char **)arg3 : "(null)");
-		break;
-	case event_im_displayed_rcvd:
-		g_snprintf(buf, sizeof buf, "%lu \"%s\" %s", (unsigned long)arg1,
-				(char *)arg2, (char *)arg3 ? (char *)arg3 : "(null)");
-		break;
-	default:
-		return 0;
-	}
-	return perl_event(event_name(event), buf);
+	return perl_event(event, arg1, arg2, arg3, arg4);
 #else
 	return 0;
 #endif
--- a/src/perl.c	Mon Oct 15 19:18:19 2001 +0000
+++ b/src/perl.c	Mon Oct 15 19:52:44 2001 +0000
@@ -131,24 +131,28 @@
 static SV *execute_perl(char *function, char *args)
 {
 	static char *perl_cmd = NULL;
+	SV *i;
 
 	if (perl_cmd)
 		g_free(perl_cmd);
-	perl_cmd = g_malloc(strlen(function) + (strlen(args) * 2) + 2 + 10);
-	sprintf(perl_cmd, "&%s('%s')", function, escape_quotes(args));
+	perl_cmd = g_malloc(strlen(function) + strlen(args) + 4);
+	sprintf(perl_cmd, "&%s(%s)", function, args);
 #ifndef HAVE_PERL_EVAL_PV
-	return (perl_eval_pv(perl_cmd, TRUE));
+	i = (perl_eval_pv(perl_cmd, TRUE));
 #else
-	return (Perl_eval_pv(perl_cmd, TRUE));
+	i = (Perl_eval_pv(perl_cmd, TRUE));
 #endif
+	return i;
 }
 
 int perl_load_file(char *script_name)
 {
+	char *name = g_strdup_printf("'%s'", escape_quotes(script_name));
 	SV *return_val;
 	if (my_perl == NULL)
 		perl_init();
-	return_val = execute_perl("load_file", script_name);
+	return_val = execute_perl("load_file", name);
+	g_free(name);
 	return SvNV (return_val);
 }
 
@@ -643,21 +647,142 @@
 	XSRETURN(0);
 }
 
-int perl_event(char *event, char *args)
+int perl_event(enum gaim_event event, void *arg1, void *arg2, void *arg3, void *arg4)
 {
+	char *buf = NULL;
 	GList *handler;
 	struct _perl_event_handlers *data;
 	SV *handler_return;
 
+	switch (event) {
+	case event_signon:
+	case event_signoff:
+		buf = g_strdup_printf("'%lu'", (unsigned long)arg1);
+		break;
+	case event_away:
+		buf = g_strdup_printf("'%lu','%s'", (unsigned long)arg1,
+				((struct gaim_connection *)arg1)->away ?
+					escape_quotes(((struct gaim_connection *)arg1)->away) : "");
+		break;
+	case event_im_recv:
+		{
+		char *tmp = *(char **)arg2 ? g_strdup(escape_quotes(*(char **)arg2)) : g_malloc0(1);
+		buf = g_strdup_printf("'%lu','%s','%s'", (unsigned long)arg1, tmp,
+			   *(char **)arg3 ? escape_quotes(*(char **)arg3) : "");
+		g_free(tmp);
+		}
+		break;
+	case event_im_send:
+		{
+		char *tmp = arg2 ? g_strdup(escape_quotes(arg2)) : g_malloc0(1);
+		buf = g_strdup_printf("'%lu','%s','%s'", (unsigned long)arg1, tmp,
+			   *(char **)arg3 ? escape_quotes(*(char **)arg3) : "");
+		g_free(tmp);
+		}
+		break;
+	case event_buddy_signon:
+	case event_buddy_signoff:
+	case event_set_info:
+	case event_buddy_away:
+	case event_buddy_back:
+	case event_buddy_idle:
+	case event_buddy_unidle:
+		buf = g_strdup_printf("'%lu','%s'", (unsigned long)arg1, escape_quotes(arg2));
+		break;
+	case event_chat_invited:
+		{
+		char *tmp2, *tmp3, *tmp4;
+		tmp2 = g_strdup(escape_quotes(arg2));
+		tmp3 = g_strdup(escape_quotes(arg3));
+		tmp4 = arg4 ? g_strdup(escape_quotes(arg4)) : g_malloc0(1);
+		buf = g_strdup_printf("'%lu','%s','%s','%s'", (unsigned long)arg1, tmp2, tmp3, tmp4);
+		g_free(tmp2);
+		g_free(tmp3);
+		g_free(tmp4);
+		}
+		break;
+	case event_chat_join:
+	case event_chat_buddy_join:
+	case event_chat_buddy_leave:
+		buf = g_strdup_printf("'%lu','%d','%s'", (unsigned long)arg1, (int)arg2,
+				escape_quotes(arg3));
+		break;
+	case event_chat_leave:
+		buf = g_strdup_printf("'%lu','%d'", (unsigned long)arg1, (int)arg2);
+		break;
+	case event_chat_recv:
+		{
+		char *t3, *t4;
+		t3 = g_strdup(escape_quotes(arg3));
+		t4 = arg4 ? g_strdup(escape_quotes(arg4)) : g_malloc0(1);
+		buf = g_strdup_printf("'%lu','%d','%s','%s'", (unsigned long)arg1, (int)arg2, t3, t4);
+		g_free(t3);
+		g_free(t4);
+		}
+		break;
+	case event_chat_send_invite:
+		{
+		char *t3, *t4;
+		t3 = g_strdup(escape_quotes(arg3));
+		t4 = *(char **)arg4 ? g_strdup(escape_quotes(*(char **)arg4)) : g_malloc0(1);
+		buf = g_strdup_printf("'%lu','%d','%s','%s'", (unsigned long)arg1, (int)arg2, t3, t4);
+		g_free(t3);
+		g_free(t4);
+		}
+		break;
+	case event_chat_send:
+		buf = g_strdup_printf("'%lu','%d','%s'", (unsigned long)arg1, (int)arg2,
+				*(char **)arg3 ? escape_quotes(*(char **)arg3) : "");
+		break;
+	case event_warned:
+		buf = g_strdup_printf("'%lu','%s','%d'", (unsigned long)arg1,
+				arg2 ? escape_quotes(arg2) : "", (int)arg3);
+		break;
+	case event_quit:
+		buf = g_malloc0(1);
+		break;
+	case event_new_conversation:
+		buf = g_strdup_printf("'%s'", escape_quotes(arg1));
+		break;
+	case event_im_displayed_sent:
+		{
+		char *tmp2, *tmp3;
+		tmp2 = g_strdup(escape_quotes(arg2));
+		tmp3 = *(char **)arg3 ? g_strdup(escape_quotes(*(char **)arg3)) : g_malloc0(1);
+		buf = g_strdup_printf("'%lu','%s','%s'", (unsigned long)arg1, tmp2, tmp3);
+		g_free(tmp2);
+		g_free(tmp3);
+		}
+		break;
+	case event_im_displayed_rcvd:
+		{
+		char *tmp2, *tmp3;
+		tmp2 = g_strdup(escape_quotes(arg2));
+		tmp3 = arg3 ? g_strdup(escape_quotes(arg3)) : g_malloc0(1);
+		buf = g_strdup_printf("%lu \"%s\" %s", (unsigned long)arg1, tmp2, tmp3);
+		g_free(tmp2);
+		g_free(tmp3);
+		}
+		break;
+	default:
+		return 0;
+	}
+
 	for (handler = perl_event_handlers; handler != NULL; handler = handler->next) {
 		data = handler->data;
-		if (!strcmp(event, data->event_type)) {
-			handler_return = execute_perl(data->handler_name, args);
-			if (SvIV(handler_return))
+		if (!strcmp(event_name(event), data->event_type)) {
+			handler_return = execute_perl(data->handler_name, buf);
+			if (SvIV(handler_return)) {
+				if (buf)
+					g_free(buf);
 				return SvIV(handler_return);
+			}
 		}
 	}
 
+	if (buf)
+		g_free(buf);
+
 	return 0;
 }