changeset 23603:ab5b9acebde3

Update the Perl plugin loader to work with Perl 5.10. I don't think this will break compiling with older versions (note that Perl micro versions are not binary compatible). Update the win32 build to use (and require and upgrade to Perl 5.10). Fixes #5137
author Daniel Atallah <daniel.atallah@gmail.com>
date Mon, 28 Jul 2008 00:52:54 +0000
parents d48d333e6ef5
children df9e569b8f1f
files ChangeLog.win32 libpurple/plugins/perl/Makefile.mingw libpurple/plugins/perl/common/Makefile.mingw libpurple/plugins/perl/perl-common.c libpurple/plugins/perl/perl-common.h libpurple/plugins/perl/perl.c libpurple/win32/global.mak pidgin/plugins/perl/common/Makefile.mingw pidgin/win32/nsis/pidgin-installer.nsi pidgin/win32/winpidgin.c
diffstat 10 files changed, 93 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog.win32	Sun Jul 27 23:57:00 2008 +0000
+++ b/ChangeLog.win32	Mon Jul 28 00:52:54 2008 +0000
@@ -1,5 +1,7 @@
 version 2.5.0 (??/??/2008):
 	* Don't install the GSSAPI SASL plugin on NT4 to avoid an error popup.
+	* Upgrade to Perl 5.10 (System Perl runtime must be upgraded for Perl
+	  plugins to continue to work).
 
 version 2.4.3 (07/01/2008):
 	* No changes
--- a/libpurple/plugins/perl/Makefile.mingw	Sun Jul 27 23:57:00 2008 +0000
+++ b/libpurple/plugins/perl/Makefile.mingw	Mon Jul 28 00:52:54 2008 +0000
@@ -47,7 +47,7 @@
 			-lws2_32 \
 			-lintl \
 			-lpurple \
-			-lperl58
+			-lperl510
 
 include $(PIDGIN_COMMON_RULES)
 
--- a/libpurple/plugins/perl/common/Makefile.mingw	Sun Jul 27 23:57:00 2008 +0000
+++ b/libpurple/plugins/perl/common/Makefile.mingw	Mon Jul 28 00:52:54 2008 +0000
@@ -5,6 +5,7 @@
 #
 
 PIDGIN_TREE_TOP := ../../../..
+GCCWARNINGS := -Wno-comment -Waggregate-return -Wcast-align -Wdeclaration-after-statement -Werror-implicit-function-declaration -Wextra -Wno-sign-compare -Wno-unused-parameter -Winit-self -Wmissing-declarations -Wmissing-prototypes -Wpointer-arith -Wundef -Wno-unused
 include $(PIDGIN_TREE_TOP)/libpurple/win32/global.mak
 
 TARGET = Purple
@@ -12,8 +13,6 @@
 EXTUTILS ?= C:/perl/lib/ExtUtils
 PERL_PLUGIN_TOP := ..
 
-CFLAGS += -Wno-comment -Wno-unused
-
 ##
 ## INCLUDE PATHS
 ##
@@ -77,7 +76,7 @@
 ##
 ## LIBRARIES
 ##
-LIBS =			-lperl58 \
+LIBS =			-lperl510 \
 			-lperl \
 			-lpurple \
 			-lglib-2.0
--- a/libpurple/plugins/perl/perl-common.c	Sun Jul 27 23:57:00 2008 +0000
+++ b/libpurple/plugins/perl/perl-common.c	Mon Jul 28 00:52:54 2008 +0000
@@ -32,7 +32,10 @@
 
 static MGVTBL vtbl_free_object =
 {
-	NULL, NULL, NULL, NULL, magic_free_object, NULL, NULL
+	0, 0, 0, 0, magic_free_object, 0, 0
+#if PERL_API_REVISION > 5 || (PERL_API_REVISION == 5 && PERL_API_VERSION >= 10)
+	, 0
+#endif
 };
 
 static SV *
--- a/libpurple/plugins/perl/perl-common.h	Sun Jul 27 23:57:00 2008 +0000
+++ b/libpurple/plugins/perl/perl-common.h	Mon Jul 28 00:52:54 2008 +0000
@@ -5,9 +5,9 @@
 #ifdef _WIN32
 #undef pipe
 #endif
+#include <perl.h>
 #include <XSUB.h>
 #include <EXTERN.h>
-#include <perl.h>
 
 /* XXX: perl defines it's own _ but I think it's safe to undef it */
 #undef _
--- a/libpurple/plugins/perl/perl.c	Sun Jul 27 23:57:00 2008 +0000
+++ b/libpurple/plugins/perl/perl.c	Mon Jul 28 00:52:54 2008 +0000
@@ -67,6 +67,10 @@
 #undef group
 
 /* perl module support */
+#ifdef _WIN32
+EXTERN_C void boot_Win32CORE (pTHX_ CV* cv);
+#endif
+
 #ifdef OLD_PERL
 extern void boot_DynaLoader _((CV * cv));
 #else
@@ -127,10 +131,14 @@
 #endif
 {
 	char *file = __FILE__;
+	dXSUB_SYS;
 
 	/* This one allows dynamic loading of perl modules in perl scripts by
 	 * the 'use perlmod;' construction */
 	newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
+#ifdef _WIN32
+	newXS("Win32CORE::bootstrap", boot_Win32CORE, file);
+#endif
 }
 
 static void
@@ -240,18 +248,26 @@
 static gboolean
 probe_perl_plugin(PurplePlugin *plugin)
 {
-	/* XXX This would be much faster if I didn't create a new
-	 *     PerlInterpreter every time I probed a plugin */
 
-	PerlInterpreter *prober = perl_alloc();
-	char *argv[] = {"", plugin->path };
+	char *args[] = {"", plugin->path };
+	char **argv = args;
+	int argc = 2;
+	PerlInterpreter *prober;
 	gboolean status = TRUE;
 	HV *plugin_info;
+
+	PERL_SYS_INIT(&argc, &argv);
+
+	/* XXX This would be much faster if we didn't create a new
+	 *     PerlInterpreter every time we probe a plugin */
+	prober = perl_alloc();
+
 	PERL_SET_CONTEXT(prober);
+
 	PL_perl_destruct_level = 1;
 	perl_construct(prober);
 
-	perl_parse(prober, xs_init, 2, argv, NULL);
+	perl_parse(prober, xs_init, argc, argv, NULL);
 
 	perl_run(prober);
 
@@ -578,7 +594,7 @@
 	load_perl_plugin,                                 /**< load           */
 	unload_perl_plugin,                               /**< unload         */
 	destroy_perl_plugin,                              /**< destroy        */
-	
+
 	/* padding */
 	NULL,
 	NULL,
--- a/libpurple/win32/global.mak	Sun Jul 27 23:57:00 2008 +0000
+++ b/libpurple/win32/global.mak	Mon Jul 28 00:52:54 2008 +0000
@@ -19,7 +19,7 @@
 MEANWHILE_TOP ?= $(WIN32_DEV_TOP)/meanwhile-1.0.2_daa1
 NSPR_TOP ?= $(WIN32_DEV_TOP)/nspr-4.6.4
 NSS_TOP ?= $(WIN32_DEV_TOP)/nss-3.11.4
-PERL_LIB_TOP ?= $(WIN32_DEV_TOP)/perl58
+PERL_LIB_TOP ?= $(WIN32_DEV_TOP)/perl-5.10.0
 SILC_TOOLKIT ?= $(WIN32_DEV_TOP)/silc-toolkit-1.1.5
 TCL_LIB_TOP ?= $(WIN32_DEV_TOP)/tcl-8.4.5
 GSTREAMER_TOP ?= $(WIN32_DEV_TOP)/gstreamer-0.10.13
@@ -56,7 +56,7 @@
 PIDGIN_EXE := $(PIDGIN_TOP)/pidgin.exe
 PIDGIN_PORTABLE_EXE := $(PIDGIN_TOP)/pidgin-portable.exe
 
-GCCWARNINGS := -Waggregate-return -Wcast-align -Wdeclaration-after-statement -Werror-implicit-function-declaration -Wextra -Wno-sign-compare -Wno-unused-parameter -Winit-self -Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Wpointer-arith -Wundef
+GCCWARNINGS ?= -Waggregate-return -Wcast-align -Wdeclaration-after-statement -Werror-implicit-function-declaration -Wextra -Wno-sign-compare -Wno-unused-parameter -Winit-self -Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Wpointer-arith -Wundef
 
 # parse the version number from the configure.ac file if it is newer
 #m4_define([purple_major_version], [2])
--- a/pidgin/plugins/perl/common/Makefile.mingw	Sun Jul 27 23:57:00 2008 +0000
+++ b/pidgin/plugins/perl/common/Makefile.mingw	Mon Jul 28 00:52:54 2008 +0000
@@ -5,13 +5,12 @@
 #
 
 PIDGIN_TREE_TOP := ../../../..
+GCCWARNINGS := -Wno-comment -Waggregate-return -Wcast-align -Wdeclaration-after-statement -Werror-implicit-function-declaration -Wextra -Wno-sign-compare -Wno-unused-parameter -Winit-self -Wmissing-declarations -Wmissing-prototypes -Wpointer-arith -Wundef -Wno-unused
 include $(PIDGIN_TREE_TOP)/libpurple/win32/global.mak
 
 TARGET = Pidgin
 EXTUTILS ?= C:/perl/lib/ExtUtils
 
-CFLAGS += -Wno-comment -Wno-unused
-
 ##
 ## INCLUDE PATHS
 ##
@@ -72,7 +71,7 @@
 ##
 ## LIBRARIES
 ##
-LIBS =			-lperl58 \
+LIBS =			-lperl510 \
 			-lperl \
 			-lpurple \
 			-lpidgin \
--- a/pidgin/win32/nsis/pidgin-installer.nsi	Sun Jul 27 23:57:00 2008 +0000
+++ b/pidgin/win32/nsis/pidgin-installer.nsi	Mon Jul 28 00:52:54 2008 +0000
@@ -72,7 +72,7 @@
 !define GTK_MIN_VERSION				"2.6.10"
 !define GTK_REG_KEY				"SOFTWARE\GTK\2.0"
 !define PERL_REG_KEY				"SOFTWARE\Perl"
-!define PERL_DLL				"perl58.dll"
+!define PERL_DLL				"perl510.dll"
 !define GTK_DEFAULT_INSTALL_PATH		"$COMMONFILES\GTK\2.0"
 !define GTK_RUNTIME_INSTALLER			"..\..\..\..\gtk_installer\gtk-runtime*.exe"
 
--- a/pidgin/win32/winpidgin.c	Sun Jul 27 23:57:00 2008 +0000
+++ b/pidgin/win32/winpidgin.c	Mon Jul 28 00:52:54 2008 +0000
@@ -89,9 +89,8 @@
 			const char *err_msg = get_win32_error_message(retv);
 
 			printf("Could not read reg key '%s' subkey '%s' value: '%s'.\nMessage: (%ld) %s\n",
-					((key == HKEY_LOCAL_MACHINE) ? "HKLM" :
-					 (key == HKEY_CURRENT_USER) ? "HKCU" :
-					 "???"),
+					(key == HKEY_LOCAL_MACHINE) ? "HKLM"
+					 : ((key == HKEY_CURRENT_USER) ? "HKCU" : "???"),
 					sub_key, val_name, retv, err_msg);
 		}
 		RegCloseKey(hkey);
@@ -216,13 +215,13 @@
 
 	/* Set up the settings dir base to be \\path\to
 	 * The actual settings dir will be \\path\to\.purple */
-	snprintf(path2, sizeof(path2), "PURPLEHOME=%s", path);
+	_snprintf(path2, sizeof(path2), "PURPLEHOME=%s", path);
 	printf("Setting settings dir: %s\n", path2);
-	putenv(path2);
+	_putenv(path2);
 
-	snprintf(path2, sizeof(path2), "PIDGIN_ASPELL_DIR=%s\\Aspell\\bin", path);
+	_snprintf(path2, sizeof(path2), "PIDGIN_ASPELL_DIR=%s\\Aspell\\bin", path);
 	printf("%s\n", path2);
-	putenv(path2);
+	_putenv(path2);
 
 	/* set the GTK+ path to be \\path\to\GTK\bin */
 	strcat(path, "\\GTK\\bin");
@@ -437,9 +436,50 @@
 
 	locale = winpidgin_get_locale();
 
-	snprintf(envstr, 25, "LANG=%s", locale);
+	_snprintf(envstr, 25, "LANG=%s", locale);
 	printf("Setting locale: %s\n", envstr);
-	putenv(envstr);
+	_putenv(envstr);
+}
+
+static void winpidgin_add_perl_to_path() {
+	char perl_path[MAX_PATH + 1];
+	DWORD plen = sizeof(perl_path);
+
+	printf("%s", "Looking for Perl... ");
+
+	if (read_reg_string(HKEY_LOCAL_MACHINE, "SOFTWARE\\Perl", "",
+			    (LPBYTE) &perl_path, &plen)) {
+		const char *path = getenv("PATH");
+		/* Enough to add "PATH=" + ";"  + perl_path + "\\bin" + \0 */
+
+		/* We *could* check for perl510.dll, but it seems unnecessary. */
+
+		printf("found in '%s'.\n", perl_path);
+
+		if (perl_path[strlen(perl_path) - 1] != '\\') {
+			strcat(perl_path, "\\");
+		}
+		strcat(perl_path, "bin");
+
+		if (!strstr(path, perl_path)) {
+			int newlen = (path ? strlen(path) : 0) + strlen(perl_path) + 10;
+			char *newpath = malloc(newlen);
+			*newpath = '\0';
+
+			_snprintf(newpath, newlen, "PATH=%s%s%s",
+				  path ? path : "",
+				  path ? ";" : "",
+				  perl_path);
+
+			printf("Adding Perl to PATH: %s\n", newpath);
+
+			_putenv(newpath);
+			free(newpath);
+		} else
+			printf("%s\n", "Perl already in PATH.");
+	} else
+		printf("%s", "not found.\n");
+
 }
 
 #define PIDGIN_WM_FOCUS_REQUEST (WM_APP + 13)
@@ -598,10 +638,10 @@
 	} else {
 		DWORD dw = GetLastError();
 		const char *err_msg = get_win32_error_message(dw);
-		snprintf(errbuf, 512,
+		_snprintf(errbuf, 512,
 			"Error getting module filename.\nError: (%u) %s",
 			(UINT) dw, err_msg);
-		printf("%s", errbuf);
+		printf("%s\n", errbuf);
 		MessageBox(NULL, errbuf, NULL, MB_OK | MB_TOPMOST);
 		pidgin_dir[0] = '\0';
 	}
@@ -631,6 +671,9 @@
 		dll_prep();
 
 	winpidgin_set_locale();
+
+	winpidgin_add_perl_to_path();
+
 	/* If help, version or multiple flag used, do not check Mutex */
 	if (!strstr(lpszCmdLine, "-h") && !strstr(lpszCmdLine, "-v"))
 		if (!winpidgin_set_running(getenv("PIDGIN_MULTI_INST") == NULL && strstr(lpszCmdLine, "-m") == NULL))
@@ -645,11 +688,11 @@
 		BOOL mod_not_found = (dw == ERROR_MOD_NOT_FOUND || dw == ERROR_DLL_NOT_FOUND);
 		const char *err_msg = get_win32_error_message(dw);
 
-		snprintf(errbuf, 512, "Error loading pidgin.dll.\nError: (%u) %s%s%s",
+		_snprintf(errbuf, 512, "Error loading pidgin.dll.\nError: (%u) %s%s%s",
 			(UINT) dw, err_msg,
 			mod_not_found ? "\n" : "",
 			mod_not_found ? "This probably means that GTK+ can't be found." : "");
-		printf("%s", errbuf);
+		printf("%s\n", errbuf);
 		MessageBox(NULL, errbuf, TEXT("Error"), MB_OK | MB_TOPMOST);
 
 		return 0;