mirror of
https://github.com/irssi/irssi.git
synced 2024-12-04 14:46:39 -05:00
Merge pull request #1192 from ailin-nemui/perl-signals-format
add "print format" signal to perl
This commit is contained in:
commit
5ba58d9067
@ -251,7 +251,7 @@ FE common
|
||||
* Provides signals:
|
||||
|
||||
completion.c:
|
||||
"complete word", GList * of char*, WINDOW_REC, char *word, char *linestart, int *want_space
|
||||
"complete word", GList * of char *s, WINDOW_REC, char *word, char *linestart, int *want_space
|
||||
|
||||
fe-common-core.c:
|
||||
"irssi init read settings"
|
||||
@ -285,6 +285,8 @@ keyboard.c:
|
||||
|
||||
printtext.c:
|
||||
"print text", TEXT_DEST_REC *dest, char *text, char *stripped
|
||||
"print format", THEME_REC *theme, char *module, TEXT_DEST_REC *dest, formatnum_args
|
||||
"print noformat", TEXT_DEST_REC *dest, char *text
|
||||
|
||||
themes.c:
|
||||
"theme created", THEME_REC
|
||||
|
@ -6,7 +6,7 @@
|
||||
#define IRSSI_GLOBAL_CONFIG "irssi.conf" /* config file name in /etc/ */
|
||||
#define IRSSI_HOME_CONFIG "config" /* config file name in ~/.irssi/ */
|
||||
|
||||
#define IRSSI_ABI_VERSION 27
|
||||
#define IRSSI_ABI_VERSION 28
|
||||
|
||||
#define DEFAULT_SERVER_ADD_PORT 6667
|
||||
#define DEFAULT_SERVER_ADD_TLS_PORT 6697
|
||||
|
@ -570,9 +570,9 @@ static void sig_print_format(THEME_REC *theme, const char *module,
|
||||
|
||||
str = format_get_text_theme_charargs(log_theme, module, dest,
|
||||
GPOINTER_TO_INT(formatnum), args);
|
||||
if (str != NULL && *str != '\0') {
|
||||
skip_next_printtext = TRUE;
|
||||
|
||||
if (*str != '\0') {
|
||||
/* add the line start format */
|
||||
linestart = format_get_level_tag(log_theme, dest);
|
||||
tmp = str;
|
||||
|
@ -650,6 +650,9 @@ char *format_get_text_theme_charargs(THEME_REC *theme, const char *module,
|
||||
MODULE_THEME_REC *module_theme;
|
||||
char *text;
|
||||
|
||||
if (module == NULL)
|
||||
return NULL;
|
||||
|
||||
module_theme = g_hash_table_lookup(theme->modules, module);
|
||||
if (module_theme == NULL)
|
||||
return NULL;
|
||||
|
@ -124,6 +124,9 @@ static void sig_print_format(THEME_REC *theme, const char *module, TEXT_DEST_REC
|
||||
if (!scrollback_format)
|
||||
return;
|
||||
|
||||
if (module == NULL)
|
||||
return;
|
||||
|
||||
info = store_lineinfo_tmp(dest);
|
||||
|
||||
formatnum = GPOINTER_TO_INT(formatnump);
|
||||
|
@ -68,13 +68,15 @@ static void add_tuple(gpointer key_, gpointer value_, gpointer user_data)
|
||||
(void) hv_store(hash, key, strlen(key), new_pv(value), 0);
|
||||
}
|
||||
|
||||
static void wrap_signal_emit(void *signal, void **p) {
|
||||
signal_emit(signal, 6, p[0], p[1], p[2], p[3], p[4], p[5]);
|
||||
static void wrap_signal_emit(void *signal, int params, void **p)
|
||||
{
|
||||
signal_emit(signal, params, p[0], p[1], p[2], p[3], p[4], p[5]);
|
||||
}
|
||||
|
||||
static void wrap_signal_continue(void *dummy, void **p) {
|
||||
static void wrap_signal_continue(void *dummy, int params, void **p)
|
||||
{
|
||||
(void)dummy;
|
||||
signal_continue(6, p[0], p[1], p[2], p[3], p[4], p[5]);
|
||||
signal_continue(params, p[0], p[1], p[2], p[3], p[4], p[5]);
|
||||
}
|
||||
|
||||
MODULE = Irssi::Core PACKAGE = Irssi
|
||||
@ -85,33 +87,14 @@ signal_emit(signal, ...)
|
||||
char *signal
|
||||
CODE:
|
||||
int signal_id;
|
||||
SV *args[SIGNAL_MAX_ARGUMENTS];
|
||||
int n, used;
|
||||
|
||||
signal_id = signal_get_uniq_id(signal);
|
||||
used = items - 1;
|
||||
if (used > SIGNAL_MAX_ARGUMENTS) {
|
||||
used = SIGNAL_MAX_ARGUMENTS;
|
||||
}
|
||||
for (n = 0; n < used; ++n) {
|
||||
args[n] = ST(n + 1);
|
||||
}
|
||||
perl_signal_args_to_c(wrap_signal_emit, signal, signal_id, args, used);
|
||||
perl_signal_args_to_c(wrap_signal_emit, signal, signal_id, &ST(1), items - 1);
|
||||
|
||||
void
|
||||
signal_continue(...)
|
||||
CODE:
|
||||
SV *args[SIGNAL_MAX_ARGUMENTS];
|
||||
int n, used;
|
||||
|
||||
used = items;
|
||||
if (used > SIGNAL_MAX_ARGUMENTS) {
|
||||
used = SIGNAL_MAX_ARGUMENTS;
|
||||
}
|
||||
for (n = 0; n < used; ++n) {
|
||||
args[n] = ST(n);
|
||||
}
|
||||
perl_signal_args_to_c(wrap_signal_continue, NULL, signal_get_emitted_id(), args, used);
|
||||
perl_signal_args_to_c(wrap_signal_continue, NULL, signal_get_emitted_id(), &ST(0), items);
|
||||
|
||||
void
|
||||
signal_add(...)
|
||||
@ -162,7 +145,7 @@ PREINIT:
|
||||
HV *hv;
|
||||
HE *he;
|
||||
I32 len, pos;
|
||||
const char *arr[7];
|
||||
const char *arr[SIGNAL_MAX_ARGUMENTS + 1];
|
||||
CODE:
|
||||
if (items != 1 || !is_hvref(ST(0)))
|
||||
croak("Usage: Irssi::signal_register(hash)");
|
||||
@ -179,7 +162,8 @@ CODE:
|
||||
|
||||
av = (AV *) SvRV(val);
|
||||
len = av_len(av)+1;
|
||||
if (len > 6) len = 6;
|
||||
if (len > SIGNAL_MAX_ARGUMENTS)
|
||||
len = SIGNAL_MAX_ARGUMENTS;
|
||||
for (pos = 0; pos < len; pos++) {
|
||||
SV **val = av_fetch(av, pos, 0);
|
||||
arr[pos] = SvPV_nolen(*val);
|
||||
|
@ -16,14 +16,15 @@ while (<>) {
|
||||
$signal = $1;
|
||||
$_ = $3;
|
||||
|
||||
s/GList \* of ([^,]*)/glistptr_\1/g;
|
||||
s/GSList of (\w+)s/gslist_\1/g;
|
||||
s/GList \* of ([^,]*)s/glistptr_\1/g;
|
||||
s/GSList of ([^,]*)s/gslist_\1/g;
|
||||
|
||||
s/char \*[^,]*/string/g;
|
||||
s/ulong \*[^,]*/ulongptr/g;
|
||||
s/int \*[^,]*/intptr/g;
|
||||
s/int [^,]*/int/g;
|
||||
|
||||
|
||||
my %map = (
|
||||
# core
|
||||
CHATNET_REC => 'iobject',
|
||||
|
@ -21,10 +21,11 @@
|
||||
#define NEED_PERL_H
|
||||
#define PERL_NO_GET_CONTEXT
|
||||
#include "module.h"
|
||||
#include <irssi/src/core/modules.h>
|
||||
#include <irssi/src/core/signals.h>
|
||||
#include <irssi/src/core/commands.h>
|
||||
#include <irssi/src/core/modules.h>
|
||||
#include <irssi/src/core/servers.h>
|
||||
#include <irssi/src/core/signals.h>
|
||||
#include <irssi/src/fe-common/core/formats.h>
|
||||
|
||||
#include <irssi/src/perl/perl-core.h>
|
||||
#include <irssi/src/perl/perl-common.h>
|
||||
@ -39,7 +40,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
char *signal;
|
||||
char *args[7];
|
||||
char *args[SIGNAL_MAX_ARGUMENTS + 1];
|
||||
int dynamic;
|
||||
} PERL_SIGNAL_ARGS_REC;
|
||||
|
||||
@ -71,9 +72,8 @@ static PERL_SIGNAL_ARGS_REC *perl_signal_args_find(int signal_id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void perl_signal_args_to_c(
|
||||
void (*callback)(void *, void **), void *cb_arg,
|
||||
int signal_id, SV **args, size_t n_args)
|
||||
void perl_signal_args_to_c(void (*callback)(void *, int, void **), void *cb_arg, int signal_id,
|
||||
SV **args, size_t n_args)
|
||||
{
|
||||
union {
|
||||
int v_int;
|
||||
@ -83,6 +83,7 @@ void perl_signal_args_to_c(
|
||||
} saved_args[SIGNAL_MAX_ARGUMENTS];
|
||||
void *p[SIGNAL_MAX_ARGUMENTS];
|
||||
PERL_SIGNAL_ARGS_REC *rec;
|
||||
char *arglist[MAX_FORMAT_PARAMS];
|
||||
size_t n;
|
||||
|
||||
if (!(rec = perl_signal_args_find(signal_id))) {
|
||||
@ -97,12 +98,41 @@ void perl_signal_args_to_c(
|
||||
void *c_arg;
|
||||
SV *arg = args[n];
|
||||
|
||||
if (!SvOK(arg)) {
|
||||
if (g_strcmp0(rec->args[n], "formatnum_args") == 0 && n >= 3) {
|
||||
const FORMAT_REC *formats;
|
||||
const char *module;
|
||||
int num;
|
||||
int formatnum;
|
||||
|
||||
module = SvPV_nolen(args[n - 2]);
|
||||
formatnum = format_find_tag(module, SvPV_nolen(arg));
|
||||
if (formatnum < 0) { /* format out of bounds */
|
||||
p[n - 2] = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
formats = g_hash_table_lookup(default_formats, module);
|
||||
arglist[formats[formatnum].params] = NULL;
|
||||
|
||||
p[n++] = GINT_TO_POINTER(formatnum);
|
||||
|
||||
for (num = 0; num < formats[formatnum].params; num++) {
|
||||
if (n + num < n_args)
|
||||
arglist[num] = SvPV_nolen(args[n + num]);
|
||||
else
|
||||
arglist[num] = "";
|
||||
}
|
||||
|
||||
p[n++] = arglist;
|
||||
n_args = n;
|
||||
|
||||
break;
|
||||
} else if (!SvOK(arg)) {
|
||||
c_arg = NULL;
|
||||
} else if (g_strcmp0(rec->args[n], "string") == 0) {
|
||||
c_arg = SvPV_nolen(arg);
|
||||
} else if (g_strcmp0(rec->args[n], "int") == 0) {
|
||||
c_arg = (void *)SvIV(arg);
|
||||
c_arg = (void *) SvIV(arg);
|
||||
} else if (g_strcmp0(rec->args[n], "ulongptr") == 0) {
|
||||
saved_args[n].v_ulong = SvUV(arg);
|
||||
c_arg = &saved_args[n].v_ulong;
|
||||
@ -120,21 +150,20 @@ void perl_signal_args_to_c(
|
||||
if (SvTYPE(t) != SVt_PVAV) {
|
||||
croak("Not an ARRAY reference");
|
||||
}
|
||||
av = (AV *)t;
|
||||
av = (AV *) t;
|
||||
|
||||
is_str = g_strcmp0(rec->args[n]+9, "char*") == 0;
|
||||
is_str = g_strcmp0(rec->args[n] + 9, "string") == 0 ||
|
||||
g_strcmp0(rec->args[n] + 9, "char*") == 0; /* deprecated form */
|
||||
|
||||
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 :
|
||||
gl = g_list_prepend(gl, x == NULL ?
|
||||
NULL :
|
||||
is_str ? g_strdup(SvPV_nolen(x)) :
|
||||
irssi_ref_object(x)
|
||||
);
|
||||
irssi_ref_object(x));
|
||||
}
|
||||
saved_args[n].v_glist = gl;
|
||||
c_arg = &saved_args[n].v_glist;
|
||||
@ -148,17 +177,13 @@ void perl_signal_args_to_c(
|
||||
if (SvTYPE(t) != SVt_PVAV) {
|
||||
croak("Not an ARRAY reference");
|
||||
}
|
||||
av = (AV *)t;
|
||||
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)
|
||||
);
|
||||
gsl = g_slist_prepend(gsl, x == NULL ? NULL : irssi_ref_object(*x));
|
||||
}
|
||||
c_arg = saved_args[n].v_gslist = gsl;
|
||||
} else {
|
||||
@ -172,7 +197,7 @@ void perl_signal_args_to_c(
|
||||
p[n] = NULL;
|
||||
}
|
||||
|
||||
callback(cb_arg, p);
|
||||
callback(cb_arg, n_args, p);
|
||||
|
||||
for (n = 0; n < SIGNAL_MAX_ARGUMENTS && n < n_args && rec->args[n] != NULL; ++n) {
|
||||
SV *arg = args[n];
|
||||
@ -192,23 +217,24 @@ void perl_signal_args_to_c(
|
||||
AV *av;
|
||||
GList *gl, *tmp;
|
||||
|
||||
is_iobject = g_strcmp0(rec->args[n]+9, "iobject") == 0;
|
||||
is_str = g_strcmp0(rec->args[n]+9, "char*") == 0;
|
||||
is_iobject = g_strcmp0(rec->args[n] + 9, "iobject") == 0;
|
||||
is_str = g_strcmp0(rec->args[n] + 9, "string") == 0 ||
|
||||
g_strcmp0(rec->args[n] + 9, "char*") == 0; /* deprecated form */
|
||||
|
||||
av = (AV *)SvRV(arg);
|
||||
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)
|
||||
);
|
||||
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_foreach(gl, (GFunc) g_free, NULL);
|
||||
}
|
||||
g_list_free(gl);
|
||||
}
|
||||
@ -246,7 +272,8 @@ static void perl_call_signal(PERL_SCRIPT_REC *script, SV *func,
|
||||
int is_iobject, is_str;
|
||||
|
||||
is_iobject = g_strcmp0(rec->args[n]+9, "iobject") == 0;
|
||||
is_str = g_strcmp0(rec->args[n]+9, "char*") == 0;
|
||||
is_str = g_strcmp0(rec->args[n] + 9, "string") == 0 ||
|
||||
g_strcmp0(rec->args[n] + 9, "char*") == 0; /* deprecated form */
|
||||
av = newAV();
|
||||
|
||||
ptr = arg;
|
||||
@ -268,7 +295,36 @@ static void perl_call_signal(PERL_SCRIPT_REC *script, SV *func,
|
||||
perlarg = newSViv(*(unsigned long *) arg);
|
||||
else if (g_strcmp0(rec->args[n], "intptr") == 0)
|
||||
saved_args[n] = perlarg = newRV_noinc(newSViv(*(int *) arg));
|
||||
else if (strncmp(rec->args[n], "gslist_", 7) == 0) {
|
||||
else if (g_strcmp0(rec->args[n], "formatnum_args") == 0 && n >= 3) {
|
||||
const THEME_REC *theme;
|
||||
const MODULE_THEME_REC *rec;
|
||||
const FORMAT_REC *formats;
|
||||
char *const *tmp;
|
||||
int formatnum;
|
||||
|
||||
theme = args[n - 3];
|
||||
if (theme == NULL) /* no theme */
|
||||
continue;
|
||||
|
||||
rec = g_hash_table_lookup(theme->modules, args[n - 2]);
|
||||
if (rec == NULL) /* no module in theme */
|
||||
continue;
|
||||
|
||||
formats = g_hash_table_lookup(default_formats, args[n - 2]);
|
||||
if (formats == NULL) /* no module in default_formats */
|
||||
continue;
|
||||
|
||||
formatnum = GPOINTER_TO_INT(arg);
|
||||
if (formatnum >= rec->count) /* format out of bounds */
|
||||
continue;
|
||||
|
||||
XPUSHs(sv_2mortal(new_pv(formats[formatnum].tag)));
|
||||
for (tmp = args[n + 1]; *tmp != NULL; tmp++) {
|
||||
XPUSHs(sv_2mortal(new_pv(*tmp)));
|
||||
}
|
||||
|
||||
continue;
|
||||
} else if (strncmp(rec->args[n], "gslist_", 7) == 0) {
|
||||
/* linked list - push as AV */
|
||||
GSList *tmp;
|
||||
int is_iobject;
|
||||
@ -338,7 +394,8 @@ static void perl_call_signal(PERL_SCRIPT_REC *script, SV *func,
|
||||
out = g_list_append(out, val);
|
||||
}
|
||||
|
||||
if (g_strcmp0(rec->args[n]+9, "char*") == 0)
|
||||
if (g_strcmp0(rec->args[n] + 9, "string") == 0 ||
|
||||
g_strcmp0(rec->args[n] + 9, "char*") == 0) /* deprecated form */
|
||||
g_list_foreach(*ret, (GFunc) g_free, NULL);
|
||||
g_list_free(*ret);
|
||||
*ret = out;
|
||||
@ -349,12 +406,15 @@ static void perl_call_signal(PERL_SCRIPT_REC *script, SV *func,
|
||||
LEAVE;
|
||||
}
|
||||
|
||||
#if SIGNAL_MAX_ARGUMENTS != 6
|
||||
#error SIGNAL_MAX_ARGUMENTS changed - update code
|
||||
#endif
|
||||
static void sig_func(const void *p1, const void *p2,
|
||||
const void *p3, const void *p4,
|
||||
const void *p5, const void *p6)
|
||||
{
|
||||
PERL_SIGNAL_REC *rec;
|
||||
const void *args[6];
|
||||
const void *args[SIGNAL_MAX_ARGUMENTS];
|
||||
|
||||
args[0] = p1; args[1] = p2; args[2] = p3;
|
||||
args[3] = p4; args[4] = p5; args[5] = p6;
|
||||
@ -553,7 +613,7 @@ void perl_signal_register(const char *signal, const char **args)
|
||||
return;
|
||||
|
||||
rec = g_new0(PERL_SIGNAL_ARGS_REC, 1);
|
||||
for (i = 0; i < 6 && args[i] != NULL; i++)
|
||||
for (i = 0; i < SIGNAL_MAX_ARGUMENTS && args[i] != NULL; i++)
|
||||
rec->args[i] = g_strdup(args[i]);
|
||||
rec->dynamic = TRUE;
|
||||
rec->signal = g_strdup(signal);
|
||||
@ -579,7 +639,7 @@ static void signal_args_free(PERL_SIGNAL_ARGS_REC *rec)
|
||||
if (!rec->dynamic)
|
||||
return;
|
||||
|
||||
for (i = 0; i < 6 && rec->args[i] != NULL; i++)
|
||||
for (i = 0; i < SIGNAL_MAX_ARGUMENTS && rec->args[i] != NULL; i++)
|
||||
g_free(rec->args[i]);
|
||||
g_free(rec->signal);
|
||||
g_free(rec);
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef IRSSI_PERL_PERL_SIGNALS_H
|
||||
#define IRSSI_PERL_PERL_SIGNALS_H
|
||||
|
||||
void perl_signal_args_to_c(void (*callback)(void *, void **), void *cb_arg,
|
||||
int signal_id, SV **args, size_t n_args);
|
||||
void perl_signal_args_to_c(void (*callback)(void *, int, void **), void *cb_arg, int signal_id,
|
||||
SV **args, size_t n_args);
|
||||
|
||||
void perl_signal_add_full(const char *signal, SV *func, int priority);
|
||||
|
||||
|
@ -104,7 +104,7 @@ PPCODE:
|
||||
g_free_not_null(ret);
|
||||
|
||||
#*******************************
|
||||
MODULE = Irssi::UI::Formats PACKAGE = Irssi::Window
|
||||
MODULE = Irssi::UI::Formats PACKAGE = Irssi::UI::Window
|
||||
#*******************************
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user