summaryrefslogtreecommitdiff
path: root/src/perl/common
diff options
context:
space:
mode:
authorTimo Sirainen <cras@irssi.org>2002-10-27 22:30:41 +0000
committercras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564>2002-10-27 22:30:41 +0000
commitd58e119a98a534045f9a016e5e41477443ba3b98 (patch)
treeb43289b4a39292b453d62d80a0f3aa19ef04b6bb /src/perl/common
parentd3f4f13f94098cdbccc54dd449d8a64debef6fd8 (diff)
downloadirssi-d58e119a98a534045f9a016e5e41477443ba3b98.zip
Exported expando interface to perl. Fix for statusbar deinit.
git-svn-id: http://svn.irssi.org/repos/irssi/trunk@2975 dbcabf3a-b0e7-0310-adc4-f8d773084564
Diffstat (limited to 'src/perl/common')
-rw-r--r--src/perl/common/Expando.xs170
-rw-r--r--src/perl/common/Irssi.xs3
-rw-r--r--src/perl/common/Server.xs2
3 files changed, 174 insertions, 1 deletions
diff --git a/src/perl/common/Expando.xs b/src/perl/common/Expando.xs
new file mode 100644
index 00000000..d3a232f7
--- /dev/null
+++ b/src/perl/common/Expando.xs
@@ -0,0 +1,170 @@
+#include "module.h"
+#include "expandos.h"
+
+typedef struct {
+ PERL_SCRIPT_REC *script;
+ SV *func;
+} PerlExpando;
+
+static GHashTable *perl_expando_defs;
+
+static char *sig_perl_expando(SERVER_REC *server, void *item, int *free_ret);
+
+static int check_expando_destroy(char *key, PerlExpando *rec,
+ PERL_SCRIPT_REC *script)
+{
+ if (rec->script == script) {
+ expando_destroy(key, sig_perl_expando);
+ SvREFCNT_dec(rec->func);
+ g_free(key);
+ g_free(rec);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void script_unregister_expandos(PERL_SCRIPT_REC *script)
+{
+ g_hash_table_foreach_remove(perl_expando_defs,
+ (GHRFunc) check_expando_destroy, script);
+}
+
+void perl_expando_init(void)
+{
+ perl_expando_defs = g_hash_table_new((GHashFunc) g_str_hash,
+ (GCompareFunc) g_str_equal);
+ signal_add("script destroyed", (SIGNAL_FUNC) script_unregister_expandos);
+}
+
+static void expando_def_destroy(char *key, PerlExpando *rec)
+{
+ SvREFCNT_dec(rec->func);
+ g_free(key);
+ g_free(rec);
+}
+
+void perl_expando_deinit(void)
+{
+ signal_remove("script destroyed", (SIGNAL_FUNC) script_unregister_expandos);
+
+ g_hash_table_foreach(perl_expando_defs,
+ (GHFunc) expando_def_destroy, NULL);
+ g_hash_table_destroy(perl_expando_defs);
+}
+
+static char *perl_expando_event(PerlExpando *rec, SERVER_REC *server,
+ WI_ITEM_REC *item, int *free_ret)
+{
+ dSP;
+ char *ret;
+ int retcount;
+
+ ENTER;
+ SAVETMPS;
+
+ PUSHMARK(SP);
+ XPUSHs(sv_2mortal(iobject_bless(server)));
+ XPUSHs(sv_2mortal(iobject_bless(item)));
+ PUTBACK;
+
+ retcount = perl_call_sv(rec->func, G_EVAL|G_SCALAR);
+ SPAGAIN;
+
+ if (SvTRUE(ERRSV)) {
+ /* make sure we don't get back here */
+ if (rec->script != NULL)
+ script_unregister_expandos(rec->script);
+
+ signal_emit("script error", 2, rec->script, SvPV(ERRSV, PL_na));
+ ret = NULL;
+ } else if (retcount > 0) {
+ ret = g_strdup(POPp);
+ *free_ret = TRUE;
+ }
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+
+ return ret;
+}
+
+static char *sig_perl_expando(SERVER_REC *server, void *item, int *free_ret)
+{
+ PerlExpando *rec;
+
+ rec = g_hash_table_lookup(perl_expando_defs, current_expando);
+ if (rec != NULL)
+ return perl_expando_event(rec, server, item, free_ret);
+ return NULL;
+}
+
+void expando_signals_add_hash(const char *key, SV *signals)
+{
+ HV *hv;
+ HE *he;
+ I32 len;
+ const char *argstr;
+ ExpandoArg arg;
+
+ if (!is_hvref(signals)) {
+ croak("Usage: Irssi::expando_create(key, func, hash)");
+ return;
+ }
+
+ hv = hvref(signals);
+ hv_iterinit(hv);
+ while ((he = hv_iternext(hv)) != NULL) {
+ SV *argsv = HeVAL(he);
+ argstr = SvPV(argsv, PL_na);
+
+ if (strcasecmp(argstr, "none") == 0)
+ arg = EXPANDO_ARG_NONE;
+ else if (strcasecmp(argstr, "server") == 0)
+ arg = EXPANDO_ARG_SERVER;
+ else if (strcasecmp(argstr, "window") == 0)
+ arg = EXPANDO_ARG_WINDOW;
+ else if (strcasecmp(argstr, "windowitem") == 0)
+ arg = EXPANDO_ARG_WINDOW_ITEM;
+ else if (strcasecmp(argstr, "never") == 0)
+ arg = EXPANDO_NEVER;
+ else {
+ croak("Unknown signal type: %s", argstr);
+ break;
+ }
+ expando_add_signal(key, hv_iterkey(he, &len), arg);
+ }
+}
+
+MODULE = Irssi::Expando PACKAGE = Irssi
+PROTOTYPES: ENABLE
+
+void
+expando_create(key, func, signals)
+ char *key
+ SV *func
+ SV *signals
+PREINIT:
+ PerlExpando *rec;
+CODE:
+ rec = g_new0(PerlExpando, 1);
+ rec->script = perl_script_find_package(perl_get_package());
+ rec->func = perl_func_sv_inc(func, perl_get_package());
+
+ expando_create(key, sig_perl_expando, NULL);
+ g_hash_table_insert(perl_expando_defs, g_strdup(key), rec);
+ expando_signals_add_hash(key, signals);
+
+void
+expando_destroy(name)
+ char *name
+PREINIT:
+ gpointer key, value;
+CODE:
+ if (g_hash_table_lookup_extended(perl_expando_defs, name, &key, &value)) {
+ g_hash_table_remove(perl_expando_defs, name);
+ g_free(key);
+ SvREFCNT_dec((SV *) value);
+ }
+ expando_destroy(name, sig_perl_expando);
diff --git a/src/perl/common/Irssi.xs b/src/perl/common/Irssi.xs
index 67d5e96c..328e32d3 100644
--- a/src/perl/common/Irssi.xs
+++ b/src/perl/common/Irssi.xs
@@ -14,16 +14,19 @@ CODE:
initialized = TRUE;
perl_settings_init();
+ perl_expando_init();
void
deinit()
CODE:
if (!initialized) return;
+ perl_expando_deinit();
perl_settings_deinit();
BOOT:
irssi_boot(Channel);
irssi_boot(Core);
+ irssi_boot(Expando);
irssi_boot(Ignore);
irssi_boot(Log);
irssi_boot(Masks);
diff --git a/src/perl/common/Server.xs b/src/perl/common/Server.xs
index adcabb16..facf1da0 100644
--- a/src/perl/common/Server.xs
+++ b/src/perl/common/Server.xs
@@ -31,7 +31,7 @@ PPCODE:
}
Irssi::Connect
-server_create_conn(chat_type, dest, port=6667, chatnet=NULL, password=NULL, nick=NULL)
+server_create_conn(chat_type, dest, port, chatnet=NULL, password=NULL, nick=NULL)
int chat_type
char *dest
int port