mirror of
https://github.com/irssi/irssi.git
synced 2026-08-10 04:13:32 +02:00
rest of the ~rewrite?
git-svn-id: http://svn.irssi.org/repos/irssi/trunk@172 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
parent
c95034c6de
commit
d29ca0b107
32 changed files with 2049 additions and 1536 deletions
|
|
@ -1,13 +1,13 @@
|
|||
if BUILD_TEXTUI
|
||||
TEXTUI=gui-text
|
||||
TEXTUI=fe-text
|
||||
endif
|
||||
|
||||
if BUILD_GNOMEUI
|
||||
GNOMEUI=gui-gnome
|
||||
GNOMEUI=fe-gnome
|
||||
endif
|
||||
|
||||
if BUILD_IRSSIBOT
|
||||
BOTUI=gui-none
|
||||
BOTUI=fe-none
|
||||
endif
|
||||
|
||||
noinst_HEADERS = \
|
||||
|
|
@ -17,4 +17,4 @@ noinst_HEADERS = \
|
|||
irssi-plugin.h \
|
||||
irssi-plugin-gui.h
|
||||
|
||||
SUBDIRS = lib-popt lib-config irc-base irc-extra ui-common $(GNOMEUI) $(TEXTUI) $(BOTUI)
|
||||
SUBDIRS = lib-popt lib-config core irc fe-common perl $(GNOMEUI) $(TEXTUI) $(BOTUI)
|
||||
|
|
|
|||
|
|
@ -13,9 +13,6 @@
|
|||
/* How often to check if there's anyone to be unbanned in knockout list */
|
||||
#define KNOCKOUT_TIMECHECK 10000
|
||||
|
||||
/* How often to check users in notify list */
|
||||
#define NOTIFY_TIMECHECK 30000
|
||||
|
||||
/* How often to check for gone status of nick */
|
||||
#define MAX_GONE_REFRESH_TIME 300
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
#include <glib.h>
|
||||
#include <gmodule.h>
|
||||
|
||||
#include "irc-base/memdebug.h"
|
||||
#include "core/memdebug.h"
|
||||
#include "nls.h"
|
||||
|
||||
#define g_free_not_null(a) \
|
||||
|
|
|
|||
|
|
@ -40,11 +40,10 @@ CONFIG_NODE *config_node_find(CONFIG_NODE *node, const char *key)
|
|||
|
||||
/* find the section from node - if not found create it unless new_type is -1.
|
||||
you can also specify in new_type if it's NODE_TYPE_LIST or NODE_TYPE_BLOCK */
|
||||
CONFIG_NODE *config_node_section(CONFIG_REC *rec, CONFIG_NODE *parent, const char *key, int new_type)
|
||||
CONFIG_NODE *config_node_section(CONFIG_NODE *parent, const char *key, int new_type)
|
||||
{
|
||||
CONFIG_NODE *node;
|
||||
|
||||
g_return_val_if_fail(rec != NULL, NULL);
|
||||
g_return_val_if_fail(parent != NULL, NULL);
|
||||
g_return_val_if_fail(is_node_list(parent), NULL);
|
||||
|
||||
|
|
@ -91,7 +90,7 @@ CONFIG_NODE *config_node_traverse(CONFIG_REC *rec, const char *section, int crea
|
|||
is_list = **tmp == '(';
|
||||
if (create) new_type = is_list ? NODE_TYPE_LIST : NODE_TYPE_BLOCK;
|
||||
|
||||
node = config_node_section(rec, node, *tmp + is_list, new_type);
|
||||
node = config_node_section(node, *tmp + is_list, new_type);
|
||||
if (node == NULL) return NULL;
|
||||
}
|
||||
g_strfreev(list);
|
||||
|
|
@ -252,3 +251,34 @@ int config_node_get_keyvalue(CONFIG_NODE *node, const char *key, const char *val
|
|||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Return all values from from the list `node' in a g_strsplit() array */
|
||||
char **config_node_get_list(CONFIG_NODE *node)
|
||||
{
|
||||
GString *values;
|
||||
GSList *tmp;
|
||||
char **ret;
|
||||
|
||||
g_return_val_if_fail(node != NULL, NULL);
|
||||
g_return_val_if_fail(is_node_list(node), NULL);
|
||||
|
||||
/* put values to string */
|
||||
values = g_string_new(NULL);
|
||||
for (tmp = node->value; tmp != NULL; tmp = tmp->next) {
|
||||
node = tmp->data;
|
||||
|
||||
if (node->type == NODE_TYPE_VALUE)
|
||||
g_string_sprintfa(values, "%s ", (char *) node->value);
|
||||
}
|
||||
|
||||
/* split the values to **str array */
|
||||
if (values->len == 0)
|
||||
ret = NULL;
|
||||
else {
|
||||
g_string_truncate(values, values->len-1);
|
||||
ret = g_strsplit(values->str, " ", -1);
|
||||
}
|
||||
|
||||
g_string_free(values, TRUE);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,13 +108,17 @@ int config_set_bool(CONFIG_REC *rec, const char *section, const char *key, int v
|
|||
CONFIG_NODE *config_node_find(CONFIG_NODE *node, const char *key);
|
||||
/* Find the section from node - if not found create it unless new_type is -1.
|
||||
You can also specify in new_type if it's NODE_TYPE_LIST or NODE_TYPE_BLOCK */
|
||||
CONFIG_NODE *config_node_section(CONFIG_REC *rec, CONFIG_NODE *parent, const char *key, int new_type);
|
||||
CONFIG_NODE *config_node_section(CONFIG_NODE *parent, const char *key, int new_type);
|
||||
/* Find the section with the whole path.
|
||||
Create the path if necessary `create' is TRUE. */
|
||||
CONFIG_NODE *config_node_traverse(CONFIG_REC *rec, const char *section, int create);
|
||||
/* Get the value of keys `key' and `key_value' and put them to
|
||||
`ret_key' and `ret_value'. Returns -1 if not found. */
|
||||
int config_node_get_keyvalue(CONFIG_NODE *node, const char *key, const char *value_key, char **ret_key, char **ret_value);
|
||||
/* Return all values from from the list `node' in a g_strsplit() array */
|
||||
char **config_node_get_list(CONFIG_NODE *node);
|
||||
/* Add all values in `array' to `node' */
|
||||
void config_node_add_list(CONFIG_NODE *node, char **array);
|
||||
|
||||
char *config_node_get_str(CONFIG_NODE *parent, const char *key, const char *def);
|
||||
int config_node_get_int(CONFIG_NODE *parent, const char *key, int def);
|
||||
|
|
@ -124,13 +128,15 @@ void config_node_set_str(CONFIG_NODE *parent, const char *key, const char *value
|
|||
void config_node_set_int(CONFIG_NODE *parent, const char *key, int value);
|
||||
void config_node_set_bool(CONFIG_NODE *parent, const char *key, int value);
|
||||
|
||||
/* add/change the value of the `key' */
|
||||
/* Add/change the value of the `key' */
|
||||
void config_node_set_str(CONFIG_NODE *parent, const char *key, const char *value);
|
||||
/* remove one node from block/list.
|
||||
/* Remove one node from block/list.
|
||||
..set_str() with value = NULL does the same. */
|
||||
void config_node_remove(CONFIG_NODE *parent, CONFIG_NODE *node);
|
||||
/* Remove n'th node from a list */
|
||||
void config_node_list_remove(CONFIG_NODE *node, int index);
|
||||
|
||||
/* clear the entire configuration */
|
||||
/* Clear the entire configuration */
|
||||
void config_nodes_remove_all(CONFIG_REC *rec);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ static void config_parse_get_token(GScanner *scanner, CONFIG_NODE *node)
|
|||
#undef g_strdup_printf /* This is free'd by GLib itself */
|
||||
scanner->value.v_string = g_strdup_printf("%lu", scanner->value.v_int);
|
||||
#ifdef MEM_DEBUG
|
||||
#define g_strdup_printf ig_strdup_printf
|
||||
#define g_strdup_printf(a, b...) ig_strdup_printf(__FILE__, __LINE__, a, ##b)
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
|
@ -127,8 +127,10 @@ static int config_parse_symbol(CONFIG_REC *rec, CONFIG_NODE *node)
|
|||
key = g_strdup(rec->scanner->value.v_string);
|
||||
|
||||
config_parse_get_token(rec->scanner, node);
|
||||
if (rec->scanner->token != '=')
|
||||
if (rec->scanner->token != '=') {
|
||||
g_free(key);
|
||||
return '=';
|
||||
}
|
||||
|
||||
config_parse_get_token(rec->scanner, node);
|
||||
}
|
||||
|
|
@ -155,7 +157,7 @@ static int config_parse_symbol(CONFIG_REC *rec, CONFIG_NODE *node)
|
|||
if (key == NULL && node->type != NODE_TYPE_LIST)
|
||||
return G_TOKEN_ERROR;
|
||||
|
||||
newnode = config_node_section(rec, node, key, NODE_TYPE_BLOCK);
|
||||
newnode = config_node_section(node, key, NODE_TYPE_BLOCK);
|
||||
config_parse_loop(rec, newnode, '}');
|
||||
g_free_not_null(key);
|
||||
|
||||
|
|
@ -170,7 +172,7 @@ static int config_parse_symbol(CONFIG_REC *rec, CONFIG_NODE *node)
|
|||
/* list */
|
||||
if (key == NULL)
|
||||
return G_TOKEN_ERROR;
|
||||
newnode = config_node_section(rec, node, key, NODE_TYPE_LIST);
|
||||
newnode = config_node_section(node, key, NODE_TYPE_LIST);
|
||||
config_parse_loop(rec, newnode, ')');
|
||||
g_free_not_null(key);
|
||||
|
||||
|
|
@ -197,17 +199,18 @@ static void config_parse_loop(CONFIG_REC *rec, CONFIG_NODE *node, int expect)
|
|||
g_return_if_fail(rec != NULL);
|
||||
g_return_if_fail(node != NULL);
|
||||
|
||||
do {
|
||||
for (;;) {
|
||||
config_parse_peek_token(rec->scanner, node);
|
||||
if (rec->scanner->next_token == expect ||
|
||||
rec->scanner->next_token == G_TOKEN_EOF) break;
|
||||
|
||||
expected_token = config_parse_symbol(rec, node);
|
||||
if (expected_token != G_TOKEN_NONE) {
|
||||
if (expected_token == G_TOKEN_ERROR)
|
||||
expected_token = G_TOKEN_NONE;
|
||||
g_scanner_unexp_token(rec->scanner, expected_token, NULL, "symbol", NULL, NULL, TRUE);
|
||||
}
|
||||
|
||||
config_parse_peek_token(rec->scanner, node);
|
||||
} while (rec->scanner->next_token != expect &&
|
||||
rec->scanner->next_token != G_TOKEN_EOF);
|
||||
}
|
||||
}
|
||||
|
||||
static void config_parse_error_func(GScanner *scanner, char *message, int is_error)
|
||||
|
|
|
|||
|
|
@ -43,6 +43,22 @@ void config_node_remove(CONFIG_NODE *parent, CONFIG_NODE *node)
|
|||
g_free(node);
|
||||
}
|
||||
|
||||
/* Remove n'th node from a list */
|
||||
void config_node_list_remove(CONFIG_NODE *node, int index)
|
||||
{
|
||||
GSList *tmp;
|
||||
|
||||
g_return_if_fail(node != NULL);
|
||||
g_return_if_fail(is_node_list(node));
|
||||
|
||||
for (tmp = node->value; tmp != NULL; tmp = tmp->next, index--) {
|
||||
if (index == 0) {
|
||||
config_node_remove(node, tmp->data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void config_nodes_remove_all(CONFIG_REC *rec)
|
||||
{
|
||||
g_return_if_fail(rec != NULL);
|
||||
|
|
@ -120,3 +136,12 @@ int config_set_bool(CONFIG_REC *rec, const char *section, const char *key, int v
|
|||
{
|
||||
return config_set_str(rec, section, key, value ? "yes" : "no");
|
||||
}
|
||||
|
||||
/* Add all values in `array' to `node' */
|
||||
void config_node_add_list(CONFIG_NODE *node, char **array)
|
||||
{
|
||||
char **tmp;
|
||||
|
||||
for (tmp = array; *tmp != NULL; tmp++)
|
||||
config_node_set_str(node, NULL, *tmp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ static int config_has_specials(const char *text)
|
|||
g_return_val_if_fail(text != NULL, FALSE);
|
||||
|
||||
while (*text != '\0') {
|
||||
if ((unsigned char) *text <= 32 || *text == '"' || *text == '\\')
|
||||
if (!isalnum((int) *text))
|
||||
return TRUE;
|
||||
text++;
|
||||
}
|
||||
|
|
@ -162,7 +162,7 @@ static int config_write_node(CONFIG_REC *rec, CONFIG_NODE *node, int line_feeds)
|
|||
case NODE_TYPE_BLOCK:
|
||||
/* key = { */
|
||||
if (node->key != NULL) {
|
||||
if (config_write_str(rec, node->key) == -1 ||
|
||||
if (config_write_word(rec, node->key, FALSE) == -1 ||
|
||||
config_write_str(rec, " = ") == -1)
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -182,7 +182,7 @@ static int config_write_node(CONFIG_REC *rec, CONFIG_NODE *node, int line_feeds)
|
|||
case NODE_TYPE_LIST:
|
||||
/* key = ( */
|
||||
if (node->key != NULL) {
|
||||
if (config_write_str(rec, node->key) == -1 ||
|
||||
if (config_write_word(rec, node->key, FALSE) == -1 ||
|
||||
config_write_str(rec, " = ") == -1)
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -327,7 +327,6 @@ int config_write(CONFIG_REC *rec, const char *fname, int create_mode)
|
|||
config_error(rec, errno == 0 ? "bug" : g_strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
write(rec->handle, "\n", 1);
|
||||
|
||||
close(rec->handle);
|
||||
rec->handle = -1;
|
||||
|
|
|
|||
30
src/perl/Makefile.am
Normal file
30
src/perl/Makefile.am
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
noinst_LTLIBRARIES = libperl.la
|
||||
|
||||
libperl_la_DEPENDENCIES = perl-signals.h
|
||||
|
||||
INCLUDES = $(GLIB_CFLAGS) \
|
||||
-DPLUGINSDIR=\""$(libdir)/irssi/plugins"\" \
|
||||
-DSCRIPTDIR=\""$(libdir)/irssi/scripts"\" \
|
||||
$(PERL_CFLAGS) \
|
||||
-I$(top_srcdir)/src \
|
||||
-I$(top_srcdir)/src/core
|
||||
|
||||
libperl_la_SOURCES = \
|
||||
irssi-perl.c \
|
||||
xsinit.c
|
||||
|
||||
perl-signals.h: $(top_srcdir)/docs/signals.txt $(srcdir)/get-signals.pl
|
||||
cat $(top_srcdir)/docs/signals.txt | $(perlpath) $(srcdir)/get-signals.pl > perl-signals.h
|
||||
|
||||
EXTRA_DIST = \
|
||||
get-signals.pl \
|
||||
xs/Irssi.xs \
|
||||
xs/Irssi.pm \
|
||||
xs/Makefile.PL.in \
|
||||
xs/typemap
|
||||
|
||||
all-local:
|
||||
cd xs && if [ ! -f Makefile ]; then $(perlpath) Makefile.PL; fi && $(MAKE) && cd ..
|
||||
|
||||
install-exec-local:
|
||||
cd xs && make install && cd ..
|
||||
38
src/perl/get-signals.pl
Executable file
38
src/perl/get-signals.pl
Executable file
|
|
@ -0,0 +1,38 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
print "static PERL_SIGNAL_ARGS_REC perl_signal_args[] =\n{\n";
|
||||
|
||||
while (<STDIN>) {
|
||||
chomp;
|
||||
|
||||
last if (/UI common/);
|
||||
next if (!/^ "([^"]*)"(<.*>)?,\s*(.*)/);
|
||||
next if (/\.\.\./);
|
||||
next if (/\(/);
|
||||
|
||||
$signal = $1;
|
||||
$_ = $3;
|
||||
|
||||
s/char \*[^,]*/string/g;
|
||||
s/ulong \*[^,]*/ulongptr/g;
|
||||
s/int[^,]*/int/g;
|
||||
s/GSList of (\w+)s/gslist_\1/g;
|
||||
|
||||
s/SERVER_REC \*[^,]*/Irssi::Server/g;
|
||||
s/RECONNECT_REC \*[^,]*/Irssi::Reconnect/g;
|
||||
s/CHANNEL_REC \*[^,]*/Irssi::Channel/g;
|
||||
s/COMMAND_REC \*[^,]*/Irssi::Command/g;
|
||||
s/NICK_REC \*[^,]*/Irssi::Nick/g;
|
||||
s/BAN_REC \*[^,]*/Irssi::Ban/g;
|
||||
s/NETSPLIT_REC \*[^,]*/Irssi::Netsplit/g;
|
||||
s/DCC_REC \*[^,]*/Irssi::Dcc/g;
|
||||
s/LOG_REC \*[^,]*/Irssi::Log/g;
|
||||
s/LOG_ITEM_REC \*[^,]*/Irssi::Logitem/g;
|
||||
s/PLUGIN_REC \*[^,]*/Irssi::Plugin/g;
|
||||
s/AUTOIGNORE_REC \*[^,]*/Irssi::Autoignore/g;
|
||||
|
||||
s/([\w:]+)(,|$)/"\1"\2/g;
|
||||
print " { -1, \"$signal\", { $_, NULL } },\n";
|
||||
}
|
||||
|
||||
print "\n { -1, NULL }\n};\n";
|
||||
529
src/perl/irssi-perl.c
Normal file
529
src/perl/irssi-perl.c
Normal file
|
|
@ -0,0 +1,529 @@
|
|||
/*
|
||||
perl.c : irssi
|
||||
|
||||
Copyright (C) 1999 Timo Sirainen
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <EXTERN.h>
|
||||
#ifndef _SEM_SEMUN_UNDEFINED
|
||||
#define HAS_UNION_SEMUN
|
||||
#endif
|
||||
#include <perl.h>
|
||||
|
||||
#undef _
|
||||
#undef PACKAGE
|
||||
|
||||
#include "module.h"
|
||||
#include "modules.h"
|
||||
#include "signals.h"
|
||||
#include "commands.h"
|
||||
|
||||
extern void xs_init(void);
|
||||
|
||||
typedef struct {
|
||||
int signal_id;
|
||||
char *signal;
|
||||
char *args[7];
|
||||
} PERL_SIGNAL_ARGS_REC;
|
||||
|
||||
typedef struct {
|
||||
char *signal;
|
||||
int signal_id;
|
||||
|
||||
char *func;
|
||||
int last;
|
||||
} PERL_SIGNAL_REC;
|
||||
|
||||
typedef struct {
|
||||
int tag;
|
||||
char *func;
|
||||
char *data;
|
||||
} PERL_TIMEOUT_REC;
|
||||
|
||||
#include "perl-signals.h"
|
||||
|
||||
static GHashTable *first_signals, *last_signals;
|
||||
static GSList *perl_timeouts;
|
||||
static PerlInterpreter *irssi_perl_interp;
|
||||
static int signal_grabbed, siglast_grabbed;
|
||||
|
||||
static void sig_signal(void *signal, ...);
|
||||
static void sig_lastsignal(void *signal, ...);
|
||||
|
||||
static void perl_signal_destroy(PERL_SIGNAL_REC *rec)
|
||||
{
|
||||
GHashTable *table;
|
||||
GSList *siglist;
|
||||
void *signal_idp;
|
||||
|
||||
table = rec->last ? last_signals : first_signals;
|
||||
signal_idp = GINT_TO_POINTER(rec->signal_id);
|
||||
|
||||
siglist = g_hash_table_lookup(table, signal_idp);
|
||||
if (siglist == NULL) return;
|
||||
|
||||
siglist = g_slist_remove(siglist, rec);
|
||||
g_hash_table_remove(table, signal_idp);
|
||||
if (siglist != NULL) g_hash_table_insert(table, signal_idp, siglist);
|
||||
|
||||
if (!rec->last && signal_grabbed && g_hash_table_size(first_signals) == 0) {
|
||||
signal_grabbed = FALSE;
|
||||
signal_remove("signal", (SIGNAL_FUNC) sig_signal);
|
||||
}
|
||||
|
||||
if (rec->last && siglast_grabbed && g_hash_table_size(last_signals) == 0) {
|
||||
siglast_grabbed = FALSE;
|
||||
signal_remove("last signal", (SIGNAL_FUNC) sig_lastsignal);
|
||||
}
|
||||
|
||||
if (strncmp(rec->signal, "command ", 8) == 0)
|
||||
command_unbind(rec->signal+8, NULL);
|
||||
|
||||
g_free(rec->signal);
|
||||
g_free(rec->func);
|
||||
g_free(rec);
|
||||
}
|
||||
|
||||
static void perl_timeout_destroy(PERL_TIMEOUT_REC *rec)
|
||||
{
|
||||
perl_timeouts = g_slist_remove(perl_timeouts, rec);
|
||||
|
||||
g_source_remove(rec->tag);
|
||||
g_free(rec->func);
|
||||
g_free(rec->data);
|
||||
g_free(rec);
|
||||
}
|
||||
|
||||
static void irssi_perl_start(void)
|
||||
{
|
||||
/* stolen from xchat, thanks :) */
|
||||
char *args[] = {"", "-e", "0"};
|
||||
char load_file[] =
|
||||
"sub load_file()\n"
|
||||
"{\n"
|
||||
" (my $file_name) = @_;\n"
|
||||
" open FH, $file_name or return 2;\n"
|
||||
" local($/) = undef;\n"
|
||||
" $file = <FH>;\n"
|
||||
" close FH;\n"
|
||||
" eval $file;\n"
|
||||
" eval $file if $@;\n"
|
||||
" return 1 if $@;\n"
|
||||
" return 0;\n"
|
||||
"}";
|
||||
|
||||
first_signals = g_hash_table_new((GHashFunc) g_direct_hash, (GCompareFunc) g_direct_equal);
|
||||
last_signals = g_hash_table_new((GHashFunc) g_direct_hash, (GCompareFunc) g_direct_equal);
|
||||
perl_timeouts = NULL;
|
||||
|
||||
irssi_perl_interp = perl_alloc();
|
||||
perl_construct(irssi_perl_interp);
|
||||
|
||||
perl_parse(irssi_perl_interp, xs_init, 3, args, NULL);
|
||||
perl_eval_pv(load_file, TRUE);
|
||||
}
|
||||
|
||||
static void signal_destroy_hash(void *key, PERL_SIGNAL_REC *rec)
|
||||
{
|
||||
perl_signal_destroy(rec);
|
||||
}
|
||||
|
||||
static void irssi_perl_stop(void)
|
||||
{
|
||||
g_hash_table_foreach(first_signals, (GHFunc) signal_destroy_hash, NULL);
|
||||
g_hash_table_destroy(first_signals);
|
||||
g_hash_table_foreach(last_signals, (GHFunc) signal_destroy_hash, NULL);
|
||||
g_hash_table_destroy(last_signals);
|
||||
|
||||
while (perl_timeouts != NULL)
|
||||
perl_timeout_destroy(perl_timeouts->data);
|
||||
|
||||
perl_destruct(irssi_perl_interp);
|
||||
perl_free(irssi_perl_interp);
|
||||
irssi_perl_interp = NULL;
|
||||
}
|
||||
|
||||
static void cmd_run(char *data)
|
||||
{
|
||||
dSP;
|
||||
struct stat statbuf;
|
||||
char *fname;
|
||||
int retcount;
|
||||
|
||||
/* add .pl suffix if it's missing */
|
||||
data = (strlen(data) <= 3 || strcmp(data+strlen(data)-3, ".pl") == 0) ?
|
||||
g_strdup(data) : g_strdup_printf("%s.pl", data);
|
||||
|
||||
if (g_path_is_absolute(data)) {
|
||||
/* whole path specified */
|
||||
fname = g_strdup(data);
|
||||
} else {
|
||||
/* check from ~/.irssi/scripts/ */
|
||||
fname = g_strdup_printf("%s/.irssi/scripts/%s", g_get_home_dir(), data);
|
||||
if (stat(fname, &statbuf) != 0) {
|
||||
/* check from SCRIPTDIR */
|
||||
g_free(fname),
|
||||
fname = g_strdup_printf(SCRIPTDIR"/%s", data);
|
||||
}
|
||||
}
|
||||
g_free(data);
|
||||
|
||||
ENTER;
|
||||
SAVETMPS;
|
||||
|
||||
PUSHMARK(SP);
|
||||
XPUSHs(sv_2mortal(newSVpv(fname, strlen(fname)))); g_free(fname);
|
||||
PUTBACK;
|
||||
|
||||
retcount = perl_call_pv("load_file", G_EVAL|G_SCALAR);
|
||||
SPAGAIN;
|
||||
|
||||
if (SvTRUE(ERRSV)) {
|
||||
STRLEN n_a;
|
||||
|
||||
signal_emit("perl error", 1, SvPV(ERRSV, n_a));
|
||||
(void) POPs;
|
||||
}
|
||||
else while (retcount--) (void) POPi;
|
||||
|
||||
PUTBACK;
|
||||
FREETMPS;
|
||||
LEAVE;
|
||||
}
|
||||
|
||||
static void cmd_flush(const char *data)
|
||||
{
|
||||
irssi_perl_stop();
|
||||
irssi_perl_start();
|
||||
}
|
||||
|
||||
static void perl_signal_to(const char *signal, const char *func, int last)
|
||||
{
|
||||
PERL_SIGNAL_REC *rec;
|
||||
GHashTable *table;
|
||||
GSList *siglist;
|
||||
void *signal_idp;
|
||||
|
||||
rec = g_new(PERL_SIGNAL_REC, 1);
|
||||
rec->signal_id = module_get_uniq_id_str("signals", signal);
|
||||
rec->signal = g_strdup(signal);
|
||||
rec->func = g_strdup(func);
|
||||
rec->last = last;
|
||||
|
||||
table = last ? last_signals : first_signals;
|
||||
signal_idp = GINT_TO_POINTER(rec->signal_id);
|
||||
|
||||
siglist = g_hash_table_lookup(table, signal_idp);
|
||||
if (siglist != NULL) g_hash_table_remove(table, signal_idp);
|
||||
|
||||
siglist = g_slist_append(siglist, rec);
|
||||
g_hash_table_insert(table, signal_idp, siglist);
|
||||
|
||||
if (!last && !signal_grabbed) {
|
||||
signal_grabbed = TRUE;
|
||||
signal_add("signal", (SIGNAL_FUNC) sig_signal);
|
||||
} else if (last && !siglast_grabbed) {
|
||||
siglast_grabbed = TRUE;
|
||||
signal_add("last signal", (SIGNAL_FUNC) sig_lastsignal);
|
||||
}
|
||||
}
|
||||
|
||||
void perl_signal_add(const char *signal, const char *func)
|
||||
{
|
||||
perl_signal_to(signal, func, FALSE);
|
||||
}
|
||||
|
||||
void perl_signal_add_last(const char *signal, const char *func)
|
||||
{
|
||||
perl_signal_to(signal, func, TRUE);
|
||||
}
|
||||
|
||||
static void perl_signal_remove_list(GSList *list, const char *func)
|
||||
{
|
||||
while (list != NULL) {
|
||||
PERL_SIGNAL_REC *rec = list->data;
|
||||
|
||||
if (strcmp(func, rec->func) == 0) {
|
||||
perl_signal_destroy(rec);
|
||||
break;
|
||||
}
|
||||
|
||||
list = list->next;
|
||||
}
|
||||
}
|
||||
|
||||
void perl_signal_remove(const char *signal, const char *func)
|
||||
{
|
||||
GSList *list;
|
||||
int signal_id;
|
||||
|
||||
signal_id = module_get_uniq_id_str("signals", signal);
|
||||
|
||||
list = g_hash_table_lookup(first_signals, GINT_TO_POINTER(signal_id));
|
||||
if (list != NULL)
|
||||
perl_signal_remove_list(list, func);
|
||||
else {
|
||||
list = g_hash_table_lookup(last_signals, GINT_TO_POINTER(signal_id));
|
||||
if (list != NULL) perl_signal_remove_list(list, func);
|
||||
}
|
||||
}
|
||||
|
||||
static int perl_timeout(PERL_TIMEOUT_REC *rec)
|
||||
{
|
||||
dSP;
|
||||
int retcount;
|
||||
|
||||
ENTER;
|
||||
SAVETMPS;
|
||||
|
||||
PUSHMARK(SP);
|
||||
XPUSHs(sv_2mortal(newSVpv(rec->data, strlen(rec->data))));
|
||||
PUTBACK;
|
||||
|
||||
retcount = perl_call_pv(rec->func, G_EVAL|G_SCALAR);
|
||||
SPAGAIN;
|
||||
|
||||
if (SvTRUE(ERRSV)) {
|
||||
STRLEN n_a;
|
||||
|
||||
signal_emit("perl error", 1, SvPV(ERRSV, n_a));
|
||||
(void) POPs;
|
||||
}
|
||||
else while (retcount--) (void) POPi;
|
||||
|
||||
PUTBACK;
|
||||
FREETMPS;
|
||||
LEAVE;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int perl_timeout_add(int msecs, const char *func, const char *data)
|
||||
{
|
||||
PERL_TIMEOUT_REC *rec;
|
||||
|
||||
rec = g_new(PERL_TIMEOUT_REC, 1);
|
||||
rec->func = g_strdup(func);
|
||||
rec->data = g_strdup(data);
|
||||
rec->tag = g_timeout_add(msecs, (GSourceFunc) perl_timeout, rec);
|
||||
|
||||
perl_timeouts = g_slist_append(perl_timeouts, rec);
|
||||
return rec->tag;
|
||||
}
|
||||
|
||||
void perl_timeout_remove(int tag)
|
||||
{
|
||||
GSList *tmp;
|
||||
|
||||
for (tmp = perl_timeouts; tmp != NULL; tmp = tmp->next) {
|
||||
PERL_TIMEOUT_REC *rec = tmp->data;
|
||||
|
||||
if (rec->tag == tag) {
|
||||
perl_timeout_destroy(rec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int call_perl(const char *func, int signal, va_list va)
|
||||
{
|
||||
dSP;
|
||||
PERL_SIGNAL_ARGS_REC *rec;
|
||||
int retcount, n, ret;
|
||||
void *arg;
|
||||
HV *stash;
|
||||
|
||||
/* first check if we find exact match */
|
||||
rec = NULL;
|
||||
for (n = 0; perl_signal_args[n].signal != NULL; n++)
|
||||
{
|
||||
if (signal == perl_signal_args[n].signal_id)
|
||||
{
|
||||
rec = &perl_signal_args[n];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rec == NULL)
|
||||
{
|
||||
/* try to find by name */
|
||||
const char *signame;
|
||||
|
||||
signame = module_find_id_str("signals", signal);
|
||||
for (n = 0; perl_signal_args[n].signal != NULL; n++)
|
||||
{
|
||||
if (strncmp(signame, perl_signal_args[n].signal,
|
||||
strlen(perl_signal_args[n].signal)) == 0)
|
||||
{
|
||||
rec = &perl_signal_args[n];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ENTER;
|
||||
SAVETMPS;
|
||||
|
||||
PUSHMARK(sp);
|
||||
|
||||
if (rec != NULL)
|
||||
{
|
||||
/* put the arguments to perl stack */
|
||||
for (n = 0; n < 7; n++)
|
||||
{
|
||||
arg = va_arg(va, gpointer);
|
||||
|
||||
if (rec->args[n] == NULL)
|
||||
break;
|
||||
|
||||
if (strcmp(rec->args[n], "string") == 0)
|
||||
XPUSHs(sv_2mortal(newSVpv(arg == NULL ? "" : arg, arg == NULL ? 0 : strlen(arg))));
|
||||
else if (strcmp(rec->args[n], "int") == 0)
|
||||
XPUSHs(sv_2mortal(newSViv(GPOINTER_TO_INT(arg))));
|
||||
else if (strcmp(rec->args[n], "ulongptr") == 0)
|
||||
XPUSHs(sv_2mortal(newSViv(*(gulong *) arg)));
|
||||
else if (strncmp(rec->args[n], "glist_", 6) == 0)
|
||||
{
|
||||
GSList *tmp;
|
||||
|
||||
stash = gv_stashpv(rec->args[n]+6, 0);
|
||||
for (tmp = arg; tmp != NULL; tmp = tmp->next)
|
||||
XPUSHs(sv_2mortal(sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(tmp->data))), stash)));
|
||||
}
|
||||
else
|
||||
{
|
||||
stash = gv_stashpv(rec->args[n], 0);
|
||||
XPUSHs(sv_2mortal(sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(arg))), stash)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PUTBACK;
|
||||
retcount = perl_call_pv((char *) func, G_EVAL|G_SCALAR);
|
||||
SPAGAIN;
|
||||
|
||||
ret = 0;
|
||||
if (SvTRUE(ERRSV))
|
||||
{
|
||||
STRLEN n_a;
|
||||
|
||||
signal_emit("perl error", 1, SvPV(ERRSV, n_a));
|
||||
(void)POPs;
|
||||
}
|
||||
else
|
||||
{
|
||||
SV *sv;
|
||||
|
||||
if (retcount > 0)
|
||||
{
|
||||
sv = POPs;
|
||||
if (SvIOK(sv) && SvIV(sv) == 1) ret = 1;
|
||||
}
|
||||
for (n = 2; n <= retcount; n++)
|
||||
(void)POPi;
|
||||
}
|
||||
|
||||
PUTBACK;
|
||||
FREETMPS;
|
||||
LEAVE;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sig_signal(void *signal, ...)
|
||||
{
|
||||
GSList *list;
|
||||
va_list va;
|
||||
|
||||
va_start(va, signal);
|
||||
|
||||
list = g_hash_table_lookup(first_signals, signal);
|
||||
while (list != NULL) {
|
||||
PERL_SIGNAL_REC *rec = list->data;
|
||||
|
||||
if (call_perl(rec->func, GPOINTER_TO_INT(signal), va)) {
|
||||
signal_stop();
|
||||
return;
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
static void sig_lastsignal(void *signal, ...)
|
||||
{
|
||||
GSList *list;
|
||||
va_list va;
|
||||
|
||||
va_start(va, signal);
|
||||
|
||||
list = g_hash_table_lookup(last_signals, signal);
|
||||
while (list != NULL) {
|
||||
PERL_SIGNAL_REC *rec = list->data;
|
||||
|
||||
if (call_perl(rec->func, GPOINTER_TO_INT(signal), va)) {
|
||||
signal_stop();
|
||||
return;
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
static void irssi_perl_autorun(void)
|
||||
{
|
||||
DIR *dirp;
|
||||
struct dirent *dp;
|
||||
char *path, *fname;
|
||||
|
||||
path = g_strdup_printf("%s/.irssi/scripts/autorun", g_get_home_dir());
|
||||
dirp = opendir(path);
|
||||
if (dirp == NULL) {
|
||||
g_free(path);
|
||||
return;
|
||||
}
|
||||
|
||||
while ((dp = readdir(dirp)) != NULL) {
|
||||
fname = g_strdup_printf("%s/%s", path, dp->d_name);
|
||||
cmd_run(fname);
|
||||
g_free(fname);
|
||||
}
|
||||
closedir(dirp);
|
||||
g_free(path);
|
||||
}
|
||||
|
||||
void irssi_perl_init(void)
|
||||
{
|
||||
command_bind("run", NULL, (SIGNAL_FUNC) cmd_run);
|
||||
command_bind("perlflush", NULL, (SIGNAL_FUNC) cmd_flush);
|
||||
signal_grabbed = siglast_grabbed = FALSE;
|
||||
|
||||
irssi_perl_start();
|
||||
irssi_perl_autorun();
|
||||
}
|
||||
|
||||
void irssi_perl_deinit(void)
|
||||
{
|
||||
irssi_perl_stop();
|
||||
|
||||
command_unbind("run", (SIGNAL_FUNC) cmd_run);
|
||||
command_unbind("perlflush", (SIGNAL_FUNC) cmd_flush);
|
||||
if (signal_grabbed) signal_remove("signal", (SIGNAL_FUNC) sig_signal);
|
||||
if (siglast_grabbed) signal_remove("last signal", (SIGNAL_FUNC) sig_lastsignal);
|
||||
}
|
||||
7
src/perl/irssi-perl.h
Normal file
7
src/perl/irssi-perl.h
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef __IRSSI_PERL_H
|
||||
#define __IRSSI_PERL_H
|
||||
|
||||
void irssi_perl_init(void);
|
||||
void irssi_perl_deinit(void);
|
||||
|
||||
#endif
|
||||
3
src/perl/module.h
Normal file
3
src/perl/module.h
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#include "common.h"
|
||||
|
||||
#define MODULE_NAME "irssi-perl"
|
||||
108
src/perl/perl-signals.h
Normal file
108
src/perl/perl-signals.h
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
static PERL_SIGNAL_ARGS_REC perl_signal_args[] =
|
||||
{
|
||||
{ -1, "gui channel open", { "CHANNEL_REC", NULL } },
|
||||
{ -1, "send command", { "string", "SERVER_REC", "CHANNEL_REC", NULL } },
|
||||
{ -1, "send command", { "string", "SERVER_REC", NULL } },
|
||||
{ -1, "command ", { "string", "SERVER_REC", "CHANNEL_REC", NULL } },
|
||||
{ -1, "default command", { "string", "SERVER_REC", "CHANNEL_REC", NULL } },
|
||||
{ -1, "server event", { "string", "SERVER_REC", "string", "string", NULL } },
|
||||
{ -1, "event ", { "string", "SERVER_REC", "string", "string", NULL } },
|
||||
{ -1, "default event", { "string", "SERVER_REC", "string", "string", NULL } },
|
||||
{ -1, "server incoming", { "SERVER_REC", "string", NULL } },
|
||||
{ -1, "redir ", { "string", "SERVER_REC", "string", "string", NULL } },
|
||||
{ -1, "ban new", { "BAN_REC", NULL } },
|
||||
{ -1, "ban remove", { "BAN_REC", NULL } },
|
||||
{ -1, "ban exception new", { "BAN_REC", NULL } },
|
||||
{ -1, "ban exception remove", { "BAN_REC", NULL } },
|
||||
{ -1, "ban type changed", { "string", NULL } },
|
||||
{ -1, "commandlist new", { "COMMAND_REC", NULL } },
|
||||
{ -1, "commandlist remove", { "COMMAND_REC", NULL } },
|
||||
{ -1, "channel created", { "CHANNEL_REC", NULL } },
|
||||
{ -1, "channel destroyed", { "CHANNEL_REC", NULL } },
|
||||
{ -1, "channel name changed", { "CHANNEL_REC", NULL } },
|
||||
{ -1, "channel topic changed", { "CHANNEL_REC", NULL } },
|
||||
{ -1, "channel server changed", { "CHANNEL_REC", "Irssi::Server", NULL } },
|
||||
{ -1, "channel query", { "CHANNEL_REC", NULL } },
|
||||
{ -1, "channel wholist", { "CHANNEL_REC", NULL } },
|
||||
{ -1, "channel sync", { "CHANNEL_REC", NULL } },
|
||||
{ -1, "ctcp msg ", { "string", "SERVER_REC", "string", "string", "string", NULL } },
|
||||
{ -1, "default ctcp msg", { "string", "SERVER_REC", "string", "string", "string", NULL } },
|
||||
{ -1, "ctcp reply ", { "string", "SERVER_REC", "string", "string", "string", NULL } },
|
||||
{ -1, "default ctcp reply", { "string", "SERVER_REC", "string", "string", "string", NULL } },
|
||||
{ -1, "server lag", { "SERVER_REC", NULL } },
|
||||
{ -1, "server lag disconnect", { "SERVER_REC", NULL } },
|
||||
{ -1, "lag", { "string", "int", NULL } },
|
||||
{ -1, "invitelist new", { "CHANNEL_REC", "string", NULL } },
|
||||
{ -1, "invitelist remove", { "CHANNEL_REC", "string", NULL } },
|
||||
{ -1, "channel mode changed", { "CHANNEL_REC", NULL } },
|
||||
{ -1, "user mode changed", { "SERVER_REC", NULL } },
|
||||
{ -1, "nick mode changed", { "CHANNEL_REC", "NICK_REC", NULL } },
|
||||
{ -1, "netsplit add", { "NETSPLIT_REC", NULL } },
|
||||
{ -1, "netsplit remove", { "NETSPLIT_REC", NULL } },
|
||||
{ -1, "nicklist new", { "CHANNEL_REC", "NICK_REC", NULL } },
|
||||
{ -1, "nicklist remove", { "CHANNEL_REC", "NICK_REC", NULL } },
|
||||
{ -1, "nicklist changed", { "CHANNEL_REC", "NICK_REC", "string", NULL } },
|
||||
{ -1, "nick gone changed", { "CHANNEL_REC", "NICK_REC", NULL } },
|
||||
{ -1, "nick ircop changed", { "CHANNEL_REC", "NICK_REC", NULL } },
|
||||
{ -1, "server nick changed", { "SERVER_REC", NULL } },
|
||||
{ -1, "massjoin", { "CHANNEL_REC", "gslist_NICK_REC", NULL } },
|
||||
{ -1, "rawlog", { "SERVER_REC", "string", NULL } },
|
||||
{ -1, "server connect failed", { "SERVER_REC", NULL } },
|
||||
{ -1, "server connected", { "SERVER_REC", NULL } },
|
||||
{ -1, "server connecting", { "SERVER_REC", "ulongptr", NULL } },
|
||||
{ -1, "server looking", { "SERVER_REC", NULL } },
|
||||
{ -1, "server disconnected", { "SERVER_REC", NULL } },
|
||||
{ -1, "event connected", { "SERVER_REC", NULL } },
|
||||
{ -1, "server reconnect new", { "RECONNECT_REC", NULL } },
|
||||
{ -1, "server reconnect remove", { "RECONNECT_REC", NULL } },
|
||||
{ -1, "server reconnect not found", { "string", NULL } },
|
||||
{ -1, "print text stripped", { "SERVER_REC", "string", "int", "string", NULL } },
|
||||
{ -1, "dcc ctcp ", { "string", "DCC_REC", NULL } },
|
||||
{ -1, "default dcc ctcp", { "string", "DCC_REC", NULL } },
|
||||
{ -1, "dcc unknown ctcp", { "string", "string", "string", NULL } },
|
||||
{ -1, "dcc reply ", { "string", "DCC_REC", NULL } },
|
||||
{ -1, "default dcc reply", { "string", "DCC_REC", NULL } },
|
||||
{ -1, "dcc unknown reply", { "string", "string", "string", NULL } },
|
||||
{ -1, "dcc chat message", { "DCC_REC", "string", NULL } },
|
||||
{ -1, "dcc created", { "DCC_REC", NULL } },
|
||||
{ -1, "dcc destroyed", { "DCC_REC", NULL } },
|
||||
{ -1, "dcc connected", { "DCC_REC", NULL } },
|
||||
{ -1, "dcc rejecting", { "DCC_REC", NULL } },
|
||||
{ -1, "dcc closed", { "DCC_REC", NULL } },
|
||||
{ -1, "dcc chat message", { "DCC_REC", "string", NULL } },
|
||||
{ -1, "dcc transfer update", { "DCC_REC", NULL } },
|
||||
{ -1, "dcc request", { "DCC_REC", NULL } },
|
||||
{ -1, "dcc get receive", { "DCC_REC", NULL } },
|
||||
{ -1, "dcc error connect", { "DCC_REC", NULL } },
|
||||
{ -1, "dcc error file create", { "DCC_REC", "string", NULL } },
|
||||
{ -1, "dcc error file not found", { "string", "string", NULL } },
|
||||
{ -1, "dcc error get not found", { "string", NULL } },
|
||||
{ -1, "dcc error send exists", { "string", "string", NULL } },
|
||||
{ -1, "dcc error unknown type", { "string", NULL } },
|
||||
{ -1, "dcc error close not found", { "string", "string", "string", NULL } },
|
||||
{ -1, "flood", { "SERVER_REC", "string", "string", "string", "string", NULL } },
|
||||
{ -1, "autoignore new", { "SERVER_REC", "AUTOIGNORE_REC", NULL } },
|
||||
{ -1, "autoignore remove", { "SERVER_REC", "AUTOIGNORE_REC", NULL } },
|
||||
{ -1, "log new", { "LOG_REC", NULL } },
|
||||
{ -1, "log remove", { "LOG_REC", NULL } },
|
||||
{ -1, "log locked", { "LOG_REC", NULL } },
|
||||
{ -1, "log started", { "LOG_REC", NULL } },
|
||||
{ -1, "log stopped", { "LOG_REC", NULL } },
|
||||
{ -1, "log written", { "LOG_REC", "string", NULL } },
|
||||
{ -1, "notifylist new", { "NOTIFYLIST_REC", NULL } },
|
||||
{ -1, "notifylist remove", { "NOTIFYLIST_REC", NULL } },
|
||||
{ -1, "notifylist joined", { "SERVER_REC", "string", "string", "string", "string", "string", NULL } },
|
||||
{ -1, "notifylist away changed", { "SERVER_REC", "string", "string", "string", "string", "string", NULL } },
|
||||
{ -1, "notifylist unidle", { "SERVER_REC", "string", "string", "string", "string", "string", NULL } },
|
||||
{ -1, "notifylist left", { "SERVER_REC", "string", "string", "string", "string", "string", NULL } },
|
||||
{ -1, "plugin created", { "PLUGIN_REC", NULL } },
|
||||
{ -1, "plugin loaded", { "PLUGIN_REC", NULL } },
|
||||
{ -1, "plugin destroyed", { "PLUGIN_REC", NULL } },
|
||||
{ -1, "plugin error already loaded", { "string", NULL } },
|
||||
{ -1, "plugin error invalid", { "string", NULL } },
|
||||
{ -1, "plugin error load", { "string", "string", NULL } },
|
||||
{ -1, "plugin error not loaded", { "string", NULL } },
|
||||
{ -1, "plugin error version", { "string", NULL } },
|
||||
|
||||
{ -1, NULL }
|
||||
};
|
||||
21
src/perl/xs/Irssi.pm
Normal file
21
src/perl/xs/Irssi.pm
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#
|
||||
# Perl interface to irssi functions.
|
||||
#
|
||||
|
||||
package Irssi;
|
||||
|
||||
use strict;
|
||||
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
|
||||
|
||||
$VERSION = "0.10";
|
||||
|
||||
require Exporter;
|
||||
require DynaLoader;
|
||||
|
||||
@ISA = qw(Exporter DynaLoader);
|
||||
@EXPORT = qw(channel_find_any);
|
||||
@EXPORT_OK = qw();
|
||||
bootstrap Irssi $VERSION;
|
||||
|
||||
1;
|
||||
|
||||
933
src/perl/xs/Irssi.xs
Normal file
933
src/perl/xs/Irssi.xs
Normal file
|
|
@ -0,0 +1,933 @@
|
|||
/* This could be split to different files / modules ..? */
|
||||
#include "EXTERN.h"
|
||||
#include "perl.h"
|
||||
#include "XSUB.h"
|
||||
|
||||
#undef _
|
||||
#include <irssi-plugin.h>
|
||||
#include <irc-base/server-setup.h>
|
||||
#include <irc-base/server-reconnect.h>
|
||||
#include <irc-base/server-redirect.h>
|
||||
|
||||
typedef SERVER_REC *Irssi__Server;
|
||||
typedef SERVER_CONNECT_REC *Irssi__Connect;
|
||||
typedef RECONNECT_REC *Irssi__Reconnect;
|
||||
typedef CHANNEL_REC *Irssi__Channel;
|
||||
typedef COMMAND_REC *Irssi__Command;
|
||||
typedef NICK_REC *Irssi__Nick;
|
||||
typedef BAN_REC *Irssi__Ban;
|
||||
typedef DCC_REC *Irssi__Dcc;
|
||||
typedef NETSPLIT_REC *Irssi__Netsplit;
|
||||
typedef AUTOIGNORE_REC *Irssi__Autoignore;
|
||||
typedef LOG_REC *Irssi__Log;
|
||||
typedef LOG_ITEM_REC *Irssi__Logitem;
|
||||
typedef PLUGIN_REC *Irssi__Plugin;
|
||||
|
||||
#define new_pv(a) (newSVpv((a) == NULL ? "" : (a), (a) == NULL ? 0 : strlen(a)))
|
||||
|
||||
void add_connect_hash(HV *hv, SERVER_CONNECT_REC *conn)
|
||||
{
|
||||
hv_store(hv, "address", 7, new_pv(conn->address), 0);
|
||||
hv_store(hv, "port", 4, newSViv(conn->port), 0);
|
||||
hv_store(hv, "password", 8, new_pv(conn->password), 0);
|
||||
|
||||
hv_store(hv, "ircnet", 6, new_pv(conn->ircnet), 0);
|
||||
hv_store(hv, "wanted_nick", 11, new_pv(conn->nick), 0);
|
||||
hv_store(hv, "alternate_nick", 14, new_pv(conn->alternate_nick), 0);
|
||||
hv_store(hv, "username", 8, new_pv(conn->username), 0);
|
||||
hv_store(hv, "realname", 8, new_pv(conn->realname), 0);
|
||||
hv_store(hv, "autojoin_channels", 17, new_pv(conn->autojoin_channels), 0);
|
||||
}
|
||||
|
||||
MODULE = Irssi PACKAGE = Irssi
|
||||
|
||||
PROTOTYPES: ENABLE
|
||||
|
||||
Irssi::Channel
|
||||
cur_channel()
|
||||
CODE:
|
||||
RETVAL = cur_channel;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
Irssi::Server
|
||||
cur_server()
|
||||
CODE:
|
||||
RETVAL = cur_channel->server;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
void
|
||||
channels()
|
||||
PREINIT:
|
||||
GSList *tmp;
|
||||
HV *stash;
|
||||
PPCODE:
|
||||
stash = gv_stashpv("Irssi::Channel", 0);
|
||||
for (tmp = channels; tmp != NULL; tmp = tmp->next) {
|
||||
XPUSHs(sv_2mortal(sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(tmp->data))), stash)));
|
||||
}
|
||||
|
||||
void
|
||||
servers()
|
||||
PREINIT:
|
||||
GSList *tmp;
|
||||
HV *stash;
|
||||
PPCODE:
|
||||
stash = gv_stashpv("Irssi::Server", 0);
|
||||
for (tmp = servers; tmp != NULL; tmp = tmp->next) {
|
||||
XPUSHs(sv_2mortal(sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(tmp->data))), stash)));
|
||||
}
|
||||
|
||||
void
|
||||
commands()
|
||||
PREINIT:
|
||||
GSList *tmp;
|
||||
HV *stash;
|
||||
PPCODE:
|
||||
stash = gv_stashpv("Irssi::Command", 0);
|
||||
for (tmp = commands; tmp != NULL; tmp = tmp->next) {
|
||||
XPUSHs(sv_2mortal(sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(tmp->data))), stash)));
|
||||
}
|
||||
|
||||
void
|
||||
dccs()
|
||||
PREINIT:
|
||||
GSList *tmp;
|
||||
HV *stash;
|
||||
PPCODE:
|
||||
stash = gv_stashpv("Irssi::Dcc", 0);
|
||||
for (tmp = dcc_conns; tmp != NULL; tmp = tmp->next) {
|
||||
XPUSHs(sv_2mortal(sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(tmp->data))), stash)));
|
||||
}
|
||||
|
||||
void
|
||||
logs()
|
||||
PREINIT:
|
||||
GSList *tmp;
|
||||
HV *stash;
|
||||
PPCODE:
|
||||
stash = gv_stashpv("Irssi::Log", 0);
|
||||
for (tmp = logs; tmp != NULL; tmp = tmp->next) {
|
||||
XPUSHs(sv_2mortal(sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(tmp->data))), stash)));
|
||||
}
|
||||
|
||||
void
|
||||
plugins()
|
||||
PREINIT:
|
||||
GSList *tmp;
|
||||
HV *stash;
|
||||
PPCODE:
|
||||
stash = gv_stashpv("Irssi::Plugin", 0);
|
||||
for (tmp = plugins; tmp != NULL; tmp = tmp->next) {
|
||||
XPUSHs(sv_2mortal(sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(tmp->data))), stash)));
|
||||
}
|
||||
|
||||
Irssi::Connect
|
||||
server_create_conn(dest, port=6667, password=NULL, nick=NULL, channels=NULL)
|
||||
char *dest
|
||||
int port
|
||||
char *password
|
||||
char *nick
|
||||
char *channels
|
||||
|
||||
Irssi::Server
|
||||
server_find_tag(tag)
|
||||
char *tag
|
||||
|
||||
Irssi::Server
|
||||
server_find_ircnet(ircnet)
|
||||
char *ircnet
|
||||
|
||||
Irssi::Channel
|
||||
channel_find(channel)
|
||||
char *channel
|
||||
CODE:
|
||||
RETVAL = channel_find(NULL, channel);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
void
|
||||
print(str)
|
||||
char *str
|
||||
CODE:
|
||||
printtext(NULL, NULL, MSGLEVEL_CLIENTNOTICE, str);
|
||||
|
||||
void
|
||||
signal_emit(signal, ...)
|
||||
char *signal
|
||||
CODE:
|
||||
void *p[6];
|
||||
int n;
|
||||
|
||||
memset(p, 0, sizeof(p));
|
||||
for (n = 1; n < items && n < 6; n++) {
|
||||
p[n-1] = SvPOKp(ST(n)) ? SvPV(ST(n), PL_na) : (void *) SvIV((SV*)SvRV(ST(n)));
|
||||
}
|
||||
signal_emit(signal, items-1, p[0], p[1], p[2], p[3], p[4], p[5]);
|
||||
|
||||
void
|
||||
signal_add(signal, func)
|
||||
char *signal
|
||||
char *func
|
||||
CODE:
|
||||
perl_signal_add(signal, func);
|
||||
|
||||
void
|
||||
signal_add_last(signal, func)
|
||||
char *signal
|
||||
char *func
|
||||
CODE:
|
||||
perl_signal_add_last(signal, func);
|
||||
|
||||
void
|
||||
signal_remove(signal, func)
|
||||
char *signal
|
||||
char *func
|
||||
CODE:
|
||||
perl_signal_remove(signal, func);
|
||||
|
||||
int
|
||||
timeout_add(msecs, func, data)
|
||||
int msecs
|
||||
char *func
|
||||
char *data
|
||||
CODE:
|
||||
RETVAL = perl_timeout_add(msecs, func, data);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
void
|
||||
timeout_remove(tag)
|
||||
int tag
|
||||
CODE:
|
||||
perl_timeout_remove(tag);
|
||||
|
||||
void
|
||||
command_bind(cmd, category, func)
|
||||
char *cmd
|
||||
char *category
|
||||
char *func
|
||||
CODE:
|
||||
char *signal;
|
||||
|
||||
command_bind(cmd, *category ? category : "Perl scripts' commands", NULL);
|
||||
signal = g_strconcat("command ", cmd, NULL);
|
||||
perl_signal_add(signal, func);
|
||||
g_free(signal);
|
||||
|
||||
void
|
||||
command_unbind(cmd, func)
|
||||
char *cmd
|
||||
char *func
|
||||
CODE:
|
||||
char *signal;
|
||||
|
||||
command_unbind(cmd, NULL);
|
||||
signal = g_strconcat("command ", cmd, NULL);
|
||||
perl_signal_remove(signal, func);
|
||||
g_free(signal);
|
||||
|
||||
void
|
||||
command(cmd, server=cur_channel->server, channel=cur_channel)
|
||||
char *cmd
|
||||
Irssi::Server server
|
||||
Irssi::Channel channel
|
||||
CODE:
|
||||
signal_emit("send command", 3, cmd, server, channel);
|
||||
|
||||
int
|
||||
is_channel(text)
|
||||
char *text
|
||||
CODE:
|
||||
RETVAL = ischannel(*text);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
int
|
||||
irc_mask_match(mask, nick, user, host)
|
||||
char *mask
|
||||
char *nick
|
||||
char *user
|
||||
char *host
|
||||
|
||||
int
|
||||
irc_mask_match_address(mask, nick, address)
|
||||
char *mask
|
||||
char *nick
|
||||
char *address
|
||||
|
||||
int
|
||||
irc_masks_match(masks, nick, address)
|
||||
char *masks
|
||||
char *nick
|
||||
char *address
|
||||
|
||||
char *
|
||||
irc_get_mask(nick, host, flags)
|
||||
char *nick
|
||||
char *host
|
||||
int flags
|
||||
|
||||
int
|
||||
level2bits(str)
|
||||
char *str
|
||||
|
||||
char *
|
||||
bits2level(bits)
|
||||
int bits
|
||||
|
||||
int
|
||||
combine_level(level, str)
|
||||
int level
|
||||
char *str
|
||||
|
||||
Irssi::Dcc
|
||||
dcc_find_item(type, nick, arg)
|
||||
int type
|
||||
char *nick
|
||||
char *arg
|
||||
|
||||
Irssi::Dcc
|
||||
dcc_find_by_port(nick, port)
|
||||
char *nick
|
||||
int port
|
||||
|
||||
char *
|
||||
dcc_type2str(type)
|
||||
int type
|
||||
|
||||
int
|
||||
dcc_str2type(type)
|
||||
char *type
|
||||
|
||||
void
|
||||
ignore_add(mask, level)
|
||||
char *mask
|
||||
char *level
|
||||
|
||||
void
|
||||
ignore_remove(mask, level)
|
||||
char *mask
|
||||
char *level
|
||||
|
||||
Irssi::Log
|
||||
log_create(fname, data)
|
||||
char *fname
|
||||
char *data
|
||||
|
||||
Irssi::Log
|
||||
log_create_with_level(fname, level)
|
||||
char *fname
|
||||
int level
|
||||
|
||||
Irssi::Log
|
||||
log_file_find(fname)
|
||||
char *fname
|
||||
|
||||
void
|
||||
notifylist_add(nick, ircnet)
|
||||
char *nick
|
||||
char *ircnet
|
||||
|
||||
Irssi::Server
|
||||
notifylist_ison(nick, serverlist)
|
||||
char *nick
|
||||
char *serverlist
|
||||
|
||||
int
|
||||
plugin_load(name, args)
|
||||
char *name
|
||||
char *args
|
||||
|
||||
char *
|
||||
plugin_get_description(name)
|
||||
char *name
|
||||
|
||||
Irssi::Plugin
|
||||
plugin_find(name)
|
||||
char *name
|
||||
|
||||
void
|
||||
setup_get(option)
|
||||
char *option
|
||||
PREINIT:
|
||||
char *ret;
|
||||
PPCODE:
|
||||
switch(setup_option_type(option)) {
|
||||
case SETUP_TYPE_TOGGLEBUTTON:
|
||||
XPUSHs(sv_2mortal(newSViv(setup_get_bool(option))));
|
||||
break;
|
||||
case SETUP_TYPE_SPIN:
|
||||
case SETUP_TYPE_INT_OBJECT:
|
||||
XPUSHs(sv_2mortal(newSViv(setup_get_int(option))));
|
||||
break;
|
||||
case SETUP_TYPE_ENTRY:
|
||||
ret = setup_get_str(option);
|
||||
XPUSHs(sv_2mortal(newSVpv(ret, strlen(ret))));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
#*******************************************************
|
||||
MODULE = Irssi PACKAGE = Irssi::Server PREFIX = server_
|
||||
#*******************************************************
|
||||
|
||||
void
|
||||
send_raw(server, cmd)
|
||||
Irssi::Server server
|
||||
char *cmd
|
||||
CODE:
|
||||
irc_send_cmd(server, cmd);
|
||||
|
||||
void
|
||||
command(server, cmd, channel=cur_channel)
|
||||
char *cmd
|
||||
Irssi::Server server
|
||||
Irssi::Channel channel
|
||||
CODE:
|
||||
if (channel->server != server) {
|
||||
GSList *tmp;
|
||||
|
||||
for (tmp = channels; tmp != NULL; tmp = tmp->next) {
|
||||
CHANNEL_REC *rec = tmp->data;
|
||||
|
||||
if (rec->server == server) {
|
||||
channel = rec;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
signal_emit("send command", 3, cmd, server, channel);
|
||||
|
||||
void
|
||||
server_disconnect(server)
|
||||
Irssi::Server server
|
||||
|
||||
Irssi::Channel
|
||||
channel_create(server, channel, type, automatic)
|
||||
Irssi::Server server
|
||||
char *channel
|
||||
int type
|
||||
int automatic
|
||||
|
||||
Irssi::Channel
|
||||
channel_find(server, channel)
|
||||
Irssi::Server server
|
||||
char *channel
|
||||
|
||||
Irssi::Channel
|
||||
channel_find_closest(server, channel, level)
|
||||
Irssi::Server server
|
||||
char *channel
|
||||
int level
|
||||
|
||||
Irssi::Channel
|
||||
channel_find_level(server, level)
|
||||
Irssi::Server server
|
||||
int level
|
||||
|
||||
void
|
||||
printtext(server, channel, level, str)
|
||||
Irssi::Server server
|
||||
char *channel
|
||||
int level
|
||||
char *str
|
||||
CODE:
|
||||
printtext(server, channel, level, str);
|
||||
|
||||
void
|
||||
irc_send_cmd_split(server, cmd, arg, max_nicks)
|
||||
Irssi::Server server
|
||||
char *cmd
|
||||
int arg
|
||||
int max_nicks
|
||||
|
||||
void
|
||||
ctcp_send_reply(server, data)
|
||||
Irssi::Server server
|
||||
char *data
|
||||
|
||||
Irssi::Netsplit
|
||||
netsplit_find(server, nick, address)
|
||||
Irssi::Server server
|
||||
char *nick
|
||||
char *address
|
||||
|
||||
Irssi::Nick
|
||||
netsplit_find_channel(server, nick, address, channel)
|
||||
Irssi::Server server
|
||||
char *nick
|
||||
char *address
|
||||
char *channel
|
||||
|
||||
void
|
||||
rawlog_input(server, str)
|
||||
Irssi::Server server
|
||||
char *str
|
||||
|
||||
void
|
||||
rawlog_output(server, str)
|
||||
Irssi::Server server
|
||||
char *str
|
||||
|
||||
void
|
||||
rawlog_redirect(server, str)
|
||||
Irssi::Server server
|
||||
char *str
|
||||
|
||||
void
|
||||
server_redirect_init(server, command, last, ...)
|
||||
Irssi::Server server
|
||||
char *command
|
||||
int last
|
||||
PREINIT:
|
||||
GSList *list;
|
||||
int n;
|
||||
CODE:
|
||||
list = NULL;
|
||||
for (n = 3; n < items; n++) {
|
||||
list = g_slist_append(list, SvPV(ST(n), PL_na));
|
||||
}
|
||||
server_redirect_initv(server, command, last, list);
|
||||
|
||||
int
|
||||
server_redirect_single_event(server, arg, last, group, event, signal, argpos)
|
||||
Irssi::Server server
|
||||
char *arg
|
||||
int last
|
||||
int group
|
||||
char *event
|
||||
char *signal
|
||||
int argpos
|
||||
|
||||
void
|
||||
server_redirect_event(server, arg, last, ...)
|
||||
Irssi::Server server
|
||||
char *arg
|
||||
int last
|
||||
PREINIT:
|
||||
int n, group;
|
||||
CODE:
|
||||
group = 0;
|
||||
for (n = 3; n+3 <= items; n += 3, last--) {
|
||||
group = server_redirect_single_event(server, arg, last > 0, group,
|
||||
(char *) SvPV(ST(n), PL_na), (char *) SvPV(ST(n+1), PL_na), (int) SvIV(ST(n+2)));
|
||||
}
|
||||
|
||||
void
|
||||
autoignore_add(server, type, nick)
|
||||
Irssi::Server server
|
||||
int type
|
||||
char *nick
|
||||
|
||||
int
|
||||
autoignore_remove(server, mask, level)
|
||||
Irssi::Server server
|
||||
char *mask
|
||||
char *level
|
||||
|
||||
int
|
||||
ignore_check(server, nick, host, type)
|
||||
Irssi::Server server
|
||||
char *nick
|
||||
char *host
|
||||
int type
|
||||
|
||||
int
|
||||
notifylist_ison_server(server, nick)
|
||||
Irssi::Server server
|
||||
char *nick
|
||||
|
||||
void
|
||||
values(server)
|
||||
Irssi::Server server
|
||||
PREINIT:
|
||||
HV *hv;
|
||||
PPCODE:
|
||||
hv = newHV();
|
||||
add_connect_hash(hv, server->connrec);
|
||||
hv_store(hv, "real_address", 12, new_pv(server->real_address), 0);
|
||||
hv_store(hv, "tag", 3, new_pv(server->tag), 0);
|
||||
hv_store(hv, "nick", 4, new_pv(server->nick), 0);
|
||||
hv_store(hv, "usermode", 8, new_pv(server->usermode), 0);
|
||||
hv_store(hv, "usermode_away", 13, newSViv(server->usermode_away), 0);
|
||||
hv_store(hv, "away_reason", 11, new_pv(server->away_reason), 0);
|
||||
hv_store(hv, "connected", 9, newSViv(server->connected), 0);
|
||||
hv_store(hv, "connection_lost", 15, newSViv(server->connection_lost), 0);
|
||||
XPUSHs(sv_2mortal(newRV_noinc((SV*)hv)));
|
||||
|
||||
#*******************************************************
|
||||
MODULE = Irssi PACKAGE = Irssi::Connect PREFIX = server_
|
||||
#*******************************************************
|
||||
|
||||
void
|
||||
values(conn)
|
||||
Irssi::Connect conn
|
||||
PREINIT:
|
||||
HV *hv;
|
||||
PPCODE:
|
||||
hv = newHV();
|
||||
add_connect_hash(hv, conn);
|
||||
XPUSHs(sv_2mortal(newRV_noinc((SV*)hv)));
|
||||
|
||||
Irssi::Server
|
||||
server_connect(conn)
|
||||
Irssi::Connect conn
|
||||
|
||||
#*******************************************************
|
||||
MODULE = Irssi PACKAGE = Irssi::Reconnect
|
||||
#*******************************************************
|
||||
|
||||
void
|
||||
values(reconnect)
|
||||
Irssi::Reconnect reconnect
|
||||
PREINIT:
|
||||
HV *hv;
|
||||
PPCODE:
|
||||
hv = newHV();
|
||||
add_connect_hash(hv, reconnect->conn);
|
||||
hv_store(hv, "tag", 3, newSViv(reconnect->tag), 0);
|
||||
hv_store(hv, "next_connect", 12, newSViv(reconnect->next_connect), 0);
|
||||
XPUSHs(sv_2mortal(newRV_noinc((SV*)hv)));
|
||||
|
||||
#*******************************************************
|
||||
MODULE = Irssi PACKAGE = Irssi::Channel PREFIX = channel_
|
||||
#*******************************************************
|
||||
|
||||
void
|
||||
command(channel, cmd)
|
||||
Irssi::Channel channel
|
||||
char *cmd
|
||||
CODE:
|
||||
signal_emit("send command", 3, cmd, channel->server, channel);
|
||||
|
||||
void
|
||||
channel_destroy(channel)
|
||||
Irssi::Channel channel
|
||||
|
||||
void
|
||||
channel_change_name(channel, name)
|
||||
Irssi::Channel channel
|
||||
char *name
|
||||
|
||||
char *
|
||||
channel_get_mode(channel)
|
||||
Irssi::Channel channel
|
||||
|
||||
Irssi::Nick
|
||||
nicklist_insert(channel, nick, op, voice, send_massjoin)
|
||||
Irssi::Channel channel
|
||||
char *nick
|
||||
int op
|
||||
int voice
|
||||
int send_massjoin
|
||||
|
||||
void
|
||||
nicklist_remove(channel, nick)
|
||||
Irssi::Channel channel
|
||||
Irssi::Nick nick
|
||||
|
||||
Irssi::Nick
|
||||
nicklist_find(channel, mask)
|
||||
Irssi::Channel channel
|
||||
char *mask
|
||||
|
||||
void
|
||||
nicklist_getnicks(channel)
|
||||
Irssi::Channel channel
|
||||
PREINIT:
|
||||
GSList *list, *tmp;
|
||||
HV *stash;
|
||||
PPCODE:
|
||||
list = nicklist_getnicks(channel);
|
||||
|
||||
stash = gv_stashpv("Irssi::Nick", 0);
|
||||
for (tmp = list; tmp != NULL; tmp = tmp->next) {
|
||||
XPUSHs(sv_2mortal(sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(tmp->data))), stash)));
|
||||
}
|
||||
g_slist_free(list);
|
||||
|
||||
Irssi::Ban
|
||||
ban_add(channel, ban, nick, time)
|
||||
Irssi::Channel channel
|
||||
char *ban
|
||||
char *nick
|
||||
time_t time
|
||||
|
||||
void
|
||||
ban_remove(channel, ban)
|
||||
Irssi::Channel channel
|
||||
char *ban
|
||||
|
||||
Irssi::Ban
|
||||
ban_exception_add(channel, ban, nick, time)
|
||||
Irssi::Channel channel
|
||||
char *ban
|
||||
char *nick
|
||||
time_t time
|
||||
|
||||
void
|
||||
ban_exception_remove(channel, ban)
|
||||
Irssi::Channel channel
|
||||
char *ban
|
||||
|
||||
char *
|
||||
ban_get_mask(channel, nick)
|
||||
Irssi::Channel channel
|
||||
char *nick
|
||||
|
||||
void
|
||||
modes_set(channel, data, mode)
|
||||
Irssi::Channel channel
|
||||
char *data
|
||||
char *mode
|
||||
CODE:
|
||||
modes_set(data, mode, channel->server, channel);
|
||||
|
||||
void
|
||||
modes_parse_channel(channel, setby, modestr)
|
||||
Irssi::Channel channel
|
||||
char *setby
|
||||
char *modestr
|
||||
|
||||
void
|
||||
invitelist_add(channel, mask)
|
||||
Irssi::Channel channel
|
||||
char *mask
|
||||
|
||||
void
|
||||
invitelist_remove(channel, mask)
|
||||
Irssi::Channel channel
|
||||
char *mask
|
||||
|
||||
void
|
||||
values(channel)
|
||||
Irssi::Channel channel
|
||||
PREINIT:
|
||||
HV *hv, *stash;
|
||||
char *type;
|
||||
PPCODE:
|
||||
switch (channel->type)
|
||||
{
|
||||
case CHANNEL_TYPE_CHANNEL:
|
||||
type = "channel";
|
||||
break;
|
||||
case CHANNEL_TYPE_QUERY:
|
||||
type = "query";
|
||||
break;
|
||||
case CHANNEL_TYPE_DCC_CHAT:
|
||||
type = "dcc chat";
|
||||
break;
|
||||
default:
|
||||
type = "empty";
|
||||
break;
|
||||
}
|
||||
hv = newHV();
|
||||
stash = gv_stashpv("Irssi::Server", 0);
|
||||
hv_store(hv, "server", 6, sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(channel->server))), stash), 0);
|
||||
|
||||
hv_store(hv, "name", 4, new_pv(channel->name), 0);
|
||||
hv_store(hv, "type", 4, new_pv(type), 0);
|
||||
|
||||
hv_store(hv, "topic", 5, new_pv(channel->topic), 0);
|
||||
hv_store(hv, "key", 3, new_pv(channel->key), 0);
|
||||
hv_store(hv, "limit", 5, newSViv(channel->limit), 0);
|
||||
|
||||
hv_store(hv, "level", 5, newSViv(channel->level), 0);
|
||||
hv_store(hv, "new_data", 8, newSViv(channel->new_data), 0);
|
||||
|
||||
hv_store(hv, "synced", 6, newSViv(channel->synced), 0);
|
||||
hv_store(hv, "wholist", 7, newSViv(channel->wholist), 0);
|
||||
hv_store(hv, "names_got", 9, newSViv(channel->names_got), 0);
|
||||
hv_store(hv, "chanop", 6, newSViv(channel->chanop), 0);
|
||||
hv_store(hv, "left", 4, newSViv(channel->left), 0);
|
||||
hv_store(hv, "kicked", 6, newSViv(channel->kicked), 0);
|
||||
|
||||
XPUSHs(sv_2mortal(newRV_noinc((SV*)hv)));
|
||||
|
||||
#*******************************************************
|
||||
MODULE = Irssi PACKAGE = Irssi::Command
|
||||
#*******************************************************
|
||||
|
||||
void
|
||||
values(cmd)
|
||||
Irssi::Command cmd
|
||||
PREINIT:
|
||||
HV *hv;
|
||||
PPCODE:
|
||||
hv = newHV();
|
||||
hv_store(hv, "cmd", 3, new_pv(cmd->cmd), 0);
|
||||
hv_store(hv, "category", 8, new_pv(cmd->category), 0);
|
||||
XPUSHs(sv_2mortal(newRV_noinc((SV*)hv)));
|
||||
|
||||
#*******************************************************
|
||||
MODULE = Irssi PACKAGE = Irssi::Nick
|
||||
#*******************************************************
|
||||
|
||||
void
|
||||
values(nick)
|
||||
Irssi::Nick nick
|
||||
PREINIT:
|
||||
HV *hv;
|
||||
PPCODE:
|
||||
hv = newHV();
|
||||
hv_store(hv, "nick", 4, new_pv(nick->nick), 0);
|
||||
hv_store(hv, "host", 4, new_pv(nick->host), 0);
|
||||
hv_store(hv, "name", 4, new_pv(nick->realname), 0);
|
||||
hv_store(hv, "hops", 4, newSViv(nick->hops), 0);
|
||||
hv_store(hv, "op", 2, newSViv(nick->op), 0);
|
||||
hv_store(hv, "voice", 5, newSViv(nick->voice), 0);
|
||||
hv_store(hv, "gone", 4, newSViv(nick->gone), 0);
|
||||
hv_store(hv, "ircop", 5, newSViv(nick->ircop), 0);
|
||||
hv_store(hv, "last_check", 10, newSViv(nick->last_check), 0);
|
||||
hv_store(hv, "send_massjoin", 13, newSViv(nick->send_massjoin), 0);
|
||||
XPUSHs(sv_2mortal(newRV_noinc((SV*)hv)));
|
||||
|
||||
#*******************************************************
|
||||
MODULE = Irssi PACKAGE = Irssi::Ban
|
||||
#*******************************************************
|
||||
|
||||
void
|
||||
values(ban)
|
||||
Irssi::Ban ban
|
||||
PREINIT:
|
||||
HV *hv;
|
||||
PPCODE:
|
||||
hv = newHV();
|
||||
hv_store(hv, "ban", 3, new_pv(ban->ban), 0);
|
||||
hv_store(hv, "setby", 5, new_pv(ban->setby), 0);
|
||||
hv_store(hv, "time", 4, newSViv(ban->time), 0);
|
||||
XPUSHs(sv_2mortal(newRV_noinc((SV*)hv)));
|
||||
|
||||
#*******************************************************
|
||||
MODULE = Irssi PACKAGE = Irssi::Dcc PREFIX = dcc_
|
||||
#*******************************************************
|
||||
|
||||
void
|
||||
dcc_destroy(dcc)
|
||||
Irssi::Dcc dcc
|
||||
|
||||
void
|
||||
values(ban)
|
||||
Irssi::Ban ban
|
||||
PREINIT:
|
||||
HV *hv;
|
||||
PPCODE:
|
||||
hv = newHV();
|
||||
hv_store(hv, "ban", 3, new_pv(ban->ban), 0);
|
||||
hv_store(hv, "setby", 5, new_pv(ban->setby), 0);
|
||||
hv_store(hv, "time", 4, newSViv(ban->time), 0);
|
||||
XPUSHs(sv_2mortal(newRV_noinc((SV*)hv)));
|
||||
|
||||
#*******************************************************
|
||||
MODULE = Irssi PACKAGE = Irssi::Netsplit
|
||||
#*******************************************************
|
||||
|
||||
void
|
||||
values(netsplit)
|
||||
Irssi::Netsplit netsplit
|
||||
PREINIT:
|
||||
HV *hv;
|
||||
PPCODE:
|
||||
hv = newHV();
|
||||
hv_store(hv, "nick", 4, new_pv(netsplit->nick), 0);
|
||||
hv_store(hv, "address", 7, new_pv(netsplit->address), 0);
|
||||
hv_store(hv, "server", 6, new_pv(netsplit->server), 0);
|
||||
hv_store(hv, "destserver", 10, new_pv(netsplit->destserver), 0);
|
||||
hv_store(hv, "destroy", 7, newSViv(netsplit->destroy), 0);
|
||||
/*FIXME: add GSList *channels;*/
|
||||
XPUSHs(sv_2mortal(newRV_noinc((SV*)hv)));
|
||||
|
||||
#*******************************************************
|
||||
MODULE = Irssi PACKAGE = Irssi::Autoignore
|
||||
#*******************************************************
|
||||
|
||||
void
|
||||
values(ai)
|
||||
Irssi::Autoignore ai
|
||||
PREINIT:
|
||||
HV *hv;
|
||||
PPCODE:
|
||||
hv = newHV();
|
||||
hv_store(hv, "nick", 4, new_pv(ai->nick), 0);
|
||||
hv_store(hv, "timeleft", 8, newSViv(ai->timeleft), 0);
|
||||
hv_store(hv, "level", 5, newSViv(ai->level), 0);
|
||||
XPUSHs(sv_2mortal(newRV_noinc((SV*)hv)));
|
||||
|
||||
#*******************************************************
|
||||
MODULE = Irssi PACKAGE = Irssi::Log PREFIX = log_
|
||||
#*******************************************************
|
||||
|
||||
void
|
||||
values(log)
|
||||
Irssi::Log log
|
||||
PREINIT:
|
||||
HV *hv;
|
||||
PPCODE:
|
||||
hv = newHV();
|
||||
hv_store(hv, "fname", 5, new_pv(log->fname), 0);
|
||||
hv_store(hv, "autoopen_log", 12, newSViv(log->autoopen_log), 0);
|
||||
hv_store(hv, "last", 4, newSViv(log->last), 0);
|
||||
hv_store(hv, "level", 5, newSViv(log->level), 0);
|
||||
/*FIXME: add GSList *items;*/
|
||||
XPUSHs(sv_2mortal(newRV_noinc((SV*)hv)));
|
||||
|
||||
void
|
||||
destroy(log)
|
||||
Irssi::Log log
|
||||
CODE:
|
||||
log_file_destroy(log);
|
||||
|
||||
int
|
||||
open(log)
|
||||
Irssi::Log log
|
||||
CODE:
|
||||
log_file_open(log);
|
||||
|
||||
void
|
||||
close(log)
|
||||
Irssi::Log log
|
||||
CODE:
|
||||
log_file_close(log);
|
||||
|
||||
void
|
||||
log_append_item(log, name, level)
|
||||
Irssi::Log log
|
||||
char *name
|
||||
int level
|
||||
|
||||
void
|
||||
log_remove_item(log, name)
|
||||
Irssi::Log log
|
||||
char *name
|
||||
|
||||
#*******************************************************
|
||||
MODULE = Irssi PACKAGE = Irssi::Logitem
|
||||
#*******************************************************
|
||||
|
||||
void
|
||||
values(item)
|
||||
Irssi::Logitem item
|
||||
PREINIT:
|
||||
HV *hv;
|
||||
PPCODE:
|
||||
hv = newHV();
|
||||
hv_store(hv, "name", 4, new_pv(item->name), 0);
|
||||
hv_store(hv, "level", 5, newSViv(item->level), 0);
|
||||
XPUSHs(sv_2mortal(newRV_noinc((SV*)hv)));
|
||||
|
||||
#*******************************************************
|
||||
MODULE = Irssi PACKAGE = Irssi::Plugin PREFIX = plugin_
|
||||
#*******************************************************
|
||||
|
||||
void
|
||||
values(plugin)
|
||||
Irssi::Plugin plugin
|
||||
PREINIT:
|
||||
HV *hv;
|
||||
PPCODE:
|
||||
hv = newHV();
|
||||
hv_store(hv, "name", 4, new_pv(plugin->name), 0);
|
||||
hv_store(hv, "description", 11, new_pv(plugin->description), 0);
|
||||
XPUSHs(sv_2mortal(newRV_noinc((SV*)hv)));
|
||||
6
src/perl/xs/Makefile.PL.in
Normal file
6
src/perl/xs/Makefile.PL.in
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
use ExtUtils::MakeMaker;
|
||||
|
||||
WriteMakefile('NAME' => 'Irssi',
|
||||
'LIBS' => '',
|
||||
'INC' => '-I@top_srcdir@/src @GLIB_CFLAGS@',
|
||||
'VERSION_FROM' => '@srcdir@/Irssi.pm');
|
||||
14
src/perl/xs/typemap
Normal file
14
src/perl/xs/typemap
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
TYPEMAP
|
||||
Irssi::Server T_PTROBJ
|
||||
Irssi::Connect T_PTROBJ
|
||||
Irssi::Reconnect T_PTROBJ
|
||||
Irssi::Channel T_PTROBJ
|
||||
Irssi::Command T_PTROBJ
|
||||
Irssi::Nick T_PTROBJ
|
||||
Irssi::Ban T_PTROBJ
|
||||
Irssi::Dcc T_PTROBJ
|
||||
Irssi::Netsplit T_PTROBJ
|
||||
Irssi::Autoignore T_PTROBJ
|
||||
Irssi::Log T_PTROBJ
|
||||
Irssi::Logitem T_PTROBJ
|
||||
Irssi::Plugin T_PTROBJ
|
||||
41
src/perl/xsinit.c
Normal file
41
src/perl/xsinit.c
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#if defined(__cplusplus) && !defined(PERL_OBJECT)
|
||||
#define is_cplusplus
|
||||
#endif
|
||||
|
||||
#ifdef is_cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <EXTERN.h>
|
||||
#include <perl.h>
|
||||
#ifdef PERL_OBJECT
|
||||
#define NO_XSLOCKS
|
||||
#include <XSUB.h>
|
||||
#include "win32iop.h"
|
||||
#include <fcntl.h>
|
||||
#include <perlhost.h>
|
||||
#endif
|
||||
#ifdef is_cplusplus
|
||||
}
|
||||
# ifndef EXTERN_C
|
||||
# define EXTERN_C extern "C"
|
||||
# endif
|
||||
#else
|
||||
# ifndef EXTERN_C
|
||||
# define EXTERN_C extern
|
||||
# endif
|
||||
#endif
|
||||
|
||||
EXTERN_C void xs_init _((void));
|
||||
|
||||
EXTERN_C void boot_DynaLoader _((CV* cv));
|
||||
|
||||
EXTERN_C void
|
||||
xs_init(void)
|
||||
{
|
||||
char *file = __FILE__;
|
||||
dXSUB_SYS;
|
||||
|
||||
/* DynaLoader is a special case */
|
||||
newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue