diff --git a/src/perl/common/Channel.xs b/src/perl/common/Channel.xs index 7ebc927b..2cd7986b 100644 --- a/src/perl/common/Channel.xs +++ b/src/perl/common/Channel.xs @@ -6,12 +6,17 @@ PREINIT: GSList *tmp; PPCODE: for (tmp = channels; tmp != NULL; tmp = tmp->next) { - CHANNEL_REC *rec = tmp->data; - - XPUSHs(sv_2mortal(sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(rec))), - irssi_get_stash(rec)))); + XPUSHs(sv_2mortal(irssi_bless((CHANNEL_REC *) tmp->data))); } +Irssi::Channel +channel_find(channel) + char *channel +CODE: + RETVAL = channel_find(NULL, channel); +OUTPUT: + RETVAL + #******************************* MODULE = Irssi PACKAGE = Irssi::Server #******************************* @@ -23,10 +28,7 @@ PREINIT: GSList *tmp; PPCODE: for (tmp = server->channels; tmp != NULL; tmp = tmp->next) { - CHANNEL_REC *rec = tmp->data; - - XPUSHs(sv_2mortal(sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(rec))), - irssi_get_stash(rec)))); + XPUSHs(sv_2mortal(irssi_bless((CHANNEL_REC *) tmp->data))); } Irssi::Channel @@ -47,17 +49,12 @@ nicklist_get_same(server, nick) char *nick PREINIT: GSList *list, *tmp; - HV *nickstash; PPCODE: list = nicklist_get_same(server, nick); - nickstash = gv_stashpv("Irssi::Nick", 0); for (tmp = list; tmp != NULL; tmp = tmp->next->next) { - CHANNEL_REC *channel = tmp->data; - - XPUSHs(sv_2mortal(sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(channel))), - irssi_get_stash(channel)))); - XPUSHs(sv_2mortal(sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(tmp->next->data))), nickstash))); + XPUSHs(sv_2mortal(irssi_bless((CHANNEL_REC *) tmp->data))); + XPUSHs(sv_2mortal(irssi_bless((NICK_REC *) tmp->next->data))); } g_slist_free(list); @@ -66,27 +63,15 @@ MODULE = Irssi PACKAGE = Irssi::Channel PREFIX = channel_ #******************************* void -values(channel) +init(channel) Irssi::Channel channel -PREINIT: - HV *hv; -PPCODE: - hv = newHV(); - perl_channel_fill_hash(hv, channel); - XPUSHs(sv_2mortal(newRV_noinc((SV*)hv))); +CODE: + perl_channel_fill_hash(hvref(ST(0)), channel); void channel_destroy(channel) Irssi::Channel channel -Irssi::Channel -channel_find(channel) - char *channel -CODE: - RETVAL = channel_find(NULL, channel); -OUTPUT: - RETVAL - void command(channel, cmd) Irssi::Channel channel @@ -95,35 +80,43 @@ CODE: signal_emit("send command", 3, cmd, channel->server, channel); Irssi::Nick -nicklist_insert(channel, nick, op, voice, send_massjoin) +nick_insert(channel, nick, op, voice, send_massjoin) Irssi::Channel channel char *nick int op int voice int send_massjoin +CODE: + RETVAL = nicklist_insert(channel, nick, op, voice, send_massjoin); +OUTPUT: + RETVAL void -nicklist_remove(channel, nick) +nick_remove(channel, nick) Irssi::Channel channel Irssi::Nick nick +CODE: + nicklist_remove(channel, nick); Irssi::Nick -nicklist_find(channel, mask) +nick_find(channel, mask) Irssi::Channel channel char *mask +CODE: + RETVAL = nicklist_find(channel, mask); +OUTPUT: + RETVAL void -nicklist_getnicks(channel) +nicks(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))); + XPUSHs(sv_2mortal(irssi_bless((NICK_REC *) tmp->data))); } g_slist_free(list); @@ -132,25 +125,8 @@ MODULE = Irssi PACKAGE = Irssi::Nick #******************************* void -values(nick) +init(nick) Irssi::Nick nick -PREINIT: - HV *hv; -PPCODE: - hv = newHV(); - hv_store(hv, "last_check", 10, newSViv(nick->last_check), 0); - - hv_store(hv, "nick", 4, new_pv(nick->nick), 0); - hv_store(hv, "host", 4, new_pv(nick->host), 0); - hv_store(hv, "realname", 8, new_pv(nick->realname), 0); - hv_store(hv, "hops", 4, newSViv(nick->hops), 0); - - hv_store(hv, "gone", 4, newSViv(nick->gone), 0); - hv_store(hv, "serverop", 8, newSViv(nick->serverop), 0); - - hv_store(hv, "send_massjoin", 13, newSViv(nick->send_massjoin), 0); - hv_store(hv, "op", 2, newSViv(nick->op), 0); - hv_store(hv, "halfop", 6, newSViv(nick->halfop), 0); - hv_store(hv, "voice", 5, newSViv(nick->voice), 0); - XPUSHs(sv_2mortal(newRV_noinc((SV*)hv))); +CODE: + perl_nick_fill_hash(hvref(ST(0)), nick); diff --git a/src/perl/common/Core.xs b/src/perl/common/Core.xs index c29a17dd..55732b4f 100644 --- a/src/perl/common/Core.xs +++ b/src/perl/common/Core.xs @@ -302,7 +302,7 @@ PREINIT: 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))); + push_bless(tmp->data, stash); } void @@ -335,12 +335,13 @@ MODULE = Irssi PACKAGE = Irssi::Command PREFIX = command_ #******************************* void -values(cmd) +init(cmd) Irssi::Command cmd PREINIT: HV *hv; -PPCODE: - hv = newHV(); - hv_store(hv, "category", 8, new_pv(cmd->category), 0); - hv_store(hv, "cmd", 3, new_pv(cmd->cmd), 0); - XPUSHs(sv_2mortal(newRV_noinc((SV*)hv))); +CODE: + hv = hvref(ST(0)); + if (hv != NULL) { + hv_store(hv, "category", 8, new_pv(cmd->category), 0); + hv_store(hv, "cmd", 3, new_pv(cmd->cmd), 0); + } diff --git a/src/perl/common/Ignore.xs b/src/perl/common/Ignore.xs index 643198f3..aab0db8b 100644 --- a/src/perl/common/Ignore.xs +++ b/src/perl/common/Ignore.xs @@ -8,7 +8,7 @@ PREINIT: PPCODE: stash = gv_stashpv("Irssi::Ignore", 0); for (tmp = servers; tmp != NULL; tmp = tmp->next) { - XPUSHs(sv_2mortal(sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(tmp->data))), stash))); + push_bless(tmp->data, stash); } int @@ -41,29 +41,31 @@ MODULE = Irssi PACKAGE = Irssi::Ignore PREFIX = ignore_ #******************************* void -values(ignore) +init(ignore) Irssi::Ignore ignore PREINIT: HV *hv; AV *av; char **tmp; -PPCODE: - hv = newHV(); - hv_store(hv, "mask", 4, new_pv(ignore->mask), 0); - hv_store(hv, "servertag", 9, new_pv(ignore->servertag), 0); - av = newAV(); - for (tmp = ignore->channels; *tmp != NULL; tmp++) { - av_push(av, new_pv(*tmp)); +CODE: + hv = hvref(ST(0)); + if (hv != NULL) { + hv_store(hv, "mask", 4, new_pv(ignore->mask), 0); + hv_store(hv, "servertag", 9, new_pv(ignore->servertag), 0); + av = newAV(); + for (tmp = ignore->channels; *tmp != NULL; tmp++) { + av_push(av, new_pv(*tmp)); + } + hv_store(hv, "channels", 8, newRV_noinc((SV*)av), 0); + hv_store(hv, "pattern", 7, new_pv(ignore->pattern), 0); + + hv_store(hv, "level", 5, newSViv(ignore->level), 0); + hv_store(hv, "except_level", 12, newSViv(ignore->except_level), 0); + + hv_store(hv, "regexp", 6, newSViv(ignore->regexp), 0); + hv_store(hv, "fullword", 8, newSViv(ignore->fullword), 0); + XPUSHs(sv_2mortal(newRV_noinc((SV*)hv))); } - hv_store(hv, "channels", 8, newRV_noinc((SV*)av), 0); - hv_store(hv, "pattern", 7, new_pv(ignore->pattern), 0); - - hv_store(hv, "level", 5, newSViv(ignore->level), 0); - hv_store(hv, "except_level", 12, newSViv(ignore->except_level), 0); - - hv_store(hv, "regexp", 6, newSViv(ignore->regexp), 0); - hv_store(hv, "fullword", 8, newSViv(ignore->fullword), 0); - XPUSHs(sv_2mortal(newRV_noinc((SV*)hv))); void ignore_add_rec(rec) diff --git a/src/perl/common/Log.xs b/src/perl/common/Log.xs index c341cf30..fbef4b72 100644 --- a/src/perl/common/Log.xs +++ b/src/perl/common/Log.xs @@ -8,7 +8,7 @@ PREINIT: 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))); + push_bless(tmp->data, stash); } Irssi::Log @@ -25,29 +25,30 @@ MODULE = Irssi PACKAGE = Irssi::Log PREFIX = log_ #******************************* void -values(log) +init(log) Irssi::Log log PREINIT: HV *hv, *stash; AV *av; GSList *tmp; -PPCODE: - hv = newHV(); - hv_store(hv, "fname", 5, new_pv(log->fname), 0); - hv_store(hv, "opened", 6, newSViv(log->opened), 0); - hv_store(hv, "level", 5, newSViv(log->level), 0); - hv_store(hv, "last", 4, newSViv(log->last), 0); - hv_store(hv, "autoopen", 8, newSViv(log->autoopen), 0); - hv_store(hv, "failed", 6, newSViv(log->failed), 0); - hv_store(hv, "temp", 4, newSViv(log->temp), 0); +CODE: + hv = hvref(ST(0)); + if (hv != NULL) { + hv_store(hv, "fname", 5, new_pv(log->fname), 0); + hv_store(hv, "opened", 6, newSViv(log->opened), 0); + hv_store(hv, "level", 5, newSViv(log->level), 0); + hv_store(hv, "last", 4, newSViv(log->last), 0); + hv_store(hv, "autoopen", 8, newSViv(log->autoopen), 0); + hv_store(hv, "failed", 6, newSViv(log->failed), 0); + hv_store(hv, "temp", 4, newSViv(log->temp), 0); - stash = gv_stashpv("Irssi::LogItem", 0); - av = newAV(); - for (tmp = log->items; tmp != NULL; tmp = tmp->next) { - av_push(av, sv_2mortal(sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(tmp->data))), stash))); + stash = gv_stashpv("Irssi::LogItem", 0); + av = newAV(); + for (tmp = log->items; tmp != NULL; tmp = tmp->next) { + av_push(av, sv_2mortal(new_bless(tmp->data, stash))); + } + hv_store(hv, "items", 4, newRV_noinc((SV*)av), 0); } - hv_store(hv, "items", 4, newRV_noinc((SV*)av), 0); - XPUSHs(sv_2mortal(newRV_noinc((SV*)hv))); void log_item_add(log, type, name, server) @@ -94,12 +95,14 @@ MODULE = Irssi PACKAGE = Irssi::LogItem #******************************* void -values(item) +init(item) Irssi::LogItem item PREINIT: HV *hv; -PPCODE: - hv = newHV(); - hv_store(hv, "type", 4, newSViv(item->type), 0); - hv_store(hv, "name", 4, new_pv(item->name), 0); - hv_store(hv, "servertag", 9, new_pv(item->servertag), 0); +CODE: + hv = hvref(ST(0)); + if (hv != NULL) { + hv_store(hv, "type", 4, newSViv(item->type), 0); + hv_store(hv, "name", 4, new_pv(item->name), 0); + hv_store(hv, "servertag", 9, new_pv(item->servertag), 0); + } diff --git a/src/perl/common/Query.xs b/src/perl/common/Query.xs index 78004e06..47758229 100644 --- a/src/perl/common/Query.xs +++ b/src/perl/common/Query.xs @@ -8,8 +8,7 @@ PPCODE: for (tmp = queries; tmp != NULL; tmp = tmp->next) { QUERY_REC *rec = tmp->data; - XPUSHs(sv_2mortal(sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(rec))), - irssi_get_stash(rec)))); + XPUSHs(sv_2mortal(irssi_bless(rec))); } #******************************* @@ -25,8 +24,7 @@ PPCODE: for (tmp = server->queries; tmp != NULL; tmp = tmp->next) { QUERY_REC *rec = tmp->data; - XPUSHs(sv_2mortal(sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(rec))), - irssi_get_stash(rec)))); + XPUSHs(sv_2mortal(irssi_bless(rec))); } Irssi::Query @@ -46,14 +44,10 @@ MODULE = Irssi PACKAGE = Irssi::Query PREFIX = query_ #******************************* void -values(query) +init(query) Irssi::Query query -PREINIT: - HV *hv; -PPCODE: - hv = newHV(); - perl_query_fill_hash(hv, query); - XPUSHs(sv_2mortal(newRV_noinc((SV*)hv))); +CODE: + perl_query_fill_hash(hvref(ST(0)), query); void query_destroy(query) diff --git a/src/perl/common/Rawlog.xs b/src/perl/common/Rawlog.xs index c7422bac..c9a37d56 100644 --- a/src/perl/common/Rawlog.xs +++ b/src/perl/common/Rawlog.xs @@ -32,23 +32,24 @@ MODULE = Irssi PACKAGE = Irssi::Rawlog PREFIX = rawlog_ #******************************* void -values(rawlog) +init(rawlog) Irssi::Rawlog rawlog PREINIT: HV *hv; AV *av; GSList *tmp; -PPCODE: - hv = newHV(); - hv_store(hv, "logging", 7, newSViv(rawlog->logging), 0); - hv_store(hv, "nlines", 6, newSViv(rawlog->nlines), 0); +CODE: + hv = hvref(ST(0)); + if (hv != NULL) { + hv_store(hv, "logging", 7, newSViv(rawlog->logging), 0); + hv_store(hv, "nlines", 6, newSViv(rawlog->nlines), 0); - av = newAV(); - for (tmp = rawlog->lines; tmp != NULL; tmp = tmp->next) { - av_push(av, new_pv(tmp->data)); + av = newAV(); + for (tmp = rawlog->lines; tmp != NULL; tmp = tmp->next) { + av_push(av, new_pv(tmp->data)); + } + hv_store(hv, "lines", 5, newRV_noinc((SV*)av), 0); } - hv_store(hv, "lines", 5, newRV_noinc((SV*)av), 0); - XPUSHs(sv_2mortal(newRV_noinc((SV*)hv))); void rawlog_destroy(rawlog) diff --git a/src/perl/common/Server.xs b/src/perl/common/Server.xs index d7b49eee..3ae1142b 100644 --- a/src/perl/common/Server.xs +++ b/src/perl/common/Server.xs @@ -6,10 +6,7 @@ PREINIT: GSList *tmp; PPCODE: for (tmp = servers; tmp != NULL; tmp = tmp->next) { - SERVER_REC *rec = tmp->data; - - XPUSHs(sv_2mortal(sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(rec))), - irssi_get_stash(rec)))); + XPUSHs(sv_2mortal(irssi_bless((SERVER_REC *) tmp->data))); } void @@ -20,7 +17,7 @@ PREINIT: PPCODE: stash = gv_stashpv("Irssi::Reconnect", 0); for (tmp = reconnects; tmp != NULL; tmp = tmp->next) { - XPUSHs(sv_2mortal(sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(tmp->data))), stash))); + push_bless(tmp->data, stash); } Irssi::Connect @@ -43,14 +40,10 @@ MODULE = Irssi PACKAGE = Irssi::Server PREFIX = server_ #******************************* void -values(server) +init(server) Irssi::Server server -PREINIT: - HV *hv; -PPCODE: - hv = newHV(); - perl_server_fill_hash(hv, server); - XPUSHs(sv_2mortal(newRV_noinc((SV*)hv))); +CODE: + perl_server_fill_hash(hvref(ST(0)), server); Irssi::Server server_connect(conn) @@ -148,14 +141,10 @@ MODULE = Irssi PACKAGE = Irssi::Connect PREFIX = server_ #******************************* void -values(conn) +init(conn) Irssi::Connect conn -PREINIT: - HV *hv; -PPCODE: - hv = newHV(); - perl_connect_fill_hash(hv, conn); - XPUSHs(sv_2mortal(newRV_noinc((SV*)hv))); +CODE: + perl_connect_fill_hash(hvref(ST(0)), conn); Irssi::Server server_connect(conn) @@ -166,14 +155,14 @@ MODULE = Irssi PACKAGE = Irssi::Reconnect #******************************* void -values(reconnect) +init(reconnect) Irssi::Reconnect reconnect PREINIT: HV *hv; -PPCODE: - hv = newHV(); - perl_connect_fill_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))); - +CODE: + hv = hvref(ST(0)); + if (hv != NULL) { + perl_reconnect_fill_hash(hv, reconnect->conn); + hv_store(hv, "tag", 3, newSViv(reconnect->tag), 0); + hv_store(hv, "next_connect", 12, newSViv(reconnect->next_connect), 0); + } diff --git a/src/perl/common/Themes.xs b/src/perl/common/Themes.xs index d8a140ac..88067562 100644 --- a/src/perl/common/Themes.xs +++ b/src/perl/common/Themes.xs @@ -5,10 +5,9 @@ theme_register(formats) SV *formats PREINIT: AV *av; - SV *sv; FORMAT_REC *formatrecs; char *key, *value; - int len, n, fpos, count; + int len, n, fpos; CODE: if (!SvROK(formats)) @@ -19,8 +18,8 @@ CODE: croak("formats list is invalid - not dividable by 3 (%d)", len); formatrecs = g_new0(FORMAT_REC, len/2+2); - formatrecs[fpos].tag = g_strdup(perl_get_package()); - formatrecs[fpos].def = g_strdup("Perl script"); + formatrecs[0].tag = g_strdup(perl_get_package()); + formatrecs[0].def = g_strdup("Perl script"); for (fpos = 1, n = 0; n < len; n++, fpos++) { key = SvPV(*av_fetch(av, n, 0), PL_na); n++; diff --git a/src/perl/common/Window.xs b/src/perl/common/Window.xs index dec58b42..f1b5437e 100644 --- a/src/perl/common/Window.xs +++ b/src/perl/common/Window.xs @@ -8,9 +8,7 @@ PREINIT: PPCODE: stash = gv_stashpv("Irssi::Window", 0); for (tmp = windows; tmp != NULL; tmp = tmp->next) { - WINDOW_REC *rec = tmp->data; - - XPUSHs(sv_2mortal(sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(rec))), stash))); + push_bless(tmp->data, stash); } @@ -134,32 +132,29 @@ MODULE = Irssi PACKAGE = Irssi::Window PREFIX=window_ #******************************* void -values(window) +init(window) Irssi::Window window PREINIT: HV *hv; -PPCODE: - hv = newHV(); - hv_store(hv, "refnum", 6, newSViv(window->refnum), 0); - hv_store(hv, "name", 4, new_pv(window->name), 0); +CODE: + hv = hvref(ST(0)); + if (hv != NULL) { + hv_store(hv, "refnum", 6, newSViv(window->refnum), 0); + hv_store(hv, "name", 4, new_pv(window->name), 0); - if (window->active) { - hv_store(hv, "active", 6, sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(window->active))), - irssi_get_stash(window->active)), 0); + if (window->active) + hv_store(hv, "active", 6, irssi_bless(window->active), 0); + if (window->active_server) + hv_store(hv, "active_server", 13, irssi_bless(window->active_server), 0); + + hv_store(hv, "lines", 5, newSViv(window->lines), 0); + + hv_store(hv, "level", 5, newSViv(window->level), 0); + hv_store(hv, "new_data", 8, newSViv(window->new_data), 0); + hv_store(hv, "last_color", 10, newSViv(window->last_color), 0); + hv_store(hv, "last_timestamp", 14, newSViv(window->last_timestamp), 0); + hv_store(hv, "last_line", 9, newSViv(window->last_line), 0); } - if (window->active_server) { - hv_store(hv, "active_server", 13, sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(window->active_server))), - irssi_get_stash(window->active_server)), 0); - } - - hv_store(hv, "lines", 5, newSViv(window->lines), 0); - - hv_store(hv, "level", 5, newSViv(window->level), 0); - hv_store(hv, "new_data", 8, newSViv(window->new_data), 0); - hv_store(hv, "last_color", 10, newSViv(window->last_color), 0); - hv_store(hv, "last_timestamp", 14, newSViv(window->last_timestamp), 0); - hv_store(hv, "last_line", 9, newSViv(window->last_line), 0); - XPUSHs(sv_2mortal(newRV_noinc((SV*)hv))); void items(window) @@ -170,8 +165,7 @@ PPCODE: for (tmp = window->items; tmp != NULL; tmp = tmp->next) { CHANNEL_REC *rec = tmp->data; - XPUSHs(sv_2mortal(sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(rec))), - irssi_get_stash(rec)))); + XPUSHs(sv_2mortal(irssi_bless(rec))); } void @@ -263,19 +257,6 @@ OUTPUT: MODULE = Irssi PACKAGE = Irssi::Windowitem #******************************* -void -values(item) - Irssi::Windowitem item -PREINIT: - HV *hv; -PPCODE: - hv = newHV(); - hv_store(hv, "server", 6, sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(item->server))), - irssi_get_stash(item->server)), 0); - hv_store(hv, "name", 4, new_pv(item->name), 0); - hv_store(hv, "new_data", 8, newSViv(item->new_data), 0); - XPUSHs(sv_2mortal(newRV_noinc((SV*)hv))); - void command(item, cmd) Irssi::Windowitem item diff --git a/src/perl/common/typemap b/src/perl/common/typemap index b642cbb4..7b90681d 100644 --- a/src/perl/common/typemap +++ b/src/perl/common/typemap @@ -1,12 +1,12 @@ TYPEMAP -Irssi::Chatnet T_PTROBJ -Irssi::Server T_PTROBJ -Irssi::Connect T_PTROBJ +Irssi::Chatnet T_IrssiObj +Irssi::Server T_IrssiObj +Irssi::Connect T_IrssiObj Irssi::Reconnect T_PTROBJ -Irssi::Channel T_PTROBJ -Irssi::Query T_PTROBJ +Irssi::Channel T_IrssiObj +Irssi::Query T_IrssiObj Irssi::Command T_PTROBJ -Irssi::Nick T_PTROBJ +Irssi::Nick T_IrssiObj Irssi::Ignore T_PTROBJ Irssi::Log T_PTROBJ Irssi::LogItem T_PTROBJ @@ -15,4 +15,15 @@ Irssi::Module T_PTROBJ Irssi::Theme T_PTROBJ Irssi::Keyinfo T_PTROBJ Irssi::Window T_PTROBJ -Irssi::Windowitem T_PTROBJ +Irssi::Windowitem T_IrssiObj + +INPUT + +T_IrssiObj + $var = irssi_ref_object($arg) + +OUTPUT + +T_IrssiObj + $arg = irssi_bless((SERVER_REC *)$var); + diff --git a/src/perl/irc/Bans.xs b/src/perl/irc/Bans.xs index cd4ea9b8..c89ff4c5 100644 --- a/src/perl/irc/Bans.xs +++ b/src/perl/irc/Bans.xs @@ -28,7 +28,7 @@ MODULE = Irssi::Irc PACKAGE = Irssi::Irc::Ban #******************************* void -values(ban) +init(ban) Irssi::Irc::Ban ban PREINIT: HV *hv; diff --git a/src/perl/irc/Dcc.xs b/src/perl/irc/Dcc.xs index 4bc0a5b0..0bbd1166 100644 --- a/src/perl/irc/Dcc.xs +++ b/src/perl/irc/Dcc.xs @@ -8,7 +8,7 @@ PREINIT: PPCODE: stash = gv_stashpv("Irssi::Irc::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))); + push_bless(tmp->data, stash); } Irssi::Irc::Dcc @@ -23,9 +23,9 @@ dcc_find_by_port(nick, port) int port void -dcc_ctcp_message(target, server, chat, notice, msg) - char *target +dcc_ctcp_message(server, target, chat, notice, msg) Irssi::Irc::Server server + char *target Irssi::Irc::Dcc chat int notice char *msg @@ -48,7 +48,7 @@ dcc_chat_send(dcc, data) char *data void -values(dcc) +init(dcc) Irssi::Irc::Dcc dcc PREINIT: HV *hv, *stash; @@ -57,12 +57,11 @@ PPCODE: hv_store(hv, "type", 4, new_pv((char *) dcc_type2str(dcc->type)), 0); hv_store(hv, "created", 7, newSViv(dcc->created), 0); - hv_store(hv, "server", 6, sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(dcc->server))), - irssi_get_stash(dcc->server)), 0); + hv_store(hv, "server", 6, irssi_bless(dcc->server), 0); hv_store(hv, "nick", 4, new_pv(dcc->nick), 0); stash = gv_stashpv("Irssi::Irc::Dcc", 0); - hv_store(hv, "chat", 4, sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(dcc->chat))), stash), 0); + hv_store(hv, "chat", 4, new_bless(dcc->chat, stash), 0); hv_store(hv, "ircnet", 6, new_pv(dcc->ircnet), 0); hv_store(hv, "mynick", 6, new_pv(dcc->mynick), 0); diff --git a/src/perl/irc/Flood.xs b/src/perl/irc/Flood.xs index 8738be04..d6b70672 100644 --- a/src/perl/irc/Flood.xs +++ b/src/perl/irc/Flood.xs @@ -17,7 +17,7 @@ MODULE = Irssi::Irc PACKAGE = Irssi::Irc::Autoignore #******************************* void -values(ai) +init(ai) Irssi::Irc::Autoignore ai PREINIT: HV *hv; diff --git a/src/perl/irc/IrcChannel.xs b/src/perl/irc/IrcChannel.xs index b78636c9..948b5b2a 100644 --- a/src/perl/irc/IrcChannel.xs +++ b/src/perl/irc/IrcChannel.xs @@ -9,7 +9,7 @@ PREINIT: PPCODE: stash = gv_stashpv("Irssi::Irc::Ban", 0); for (tmp = channel->banlist; tmp != NULL; tmp = tmp->next) { - XPUSHs(sv_2mortal(sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(tmp->data))), stash))); + push_bless(tmp->data, stash); } void @@ -21,7 +21,7 @@ PREINIT: PPCODE: stash = gv_stashpv("Irssi::Irc::Ban", 0); for (tmp = channel->ebanlist; tmp != NULL; tmp = tmp->next) { - XPUSHs(sv_2mortal(sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(tmp->data))), stash))); + push_bless(tmp->data, stash); } void diff --git a/src/perl/irc/IrcServer.xs b/src/perl/irc/IrcServer.xs index 2d4108e9..c39abaa4 100644 --- a/src/perl/irc/IrcServer.xs +++ b/src/perl/irc/IrcServer.xs @@ -1,19 +1,5 @@ MODULE = Irssi::Irc PACKAGE = Irssi::Irc::Server PREFIX = irc_server_ -void -values(server) - Irssi::Irc::Server server -PREINIT: - HV *hv; -PPCODE: - hv = newHV(); - perl_server_fill_hash(hv, (SERVER_REC *) server); - - hv_store(hv, "real_address", 12, new_pv(server->real_address), 0); - hv_store(hv, "usermode", 8, new_pv(server->usermode), 0); - hv_store(hv, "userhost", 8, new_pv(server->userhost), 0); - XPUSHs(sv_2mortal(newRV_noinc((SV*)hv))); - char * irc_server_get_channels(server) Irssi::Irc::Server server @@ -41,20 +27,36 @@ send_raw_split(server, cmd, nickarg, max_nicks) CODE: irc_send_cmd_split(server, cmd, nickarg, max_nicks); -MODULE = Irssi::Irc PACKAGE = Irssi::Irc::Connect PREFIX = irc_server_ - void -values(conn) - Irssi::Irc::Connect conn +init(server) + Irssi::Irc::Server server PREINIT: - HV *hv; -PPCODE: - hv = newHV(); - perl_server_connect_fill_hash(hv, (SERVER_CONNECT_REC *) conn); + HV *hv; +CODE: + hv = hvref(ST(0)); + if (hv != NULL) { + perl_server_fill_hash(hv, server); - hv_store(hv, "alternate_nick", 14, new_pv(conn->alternate_nick), 0); - XPUSHs(sv_2mortal(newRV_noinc((SV*)hv))); + hv_store(hv, "real_address", 12, new_pv(server->real_address), 0); + hv_store(hv, "usermode", 8, new_pv(server->usermode), 0); + hv_store(hv, "userhost", 8, new_pv(server->userhost), 0); + } + + +MODULE = Irssi::Irc PACKAGE = Irssi::Irc::Connect PREFIX = irc_server_ Irssi::Irc::Server irc_server_connect(conn) Irssi::Irc::Connect conn + +void +init(conn) + Irssi::Irc::Connect conn +PREINIT: + HV *hv; +CODE: + hv = hvref(ST(0)); + if (hv != NULL) { + perl_connect_fill_hash(hv, conn); + hv_store(hv, "alternate_nick", 14, new_pv(conn->alternate_nick), 0); + } diff --git a/src/perl/irc/Netsplit.xs b/src/perl/irc/Netsplit.xs index 4dad9c1d..a7669b43 100644 --- a/src/perl/irc/Netsplit.xs +++ b/src/perl/irc/Netsplit.xs @@ -6,7 +6,7 @@ netsplit_find(server, nick, address) char *nick char *address -Irssi::Nick +Irssi::Irc::Nick netsplit_find_channel(server, nick, address, channel) Irssi::Irc::Server server char *nick @@ -19,7 +19,7 @@ MODULE = Irssi::Irc PACKAGE = Irssi::Irc::Netsplit #******************************* void -values(netsplit) +init(netsplit) Irssi::Irc::Netsplit netsplit PREINIT: HV *hv, *stash; @@ -30,7 +30,7 @@ PPCODE: hv_store(hv, "destroy", 7, newSViv(netsplit->destroy), 0); stash = gv_stashpv("Irssi::Irc::Netsplitserver", 0); - hv_store(hv, "server", 6, sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(netsplit->server))), stash), 0); + hv_store(hv, "server", 6, new_bless(netsplit->server, stash), 0); /*FIXME: add GSList *channels;*/ XPUSHs(sv_2mortal(newRV_noinc((SV*)hv))); @@ -39,7 +39,7 @@ MODULE = Irssi::Irc PACKAGE = Irssi::Irc::Netsplitserver #******************************* void -values(rec) +init(rec) Irssi::Irc::Netsplitserver rec PREINIT: HV *hv; diff --git a/src/perl/irc/Notifylist.xs b/src/perl/irc/Notifylist.xs index 4770aa12..3ef75c04 100644 --- a/src/perl/irc/Notifylist.xs +++ b/src/perl/irc/Notifylist.xs @@ -8,7 +8,7 @@ PREINIT: PPCODE: stash = gv_stashpv("Irssi::Irc::Notifylist", 0); for (tmp = notifies; tmp != NULL; tmp = tmp->next) { - XPUSHs(sv_2mortal(sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(tmp->data))), stash))); + push_bless(tmp->data, stash); } Irssi::Irc::Notifylist @@ -46,7 +46,7 @@ MODULE = Irssi::Irc PACKAGE = Irssi::Irc::Notifylist PREFIX = notifylist_ #******************************* void -values(notify) +init(notify) Irssi::Irc::Notifylist notify PREINIT: HV *hv; diff --git a/src/perl/irc/module.h b/src/perl/irc/module.h index 2c2f24c7..59fcd03c 100644 --- a/src/perl/irc/module.h +++ b/src/perl/irc/module.h @@ -1,5 +1,6 @@ #include "../common/module.h" +#include "irc.h" #include "irc-servers.h" #include "irc-channels.h" #include "irc-queries.h" @@ -17,6 +18,7 @@ typedef IRC_SERVER_REC *Irssi__Irc__Server; typedef IRC_SERVER_CONNECT_REC *Irssi__Irc__Connect; typedef IRC_CHANNEL_REC *Irssi__Irc__Channel; typedef QUERY_REC *Irssi__Irc__Query; +typedef NICK_REC *Irssi__Irc__Nick; typedef BAN_REC *Irssi__Irc__Ban; typedef DCC_REC *Irssi__Irc__Dcc; diff --git a/src/perl/irc/typemap b/src/perl/irc/typemap index 88035c57..8bec8f9f 100644 --- a/src/perl/irc/typemap +++ b/src/perl/irc/typemap @@ -1,8 +1,10 @@ TYPEMAP -Irssi::Irc::Server T_PTROBJ -Irssi::Irc::Connect T_PTROBJ -Irssi::Irc::Channel T_PTROBJ -Irssi::Irc::Query T_PTROBJ +Irssi::Irc::Server T_IrssiObj +Irssi::Irc::Connect T_IrssiObj +Irssi::Irc::Channel T_IrssiObj +Irssi::Irc::Query T_IrssiObj +Irssi::Irc::Nick T_IrssiObj + Irssi::Irc::Ban T_PTROBJ Irssi::Irc::Dcc T_PTROBJ Irssi::Irc::Netsplit T_PTROBJ @@ -10,4 +12,13 @@ Irssi::Irc::Netsplitserver T_PTROBJ Irssi::Irc::Autoignore T_PTROBJ Irssi::Irc::Notifylist T_PTROBJ -Irssi::Nick T_PTROBJ +INPUT + +T_IrssiObj + $var = irssi_ref_object($arg) + +OUTPUT + +T_IrssiObj + $arg = irssi_bless((SERVER_REC *)$var); + diff --git a/src/perl/perl-common.c b/src/perl/perl-common.c index b1a6e2f7..e029b6dd 100644 --- a/src/perl/perl-common.c +++ b/src/perl/perl-common.c @@ -36,38 +36,93 @@ #include "servers.h" #include "channels.h" #include "queries.h" -#include "window-item-def.h" +#include "nicklist.h" #include "perl-common.h" #include "fe-common/core/formats.h" #include "fe-common/core/printtext.h" -GHashTable *perl_stashes; +static GHashTable *perl_stashes; /* returns the package who called us */ char *perl_get_package(void) { STRLEN n_a; - - perl_eval_pv("($package) = caller;", TRUE); - return SvPV(perl_get_sv("package", FALSE), n_a); + return SvPV(perl_eval_pv("caller", TRUE), n_a); } -HV *irssi_get_stash_item(int type, int chat_type) +static void object_fill_values(SV *sv, const char *stash) { - char *str; + dSP; + char str[100]; + + ENTER; + SAVETMPS; + + PUSHMARK(SP); + XPUSHs(sv_mortalcopy(sv)); + PUTBACK; + + g_snprintf(str, sizeof(str), "%s::init", stash); + perl_call_method(str, G_DISCARD); + SPAGAIN; + + PUTBACK; + FREETMPS; + LEAVE; +} + +SV *irssi_bless_object(int type, int chat_type, void *object) +{ + char *str; + HV *stash, *hv; + SV *sv; str = g_hash_table_lookup(perl_stashes, GINT_TO_POINTER(type | (chat_type << 24))); - g_return_val_if_fail(str != NULL, gv_stashpv("", 0)); - return gv_stashpv(str, 1); + g_return_val_if_fail(str != NULL, newSViv(GPOINTER_TO_INT(object))); + + stash = gv_stashpv(str, 1); + + hv = newHV(); + hv_store(hv, "_irssi", 6, newSViv(GPOINTER_TO_INT(object)), 0); + + sv = sv_bless(newRV_noinc((SV*)hv), stash); + object_fill_values(sv, str); + return sv; + +} + +void *irssi_ref_object(SV *o) +{ + SV **sv; + HV *hv; + + hv = hvref(o); + if (hv == NULL) + return 0; + + sv = hv_fetch(hv, "_irssi", 6, 0); + if (sv == NULL) + croak("variable is damaged"); + return GINT_TO_POINTER(SvIV(*sv)); +} + +void irssi_add_object(int type, int chat_type, const char *stash) +{ + g_hash_table_insert(perl_stashes, + GINT_TO_POINTER(type | (chat_type << 24)), + g_strdup(stash)); } void perl_connect_fill_hash(HV *hv, SERVER_CONNECT_REC *conn) { char *type, *chat_type; + g_return_if_fail(hv != NULL); + g_return_if_fail(conn != NULL); + type = "SERVER CONNECT"; chat_type = (char *) chat_protocol_find_id(conn->chat_type)->name; @@ -89,6 +144,9 @@ void perl_server_fill_hash(HV *hv, SERVER_REC *server) char *type, *chat_type; HV *stash; + g_return_if_fail(hv != NULL); + g_return_if_fail(server != NULL); + perl_connect_fill_hash(hv, server->connrec); type = "SERVER"; @@ -123,6 +181,9 @@ void perl_window_item_fill_hash(HV *hv, WI_ITEM_REC *item) { char *type, *chat_type; + g_return_if_fail(hv != NULL); + g_return_if_fail(item != NULL); + type = (char *) module_find_id_str("WINDOW ITEM", item->type); chat_type = (char *) chat_protocol_find_id(item->chat_type)->name; @@ -130,8 +191,7 @@ void perl_window_item_fill_hash(HV *hv, WI_ITEM_REC *item) hv_store(hv, "chat_type", 9, new_pv(chat_type), 0); if (item->server != NULL) { - hv_store(hv, "server", 6, sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(item->server))), - irssi_get_stash(item->server)), 0); + hv_store(hv, "server", 6, irssi_bless(item->server), 0); } hv_store(hv, "name", 4, new_pv(item->name), 0); @@ -142,6 +202,9 @@ void perl_window_item_fill_hash(HV *hv, WI_ITEM_REC *item) void perl_channel_fill_hash(HV *hv, CHANNEL_REC *channel) { + g_return_if_fail(hv != NULL); + g_return_if_fail(channel != NULL); + perl_window_item_fill_hash(hv, (WI_ITEM_REC *) channel); hv_store(hv, "topic", 5, new_pv(channel->topic), 0); @@ -163,6 +226,9 @@ void perl_channel_fill_hash(HV *hv, CHANNEL_REC *channel) void perl_query_fill_hash(HV *hv, QUERY_REC *query) { + g_return_if_fail(hv != NULL); + g_return_if_fail(query != NULL); + perl_window_item_fill_hash(hv, (WI_ITEM_REC *) query); hv_store(hv, "address", 7, new_pv(query->address), 0); @@ -170,6 +236,32 @@ void perl_query_fill_hash(HV *hv, QUERY_REC *query) hv_store(hv, "unwanted", 8, newSViv(query->unwanted), 0); } +void perl_nick_fill_hash(HV *hv, NICK_REC *nick) +{ + char *type, *chat_type; + + g_return_if_fail(hv != NULL); + g_return_if_fail(nick != NULL); + + type = "NICK"; + chat_type = (char *) chat_protocol_find_id(nick->chat_type)->name; + + hv_store(hv, "last_check", 10, newSViv(nick->last_check), 0); + + hv_store(hv, "nick", 4, new_pv(nick->nick), 0); + hv_store(hv, "host", 4, new_pv(nick->host), 0); + hv_store(hv, "realname", 8, new_pv(nick->realname), 0); + hv_store(hv, "hops", 4, newSViv(nick->hops), 0); + + hv_store(hv, "gone", 4, newSViv(nick->gone), 0); + hv_store(hv, "serverop", 8, newSViv(nick->serverop), 0); + + hv_store(hv, "send_massjoin", 13, newSViv(nick->send_massjoin), 0); + hv_store(hv, "op", 2, newSViv(nick->op), 0); + hv_store(hv, "halfop", 6, newSViv(nick->halfop), 0); + hv_store(hv, "voice", 5, newSViv(nick->voice), 0); +} + void printformat_perl(TEXT_DEST_REC *dest, char *format, char **arglist) { THEME_REC *theme; @@ -210,7 +302,8 @@ static void perl_register_protocol(CHAT_PROTOCOL_REC *rec) static char *items[] = { "Chatnet", "Server", "ServerConnect", "ServerSetup", - "Channel", "Query" + "Channel", "Query", + "Nick" }; char *name, stash[100], code[100]; int type, chat_type, n; @@ -224,20 +317,25 @@ static void perl_register_protocol(CHAT_PROTOCOL_REC *rec) /* window items: channel, query */ type = module_get_uniq_id_str("WINDOW ITEM TYPE", "CHANNEL"); g_snprintf(stash, sizeof(stash), "Irssi::%s::Channel", name); - irssi_add_stash(type, chat_type, stash); + irssi_add_object(type, chat_type, stash); type = module_get_uniq_id_str("WINDOW ITEM TYPE", "QUERY"); g_snprintf(stash, sizeof(stash), "Irssi::%s::Query", name); - irssi_add_stash(type, chat_type, stash); + irssi_add_object(type, chat_type, stash); + + /* channel nicks */ + type = module_get_uniq_id("NICK", 0); + g_snprintf(stash, sizeof(stash), "Irssi::%s::Nick", name); + irssi_add_object(type, chat_type, stash); /* server specific */ type = module_get_uniq_id("SERVER", 0); g_snprintf(stash, sizeof(stash), "Irssi::%s::Server", name); - irssi_add_stash(type, chat_type, stash); + irssi_add_object(type, chat_type, stash); type = module_get_uniq_id("SERVER CONNECT", 0); g_snprintf(stash, sizeof(stash), "Irssi::%s::Connect", name); - irssi_add_stash(type, chat_type, stash); + irssi_add_object(type, chat_type, stash); /* register ISAs */ for (n = 0; n < sizeof(items)/sizeof(items[0]); n++) { @@ -265,7 +363,7 @@ static void perl_unregister_protocol(CHAT_PROTOCOL_REC *rec) GINT_TO_POINTER(rec->id)); } -static void free_perl_stash(void *key, void *value) +static void free_perl_stash(void *key, char *value) { g_free(value); } diff --git a/src/perl/perl-common.h b/src/perl/perl-common.h index 267ab094..e4987337 100644 --- a/src/perl/perl-common.h +++ b/src/perl/perl-common.h @@ -7,19 +7,25 @@ #define new_bless(obj, stash) \ sv_bless(newRV_noinc(newSViv(GPOINTER_TO_INT(obj))), stash) -extern GHashTable *perl_stashes; +#define is_hvref(o) \ + ((o) && SvROK(o) && SvRV(o) && (SvTYPE(SvRV(o)) == SVt_PVHV)) + +#define hvref(o) \ + (is_hvref(o) ? (HV *)SvRV(o) : NULL) + +#define push_bless(obj, stash) \ + XPUSHs(sv_2mortal(new_bless(obj, stash))) + +#define irssi_bless(object) \ + irssi_bless_object((object)->type, (object)->chat_type, object) /* returns the package who called us */ char *perl_get_package(void); -HV *irssi_get_stash_item(int type, int chat_type); +SV *irssi_bless_object(int type, int chat_type, void *object); +void *irssi_ref_object(SV *o); -#define irssi_get_stash(item) \ - irssi_get_stash_item((item)->type, (item)->chat_type) - -#define irssi_add_stash(type, chat_type, stash) \ - g_hash_table_insert(perl_stashes, GINT_TO_POINTER(type | \ - (chat_type << 24)), g_strdup(stash)) +void irssi_add_object(int type, int chat_type, const char *stash); void perl_common_init(void); void perl_common_deinit(void); diff --git a/src/perl/perl.c b/src/perl/perl.c index 3d9c0f20..b4639ef9 100644 --- a/src/perl/perl.c +++ b/src/perl/perl.c @@ -348,8 +348,8 @@ static void cmd_run(const char *data) SAVETMPS; PUSHMARK(SP); - XPUSHs(sv_2mortal(newSVpv(fname, strlen(fname)))); g_free(fname); - XPUSHs(sv_2mortal(newSVpv(name, strlen(name)))); g_free(name); + XPUSHs(sv_2mortal(new_pv(fname))); g_free(fname); + XPUSHs(sv_2mortal(new_pv(name))); g_free(name); PUTBACK; retcount = perl_call_pv("Irssi::Load::eval_file", @@ -360,7 +360,6 @@ static void cmd_run(const char *data) STRLEN n_a; signal_emit("gui dialog", 2, "error", SvPV(ERRSV, n_a)); - (void) POPs; } else if (retcount > 0) { char *str = POPp; @@ -478,7 +477,7 @@ static int perl_source_event(PERL_SOURCE_REC *rec) SAVETMPS; PUSHMARK(SP); - XPUSHs(sv_2mortal(newSVpv(rec->data, strlen(rec->data)))); + XPUSHs(sv_2mortal(new_pv(rec->data))); PUTBACK; retcount = perl_call_pv(rec->func, G_EVAL|G_SCALAR); @@ -488,9 +487,7 @@ static int perl_source_event(PERL_SOURCE_REC *rec) STRLEN n_a; signal_emit("perl error", 1, SvPV(ERRSV, n_a)); - (void) POPs; } - else while (retcount--) (void) POPi; PUTBACK; FREETMPS; @@ -516,12 +513,16 @@ int perl_input_add(int source, int condition, const char *func, const char *data) { PERL_SOURCE_REC *rec; + GIOChannel *channel; rec = g_new(PERL_SOURCE_REC, 1); rec->func = g_strdup_printf("%s::%s", perl_get_package(), func); rec->data = g_strdup(data); - rec->tag = g_input_add(source, condition, + + channel = g_io_channel_unix_new(source); + rec->tag = g_input_add(channel, condition, (GInputFunction) perl_source_event, rec); + g_io_channel_unref(channel); perl_sources = g_slist_append(perl_sources, rec); return rec->tag; @@ -562,62 +563,72 @@ static PERL_SIGNAL_ARGS_REC *perl_signal_find(int signal) return NULL; } - -static int call_perl(const char *func, int signal, va_list va) +/* get arguments to args */ +static int perl_get_args(int signal, SV **args, va_list va) { - dSP; PERL_SIGNAL_ARGS_REC *rec; - int retcount, ret; - HV *stash; void *arg; int n; - /* first check if we find exact match */ rec = perl_signal_find(signal); + if (rec == NULL) + return 0; + + for (n = 0; n < 7 && rec->args[n] != NULL; n++) { + arg = va_arg(va, void *); + + if (strcmp(rec->args[n], "string") == 0) + args[n] = new_pv(arg); + else if (strcmp(rec->args[n], "int") == 0) + args[n] = newSViv(GPOINTER_TO_INT(arg)); + else if (strcmp(rec->args[n], "ulongptr") == 0) + args[n] = newSViv(*(unsigned long *) arg); + else if (strncmp(rec->args[n], "gslist_", 7) == 0) { + /* linked list - push as AV */ + GSList *tmp; + AV *av; + + av = newAV(); + stash = gv_stashpv(rec->args[n]+7, 0); + for (tmp = arg; tmp != NULL; tmp = tmp->next) + av_push(av, sv_2mortal(new_bless(tmp->data, stash))); + args[n] = (SV*)av; + } else if (arg == NULL) { + /* don't bless NULL arguments */ + args[n] = newSViv(0); + } else if (strcmp(rec->args[n], "iobject") == 0) { + /* "irssi object" - any struct that has + "int type; int chat_type" as its first + variables (server, channel, ..) */ + args[n] = irssi_bless((SERVER_REC *) arg); + } else { + /* blessed object */ + stash = gv_stashpv(rec->args[n], 0); + args[n] = new_bless(arg, stash); + } + } + return n; +} + +static int call_perl(const char *func, int signal, va_list va) +{ + dSP; + SV *args[7]; + int retcount, ret; + + int n, count; + + /* save the arguments to SV*[] list first, because irssi_bless() + calls perl_call_method() and trashes the stack */ + count = perl_get_args(signal, args, va); ENTER; SAVETMPS; PUSHMARK(sp); - - if (rec != NULL) { - /* push the arguments to perl stack */ - for (n = 0; n < 7 && rec->args[n] != NULL; n++) { - arg = va_arg(va, void *); - - if (strcmp(rec->args[n], "string") == 0) - XPUSHs(sv_2mortal(new_pv(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(*(unsigned long *) arg))); - else if (strncmp(rec->args[n], "gslist_", 7) == 0) { - /* linked list - push as AV */ - GSList *tmp; - AV *av; - - av = newAV(); - stash = gv_stashpv(rec->args[n]+7, 0); - for (tmp = arg; tmp != NULL; tmp = tmp->next) - av_push(av, sv_2mortal(new_bless(tmp->data, stash))); - XPUSHs(newRV_noinc((SV*)av)); - } else if (arg == NULL) { - /* don't bless NULL arguments */ - XPUSHs(sv_2mortal(newSViv(0))); - } else if (strcmp(rec->args[n], "iobject") == 0) { - /* "irssi object" - any struct that has - "int type; int chat_type" as its first - variables (server, channel, ..) */ - stash = irssi_get_stash((SERVER_REC *) arg); - XPUSHs(sv_2mortal(new_bless(arg, stash))); - } else { - /* blessed object */ - stash = gv_stashpv(rec->args[n], 0); - XPUSHs(sv_2mortal(new_bless(arg, stash))); - } - } - } + for (n = 0; n < count; n++) + XPUSHs(sv_2mortal(args[n])); PUTBACK; retcount = perl_call_pv((char *) func, G_EVAL|G_SCALAR);