1
0
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:
ailin-nemui 2020-05-14 11:20:22 +02:00 committed by GitHub
commit 5ba58d9067
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 216 additions and 163 deletions

View File

@ -251,7 +251,7 @@ FE common
* Provides signals: * Provides signals:
completion.c: 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: fe-common-core.c:
"irssi init read settings" "irssi init read settings"
@ -285,6 +285,8 @@ keyboard.c:
printtext.c: printtext.c:
"print text", TEXT_DEST_REC *dest, char *text, char *stripped "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: themes.c:
"theme created", THEME_REC "theme created", THEME_REC

View File

@ -6,7 +6,7 @@
#define IRSSI_GLOBAL_CONFIG "irssi.conf" /* config file name in /etc/ */ #define IRSSI_GLOBAL_CONFIG "irssi.conf" /* config file name in /etc/ */
#define IRSSI_HOME_CONFIG "config" /* config file name in ~/.irssi/ */ #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_PORT 6667
#define DEFAULT_SERVER_ADD_TLS_PORT 6697 #define DEFAULT_SERVER_ADD_TLS_PORT 6697

View File

@ -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, str = format_get_text_theme_charargs(log_theme, module, dest,
GPOINTER_TO_INT(formatnum), args); GPOINTER_TO_INT(formatnum), args);
if (str != NULL && *str != '\0') {
skip_next_printtext = TRUE; skip_next_printtext = TRUE;
if (*str != '\0') {
/* add the line start format */ /* add the line start format */
linestart = format_get_level_tag(log_theme, dest); linestart = format_get_level_tag(log_theme, dest);
tmp = str; tmp = str;

View File

@ -650,6 +650,9 @@ char *format_get_text_theme_charargs(THEME_REC *theme, const char *module,
MODULE_THEME_REC *module_theme; MODULE_THEME_REC *module_theme;
char *text; char *text;
if (module == NULL)
return NULL;
module_theme = g_hash_table_lookup(theme->modules, module); module_theme = g_hash_table_lookup(theme->modules, module);
if (module_theme == NULL) if (module_theme == NULL)
return NULL; return NULL;

View File

@ -124,6 +124,9 @@ static void sig_print_format(THEME_REC *theme, const char *module, TEXT_DEST_REC
if (!scrollback_format) if (!scrollback_format)
return; return;
if (module == NULL)
return;
info = store_lineinfo_tmp(dest); info = store_lineinfo_tmp(dest);
formatnum = GPOINTER_TO_INT(formatnump); formatnum = GPOINTER_TO_INT(formatnump);

View File

@ -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); (void) hv_store(hash, key, strlen(key), new_pv(value), 0);
} }
static void wrap_signal_emit(void *signal, void **p) { static void wrap_signal_emit(void *signal, int params, void **p)
signal_emit(signal, 6, p[0], p[1], p[2], p[3], p[4], p[5]); {
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; (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 MODULE = Irssi::Core PACKAGE = Irssi
@ -85,33 +87,14 @@ signal_emit(signal, ...)
char *signal char *signal
CODE: CODE:
int signal_id; int signal_id;
SV *args[SIGNAL_MAX_ARGUMENTS];
int n, used;
signal_id = signal_get_uniq_id(signal); signal_id = signal_get_uniq_id(signal);
used = items - 1; perl_signal_args_to_c(wrap_signal_emit, signal, signal_id, &ST(1), 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);
void void
signal_continue(...) signal_continue(...)
CODE: CODE:
SV *args[SIGNAL_MAX_ARGUMENTS]; perl_signal_args_to_c(wrap_signal_continue, NULL, signal_get_emitted_id(), &ST(0), items);
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);
void void
signal_add(...) signal_add(...)
@ -162,7 +145,7 @@ PREINIT:
HV *hv; HV *hv;
HE *he; HE *he;
I32 len, pos; I32 len, pos;
const char *arr[7]; const char *arr[SIGNAL_MAX_ARGUMENTS + 1];
CODE: CODE:
if (items != 1 || !is_hvref(ST(0))) if (items != 1 || !is_hvref(ST(0)))
croak("Usage: Irssi::signal_register(hash)"); croak("Usage: Irssi::signal_register(hash)");
@ -179,7 +162,8 @@ CODE:
av = (AV *) SvRV(val); av = (AV *) SvRV(val);
len = av_len(av)+1; 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++) { for (pos = 0; pos < len; pos++) {
SV **val = av_fetch(av, pos, 0); SV **val = av_fetch(av, pos, 0);
arr[pos] = SvPV_nolen(*val); arr[pos] = SvPV_nolen(*val);

View File

@ -16,14 +16,15 @@ while (<>) {
$signal = $1; $signal = $1;
$_ = $3; $_ = $3;
s/GList \* of ([^,]*)/glistptr_\1/g; s/GList \* of ([^,]*)s/glistptr_\1/g;
s/GSList of (\w+)s/gslist_\1/g; s/GSList of ([^,]*)s/gslist_\1/g;
s/char \*[^,]*/string/g; s/char \*[^,]*/string/g;
s/ulong \*[^,]*/ulongptr/g; s/ulong \*[^,]*/ulongptr/g;
s/int \*[^,]*/intptr/g; s/int \*[^,]*/intptr/g;
s/int [^,]*/int/g; s/int [^,]*/int/g;
my %map = ( my %map = (
# core # core
CHATNET_REC => 'iobject', CHATNET_REC => 'iobject',

View File

@ -21,10 +21,11 @@
#define NEED_PERL_H #define NEED_PERL_H
#define PERL_NO_GET_CONTEXT #define PERL_NO_GET_CONTEXT
#include "module.h" #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/commands.h>
#include <irssi/src/core/modules.h>
#include <irssi/src/core/servers.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-core.h>
#include <irssi/src/perl/perl-common.h> #include <irssi/src/perl/perl-common.h>
@ -39,7 +40,7 @@ typedef struct {
typedef struct { typedef struct {
char *signal; char *signal;
char *args[7]; char *args[SIGNAL_MAX_ARGUMENTS + 1];
int dynamic; int dynamic;
} PERL_SIGNAL_ARGS_REC; } PERL_SIGNAL_ARGS_REC;
@ -71,9 +72,8 @@ static PERL_SIGNAL_ARGS_REC *perl_signal_args_find(int signal_id)
return NULL; return NULL;
} }
void perl_signal_args_to_c( void perl_signal_args_to_c(void (*callback)(void *, int, void **), void *cb_arg, int signal_id,
void (*callback)(void *, void **), void *cb_arg, SV **args, size_t n_args)
int signal_id, SV **args, size_t n_args)
{ {
union { union {
int v_int; int v_int;
@ -83,6 +83,7 @@ void perl_signal_args_to_c(
} saved_args[SIGNAL_MAX_ARGUMENTS]; } saved_args[SIGNAL_MAX_ARGUMENTS];
void *p[SIGNAL_MAX_ARGUMENTS]; void *p[SIGNAL_MAX_ARGUMENTS];
PERL_SIGNAL_ARGS_REC *rec; PERL_SIGNAL_ARGS_REC *rec;
char *arglist[MAX_FORMAT_PARAMS];
size_t n; size_t n;
if (!(rec = perl_signal_args_find(signal_id))) { if (!(rec = perl_signal_args_find(signal_id))) {
@ -97,7 +98,36 @@ void perl_signal_args_to_c(
void *c_arg; void *c_arg;
SV *arg = args[n]; 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; c_arg = NULL;
} else if (g_strcmp0(rec->args[n], "string") == 0) { } else if (g_strcmp0(rec->args[n], "string") == 0) {
c_arg = SvPV_nolen(arg); c_arg = SvPV_nolen(arg);
@ -122,19 +152,18 @@ void perl_signal_args_to_c(
} }
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; gl = NULL;
count = av_len(av) + 1; count = av_len(av) + 1;
while (count-- > 0) { while (count-- > 0) {
SV **px = av_fetch(av, count, 0); SV **px = av_fetch(av, count, 0);
SV *x = px ? *px : NULL; SV *x = px ? *px : NULL;
gl = g_list_prepend( gl = g_list_prepend(gl, x == NULL ?
gl, NULL :
x == NULL ? NULL :
is_str ? g_strdup(SvPV_nolen(x)) : is_str ? g_strdup(SvPV_nolen(x)) :
irssi_ref_object(x) irssi_ref_object(x));
);
} }
saved_args[n].v_glist = gl; saved_args[n].v_glist = gl;
c_arg = &saved_args[n].v_glist; c_arg = &saved_args[n].v_glist;
@ -154,11 +183,7 @@ void perl_signal_args_to_c(
count = av_len(av) + 1; count = av_len(av) + 1;
while (count-- > 0) { while (count-- > 0) {
SV **x = av_fetch(av, count, 0); SV **x = av_fetch(av, count, 0);
gsl = g_slist_prepend( gsl = g_slist_prepend(gsl, x == NULL ? NULL : irssi_ref_object(*x));
gsl,
x == NULL ? NULL :
irssi_ref_object(*x)
);
} }
c_arg = saved_args[n].v_gslist = gsl; c_arg = saved_args[n].v_gslist = gsl;
} else { } else {
@ -172,7 +197,7 @@ void perl_signal_args_to_c(
p[n] = NULL; 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) { for (n = 0; n < SIGNAL_MAX_ARGUMENTS && n < n_args && rec->args[n] != NULL; ++n) {
SV *arg = args[n]; SV *arg = args[n];
@ -193,18 +218,19 @@ void perl_signal_args_to_c(
GList *gl, *tmp; GList *gl, *tmp;
is_iobject = g_strcmp0(rec->args[n] + 9, "iobject") == 0; 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 = (AV *) SvRV(arg); av = (AV *) SvRV(arg);
av_clear(av); av_clear(av);
gl = saved_args[n].v_glist; gl = saved_args[n].v_glist;
for (tmp = gl; tmp != NULL; tmp = tmp->next) { for (tmp = gl; tmp != NULL; tmp = tmp->next) {
av_push(av, av_push(av, is_iobject ?
is_iobject ? iobject_bless((SERVER_REC *)tmp->data) : iobject_bless((SERVER_REC *) tmp->data) :
is_str ? new_pv(tmp->data) : is_str ?
irssi_bless_plain(rec->args[n]+9, tmp->data) new_pv(tmp->data) :
); irssi_bless_plain(rec->args[n] + 9, tmp->data));
} }
if (is_str) { if (is_str) {
@ -246,7 +272,8 @@ static void perl_call_signal(PERL_SCRIPT_REC *script, SV *func,
int is_iobject, is_str; int is_iobject, is_str;
is_iobject = g_strcmp0(rec->args[n]+9, "iobject") == 0; 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(); av = newAV();
ptr = arg; ptr = arg;
@ -268,7 +295,36 @@ static void perl_call_signal(PERL_SCRIPT_REC *script, SV *func,
perlarg = newSViv(*(unsigned long *) arg); perlarg = newSViv(*(unsigned long *) arg);
else if (g_strcmp0(rec->args[n], "intptr") == 0) else if (g_strcmp0(rec->args[n], "intptr") == 0)
saved_args[n] = perlarg = newRV_noinc(newSViv(*(int *) arg)); 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 */ /* linked list - push as AV */
GSList *tmp; GSList *tmp;
int is_iobject; int is_iobject;
@ -338,7 +394,8 @@ static void perl_call_signal(PERL_SCRIPT_REC *script, SV *func,
out = g_list_append(out, val); 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_foreach(*ret, (GFunc) g_free, NULL);
g_list_free(*ret); g_list_free(*ret);
*ret = out; *ret = out;
@ -349,12 +406,15 @@ static void perl_call_signal(PERL_SCRIPT_REC *script, SV *func,
LEAVE; LEAVE;
} }
#if SIGNAL_MAX_ARGUMENTS != 6
#error SIGNAL_MAX_ARGUMENTS changed - update code
#endif
static void sig_func(const void *p1, const void *p2, static void sig_func(const void *p1, const void *p2,
const void *p3, const void *p4, const void *p3, const void *p4,
const void *p5, const void *p6) const void *p5, const void *p6)
{ {
PERL_SIGNAL_REC *rec; PERL_SIGNAL_REC *rec;
const void *args[6]; const void *args[SIGNAL_MAX_ARGUMENTS];
args[0] = p1; args[1] = p2; args[2] = p3; args[0] = p1; args[1] = p2; args[2] = p3;
args[3] = p4; args[4] = p5; args[5] = p6; args[3] = p4; args[4] = p5; args[5] = p6;
@ -553,7 +613,7 @@ void perl_signal_register(const char *signal, const char **args)
return; return;
rec = g_new0(PERL_SIGNAL_ARGS_REC, 1); 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->args[i] = g_strdup(args[i]);
rec->dynamic = TRUE; rec->dynamic = TRUE;
rec->signal = g_strdup(signal); rec->signal = g_strdup(signal);
@ -579,7 +639,7 @@ static void signal_args_free(PERL_SIGNAL_ARGS_REC *rec)
if (!rec->dynamic) if (!rec->dynamic)
return; 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->args[i]);
g_free(rec->signal); g_free(rec->signal);
g_free(rec); g_free(rec);

View File

@ -1,8 +1,8 @@
#ifndef IRSSI_PERL_PERL_SIGNALS_H #ifndef IRSSI_PERL_PERL_SIGNALS_H
#define IRSSI_PERL_PERL_SIGNALS_H #define IRSSI_PERL_PERL_SIGNALS_H
void perl_signal_args_to_c(void (*callback)(void *, void **), void *cb_arg, void perl_signal_args_to_c(void (*callback)(void *, int, void **), void *cb_arg, int signal_id,
int signal_id, SV **args, size_t n_args); SV **args, size_t n_args);
void perl_signal_add_full(const char *signal, SV *func, int priority); void perl_signal_add_full(const char *signal, SV *func, int priority);

View File

@ -104,7 +104,7 @@ PPCODE:
g_free_not_null(ret); g_free_not_null(ret);
#******************************* #*******************************
MODULE = Irssi::UI::Formats PACKAGE = Irssi::Window MODULE = Irssi::UI::Formats PACKAGE = Irssi::UI::Window
#******************************* #*******************************
void void