wez             Thu Jan 30 04:04:36 2003 EDT

  Added files:                 
    /embed/php-irssi    channel.c genobjdefs.php nick.c php-irssi-obj.c 
                        php-irssi-obj.h php-irssi.h server.c typemap.php 

  Modified files:              
    /embed/php-irssi    .cvsignore Makefile.am README ext-irssi.c 
                        gensignals.php php-core.c php-core.h 
  Log:
  Big patch for ZE2 support.
  
  
Index: embed/php-irssi/.cvsignore
diff -u embed/php-irssi/.cvsignore:1.2 embed/php-irssi/.cvsignore:1.3
--- embed/php-irssi/.cvsignore:1.2      Wed Jan 29 13:50:33 2003
+++ embed/php-irssi/.cvsignore  Thu Jan 30 04:04:35 2003
@@ -6,3 +6,4 @@
 *.o
 *.la
 php-signals-list.h
+php-irssi-obj-defs.h
Index: embed/php-irssi/Makefile.am
diff -u embed/php-irssi/Makefile.am:1.2 embed/php-irssi/Makefile.am:1.3
--- embed/php-irssi/Makefile.am:1.2     Wed Jan 29 16:10:53 2003
+++ embed/php-irssi/Makefile.am Thu Jan 30 04:04:35 2003
@@ -18,9 +18,13 @@
        $(LIBPHP_CFLAGS)
 
 libphp_core_la_SOURCES = \
-       php-core.c ext-irssi.c
+       php-core.c ext-irssi.c php-irssi-obj.c server.c channel.c nick.c
 
 php-core.c: php-signals-list.h
+php-irssi-obj.c: php-irssi-obj-defs.h
 
-php-signals-list.h: $(top_srcdir)/docs/signals.txt $(srcdir)/gensignals.php
-       php $(srcdir)/gensignals.php < $(top_srcdir)/docs/signals.txt > 
php-signals-list.h
+php-irssi-obj-defs.h: $(srcdir)/genobjdefs.php $(srcdir)/typemap.php
+       $(LIBPHP_PREFIX)/bin/php $(srcdir)/genobjdefs.php "$(top_srcdir)" > 
+php-irssi-obj-defs.h
+
+php-signals-list.h: $(top_srcdir)/docs/signals.txt $(srcdir)/gensignals.php 
+$(srcdir)/typemap.php
+       $(LIBPHP_PREFIX)/bin/php $(srcdir)/gensignals.php < 
+$(top_srcdir)/docs/signals.txt > php-signals-list.h
Index: embed/php-irssi/README
diff -u embed/php-irssi/README:1.2 embed/php-irssi/README:1.3
--- embed/php-irssi/README:1.2  Wed Jan 29 13:49:13 2003
+++ embed/php-irssi/README      Thu Jan 30 04:04:35 2003
@@ -3,44 +3,45 @@
 
 You need:
 
-o PHP 4.3.1-dev or higher, with sapi/embed and an installed php cli binary
+o PHP 5-dev or higher, with sapi/embed and an installed php cli binary
   (it needs to be in your path).
   
 o CVS version of irssi:
 
-       cvs -d:pserver:[EMAIL PROTECTED]:/home/cvs login 
-       Just hit enter as the password
-       cvs -z3 -d:pserver:[EMAIL PROTECTED]:/home/cvs co -P irssi
+    cvs -d:pserver:[EMAIL PROTECTED]:/home/cvs login 
+    Just hit enter as the password
+    cvs -z3 -d:pserver:[EMAIL PROTECTED]:/home/cvs co -P irssi
 
 Then you need to apply a patch; the patch removes an unused "execute" function
 from the irssi source which would otherwise prevent the ZE from running the
 code it compiled.
 It also adds the configure option for building the php module.
 
-       patch < path/to/irssi.diff
+    patch < path/to/irssi.diff
 
 Now mv this dir into irssi/src/,
 
 and from the top irssi dir;
 
-       ./autogen.sh --without-perl --with-php
+    ./autogen.sh --without-perl --with-php
 
 To use:
 
-       cd irssi/src/php && make install
-       irssi
+    cd irssi/src/php && make install
+    irssi
 
 At the irssi prompt:
 
-       /load php
-       /php $any_php_statement_here_will_be_evaled;
-       /unload php
+    /load php
+    /php $any_php_statement_here_will_be_evaled;
+    /unload php
 
 If you put PHP scripts in ~/.irssi/scripts/autorun/, they will be automatically
 included when the php module is loaded.
 
 You can manually "load" a script like this:
 
-       /php include "/path/to/script";
+    /php include "/path/to/script";
 
 
+vim:tw=78:et
Index: embed/php-irssi/ext-irssi.c
diff -u embed/php-irssi/ext-irssi.c:1.1.1.1 embed/php-irssi/ext-irssi.c:1.2
--- embed/php-irssi/ext-irssi.c:1.1.1.1 Wed Jan 29 13:42:35 2003
+++ embed/php-irssi/ext-irssi.c Thu Jan 30 04:04:35 2003
@@ -1,23 +1,22 @@
-#define MODULE_NAME "php/core"
-#include "common.h"
-
-#include "modules.h"
-#include "core.h"
-#include "signals.h"
-#include "misc.h"
-#include "irc.h"
-#include "irc-servers.h"
-#include "channels.h"
-#include "nicklist.h"
-#include "settings.h"
-#include "servers.h"
-#include "commands.h"
-#include "levels.h"
-#include "fe-windows.h"
-#include "lib-config/iconfig.h" /* FIXME: remove before .99 */
-
-#include <php_embed.h>
-
+/*
+  +----------------------------------------------------------------------+
+  | PHP for IRSSI                                                        |
+  +----------------------------------------------------------------------+
+  | Copyright (c) 1997-2003 The PHP Group                                |
+  +----------------------------------------------------------------------+
+  | This source file is subject to version 2.02 of the PHP license,      |
+  | that is bundled with this package in the file LICENSE, and is        |
+  | available at through the world-wide-web at                           |
+  | http://www.php.net/license/2_02.txt.                                 |
+  | If you did not receive a copy of the PHP license and are unable to   |
+  | obtain it through the world-wide-web, please send a note to          |
+  | [EMAIL PROTECTED] so we can mail you a copy immediately.               |
+  +----------------------------------------------------------------------+
+  | Author: Wez Furlong <[EMAIL PROTECTED]>                                    |
+  +----------------------------------------------------------------------+
+  $Id: ext-irssi.c,v 1.2 2003/01/30 09:04:35 wez Exp $
+*/
+#include "php-irssi.h"
 #include "php-signals-list.h" /* generated by php during make */
 
 /* Goals:
@@ -33,17 +32,6 @@
  * Could write overloaded objects where a property make sense.
  * */
 
-static zend_class_entry
-       server_class_entry,
-       channel_class_entry,
-       nick_class_entry;
-
-enum {
-       IDX_SERVER,
-       IDX_CHANNEL,
-       IDX_NICK
-};
-
 struct sig_record {
        zval *handler;
        int signal_id;
@@ -52,105 +40,19 @@
 
 HashTable *bound_signals;
 
-/* Given a nick record, create a PHP nick object */
-static inline void export_nick(zval *obj, CHANNEL_REC *cr, NICK_REC *nr TSRMLS_DC)
-{
-       zval *tmp;
-       
-       object_init_ex(obj, &nick_class_entry);
-
-       MAKE_STD_ZVAL(tmp);
-       ZVAL_STRING(tmp, cr->name, 1);
-       zend_hash_index_update(Z_OBJPROP_P(obj), IDX_CHANNEL, (void*)&tmp, 
sizeof(tmp), NULL);
-
-       MAKE_STD_ZVAL(tmp);
-       ZVAL_STRING(tmp, nr->nick, 1);
-       zend_hash_index_update(Z_OBJPROP_P(obj), IDX_NICK, (void*)&tmp, sizeof(tmp), 
NULL);
-}
-
-/* Given a channel record, create a channel object */
-static inline void export_channel(zval *obj, CHANNEL_REC *cr TSRMLS_DC)
-{
-       zval *tmp;
-
-       object_init_ex(obj, &channel_class_entry);
-
-       MAKE_STD_ZVAL(tmp);
-       ZVAL_STRING(tmp, cr->server->tag, 1);
-
-       zend_hash_index_update(Z_OBJPROP_P(obj), IDX_SERVER, (void*)&tmp, sizeof(tmp), 
NULL);
-
-       MAKE_STD_ZVAL(tmp);
-       ZVAL_STRING(tmp, cr->name, 1);
-
-       zend_hash_index_update(Z_OBJPROP_P(obj), IDX_CHANNEL, (void*)&tmp, 
sizeof(tmp), NULL);
-}
-
-/* Given a server record, create a server object */
-static inline void export_server(zval *obj, SERVER_REC *srv TSRMLS_DC)
+void php_irssi_export_GList(zval *val, GSList *the_list TSRMLS_DC)
 {
-       zval *tmp;
-
-       object_init_ex(obj, &server_class_entry);
-
-       MAKE_STD_ZVAL(tmp);
-       ZVAL_STRING(tmp, srv->tag, 1);
-
-       zend_hash_index_update(Z_OBJPROP_P(obj), IDX_SERVER, (void*)&tmp, sizeof(tmp), 
NULL);
-}
-
-static SERVER_REC *map_server(zval *object TSRMLS_DC)
-{
-       zval **zname;
-
-       if (zend_hash_index_find(Z_OBJPROP_P(object), IDX_SERVER, (void **)&zname) == 
FAILURE) {
-               return NULL;
-       }
+       zval *str;
        
-       return server_find_tag(Z_STRVAL_PP(zname));
-}
-#define SV_FETCH()     SERVER_REC *server = map_server(getThis() TSRMLS_CC); if 
(server == NULL) RETURN_NULL();
-
-/* find the channel record associated with a channel object */
-static CHANNEL_REC *map_channel(zval *object TSRMLS_DC)
-{
-       zval **zname;
-       SERVER_REC *server = NULL;
-
-       /* try to map it to the correct server first.
-        * it does not have to succeed; server can be null in channel_find,
-        * in which case the first matching channel will be found */
-       if (zend_hash_index_find(Z_OBJPROP_P(object), IDX_SERVER, (void **)&zname) == 
SUCCESS) {
-               server = server_find_tag(Z_STRVAL_PP(zname));
-       }
-
-       if (zend_hash_index_find(Z_OBJPROP_P(object), IDX_CHANNEL, (void **)&zname) == 
FAILURE) {
-               return NULL;
+       array_init(val);
+       for (; the_list != NULL; the_list = the_list->next) {
+               MAKE_STD_ZVAL(str);
+               ZVAL_STRING(val, (char*)the_list->data, 1);
        }
-       
-       return channel_find(server, Z_STRVAL_PP(zname));
 }
 
-#define CH_FETCH()     CHANNEL_REC *channel = map_channel(getThis() TSRMLS_CC); if 
(channel == NULL) RETURN_NULL();
-
-static NICK_REC *map_nick(zval *object, CHANNEL_REC **channel TSRMLS_DC)
-{
-       zval **zname;
-
-       *channel = map_channel(object TSRMLS_CC);
 
-       if (*channel == NULL) {
-               return NULL;
-       }
-       
-       if (zend_hash_index_find(Z_OBJPROP_P(object), IDX_NICK, (void **)&zname) == 
FAILURE) {
-               return NULL;
-       }
-       
-       return nicklist_find(*channel, Z_STRVAL_PP(zname));
-}
 
-#define NK_FETCH()     CHANNEL_REC *channel; NICK_REC *nick = map_nick(getThis(), 
&channel TSRMLS_CC); if (channel == NULL || nick == NULL) RETURN_NULL();
 
 
 /* Signals */
@@ -201,14 +103,14 @@
                                ZVAL_STRING(val, (char *)args[i], 1);
                                break;
                        case PIAT_SERVER:
-                               export_server(val, (SERVER_REC*)args[i] TSRMLS_CC);
+                               php_irssi_export_SERVER(val, (SERVER_REC*)args[i] 
+TSRMLS_CC);
                                break;
                        case PIAT_CHANNEL:
-                               export_channel(val, (CHANNEL_REC*)args[i] TSRMLS_CC);
+                               php_irssi_export_CHANNEL(val, (CHANNEL_REC*)args[i] 
+TSRMLS_CC);
                                break;
                        case PIAT_NICK:
                                /* a NICK only ever follows a channel */
-                               export_nick(val, (CHANNEL_REC*)args[i-1], 
(NICK_REC*)args[i] TSRMLS_CC);
+                               php_irssi_export_NICK(val, (CHANNEL_REC*)args[i-1], 
+(NICK_REC*)args[i] TSRMLS_CC);
                                break;
                        case PIAT_INT:
                                ZVAL_LONG(val, *(int *)args[i]);
@@ -216,6 +118,9 @@
                        case PIAT_ULONG:
                                ZVAL_LONG(val, *(ulong *)args[i]);
                                break;
+                       case PIAT_ARRAY_OF_STRING:
+                               php_irssi_export_GList(val, (GSList*)args[i] 
+TSRMLS_CC);
+                               break;
                        default:
                                ZVAL_NULL(val);
                }
@@ -247,323 +152,6 @@
        }
 }
 
-/* ---------- Channel functions */
-
-/* Returns an array of nick objects corresponding to each person on this channel */
-PHP_FUNCTION(channel_get_nicks)
-{
-       GSList *list, *tmp;
-       zval *obj;
-       CH_FETCH();
-
-       list = nicklist_getnicks(channel);
-       array_init(return_value);
-
-       if (list) {
-               for (tmp = list; tmp != NULL; tmp = tmp->next) {
-                       MAKE_STD_ZVAL(obj);
-                       export_nick(obj, channel, (NICK_REC*)tmp->data);
-                       add_next_index_zval(return_value, obj);
-               }
-               g_slist_free(list);
-       }
-               
-}
-
-PHP_FUNCTION(channel_nick_find)
-{
-       char *nick;
-       long nicklen;
-       NICK_REC *n;
-       CH_FETCH();
-
-       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &nick, 
&nicklen)) {
-               return;
-       }
-
-       n = nicklist_find(channel, nick);
-
-       if (n) {
-               export_nick(return_value, channel, n);
-       } else {
-               RETURN_NULL();
-       }
-       
-}
-
-PHP_FUNCTION(channel_nick_find_mask)
-{
-       char *nick;
-       long nicklen;
-       NICK_REC *n;
-       CH_FETCH();
-
-       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &nick, 
&nicklen)) {
-               return;
-       }
-
-       n = nicklist_find_mask(channel, nick);
-
-       if (n) {
-               export_nick(return_value, channel, n);
-       } else {
-               RETURN_NULL();
-       }
-       
-}
-
-PHP_FUNCTION(channel_get_name)
-{
-       CH_FETCH();
-
-       RETURN_STRING(channel->name, 1);
-}
-
-PHP_FUNCTION(channel_get_topic)
-{
-       CH_FETCH();
-
-       RETURN_STRING(channel->topic, 1);
-}
-
-PHP_FUNCTION(channel_get_topic_by)
-{
-       CH_FETCH();
-
-       RETURN_STRING(channel->topic_by, 1);
-}
-
-PHP_FUNCTION(channel_get_modes)
-{
-       CH_FETCH();
-       
-       array_init(return_value);
-
-       add_assoc_bool(return_value, "no_modes", channel->no_modes);
-       add_assoc_long(return_value, "limit", channel->limit);
-       if (channel->mode)
-               add_assoc_string(return_value, "mode", channel->mode, 1);
-       else
-               add_assoc_null(return_value, "mode");
-
-       if (channel->key)
-               add_assoc_string(return_value, "key", channel->key, 1);
-       else
-               add_assoc_null(return_value, "key");
-       
-}
-
-PHP_FUNCTION(channel_get_status)
-{
-       CH_FETCH();
-
-       array_init(return_value);
-
-       add_assoc_bool(return_value, "chanop", channel->chanop);
-       add_assoc_bool(return_value, "names_got", channel->names_got);
-       add_assoc_bool(return_value, "wholist", channel->wholist);
-       add_assoc_bool(return_value, "synced", channel->synced);
-       add_assoc_bool(return_value, "joined", channel->joined);
-       add_assoc_bool(return_value, "left", channel->left);
-       add_assoc_bool(return_value, "kicked", channel->kicked);
-       add_assoc_bool(return_value, "session_rejoin", channel->session_rejoin);
-       add_assoc_bool(return_value, "destroying", channel->destroying);
-}
-
-PHP_FUNCTION(channel_get_own_nick)
-{
-       CH_FETCH();
-
-       export_nick(return_value, channel, channel->ownnick);
-}
-
-PHP_FUNCTION(channel_get_server)
-{
-       CH_FETCH();
-
-       export_server(return_value, channel->server TSRMLS_CC);
-}
-
-PHP_FUNCTION(channel_send)
-{
-       char *msg;
-       long msg_len;
-       CH_FETCH();
-
-       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &msg, 
&msg_len)) {
-               return;
-       }
-
-       (channel->server->send_message)(channel->server, channel->name, msg, 
SEND_TARGET_CHANNEL);
-       
-}
-
-static function_entry irssi_channel_methods[] = {
-       PHP_NAMED_FE(get_nicks, PHP_FN(channel_get_nicks), NULL)
-       PHP_NAMED_FE(nick_find, PHP_FN(channel_nick_find), NULL)
-       PHP_NAMED_FE(nick_find_mask, PHP_FN(channel_nick_find_mask), NULL)
-       PHP_NAMED_FE(get_name, PHP_FN(channel_get_name), NULL)
-       PHP_NAMED_FE(get_topic, PHP_FN(channel_get_topic), NULL)
-       PHP_NAMED_FE(get_topic_by, PHP_FN(channel_get_topic_by), NULL)
-       PHP_NAMED_FE(get_modes, PHP_FN(channel_get_modes), NULL)
-       PHP_NAMED_FE(get_status, PHP_FN(channel_get_status), NULL)
-       PHP_NAMED_FE(get_own_nick, PHP_FN(channel_get_own_nick), NULL)
-       PHP_NAMED_FE(get_server, PHP_FN(channel_get_server), NULL)
-       PHP_NAMED_FE(send, PHP_FN(channel_send), NULL)
-       NULL, NULL, NULL
-};
-
-/* ---------- Nick functions */
-
-
-PHP_FUNCTION(nick_get_nick)
-{
-       NK_FETCH();
-
-       RETURN_STRING(nick->nick, 1);
-}
-
-PHP_FUNCTION(nick_get_host)
-{
-       NK_FETCH();
-
-       RETURN_STRING(nick->host, 1);
-}
-
-PHP_FUNCTION(nick_get_realname)
-{
-       NK_FETCH();
-
-       RETURN_STRING(nick->realname, 1);
-}
-
-PHP_FUNCTION(nick_get_server_status)
-{
-       NK_FETCH();
-
-       array_init(return_value);
-
-       add_assoc_bool(return_value, "gone", nick->gone);
-       add_assoc_bool(return_value, "serverop", nick->serverop);
-       add_assoc_long(return_value, "last_check", nick->last_check);
-}
-
-PHP_FUNCTION(nick_get_channel_status)
-{
-       NK_FETCH();
-
-       array_init(return_value);
-
-       add_assoc_bool(return_value, "send_massjoin", nick->send_massjoin);
-       add_assoc_bool(return_value, "op", nick->op);
-       add_assoc_bool(return_value, "halfop", nick->halfop);
-       add_assoc_bool(return_value, "voice", nick->voice);
-}
-       
-       
-
-static function_entry irssi_nick_methods[] = {
-       PHP_NAMED_FE(get_nick, PHP_FN(nick_get_nick), NULL)
-       PHP_NAMED_FE(get_host, PHP_FN(nick_get_host), NULL)
-       PHP_NAMED_FE(get_realname, PHP_FN(nick_get_realname), NULL)
-       PHP_NAMED_FE(get_server_status, PHP_FN(nick_get_server_status), NULL)
-       PHP_NAMED_FE(get_channel_status, PHP_FN(nick_get_channel_status), NULL)
-       NULL, NULL, NULL
-};
-
-/* ---------- Server functions */
-
-PHP_FUNCTION(server_privmsg)
-{
-       char *target, *msg;
-       long target_len, msg_len;
-       long target_type; /* IRSSI_SEND_TARGET_X */
-       SV_FETCH();
-
-       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssl", 
&target, &target_len, &msg, &msg_len, &target_type)) {
-               return;
-       }
-
-       (server->send_message)(server, target, msg, target_type);
-
-       signal_emit(target_type == SEND_TARGET_CHANNEL ? "message own_public" : 
"message own_private", 4, server, msg, target, target);
-}
-
-PHP_FUNCTION(server_send_cmd)
-{
-       char *cmd;
-       long cmd_len;
-       IRC_SERVER_REC *isrv;
-       SV_FETCH();
-
-       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &cmd, 
&cmd_len)) {
-               return;
-       }
-
-       isrv = IRC_SERVER(server);
-
-       if (isrv) {
-               irc_send_cmd(isrv, cmd);
-       }
-}
-
-PHP_FUNCTION(server_send_cmd_now)
-{
-       char *cmd;
-       long cmd_len;
-       IRC_SERVER_REC *isrv;
-       SV_FETCH();
-
-       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &cmd, 
&cmd_len)) {
-               return;
-       }
-
-       isrv = IRC_SERVER(server);
-
-       if (isrv) {
-               irc_send_cmd_now(isrv, cmd);
-       }
-}
-
-PHP_FUNCTION(server_channels_join)
-{
-       char *cmd;
-       long cmd_len;
-       SV_FETCH();
-
-       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &cmd, 
&cmd_len)) {
-               return;
-       }
-
-       server->channels_join(server, cmd, 0);
-       
-}
-
-PHP_FUNCTION(server_get_channel_list)
-{
-       GSList *tmp;
-       zval *obj;
-       SV_FETCH();
-
-       array_init(return_value);
-       for (tmp = server->channels; tmp != NULL; tmp = tmp->next) {
-               MAKE_STD_ZVAL(obj);
-               export_channel(obj, (CHANNEL_REC*)tmp->data);
-               add_next_index_zval(return_value, obj);
-       }
-       
-}
-
-static function_entry irssi_server_methods[] = {
-       PHP_NAMED_FE(privmsg,   PHP_FN(server_privmsg), NULL)
-       PHP_NAMED_FE(send_cmd,  PHP_FN(server_send_cmd), NULL)
-       PHP_NAMED_FE(send_cmd_now,      PHP_FN(server_send_cmd_now), NULL)
-       PHP_NAMED_FE(channels_join,     PHP_FN(server_channels_join), NULL)
-       PHP_NAMED_FE(get_channels,      PHP_FN(server_get_channel_list), NULL)
-       NULL, NULL, NULL
-};
-
-
 /* ---------- Global functions */
 
 PHP_FUNCTION(irssi_server_list)
@@ -574,7 +162,7 @@
        array_init(return_value);
        for (tmp = servers; tmp != NULL; tmp = tmp->next) {
                MAKE_STD_ZVAL(obj);
-               export_server(obj, (SERVER_REC*)tmp->data);
+               php_irssi_export_SERVER(obj, (SERVER_REC*)tmp->data);
                add_next_index_zval(return_value, obj);
        }
 }
@@ -587,7 +175,7 @@
        array_init(return_value);
        for (tmp = channels; tmp != NULL; tmp = tmp->next) {
                MAKE_STD_ZVAL(obj);
-               export_channel(obj, (CHANNEL_REC*)tmp->data);
+               php_irssi_export_CHANNEL(obj, (CHANNEL_REC*)tmp->data);
                add_next_index_zval(return_value, obj);
        }
 }
@@ -698,6 +286,8 @@
                        case PIAT_ULONG:
                                args[i] = &Z_LVAL_PP(zargs[i+1]);
                                break;
+                       case PIAT_ARRAY_OF_STRING:
+                               /* make it into a GSList of char * */
                        default:
                                args[i] = NULL;
                }
@@ -732,18 +322,8 @@
 {
        ALLOC_HASHTABLE(bound_signals);
        zend_hash_init(bound_signals, 0, NULL, sig_rec_dtor, 0);
-       
-       INIT_CLASS_ENTRY(server_class_entry, "irssi_server", irssi_server_methods);
-       INIT_CLASS_ENTRY(channel_class_entry, "irssi_channel", irssi_channel_methods);
-       INIT_CLASS_ENTRY(nick_class_entry, "irssi_nick", irssi_nick_methods);
-
-       if (NULL == zend_register_internal_class(&channel_class_entry TSRMLS_CC)
-                       || NULL == zend_register_internal_class(&nick_class_entry 
TSRMLS_CC)
-                       || NULL == zend_register_internal_class(&server_class_entry 
TSRMLS_CC)
-                       ) {
-               return FAILURE;
-       }
 
+       php_irssi_init_objects();
        
        /* let's have some constants */
        REGISTER_LONG_CONSTANT("IRSSI_MSGLEVEL_CRAP", MSGLEVEL_CRAP, 
CONST_CS|CONST_PERSISTENT);
@@ -793,6 +373,7 @@
                FREE_HASHTABLE(bound_signals);
                bound_signals = NULL;
        }
+       php_irssi_fini_objects();
 }
 
 static function_entry php_irssi_functions[] = {
@@ -819,3 +400,11 @@
 };
 
 
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * indent-tabs-mode: t
+ * End:
+ */
Index: embed/php-irssi/gensignals.php
diff -u embed/php-irssi/gensignals.php:1.1.1.1 embed/php-irssi/gensignals.php:1.2
--- embed/php-irssi/gensignals.php:1.1.1.1      Wed Jan 29 13:42:35 2003
+++ embed/php-irssi/gensignals.php      Thu Jan 30 04:04:35 2003
@@ -1,33 +1,27 @@
 <?php
+/*
+  +----------------------------------------------------------------------+
+  | PHP for IRSSI                                                        |
+  +----------------------------------------------------------------------+
+  | Copyright (c) 1997-2003 The PHP Group                                |
+  +----------------------------------------------------------------------+
+  | This source file is subject to version 2.02 of the PHP license,      |
+  | that is bundled with this package in the file LICENSE, and is        |
+  | available at through the world-wide-web at                           |
+  | http://www.php.net/license/2_02.txt.                                 |
+  | If you did not receive a copy of the PHP license and are unable to   |
+  | obtain it through the world-wide-web, please send a note to          |
+  | [EMAIL PROTECTED] so we can mail you a copy immediately.               |
+  +----------------------------------------------------------------------+
+  | Author: Wez Furlong <[EMAIL PROTECTED]>                                    |
+  +----------------------------------------------------------------------+
+  $Id: gensignals.php,v 1.2 2003/01/30 09:04:35 wez Exp $
+*/
+
 /* Generate signal information from the signals.txt file in the docs
  * dir */
 
-/* This array describes the functions that can be used to convert between
- * irssi and php/ze types */
-
-$marshal = array(
-       "char *"                => "PIAT_STRING",
-       "SERVER_REC"    => "PIAT_SERVER",
-       "CHANNEL_REC"   => "PIAT_CHANNEL",
-       "int"                   => "PIAT_INT",
-       "ulong"                 => "PIAT_ULONG",
-       "NICK_REC"              => "PIAT_NICK",
-       "GList * of char*" => "PIAT_ARRAY_OF_STRING",
-       );
-
-echo "enum php_irssi_arg_type_t {\n";
-echo implode(",\n", array_values($marshal));
-echo "\n};\n\n";
-
-echo <<<EOD
-struct php_irssi_signal_args {
-       const char *signame;
-       int sigid;      /* bound at runtime */
-       int argc;       /* number of args */
-       int argtypes[SIGNAL_MAX_ARGUMENTS];
-};
-
-EOD;
+include "typemap.php";
 
 echo "static struct php_irssi_signal_args php_irssi_sig_args_table[] = {\n";
 
@@ -55,18 +49,11 @@
        $record = array();
 
        foreach ($args as $arg) {
-               $ok = false;
-               foreach ($marshal as $type => $handler) {
-                       if (substr($arg, 0, strlen($type)) == $type) {
-                               $ok = true;
-                               /* we know the type for the param and can convert it */
-                               $record[] = $handler;
-                               break;
-                       }
-               }
-               if (!$ok) {
+               $ok = match_decl($arg, $unused, $handler);
+               if ($ok)
+                       $record[] = $handler;
+               else
                        break;
-               }
        }
 
        if ($ok) {
Index: embed/php-irssi/php-core.c
diff -u embed/php-irssi/php-core.c:1.1.1.1 embed/php-irssi/php-core.c:1.2
--- embed/php-irssi/php-core.c:1.1.1.1  Wed Jan 29 13:42:35 2003
+++ embed/php-irssi/php-core.c  Thu Jan 30 04:04:35 2003
@@ -1,3 +1,21 @@
+/*
+  +----------------------------------------------------------------------+
+  | PHP for IRSSI                                                        |
+  +----------------------------------------------------------------------+
+  | Copyright (c) 1997-2003 The PHP Group                                |
+  +----------------------------------------------------------------------+
+  | This source file is subject to version 2.02 of the PHP license,      |
+  | that is bundled with this package in the file LICENSE, and is        |
+  | available at through the world-wide-web at                           |
+  | http://www.php.net/license/2_02.txt.                                 |
+  | If you did not receive a copy of the PHP license and are unable to   |
+  | obtain it through the world-wide-web, please send a note to          |
+  | [EMAIL PROTECTED] so we can mail you a copy immediately.               |
+  +----------------------------------------------------------------------+
+  | Author: Wez Furlong <[EMAIL PROTECTED]>                                    |
+  +----------------------------------------------------------------------+
+  $Id: php-core.c,v 1.2 2003/01/30 09:04:35 wez Exp $
+*/
 #define MODULE_NAME "php/core"
 #include "common.h"
 
@@ -195,3 +213,14 @@
 
        signal_emit("php unloaded", 0);
 }
+
+
+
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * indent-tabs-mode: t
+ * End:
+ */
Index: embed/php-irssi/php-core.h
diff -u embed/php-irssi/php-core.h:1.1.1.1 embed/php-irssi/php-core.h:1.2
--- embed/php-irssi/php-core.h:1.1.1.1  Wed Jan 29 13:42:34 2003
+++ embed/php-irssi/php-core.h  Thu Jan 30 04:04:35 2003
@@ -1,3 +1,21 @@
+/*
+  +----------------------------------------------------------------------+
+  | PHP for IRSSI                                                        |
+  +----------------------------------------------------------------------+
+  | Copyright (c) 1997-2003 The PHP Group                                |
+  +----------------------------------------------------------------------+
+  | This source file is subject to version 2.02 of the PHP license,      |
+  | that is bundled with this package in the file LICENSE, and is        |
+  | available at through the world-wide-web at                           |
+  | http://www.php.net/license/2_02.txt.                                 |
+  | If you did not receive a copy of the PHP license and are unable to   |
+  | obtain it through the world-wide-web, please send a note to          |
+  | [EMAIL PROTECTED] so we can mail you a copy immediately.               |
+  +----------------------------------------------------------------------+
+  | Author: Wez Furlong <[EMAIL PROTECTED]>                                    |
+  +----------------------------------------------------------------------+
+  $Id: php-core.h,v 1.2 2003/01/30 09:04:35 wez Exp $
+*/
 
 enum php_irssi_signal_arg_item {
        item_NULL,

Index: embed/php-irssi/channel.c
+++ embed/php-irssi/channel.c
/*
  +----------------------------------------------------------------------+
  | PHP for IRSSI                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2003 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 2.02 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available at through the world-wide-web at                           |
  | http://www.php.net/license/2_02.txt.                                 |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | [EMAIL PROTECTED] so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Wez Furlong <[EMAIL PROTECTED]>                                    |
  +----------------------------------------------------------------------+
  $Id: channel.c,v 1.1 2003/01/30 09:04:35 wez Exp $
*/
#include "php-irssi.h"

/* ---------- Channel functions */
/* Given a channel record, create a channel object */
void php_irssi_export_CHANNEL(zval *obj, CHANNEL_REC *cr TSRMLS_DC)
{
        struct php_irssi_obj_ref *ref;

        php_irssi_create_wrapper(&ref, "CHANNEL", obj TSRMLS_CC);
        if (ref) {
                ref->idents[IDX_CHANNEL] = estrdup(cr->name);
                ref->idents[IDX_SERVER] = estrdup(cr->server->tag);
        }
}

/* find the channel record associated with a channel object */
CHANNEL_REC *map_channel(zval *object TSRMLS_DC)
{
        struct php_irssi_obj_ref *ref;
        SERVER_REC *server = NULL;

        ref = php_irssi_ref_from_wrapper(object, "CHANNEL" TSRMLS_CC);

        if (ref == NULL)
                return NULL;

        /* try to map it to the correct server first.
         * it does not have to succeed; server can be null in channel_find,
         * in which case the first matching channel will be found */
        server = server_find_tag(ref->idents[IDX_SERVER]);

        return channel_find(server, ref->idents[IDX_CHANNEL]);
}


/* Returns an array of nick objects corresponding to each person on this channel */
PHP_FUNCTION(channel_get_nicks)
{
        GSList *list, *tmp;
        zval *obj;
        CH_FETCH();

        list = nicklist_getnicks(channel);
        array_init(return_value);

        if (list) {
                for (tmp = list; tmp != NULL; tmp = tmp->next) {
                        MAKE_STD_ZVAL(obj);
                        php_irssi_export_NICK(obj, channel, (NICK_REC*)tmp->data);
                        add_next_index_zval(return_value, obj);
                }
                g_slist_free(list);
        }
                
}

PHP_FUNCTION(channel_nick_find)
{
        char *nick;
        long nicklen;
        NICK_REC *n;
        CH_FETCH();

        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &nick, 
&nicklen)) {
                return;
        }

        n = nicklist_find(channel, nick);

        if (n) {
                php_irssi_export_NICK(return_value, channel, n);
        } else {
                RETURN_NULL();
        }
        
}

PHP_FUNCTION(channel_nick_find_mask)
{
        char *nick;
        long nicklen;
        NICK_REC *n;
        CH_FETCH();

        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &nick, 
&nicklen)) {
                return;
        }

        n = nicklist_find_mask(channel, nick);

        if (n) {
                php_irssi_export_NICK(return_value, channel, n);
        } else {
                RETURN_NULL();
        }
        
}

PHP_FUNCTION(channel_get_name)
{
        CH_FETCH();

        RETURN_STRING(channel->name, 1);
}

PHP_FUNCTION(channel_get_topic)
{
        CH_FETCH();

        RETURN_STRING(channel->topic, 1);
}

PHP_FUNCTION(channel_get_topic_by)
{
        CH_FETCH();

        RETURN_STRING(channel->topic_by, 1);
}

PHP_FUNCTION(channel_get_modes)
{
        CH_FETCH();
        
        array_init(return_value);

        add_assoc_bool(return_value, "no_modes", channel->no_modes);
        add_assoc_long(return_value, "limit", channel->limit);
        if (channel->mode)
                add_assoc_string(return_value, "mode", channel->mode, 1);
        else
                add_assoc_null(return_value, "mode");

        if (channel->key)
                add_assoc_string(return_value, "key", channel->key, 1);
        else
                add_assoc_null(return_value, "key");
        
}

PHP_FUNCTION(channel_get_status)
{
        CH_FETCH();

        array_init(return_value);

        add_assoc_bool(return_value, "chanop", channel->chanop);
        add_assoc_bool(return_value, "names_got", channel->names_got);
        add_assoc_bool(return_value, "wholist", channel->wholist);
        add_assoc_bool(return_value, "synced", channel->synced);
        add_assoc_bool(return_value, "joined", channel->joined);
        add_assoc_bool(return_value, "left", channel->left);
        add_assoc_bool(return_value, "kicked", channel->kicked);
        add_assoc_bool(return_value, "session_rejoin", channel->session_rejoin);
        add_assoc_bool(return_value, "destroying", channel->destroying);
}

PHP_FUNCTION(channel_get_own_nick)
{
        CH_FETCH();

        php_irssi_export_NICK(return_value, channel, channel->ownnick);
}

PHP_FUNCTION(channel_get_server)
{
        CH_FETCH();

        php_irssi_export_SERVER(return_value, channel->server TSRMLS_CC);
}

PHP_FUNCTION(channel_send)
{
        char *msg;
        long msg_len;
        CH_FETCH();

        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &msg, 
&msg_len)) {
                return;
        }

        (channel->server->send_message)(channel->server, channel->name, msg, 
SEND_TARGET_CHANNEL);
        
}

function_entry php_irssi_CHANNEL_funcs[] = {
        PHP_NAMED_FE(get_nicks, PHP_FN(channel_get_nicks), NULL)
        PHP_NAMED_FE(nick_find, PHP_FN(channel_nick_find), NULL)
        PHP_NAMED_FE(nick_find_mask, PHP_FN(channel_nick_find_mask), NULL)
        PHP_NAMED_FE(get_name, PHP_FN(channel_get_name), NULL)
        PHP_NAMED_FE(get_topic, PHP_FN(channel_get_topic), NULL)
        PHP_NAMED_FE(get_topic_by, PHP_FN(channel_get_topic_by), NULL)
        PHP_NAMED_FE(get_modes, PHP_FN(channel_get_modes), NULL)
        PHP_NAMED_FE(get_status, PHP_FN(channel_get_status), NULL)
        PHP_NAMED_FE(get_own_nick, PHP_FN(channel_get_own_nick), NULL)
        PHP_NAMED_FE(get_server, PHP_FN(channel_get_server), NULL)
        PHP_NAMED_FE(send, PHP_FN(channel_send), NULL)
        NULL, NULL, NULL
};


/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */

Index: embed/php-irssi/genobjdefs.php
+++ embed/php-irssi/genobjdefs.php
<?php
/*
  +----------------------------------------------------------------------+
  | PHP for IRSSI                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2003 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 2.02 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available at through the world-wide-web at                           |
  | http://www.php.net/license/2_02.txt.                                 |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | [EMAIL PROTECTED] so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Wez Furlong <[EMAIL PROTECTED]>                                    |
  +----------------------------------------------------------------------+
  $Id: genobjdefs.php,v 1.1 2003/01/30 09:04:35 wez Exp $
*/

/* We build three sets of tables:
 * o The first lists properties of the different irssi internal object
 *   types.
 * o The second lists methods of the different irssi objects
 * o The third binds those together so that the runtime init can
 *   map ids to type identification.
 */

$top_srcdir = realpath($argv[1]);
$objects_to_scan = array(
        "src/core/server-rec.h" => array("SERVER_REC", "server"),
        "src/core/channel-rec.h"=> array("CHANNEL_REC", "channel"),
        );

$obj_bind = array();
include "typemap.php";

foreach ($objects_to_scan as $filename => $data)
{

        list($iclass, $pclass) = $data;
        
        $obj_props = array();
        $obj_methods = array();
        
        $source = file_get_contents($top_srcdir . DIRECTORY_SEPARATOR . $filename);

        $rel = dirname($top_srcdir . DIRECTORY_SEPARATOR . $filename);

        /* chase includes */
        while (preg_match('/^#include\s+"(.*)"/sm', $source, $matches, 
PREG_OFFSET_CAPTURE)) {
                $inc = file_get_contents($rel . DIRECTORY_SEPARATOR . $matches[1][0]);

                $left = substr($source, 0, $matches[0][1]);
                $right = substr($source, $matches[0][1] + strlen($matches[0][0]));

                $source = $left . $inc . $right;
        }
        
        /* join logical lines, strip comments and pre-proc statements */
        $source = str_replace("\\\n", " ", $source);

        $source = preg_replace('/^#.*$/Usm', "", $source);
        $source = preg_replace('@/\*.*\*/@Usm', "", $source);

        $stmts = explode(";", $source);

        foreach ($stmts as $stmt) {
                $stmt = trim(preg_replace('/\s+/', ' ', $stmt));
                if (strlen($stmt) == 0)
                        continue;

                if (match_decl($stmt, $name, $handler)) {
                        $obj_props[] = array($handler, $name);
                }
        }

        /* Emit code */
        printf("struct php_irssi_class_props php_irssi_%s_props[] = {\n", $iclass);

        foreach ($obj_props as $data) {
                list($handler, $name) = $data;
        
                if ($handler == "PIAT_BOOL")
                        continue;
        
                printf("{ \"%s\", %d, %s, offset_of(%s, %s) },\n", $name, 
strlen($name), $handler, $iclass, $name);
        }
        printf("{ NULL, 0, 0, 0 }\n};\n\n");

        $obj_bind[] = array($iclass, $pclass);
}

foreach ($obj_bind as $data) {
        list($iclass, $pclass) = $data;
        $label = preg_replace('/_.*/', '', $iclass);

        printf("void *php_irssi_resolve_to_%s(struct php_irssi_obj_ref *ref);\n", 
$iclass);
        printf("extern function_entry php_irssi_%s_funcs[];\n", $label);
}

printf("\nstatic struct php_irssi_obj_bind php_irssi_object_bindings[] = {\n");
foreach ($obj_bind as $data) {
        list($iclass, $pclass) = $data;
        $label = preg_replace('/_.*/', '', $iclass);
        printf("{ \"%s\", 0, php_irssi_%s_props, php_irssi_resolve_to_%s, \"%s\", 
php_irssi_%s_funcs, NULL, NULL },\n", $label, $iclass, $iclass, $pclass, $label);
}
printf("{ NULL, 0, NULL }\n};\n\n");


?>

Index: embed/php-irssi/nick.c
+++ embed/php-irssi/nick.c
/*
  +----------------------------------------------------------------------+
  | PHP for IRSSI                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2003 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 2.02 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available at through the world-wide-web at                           |
  | http://www.php.net/license/2_02.txt.                                 |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | [EMAIL PROTECTED] so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Wez Furlong <[EMAIL PROTECTED]>                                    |
  +----------------------------------------------------------------------+
  $Id: nick.c,v 1.1 2003/01/30 09:04:35 wez Exp $
*/
#include "php-irssi.h"
/* ---------- Nick functions */
NICK_REC *map_nick(zval *object, CHANNEL_REC **channel TSRMLS_DC)
{
        struct php_irssi_obj_ref *ref;
        SERVER_REC *server = NULL;
        
        ref = php_irssi_ref_from_wrapper(object, "CHANNEL" TSRMLS_CC);
        if (ref == NULL)
                return NULL;

        server = server_find_tag(ref->idents[IDX_SERVER]);
        *channel = channel_find(server, ref->idents[IDX_CHANNEL]);

        if (*channel == NULL) {
                return NULL;
        }
        
        return nicklist_find(*channel, ref->idents[IDX_NICK]);
}

/* Given a nick record, create a PHP nick object */
void php_irssi_export_NICK(zval *obj, CHANNEL_REC *cr, NICK_REC *nr TSRMLS_DC)
{
        struct php_irssi_obj_ref *ref;

        php_irssi_create_wrapper(&ref, "NICK", obj TSRMLS_CC);
        if (ref) {
                ref->idents[IDX_SERVER] = estrdup(cr->server->tag);
                ref->idents[IDX_CHANNEL] = estrdup(cr->name);
                ref->idents[IDX_NICK] = estrdup(nr->nick);
        }
}

PHP_FUNCTION(nick_get_nick)
{
        NK_FETCH();

        RETURN_STRING(nick->nick, 1);
}

PHP_FUNCTION(nick_get_host)
{
        NK_FETCH();

        RETURN_STRING(nick->host, 1);
}

PHP_FUNCTION(nick_get_realname)
{
        NK_FETCH();

        RETURN_STRING(nick->realname, 1);
}

PHP_FUNCTION(nick_get_server_status)
{
        NK_FETCH();

        array_init(return_value);

        add_assoc_bool(return_value, "gone", nick->gone);
        add_assoc_bool(return_value, "serverop", nick->serverop);
        add_assoc_long(return_value, "last_check", nick->last_check);
}

PHP_FUNCTION(nick_get_channel_status)
{
        NK_FETCH();

        array_init(return_value);

        add_assoc_bool(return_value, "send_massjoin", nick->send_massjoin);
        add_assoc_bool(return_value, "op", nick->op);
        add_assoc_bool(return_value, "halfop", nick->halfop);
        add_assoc_bool(return_value, "voice", nick->voice);
}
        
        

function_entry php_irssi_NICK_funcs[] = {
        PHP_NAMED_FE(get_nick, PHP_FN(nick_get_nick), NULL)
        PHP_NAMED_FE(get_host, PHP_FN(nick_get_host), NULL)
        PHP_NAMED_FE(get_realname, PHP_FN(nick_get_realname), NULL)
        PHP_NAMED_FE(get_server_status, PHP_FN(nick_get_server_status), NULL)
        PHP_NAMED_FE(get_channel_status, PHP_FN(nick_get_channel_status), NULL)
        NULL, NULL, NULL
};



/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */

Index: embed/php-irssi/php-irssi-obj.c
+++ embed/php-irssi/php-irssi-obj.c
/*
  +----------------------------------------------------------------------+
  | PHP for IRSSI                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2003 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 2.02 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available at through the world-wide-web at                           |
  | http://www.php.net/license/2_02.txt.                                 |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | [EMAIL PROTECTED] so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Wez Furlong <[EMAIL PROTECTED]>                                    |
  +----------------------------------------------------------------------+
  $Id: php-irssi-obj.c,v 1.1 2003/01/30 09:04:35 wez Exp $
*/
#include "php-irssi.h"
#include "php-irssi-obj-defs.h"

void *php_irssi_resolve_to_SERVER_REC(struct php_irssi_obj_ref *ref)
{
        return server_find_tag(ref->idents[IDX_SERVER]);
}

void *php_irssi_resolve_to_CHANNEL_REC(struct php_irssi_obj_ref *ref)
{
        SERVER_REC *server = NULL;
        
        server = server_find_tag(ref->idents[IDX_SERVER]);
        return channel_find(server, ref->idents[IDX_CHANNEL]);
}


void php_irssi_C_to_PHP(zval **rval, int type, void *arg TSRMLS_DC)
{
        zval *val;
        MAKE_STD_ZVAL(val);

        switch(type) {
                case PIAT_STRING:
                        ZVAL_STRING(val, *(char **)arg, 1);
                        break;
                case PIAT_SERVER:
                        php_irssi_export_SERVER(val, (SERVER_REC*)arg TSRMLS_CC);
                        break;
                case PIAT_CHANNEL:
                        php_irssi_export_CHANNEL(val, (CHANNEL_REC*)arg TSRMLS_CC);
                        break;
                case PIAT_INT:
                        ZVAL_LONG(val, *(int *)arg);
                        break;
                case PIAT_ULONG:
                        ZVAL_LONG(val, *(ulong *)arg);
                        break;
                case PIAT_ARRAY_OF_STRING:
                        php_irssi_export_GList(val, (GSList*)arg TSRMLS_CC);
                        break;
                case PIAT_NICK:
                        /* We need some context for a NICK */
                default:
                        ZVAL_NULL(val);
        }
        *rval = val;
        ZVAL_DELREF(val);
}



static zval* pih_read_prop(zval *object, zval *member, int type TSRMLS_DC)
{
        struct php_irssi_obj_ref *ref = zend_object_store_get_object(object TSRMLS_CC);
        zval tmp_member;
        zval *retval = NULL;
        struct php_irssi_class_props **props;
        void *arg;

        if (member->type != IS_STRING) {
                tmp_member = *member;
                zval_copy_ctor(&tmp_member);
                convert_to_string(&tmp_member);
                member = &tmp_member;
        }

        /* look for property binding */
        if (zend_hash_find(ref->binding->hprops, Z_STRVAL_P(member), 
Z_STRLEN_P(member)+1, (void **) &props) == FAILURE) {
                zend_error(E_NOTICE,"Undefined property:  %s", Z_STRVAL_P(member));
                return EG(uninitialized_zval_ptr);
        }

        /* found the binding; process it */
        arg = ref->binding->resolve(ref);
        php_irssi_C_to_PHP(&retval, (*props)->proptype, arg + (*props)->offset);
        
        return retval;
}

static void pih_write_prop(zval *object, zval *member, zval *value TSRMLS_DC)
{
        /* TODO: determine the internal irssi object type and use the generated
         * offset and type map to map the value */
}

static int pih_has_prop(zval *object, zval *member, int check_empty TSRMLS_DC)
{
        struct php_irssi_obj_ref *ref = zend_object_store_get_object(object TSRMLS_CC);
        zval tmp_member;
        zval *retval = NULL;
        struct php_irssi_class_props **props;
        void *arg;

        if (member->type != IS_STRING) {
                tmp_member = *member;
                zval_copy_ctor(&tmp_member);
                convert_to_string(&tmp_member);
                member = &tmp_member;
        }

        if (zend_hash_find(ref->binding->hprops, Z_STRVAL_P(member), 
Z_STRLEN_P(member)+1, (void **) &props) == FAILURE) {
                return 0;
        }

        return 1;

}

static HashTable *pih_get_properties(zval *object TSRMLS_DC)
{
        return NULL;
}

static union _zend_function* pih_get_method(zval *object, char *method, int method_len 
TSRMLS_DC)
{
        struct php_irssi_obj_ref *ref = zend_object_store_get_object(object TSRMLS_CC);
        struct php_irssi_class_props **props;
        zend_function *func_method;

        if (zend_hash_find(ref->binding->hfuncs, method, method_len+1, (void 
**)&func_method) == FAILURE) {
                return NULL;
        }
        free_alloca(lc_method_name);
        return func_method;
}

static union _zend_function* pih_get_ctor(zval *object TSRMLS_DC)
{
        return NULL;
}

static int pih_get_class_name(zval *object, char **class_name, zend_uint 
*class_name_len, int parent TSRMLS_DC)
{
        struct php_irssi_obj_ref *ref = zend_object_store_get_object(object TSRMLS_CC);

        if (parent) {
                *class_name = "irssi";
                *class_name_len = 5;
        } else {
                *class_name = (char*)ref->binding->classname;
                *class_name_len = strlen(*class_name);
        }
        return SUCCESS;
        
}

static int pih_compare_objects(zval *o1, zval *o2 TSRMLS_DC)
{
}

zend_object_handlers php_irssi_handlers = {
        ZEND_OBJECTS_STORE_HANDLERS,

        pih_read_prop,
        pih_write_prop,
        NULL,
        NULL,
        NULL,
        NULL,
        pih_has_prop,
        NULL,   /* can't unset props */
        pih_get_properties,
        pih_get_method,
        NULL,
        pih_get_ctor,
        NULL,
        pih_get_class_name,
        
};

static void clone_object(struct php_irssi_obj_ref *object, struct php_irssi_obj_ref 
**object_clone TSRMLS_DC)
{
        int i;
        
        *object_clone = emalloc(sizeof(**object_clone));
        memcpy(*object_clone, object, sizeof(**object_clone));

        for (i = 0; i < PHP_IRSSI_MAX_IDENTS; i++) {
                (*object_clone)->idents[i] = estrdup((*object_clone)->idents[i]);
        }
}

static void destroy_object(struct php_irssi_obj_ref *ref, zend_object_handle handle 
TSRMLS_DC)
{
        int i;

        for (i = 0; i < PHP_IRSSI_MAX_IDENTS; i++) {
                if (ref->idents[i])
                        efree(ref->idents[i]);
        }
        efree(ref);
}

/* Create an irssi object wrapper */
zend_object_value php_irssi_create_wrapper(struct php_irssi_obj_ref **ref, char 
*objname, zval *zobj TSRMLS_DC)
{
        zend_object_value retval;
        int i, objid;
        
        objid = module_get_uniq_id(objname, 0);
        *ref = ecalloc(1, sizeof(struct php_irssi_obj_ref));
        
        for (i = 0; php_irssi_object_bindings[i].bindname != NULL; i++) {
                if (php_irssi_object_bindings[i].bindtype == objid) {
                        (*ref)->binding = &php_irssi_object_bindings[i];
                }
        }
        
        retval.handle = zend_objects_store_put(*ref, 
(zend_objects_store_dtor_t)destroy_object, (zend_objects_store_clone_t)clone_object 
TSRMLS_CC);
        retval.handlers = &php_irssi_handlers;
        
        if (zobj) {
                Z_TYPE_P(zobj) = IS_OBJECT;
                zobj->value.obj = retval;
                ZVAL_DELREF(zobj);
        }
        
        return retval;
}

struct php_irssi_obj_ref *php_irssi_ref_from_wrapper(zval *obj, char *objname 
TSRMLS_DC)
{
        struct php_irssi_obj_ref *ref = zend_object_store_get_object(obj TSRMLS_CC);

        /* verify the binding */
        if (ref->binding->bindtype == module_get_uniq_id(objname, 0)) {
                return ref;
        }
        /* this is not the object you are looking for */
        return NULL;
}


static zend_class_entry php_irssi_ce;


int php_irssi_init_objects(void)
{
        int i, j;
        struct php_irssi_obj_bind *bind;
        struct php_irssi_class_props *props;
        
        INIT_CLASS_ENTRY(php_irssi_ce, "irssi", NULL);
        
        /* bind the bindtypes to names */
        for (i = 0; php_irssi_object_bindings[i].bindname != NULL; i++) {
                bind = & php_irssi_object_bindings[i];
                bind->bindtype = module_get_uniq_id(bind->bindname, 0);

                /* fill the hash tables for props etc. */
                if (bind->proptable) {
                        
                        ALLOC_HASHTABLE(bind->hprops);
                        zend_hash_init(bind->hprops, 0, NULL, NULL, 0);
                        
                        for (j = 0; bind->proptable[j].propname != NULL; j++) {
                                props = &bind->proptable[j];
                                
                                zend_hash_update(bind->hprops, (char*)props->propname, 
props->propnamelen + 1, (void**)&props, sizeof(props), NULL);
                        }
                }
                if (bind->functable) {
                        ALLOC_HASHTABLE(bind->hfuncs);
                        zend_hash_init(bind->hfuncs, 0, NULL, NULL, 0);
                        
                        zend_register_functions(&php_irssi_ce, bind->functable, 
bind->hfuncs, MODULE_PERSISTENT TSRMLS_CC);
                }
        }

}

void php_irssi_fini_objects(void)
{
        int i, j;
        struct php_irssi_obj_bind *bind;
        struct php_irssi_class_props *props;
        
        /* bind the bindtypes to names */
        for (i = 0; php_irssi_object_bindings[i].bindname != NULL; i++) {
                bind = & php_irssi_object_bindings[i];

                /* fill the hash tables for props etc. */
                if (bind->hprops) {
                        zend_hash_destroy(bind->hprops);
                        FREE_HASHTABLE(bind->hprops);
                }
                if (bind->hfuncs) {
                        zend_hash_destroy(bind->hfuncs);
                        FREE_HASHTABLE(bind->hfuncs);
                }
        }
}



/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */

Index: embed/php-irssi/php-irssi-obj.h
+++ embed/php-irssi/php-irssi-obj.h
/*
  +----------------------------------------------------------------------+
  | PHP for IRSSI                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2003 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 2.02 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available at through the world-wide-web at                           |
  | http://www.php.net/license/2_02.txt.                                 |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | [EMAIL PROTECTED] so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Wez Furlong <[EMAIL PROTECTED]>                                    |
  +----------------------------------------------------------------------+
  $Id: php-irssi-obj.h,v 1.1 2003/01/30 09:04:35 wez Exp $
*/

extern zend_object_handlers php_irssi_handlers;
zend_object_value php_irssi_create_wrapper(struct php_irssi_obj_ref **ref, char 
*objname, zval *zobj TSRMLS_DC);
struct php_irssi_obj_ref *php_irssi_ref_from_wrapper(zval *obj, char *objname 
TSRMLS_DC);
int php_irssi_init_objects(void);


void php_irssi_C_to_PHP(zval **val, int type, void *arg TSRMLS_DC);
void php_irssi_export_NICK(zval *obj, CHANNEL_REC *cr, NICK_REC *nr TSRMLS_DC);
void php_irssi_export_CHANNEL(zval *obj, CHANNEL_REC *cr TSRMLS_DC);
void php_irssi_export_SERVER(zval *obj, SERVER_REC *srv TSRMLS_DC);
void export_GList(zval *val, GSList *the_list TSRMLS_DC);

Index: embed/php-irssi/php-irssi.h
+++ embed/php-irssi/php-irssi.h
/*
  +----------------------------------------------------------------------+
  | PHP for IRSSI                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2003 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 2.02 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available at through the world-wide-web at                           |
  | http://www.php.net/license/2_02.txt.                                 |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | [EMAIL PROTECTED] so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Wez Furlong <[EMAIL PROTECTED]>                                    |
  +----------------------------------------------------------------------+
  $Id: php-irssi.h,v 1.1 2003/01/30 09:04:35 wez Exp $
*/

#define MODULE_NAME "php/core"
#include "common.h"

#include "modules.h"
#include "core.h"
#include "signals.h"
#include "misc.h"
#include "irc.h"
#include "irc-servers.h"
#include "channels.h"
#include "nicklist.h"
#include "settings.h"
#include "servers.h"
#include "commands.h"
#include "levels.h"
#include "fe-windows.h"
#include "lib-config/iconfig.h" /* FIXME: remove before .99 */

#include <php_embed.h>

enum php_irssi_arg_type_t {
        PIAT_STRING,
        PIAT_SERVER,
        PIAT_CHANNEL,
        PIAT_INT,
        PIAT_ULONG,
        PIAT_NICK,
        PIAT_ARRAY_OF_STRING,
        PIAT_BOOL
};

struct php_irssi_signal_args {
        const char *signame;
        int sigid;      /* bound at runtime */
        int argc;       /* number of args */
        int argtypes[SIGNAL_MAX_ARGUMENTS];
};

struct php_irssi_class_props {
        const char *propname;
        int propnamelen;
        int proptype;
        size_t offset;  /* from base of the relevant struct */
};

#ifndef offset_of
# define offset_of(type,member) ((size_t)(&((type *)0)->member))
#endif

struct php_irssi_obj_ref;

struct php_irssi_obj_bind {
        const char *bindname;
        int bindtype;   /* module_get_uniq_id(bindname, 0) -> resolved at runtime */
        struct php_irssi_class_props *proptable;
        void *(*resolve)(struct php_irssi_obj_ref *ref);
        const char *classname;  /* name of PHP class */ 
        function_entry *functable;
        /* --- runtime --- */
        HashTable *hprops;      /* hashed version of proptable */
        HashTable *hfuncs;      /* hashed version of functable */
};

#define PHP_IRSSI_MAX_IDENTS    4
enum {
        IDX_SERVER,
        IDX_CHANNEL,
        IDX_NICK
};


/* kept in the object store */
struct php_irssi_obj_ref {
        struct php_irssi_obj_bind *binding;
        char *idents[PHP_IRSSI_MAX_IDENTS];
};

#include "php-irssi-obj.h"

#define inline /* nothing */

SERVER_REC *map_server(zval *object TSRMLS_DC);
CHANNEL_REC *map_channel(zval *object TSRMLS_DC);
NICK_REC *map_nick(zval *object, CHANNEL_REC **channel TSRMLS_DC);

#define SV_FETCH()      SERVER_REC *server = map_server(getThis() TSRMLS_CC); if 
(server == NULL) RETURN_NULL();
#define CH_FETCH()      CHANNEL_REC *channel = map_channel(getThis() TSRMLS_CC); if 
(channel == NULL) RETURN_NULL();
#define NK_FETCH()      CHANNEL_REC *channel; NICK_REC *nick = map_nick(getThis(), 
&channel TSRMLS_CC); if (channel == NULL || nick == NULL) RETURN_NULL();

Index: embed/php-irssi/server.c
+++ embed/php-irssi/server.c
/*
  +----------------------------------------------------------------------+
  | PHP for IRSSI                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2003 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 2.02 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available at through the world-wide-web at                           |
  | http://www.php.net/license/2_02.txt.                                 |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | [EMAIL PROTECTED] so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Wez Furlong <[EMAIL PROTECTED]>                                    |
  +----------------------------------------------------------------------+
  $Id: server.c,v 1.1 2003/01/30 09:04:35 wez Exp $
*/

#include "php-irssi.h"

/* ---------- Server functions */
/* Given a server record, create a server object */
void php_irssi_export_SERVER(zval *obj, SERVER_REC *srv TSRMLS_DC)
{
        struct php_irssi_obj_ref *ref;

        php_irssi_create_wrapper(&ref, "SERVER", obj TSRMLS_CC);
        if (ref) {
                ref->idents[IDX_SERVER] = estrdup(srv->tag);
        }
}

SERVER_REC *map_server(zval *object TSRMLS_DC)
{
        struct php_irssi_obj_ref *ref;

        ref = php_irssi_ref_from_wrapper(object, "SERVER" TSRMLS_CC);
        if (ref)
                return server_find_tag(ref->idents[IDX_SERVER]);

        return NULL;
}


PHP_FUNCTION(server_privmsg)
{
        char *target, *msg;
        long target_len, msg_len;
        long target_type; /* IRSSI_SEND_TARGET_X */
        SV_FETCH();

        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssl", 
&target, &target_len, &msg, &msg_len, &target_type)) {
                return;
        }

        (server->send_message)(server, target, msg, target_type);

        signal_emit(target_type == SEND_TARGET_CHANNEL ? "message own_public" : 
"message own_private", 4, server, msg, target, target);
}

PHP_FUNCTION(server_send_cmd)
{
        char *cmd;
        long cmd_len;
        IRC_SERVER_REC *isrv;
        SV_FETCH();

        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &cmd, 
&cmd_len)) {
                return;
        }

        isrv = IRC_SERVER(server);

        if (isrv) {
                irc_send_cmd(isrv, cmd);
        }
}

PHP_FUNCTION(server_send_cmd_now)
{
        char *cmd;
        long cmd_len;
        IRC_SERVER_REC *isrv;
        SV_FETCH();

        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &cmd, 
&cmd_len)) {
                return;
        }

        isrv = IRC_SERVER(server);

        if (isrv) {
                irc_send_cmd_now(isrv, cmd);
        }
}

PHP_FUNCTION(server_channels_join)
{
        char *cmd;
        long cmd_len;
        SV_FETCH();

        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &cmd, 
&cmd_len)) {
                return;
        }

        server->channels_join(server, cmd, 0);
        
}

PHP_FUNCTION(server_get_channel_list)
{
        GSList *tmp;
        zval *obj;
        SV_FETCH();

        array_init(return_value);
        for (tmp = server->channels; tmp != NULL; tmp = tmp->next) {
                MAKE_STD_ZVAL(obj);
                php_irssi_export_CHANNEL(obj, (CHANNEL_REC*)tmp->data);
                add_next_index_zval(return_value, obj);
        }
        
}

function_entry php_irssi_SERVER_funcs[] = {
        PHP_NAMED_FE(privmsg,   PHP_FN(server_privmsg), NULL)
        PHP_NAMED_FE(send_cmd,  PHP_FN(server_send_cmd), NULL)
        PHP_NAMED_FE(send_cmd_now,      PHP_FN(server_send_cmd_now), NULL)
        PHP_NAMED_FE(channels_join,     PHP_FN(server_channels_join), NULL)
        PHP_NAMED_FE(get_channels,      PHP_FN(server_get_channel_list), NULL)
        NULL, NULL, NULL
};



/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * indent-tabs-mode: t
 * End:
 */

Index: embed/php-irssi/typemap.php
+++ embed/php-irssi/typemap.php
<?php
/*
  +----------------------------------------------------------------------+
  | PHP for IRSSI                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2003 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 2.02 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available at through the world-wide-web at                           |
  | http://www.php.net/license/2_02.txt.                                 |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | [EMAIL PROTECTED] so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Wez Furlong <[EMAIL PROTECTED]>                                    |
  +----------------------------------------------------------------------+
  $Id: typemap.php,v 1.1 2003/01/30 09:04:35 wez Exp $
*/

/* This array describes the functions that can be used to convert between
 * irssi and php/ze types */

$marshal = array(
        "char *"                => array("PIAT_STRING", false),
        "SERVER_REC"    => array("PIAT_SERVER", true),
        "CHANNEL_REC"   => array("PIAT_CHANNEL", true),
        "time_t"                => array("PIAT_INT", false),
        "int"                   => array("PIAT_INT", false),
        "unsigned int"  => array("PIAT_INT", false),
        "ulong"                 => array("PIAT_ULONG", false),
        "NICK_REC"              => array("PIAT_NICK", true),
        "GList * of char*" => array("PIAT_ARRAY_OF_STRING", false),
        );

function match_decl($decl, &$name, &$handler, $pointers = false)
{
        static $bool_handlers = array("PIAT_INT");

        $decl = trim($decl);

        foreach ($GLOBALS['marshal'] as $type => $hdata) {

                list($handler, $impptr) = $hdata;
        
                if ($impptr && $pointers)
                        $type .= " *";
        
                if (substr($decl, 0, strlen($type)) == $type) {

                        /* special case for bool */
                        if (in_array($handler, $bool_handlers) && preg_match('/:1$/', 
$decl)) {
                                $handler = "PIAT_BOOL";
                        }
                        

                        $name = trim(preg_replace('/:.*/', '', substr($decl, 
strlen($type))));

                        if ($name{0} == '*' || $name{0} == '(') {
                                /* pointer or pointer to function */
                                continue;
                        }
                        
                        return true;
                }
        }
        
        return false;
}

?>

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to