summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Sirainen <cras@irssi.org>2002-12-04 22:17:07 +0000
committercras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564>2002-12-04 22:17:07 +0000
commit6230c055f2f2f62ffe4cd242105db938a9f030d5 (patch)
tree2167229e196df0607f380a87b5b8a31fa6524aad
parent54000e19082a1fd9d8ad1e093e7ebcf23232721a (diff)
downloadirssi-6230c055f2f2f62ffe4cd242105db938a9f030d5.zip
Added Irssi::signal_register() to dynamically register new signals.
git-svn-id: http://svn.irssi.org/repos/irssi/trunk@3045 dbcabf3a-b0e7-0310-adc4-f8d773084564
-rw-r--r--src/perl/common/Core.xs33
-rw-r--r--src/perl/perl-signals.c67
-rw-r--r--src/perl/perl-signals.h2
3 files changed, 89 insertions, 13 deletions
diff --git a/src/perl/common/Core.xs b/src/perl/common/Core.xs
index 8230e77f..10cd3936 100644
--- a/src/perl/common/Core.xs
+++ b/src/perl/common/Core.xs
@@ -142,6 +142,39 @@ CODE:
else
perl_signal_add_hash(SvIV(ST(0)), ST(1));
+void
+signal_register(...)
+PREINIT:
+ HV *hv;
+ HE *he;
+ I32 len, pos;
+ const char *arr[7];
+CODE:
+ if (items != 1 || !is_hvref(ST(0)))
+ croak("Usage: Irssi::signal_register(hash)");
+
+ hv = hvref(ST(0));
+ hv_iterinit(hv);
+ while ((he = hv_iternext(hv)) != NULL) {
+ const char *key = hv_iterkey(he, &len);
+ SV *val = HeVAL(he);
+ AV *av;
+
+ if (!SvROK(val) || SvTYPE(SvRV(val)) != SVt_PVAV)
+ croak("not array reference");
+
+ av = (AV *) SvRV(val);
+ len = av_len(av)+1;
+ if (len > 6) len = 6;
+ for (pos = 0; pos < len; pos++) {
+ SV **val = av_fetch(av, pos, 0);
+ arr[pos] = SvPV(*val, PL_na);
+ }
+ arr[pos] = NULL;
+ perl_signal_register(key, arr);
+ }
+
+
int
SIGNAL_PRIORITY_LOW()
CODE:
diff --git a/src/perl/perl-signals.c b/src/perl/perl-signals.c
index 6dcde221..85e537de 100644
--- a/src/perl/perl-signals.c
+++ b/src/perl/perl-signals.c
@@ -39,6 +39,7 @@ typedef struct {
typedef struct {
char *signal;
char *args[7];
+ int dynamic;
} PERL_SIGNAL_ARGS_REC;
#include "perl-signals-list.h"
@@ -388,6 +389,34 @@ void perl_signals_stop(void)
signals = NULL;
}
+static void register_signal_rec(PERL_SIGNAL_ARGS_REC *rec)
+{
+ if (rec->signal[strlen(rec->signal)-1] == ' ') {
+ perl_signal_args_partial =
+ g_slist_append(perl_signal_args_partial, rec);
+ } else {
+ int signal_id = signal_get_uniq_id(rec->signal);
+ g_hash_table_insert(perl_signal_args_hash,
+ GINT_TO_POINTER(signal_id), rec);
+ }
+}
+
+void perl_signal_register(const char *signal, const char **args)
+{
+ PERL_SIGNAL_ARGS_REC *rec;
+ int i;
+
+ if (perl_signal_args_find(signal_get_uniq_id(signal)) != NULL)
+ return;
+
+ rec = g_new0(PERL_SIGNAL_ARGS_REC, 1);
+ for (i = 0; i < 6 && args[i] != NULL; i++)
+ rec->args[i] = g_strdup(args[i]);
+ rec->dynamic = TRUE;
+ rec->signal = g_strdup(signal);
+ register_signal_rec(rec);
+}
+
void perl_signals_init(void)
{
int n;
@@ -396,23 +425,35 @@ void perl_signals_init(void)
(GCompareFunc) g_direct_equal);
perl_signal_args_partial = NULL;
- for (n = 0; perl_signal_args[n].signal != NULL; n++) {
- PERL_SIGNAL_ARGS_REC *rec = &perl_signal_args[n];
+ for (n = 0; perl_signal_args[n].signal != NULL; n++)
+ register_signal_rec(&perl_signal_args[n]);
+}
- if (rec->signal[strlen(rec->signal)-1] == ' ') {
- perl_signal_args_partial =
- g_slist_append(perl_signal_args_partial, rec);
- } else {
- int signal_id = signal_get_uniq_id(rec->signal);
- g_hash_table_insert(perl_signal_args_hash,
- GINT_TO_POINTER(signal_id),
- rec);
- }
- }
+static void signal_args_free(PERL_SIGNAL_ARGS_REC *rec)
+{
+ int i;
+
+ if (!rec->dynamic)
+ return;
+
+ for (i = 0; i < 6 && rec->args[i] != NULL; i++)
+ g_free(rec->args[i]);
+ g_free(rec->signal);
+ g_free(rec);
+}
+
+static void signal_args_hash_free(void *key, PERL_SIGNAL_ARGS_REC *rec)
+{
+ signal_args_free(rec);
}
void perl_signals_deinit(void)
{
- g_slist_free(perl_signal_args_partial);
+ g_slist_foreach(perl_signal_args_partial,
+ (GFunc) signal_args_free, NULL);
+ g_slist_free(perl_signal_args_partial);
+
+ g_hash_table_foreach(perl_signal_args_hash,
+ (GHFunc) signal_args_hash_free, NULL);
g_hash_table_destroy(perl_signal_args_hash);
}
diff --git a/src/perl/perl-signals.h b/src/perl/perl-signals.h
index 60e6636e..f0b8e442 100644
--- a/src/perl/perl-signals.h
+++ b/src/perl/perl-signals.h
@@ -21,6 +21,8 @@ void perl_command_unbind(const char *cmd, SV *func);
void perl_command_runsub(const char *cmd, const char *data,
SERVER_REC *server, WI_ITEM_REC *item);
+void perl_signal_register(const char *signal, const char **args);
+
void perl_signals_start(void);
void perl_signals_stop(void);