Exemplo n.º 1
0
static int perl_source_event(PERL_SOURCE_REC *rec)
{
	dSP;
	int retcount;

	ENTER;
	SAVETMPS;

	PUSHMARK(SP);
	XPUSHs(sv_2mortal(new_pv(rec->data)));
	PUTBACK;

	retcount = perl_call_pv(rec->func, G_EVAL|G_DISCARD);
	SPAGAIN;

	if (SvTRUE(ERRSV)) {
		STRLEN n_a;

		signal_emit("perl error", 1, SvPV(ERRSV, n_a));
	}

	PUTBACK;
	FREETMPS;
	LEAVE;

	return 1;
}
Exemplo n.º 2
0
static int perl_script_eval(PERL_SCRIPT_REC *script)
{
	dSP;
	char *error;
	int retcount;
	SV *ret;

	ENTER;
	SAVETMPS;

	PUSHMARK(SP);
	XPUSHs(sv_2mortal(new_pv(script->path != NULL ? script->path :
				 script->data)));
	XPUSHs(sv_2mortal(new_pv(script->name)));
	PUTBACK;

	retcount = perl_call_pv(script->path != NULL ?
				"Irssi::Core::eval_file" :
				"Irssi::Core::eval_data",
				G_EVAL|G_SCALAR);
	SPAGAIN;

        error = NULL;
	if (SvTRUE(ERRSV)) {
		error = SvPV(ERRSV, PL_na);

		if (error != NULL) {
			error = g_strdup(error);
			signal_emit("script error", 2, script, error);
			g_free(error);
		}
	} else if (retcount > 0) {
		ret = POPs;
	}

	PUTBACK;
	FREETMPS;
	LEAVE;

        return error == NULL;
}
Exemplo n.º 3
0
static int perl_script_eval(PERL_SCRIPT_REC *script)
{
	dSP;
	char *error;

	ENTER;
	SAVETMPS;

	PUSHMARK(SP);
	XPUSHs(sv_2mortal(new_pv(script->path != NULL ? script->path :
				 script->data)));
	XPUSHs(sv_2mortal(new_pv(script->name)));
	PUTBACK;

	perl_call_pv(script->path != NULL ?
                              "Irssi::Core::eval_file" :
                              "Irssi::Core::eval_data",
                              G_EVAL|G_DISCARD);
	SPAGAIN;

        error = NULL;
	if (SvTRUE(ERRSV)) {
		error = SvPV_nolen(ERRSV);

		if (error != NULL) {
			error = g_strdup(error);
			signal_emit("script error", 2, script, error);
			g_free(error);
		}
	}

	FREETMPS;
	LEAVE;

        return error == NULL;
}
Exemplo n.º 4
0
static void perl_script_destroy_package(PERL_SCRIPT_REC *script)
{
	dSP;

	ENTER;
	SAVETMPS;

	PUSHMARK(SP);
	XPUSHs(sv_2mortal(new_pv(script->package)));
	PUTBACK;

	perl_call_pv("Irssi::Core::destroy", G_VOID|G_EVAL|G_DISCARD);

	FREETMPS;
	LEAVE;
}
Exemplo n.º 5
0
void perl_signal_args_to_c(
        void (*callback)(void *, void **), void *cb_arg,
        int signal_id, SV **args, size_t n_args)
{
        union {
                int v_int;
                unsigned long v_ulong;
                GSList *v_gslist;
                GList *v_glist;
        } saved_args[SIGNAL_MAX_ARGUMENTS];
        void *p[SIGNAL_MAX_ARGUMENTS];
        PERL_SIGNAL_ARGS_REC *rec;
        size_t n;

        if (!(rec = perl_signal_args_find(signal_id))) {
                const char *name = signal_get_id_str(signal_id);
                if (!name) {
                        croak("%d is not a known signal id", signal_id);
                }
                croak("\"%s\" is not a registered signal", name);
        }

        for (n = 0; n < SIGNAL_MAX_ARGUMENTS && n < n_args && rec->args[n] != NULL; ++n) {
                void *c_arg;
                SV *arg = args[n];

                if (!SvOK(arg)) {
                        c_arg = NULL;
                } else if (strcmp(rec->args[n], "string") == 0) {
                        c_arg = SvPV_nolen(arg);
                } else if (strcmp(rec->args[n], "int") == 0) {
                        c_arg = (void *)SvIV(arg);
                } else if (strcmp(rec->args[n], "ulongptr") == 0) {
                        saved_args[n].v_ulong = SvUV(arg);
                        c_arg = &saved_args[n].v_ulong;
                } else if (strcmp(rec->args[n], "intptr") == 0) {
                        saved_args[n].v_int = SvIV(SvRV(arg));
                        c_arg = &saved_args[n].v_int;
                } else if (strncmp(rec->args[n], "glistptr_", 9) == 0) {
                        GList *gl;
                        int is_str;
                        AV *av;
                        SV *t;
                        int count;

                        t = SvRV(arg);
                        if (SvTYPE(t) != SVt_PVAV) {
                                croak("Not an ARRAY reference");
                        }
                        av = (AV *)t;

                        is_str = strcmp(rec->args[n]+9, "char*") == 0;

                        gl = NULL;
                        count = av_len(av) + 1;
                        while (count-- > 0) {
                                SV **px = av_fetch(av, count, 0);
                                SV *x = px ? *px : NULL;
                                gl = g_list_prepend(
                                        gl,
                                        x == NULL ? NULL :
                                        is_str ? g_strdup(SvPV_nolen(x)) :
                                        irssi_ref_object(x)
                                );
                        }
                        saved_args[n].v_glist = gl;
                        c_arg = &saved_args[n].v_glist;
                } else if (strncmp(rec->args[n], "gslist_", 7) == 0) {
                        GSList *gsl;
                        AV *av;
                        SV *t;
                        int count;

                        t = SvRV(arg);
                        if (SvTYPE(t) != SVt_PVAV) {
                                croak("Not an ARRAY reference");
                        }
                        av = (AV *)t;

                        gsl = NULL;
                        count = av_len(av) + 1;
                        while (count-- > 0) {
                                SV **x = av_fetch(av, count, 0);
                                gsl = g_slist_prepend(
                                        gsl,
                                        x == NULL ? NULL :
                                        irssi_ref_object(*x)
                                );
                        }
                        c_arg = saved_args[n].v_gslist = gsl;
                } else {
                        c_arg = irssi_ref_object(arg);
                }

                p[n] = c_arg;
        }

        for (; n < SIGNAL_MAX_ARGUMENTS; ++n) {
                p[n] = NULL;
        }

        callback(cb_arg, p);

        for (n = 0; n < SIGNAL_MAX_ARGUMENTS && n < n_args && rec->args[n] != NULL; ++n) {
                SV *arg = args[n];

                if (!SvOK(arg)) {
                        continue;
                }

                if (strcmp(rec->args[n], "intptr") == 0) {
                        SV *t = SvRV(arg);
                        SvIOK_only(t);
                        SvIV_set(t, saved_args[n].v_int);
                } else if (strncmp(rec->args[n], "gslist_", 7) == 0) {
                        g_slist_free(saved_args[n].v_gslist);
                } else if (strncmp(rec->args[n], "glistptr_", 9) == 0) {
                        int is_iobject, is_str;
                        AV *av;
                        GList *gl, *tmp;

                        is_iobject = strcmp(rec->args[n]+9, "iobject") == 0;
                        is_str = strcmp(rec->args[n]+9, "char*") == 0;

                        av = (AV *)SvRV(arg);
                        av_clear(av);

                        gl = saved_args[n].v_glist;
                        for (tmp = gl; tmp != NULL; tmp = tmp->next) {
                                av_push(av,
                                        is_iobject ? iobject_bless((SERVER_REC *)tmp->data) :
                                        is_str ? new_pv(tmp->data) :
                                        irssi_bless_plain(rec->args[n]+9, tmp->data)
                                );
                        }

                        if (is_str) {
                                g_list_foreach(gl, (GFunc)g_free, NULL);
                        }
                        g_list_free(gl);
                }
        }
}
Exemplo n.º 6
0
static void perl_call_signal(PERL_SCRIPT_REC *script, SV *func,
			     int signal_id, gconstpointer *args)
{
	dSP;

	PERL_SIGNAL_ARGS_REC *rec;
	SV *sv, *perlarg, *saved_args[SIGNAL_MAX_ARGUMENTS];
	AV *av;
        void *arg;
	int n;


	ENTER;
	SAVETMPS;

	PUSHMARK(sp);

	/* push signal argument to perl stack */
	rec = perl_signal_args_find(signal_id);

        memset(saved_args, 0, sizeof(saved_args));
	for (n = 0; n < SIGNAL_MAX_ARGUMENTS &&
		    rec != NULL && rec->args[n] != NULL; n++) {
		arg = (void *) args[n];

                if (strncmp(rec->args[n], "glistptr_", 9) == 0) {
			/* pointer to linked list - push as AV */
			GList *tmp, **ptr;
                        int is_iobject, is_str;

                        is_iobject = strcmp(rec->args[n]+9, "iobject") == 0;
                        is_str = strcmp(rec->args[n]+9, "char*") == 0;
			av = newAV();

			ptr = arg;
			for (tmp = *ptr; tmp != NULL; tmp = tmp->next) {
				sv = is_iobject ? iobject_bless((SERVER_REC *) tmp->data) :
					is_str ? new_pv(tmp->data) :
					irssi_bless_plain(rec->args[n]+9, tmp->data);
				av_push(av, sv);
			}

			saved_args[n] = perlarg = newRV_noinc((SV *) av);
                } else if (strcmp(rec->args[n], "int") == 0)
                        perlarg = newSViv((IV)arg);
                else if (arg == NULL)
                        perlarg = &PL_sv_undef;
                else if (strcmp(rec->args[n], "string") == 0)
                        perlarg = new_pv(arg);
                else if (strcmp(rec->args[n], "ulongptr") == 0)
                        perlarg = newSViv(*(unsigned long *) arg);
                else if (strcmp(rec->args[n], "intptr") == 0)
                        saved_args[n] = perlarg = newRV_noinc(newSViv(*(int *) arg));
                else if (strncmp(rec->args[n], "gslist_", 7) == 0) {
			/* linked list - push as AV */
			GSList *tmp;
			int is_iobject;

                        is_iobject = strcmp(rec->args[n]+7, "iobject") == 0;
			av = newAV();
			for (tmp = arg; tmp != NULL; tmp = tmp->next) {
				sv = is_iobject ? iobject_bless((SERVER_REC *) tmp->data) :
					irssi_bless_plain(rec->args[n]+7, tmp->data);
				av_push(av, sv);
			}

			perlarg = newRV_noinc((SV *) av);
		} else if (strcmp(rec->args[n], "iobject") == 0) {
			/* "irssi object" - any struct that has
			   "int type; int chat_type" as it's first
			   variables (server, channel, ..) */
			perlarg = iobject_bless((SERVER_REC *) arg);
		} else if (strcmp(rec->args[n], "siobject") == 0) {
			/* "simple irssi object" - any struct that has
			   int type; as it's first variable (dcc) */
			perlarg = simple_iobject_bless((SERVER_REC *) arg);
		} else {
			/* blessed object */
			perlarg = plain_bless(arg, rec->args[n]);
		}
		XPUSHs(sv_2mortal(perlarg));
	}

	PUTBACK;
	perl_call_sv(func, G_EVAL|G_DISCARD);
	SPAGAIN;

	if (SvTRUE(ERRSV)) {
		char *error = g_strdup(SvPV_nolen(ERRSV));
		signal_emit("script error", 2, script, error);
                g_free(error);
                rec = NULL;
	}

        /* restore arguments the perl script modified */
	for (n = 0; n < SIGNAL_MAX_ARGUMENTS &&
		    rec != NULL && rec->args[n] != NULL; n++) {
		arg = (void *) args[n];

		if (saved_args[n] == NULL)
                        continue;

		if (strcmp(rec->args[n], "intptr") == 0) {
			int *val = arg;
			*val = SvIV(SvRV(saved_args[n]));
		} else if (strncmp(rec->args[n], "glistptr_", 9) == 0) {
                        GList **ret = arg;
			GList *out = NULL;
                        void *val;
                        int count;

			av = (AV *) SvRV(saved_args[n]);
                        count = av_len(av);
			while (count-- >= 0) {
				sv = av_shift(av);
				if (SvPOKp(sv))
					val = g_strdup(SvPV_nolen(sv));
				else
                                        val = GINT_TO_POINTER(SvIV(sv));

				out = g_list_append(out, val);
			}

			if (strcmp(rec->args[n]+9, "char*") == 0)
                                g_list_foreach(*ret, (GFunc) g_free, NULL);
			g_list_free(*ret);
                        *ret = out;
		}
	}

	FREETMPS;
	LEAVE;
}
Exemplo n.º 7
0
static void cmd_run(const char *data)
{
	dSP;
	struct stat statbuf;
	char *fname, *name, *p;
	int retcount;

	if (g_path_is_absolute(data)) {
		/* whole path specified */
		fname = g_strdup(data);
	} else {
		/* add .pl suffix if it's missing */
		name = (strlen(data) > 3 && strcmp(data+strlen(data)-3, ".pl") == 0) ?
			g_strdup(data) : g_strdup_printf("%s.pl", data);

		/* check from ~/.irssi/scripts/ */
		fname = g_strdup_printf("%s/.irssi/scripts/%s", g_get_home_dir(), name);
		if (stat(fname, &statbuf) != 0) {
			/* check from SCRIPTDIR */
			g_free(fname),
			fname = g_strdup_printf(SCRIPTDIR"/%s", name);
		}
		g_free(name);
	}

	/* get script name */
	name = g_strdup(g_basename(fname));
	p = strrchr(name, '.');
	if (p != NULL) *p = '\0';

	script_fix_name(name);
	perl_script_destroy(name);

	ENTER;
	SAVETMPS;

	PUSHMARK(SP);
	XPUSHs(sv_2mortal(new_pv(fname))); g_free(fname);
	XPUSHs(sv_2mortal(new_pv(name)));
	PUTBACK;

	retcount = perl_call_pv("Irssi::Load::eval_file",
				G_EVAL|G_SCALAR);
	SPAGAIN;

	if (SvTRUE(ERRSV)) {
		STRLEN n_a;

		signal_emit("gui dialog", 2, "error", SvPV(ERRSV, n_a));
	}
	else if (retcount > 0) {
		char *str = POPp;

		if (str != NULL && *str != '\0')
			signal_emit("gui dialog", 2, "error", str);
	}

	PUTBACK;
	FREETMPS;
	LEAVE;

	perl_scripts = g_slist_append(perl_scripts, g_strdup(name));
	signal_emit("script new", 2, "PERL", name);
        g_free(name);
}