Mercurial > pidgin
diff plugins/perl/perl-common.c @ 6520:2e2593d95121
[gaim-migrate @ 7037]
Added timeout handler support to perl. It may not work. Probably should,
but who knows.
committer: Tailor Script <tailor@pidgin.im>
author | Christian Hammond <chipx86@chipx86.com> |
---|---|
date | Wed, 20 Aug 2003 10:25:58 +0000 |
parents | cbd24b37350d |
children | 7c42b8ca3222 |
line wrap: on
line diff
--- a/plugins/perl/perl-common.c Wed Aug 20 09:33:56 2003 +0000 +++ b/plugins/perl/perl-common.c Wed Aug 20 10:25:58 2003 +0000 @@ -1,7 +1,4 @@ -#include <XSUB.h> -#include <EXTERN.h> -#include <perl.h> -#include <glib.h> +#include "debug.h" #include "perl-common.h" @@ -105,3 +102,119 @@ return p; } +/* + 2003/02/06: execute_perl modified by Mark Doliner <mark@kingant.net> + Pass parameters by pushing them onto the stack rather than + passing an array of strings. This way, perl scripts can + modify the parameters and we can get the changed values + and then shoot ourselves. I mean, uh, use them. + + 2001/06/14: execute_perl replaced by Martin Persson <mep@passagen.se> + previous use of perl_eval leaked memory, replaced with + a version that uses perl_call instead + + 30/11/2002: execute_perl modified by Eric Timme <timothy@voidnet.com> + args changed to char** so that we can have preparsed + arguments again, and many headaches ensued! This essentially + means we replaced one hacked method with a messier hacked + method out of perceived necessity. Formerly execute_perl + required a single char_ptr, and it would insert it into an + array of character pointers and NULL terminate the new array. + Now we have to pass in pre-terminated character pointer arrays + to accomodate functions that want to pass in multiple arguments. + + Previously arguments were preparsed because an argument list + was constructed in the form 'arg one','arg two' and was + executed via a call like &funcname(arglist) (see .59.x), so + the arglist was magically pre-parsed because of the method. + With Martin Persson's change to perl_call we now need to + use a null terminated list of character pointers for arguments + if we wish them to be parsed. Lacking a better way to allow + for both single arguments and many I created a NULL terminated + array in every function that called execute_perl and passed + that list into the function. In the former version a single + character pointer was passed in, and was placed into an array + of character pointers with two elements, with a NULL element + tacked onto the back, but this method no longer seemed prudent. + + Enhancements in the future might be to get rid of pre-declaring + the array sizes? I am not comfortable enough with this + subject to attempt it myself and hope it to stand the test + of time. +*/ +int +execute_perl(const char *function, int argc, char **args) +{ + int count = 0, i, ret_value = 1; + SV *sv_args[argc]; + STRLEN na; + + /* + * Set up the perl environment, push arguments onto the + * perl stack, then call the given function + */ + dSP; + ENTER; + SAVETMPS; + PUSHMARK(sp); + + for (i = 0; i < argc; i++) { + if (args[i]) { + sv_args[i] = sv_2mortal(newSVpv(args[i], 0)); + XPUSHs(sv_args[i]); + } + } + + PUTBACK; + count = call_pv(function, G_EVAL | G_SCALAR); + SPAGAIN; + + /* + * Check for "die," make sure we have 1 argument, and set our + * return value. + */ + if (SvTRUE(ERRSV)) { + gaim_debug(GAIM_DEBUG_ERROR, "perl", + "Perl function %s exited abnormally: %s\n", + function, SvPV(ERRSV, na)); + POPs; + } + else if (count != 1) { + /* + * This should NEVER happen. G_SCALAR ensures that we WILL + * have 1 parameter. + */ + gaim_debug(GAIM_DEBUG_ERROR, "perl", + "Perl error from %s: expected 1 return value, " + "but got %d\n", function, count); + } + else + ret_value = POPi; + + /* Check for changed arguments */ + for (i = 0; i < argc; i++) { + if (args[i] && strcmp(args[i], SvPVX(sv_args[i]))) { + /* + * Shizzel. So the perl script changed one of the parameters, + * and we want this change to affect the original parameters. + * args[i] is just a tempory little list of pointers. We don't + * want to free args[i] here because the new parameter doesn't + * overwrite the data that args[i] points to. That is done by + * the function that called execute_perl. I'm not explaining this + * very well. See, it's aggregate... Oh, but if 2 perl scripts + * both modify the data, _that's_ a memleak. This is really kind + * of hackish. I should fix it. Look how long this comment is. + * Holy crap. + */ + args[i] = g_strdup(SvPV(sv_args[i], na)); + } + } + + PUTBACK; + FREETMPS; + LEAVE; + + return ret_value; +} + +