5 PERL_SCRIPT_REC *script;
9 static GHashTable *perl_expando_defs;
11 static char *sig_perl_expando(SERVER_REC *server, void *item, int *free_ret);
13 static int check_expando_destroy(char *key, PerlExpando *rec,
14 PERL_SCRIPT_REC *script)
16 if (rec->script == script) {
17 expando_destroy(key, sig_perl_expando);
18 SvREFCNT_dec(rec->func);
27 static void script_unregister_expandos(PERL_SCRIPT_REC *script)
29 g_hash_table_foreach_remove(perl_expando_defs,
30 (GHRFunc) check_expando_destroy, script);
33 void perl_expando_init(void)
35 perl_expando_defs = g_hash_table_new((GHashFunc) g_str_hash,
36 (GCompareFunc) g_str_equal);
37 signal_add("script destroyed", (SIGNAL_FUNC) script_unregister_expandos);
40 static void expando_def_destroy(char *key, PerlExpando *rec)
42 SvREFCNT_dec(rec->func);
47 void perl_expando_deinit(void)
49 signal_remove("script destroyed", (SIGNAL_FUNC) script_unregister_expandos);
51 g_hash_table_foreach(perl_expando_defs,
52 (GHFunc) expando_def_destroy, NULL);
53 g_hash_table_destroy(perl_expando_defs);
56 static char *perl_expando_event(PerlExpando *rec, SERVER_REC *server,
57 WI_ITEM_REC *item, int *free_ret)
67 XPUSHs(sv_2mortal(iobject_bless(server)));
68 XPUSHs(sv_2mortal(iobject_bless(item)));
71 retcount = perl_call_sv(rec->func, G_EVAL|G_SCALAR);
76 /* make sure we don't get back here */
77 if (rec->script != NULL)
78 script_unregister_expandos(rec->script);
80 signal_emit("script error", 2, rec->script, SvPV(ERRSV, PL_na));
81 } else if (retcount > 0) {
93 static char *sig_perl_expando(SERVER_REC *server, void *item, int *free_ret)
97 rec = g_hash_table_lookup(perl_expando_defs, current_expando);
99 return perl_expando_event(rec, server, item, free_ret);
103 void expando_signals_add_hash(const char *key, SV *signals)
111 if (!is_hvref(signals)) {
112 croak("Usage: Irssi::expando_create(key, func, hash)");
118 while ((he = hv_iternext(hv)) != NULL) {
119 SV *argsv = HeVAL(he);
120 argstr = SvPV(argsv, PL_na);
122 if (strcasecmp(argstr, "none") == 0)
123 arg = EXPANDO_ARG_NONE;
124 else if (strcasecmp(argstr, "server") == 0)
125 arg = EXPANDO_ARG_SERVER;
126 else if (strcasecmp(argstr, "window") == 0)
127 arg = EXPANDO_ARG_WINDOW;
128 else if (strcasecmp(argstr, "windowitem") == 0)
129 arg = EXPANDO_ARG_WINDOW_ITEM;
130 else if (strcasecmp(argstr, "never") == 0)
133 croak("Unknown signal type: %s", argstr);
136 expando_add_signal(key, hv_iterkey(he, &len), arg);
140 MODULE = Irssi::Expando PACKAGE = Irssi
144 expando_create(key, func, signals)
151 rec = g_new0(PerlExpando, 1);
152 rec->script = perl_script_find_package(perl_get_package());
153 rec->func = perl_func_sv_inc(func, perl_get_package());
155 expando_create(key, sig_perl_expando, NULL);
156 g_hash_table_insert(perl_expando_defs, g_strdup(key), rec);
157 expando_signals_add_hash(key, signals);
160 expando_destroy(name)
165 if (g_hash_table_lookup_extended(perl_expando_defs, name, &key, &value)) {
166 g_hash_table_remove(perl_expando_defs, name);
168 SvREFCNT_dec((SV *) value);
170 expando_destroy(name, sig_perl_expando);