diff options
author | Timo Sirainen <cras@irssi.org> | 2002-10-27 22:30:41 +0000 |
---|---|---|
committer | cras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564> | 2002-10-27 22:30:41 +0000 |
commit | d58e119a98a534045f9a016e5e41477443ba3b98 (patch) | |
tree | b43289b4a39292b453d62d80a0f3aa19ef04b6bb /src/perl/common | |
parent | d3f4f13f94098cdbccc54dd449d8a64debef6fd8 (diff) | |
download | irssi-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.xs | 170 | ||||
-rw-r--r-- | src/perl/common/Irssi.xs | 3 | ||||
-rw-r--r-- | src/perl/common/Server.xs | 2 |
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 |