cvs: embed /php-irssi channel.c ext-irssi.c gensignals.php nick.c php-core.c server.c /php-irssi/examples command.php
[email protected] ("Wez Furlong") Sun, 02 Feb 2003 21:05:26 -0000
| Newsgroups | php.embed.cvs |
|---|---|
| Message-ID | <cvswez1044219926@cvsserver> |
--wez1044219926
Content-Type: text/plain
wez Sun Feb 2 16:05:26 2003 EDT
Added files:
/embed/php-irssi/examples command.php
Modified files:
/embed/php-irssi channel.c ext-irssi.c gensignals.php nick.c
php-core.c server.c
Log:
Implement command binding.
Add an example.
Allow NULL channel/server/nick objects when mapping to PHP-space.
--wez1044219926
Content-Type: text/plain
Content-Disposition: attachment; filename="wez-20030202160526.txt"
Index: embed/php-irssi/channel.c
diff -u embed/php-irssi/channel.c:1.4 embed/php-irssi/channel.c:1.5
--- embed/php-irssi/channel.c:1.4 Sun Feb 2 13:26:52 2003
+++ embed/php-irssi/channel.c Sun Feb 2 16:05:25 2003
@@ -14,7 +14,7 @@
+----------------------------------------------------------------------+
| Author: Wez Furlong <[email protected]> |
+----------------------------------------------------------------------+
- $Id: channel.c,v 1.4 2003/02/02 18:26:52 wez Exp $
+ $Id: channel.c,v 1.5 2003/02/02 21:05:25 wez Exp $
*/
#include "php-irssi.h"
#define PHP_IRSSI_PROTOS_ONLY
@@ -27,6 +27,11 @@
{
struct php_irssi_obj_ref *ref;
+ if (cr == NULL) {
+ ZVAL_NULL(obj);
+ return;
+ }
+
php_irssi_create_wrapper(&ref, "CHANNEL", obj TSRMLS_CC);
if (ref) {
ref->idents[IDX_CHANNEL] = estrdup(cr->name);
Index: embed/php-irssi/ext-irssi.c
diff -u embed/php-irssi/ext-irssi.c:1.13 embed/php-irssi/ext-irssi.c:1.14
--- embed/php-irssi/ext-irssi.c:1.13 Sun Feb 2 14:18:27 2003
+++ embed/php-irssi/ext-irssi.c Sun Feb 2 16:05:25 2003
@@ -14,7 +14,7 @@
+----------------------------------------------------------------------+
| Author: Wez Furlong <[email protected]> |
+----------------------------------------------------------------------+
- $Id: ext-irssi.c,v 1.13 2003/02/02 19:18:27 wez Exp $
+ $Id: ext-irssi.c,v 1.14 2003/02/02 21:05:25 wez Exp $
*/
#include "php-irssi.h"
#include "php-signals-list.h" /* generated by php during make */
@@ -29,7 +29,8 @@
struct sig_record {
zval *handler;
zval *arg;
- enum { SIG_REC_TYPE_SIGNAL, SIG_REC_TYPE_TIMEOUT } type;
+ enum { SIG_REC_TYPE_SIGNAL, SIG_REC_TYPE_TIMEOUT, SIG_REC_TYPE_COMMAND} type;
+ struct php_irssi_signal_args *sigargs;
union {
struct {
int signal_id;
@@ -38,6 +39,9 @@
int tag;
int one_shot;
} timeout;
+ struct {
+ char *command;
+ } cmd;
} v;
};
@@ -60,7 +64,7 @@
/* Signals */
-static char *signal_hash_key(char *signame, zval *callback TSRMLS_DC)
+static char *signal_hash_key(char *signame, zval *callback, char *prefix TSRMLS_DC)
{
char *key = NULL;
@@ -77,17 +81,17 @@
convert_to_string_ex(func);
if (Z_TYPE_PP(obj) == IS_OBJECT) {
- spprintf(&key, 0, "%s@%d@%s", signame, (*obj)->value.obj.handle, Z_STRVAL_PP(func));
+ spprintf(&key, 0, "%s@%s@%d@%s", prefix, signame, (*obj)->value.obj.handle, Z_STRVAL_PP(func));
return key;
}
/* class name */
convert_to_string_ex(obj);
- spprintf(&key, 0, "%s@%s@%s", signame, Z_STRVAL_PP(obj), Z_STRVAL_PP(func));
+ spprintf(&key, 0, "%s@%s@%s@%s", prefix, signame, Z_STRVAL_PP(obj), Z_STRVAL_PP(func));
return key;
}
if (Z_TYPE_P(callback) == IS_STRING) {
- spprintf(&key, 0, "%s@%s", signame, Z_STRVAL_P(callback));
+ spprintf(&key, 0, "%s@%s@%s", prefix, signame, Z_STRVAL_P(callback));
return key;
}
return NULL;
@@ -148,64 +152,60 @@
const void *args[6];
int sigid = signal_get_emitted_id();
struct sig_record *rec = (struct sig_record*)signal_get_user_data();
- struct php_irssi_signal_args *sigargs;
zval ***zargs;
zval *val, *retval = NULL, *func_name = NULL;
- int i, call_result;
+ int i, argc = 0, call_result;
args[0] = p1; args[1] = p2; args[2] = p3;
args[3] = p4; args[4] = p5; args[5] = p6;
- /* first, find out which signal it is */
- sigargs = sigid_to_args(sigid);
-
- if (sigargs == NULL)
- return;
-
func_name = rec->handler;
-
- zargs = emalloc(sigargs->argc * sizeof(zval **));
-
- for (i = 0; i < sigargs->argc; i++) {
- /* TODO: would be nice to replace this with php_irssi_C_to_PHP(),
- * but we need to make some assumptions and optimizations here
- * for the NICK records */
-
- zargs[i] = emalloc(sizeof(zval *));
- MAKE_STD_ZVAL(*zargs[i]);
- val = *zargs[i];
- switch(sigargs->argtypes[i]) {
- case PIAT_STRING:
- ZVAL_STRING(val, (char *)args[i], 1);
- break;
- case PIAT_SERVER:
- php_irssi_export_SERVER(val, (SERVER_REC*)args[i] TSRMLS_CC);
- break;
- case PIAT_CHANNEL:
- php_irssi_export_CHANNEL(val, (CHANNEL_REC*)args[i] TSRMLS_CC);
- break;
- case PIAT_NICK:
- /* a NICK only ever follows a channel */
- 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]);
- break;
- case PIAT_ULONG:
- ZVAL_LONG(val, *(ulong *)args[i]);
- break;
- case PIAT_WI_ITEM:
- php_irssi_export_WI_ITEM(val, (WI_ITEM_REC*)args[i] TSRMLS_CC);
- break;
- case PIAT_WINDOW:
- php_irssi_export_WINDOW(val, (WINDOW_REC*)args[i] TSRMLS_CC);
- break;
- case PIAT_ARRAY_OF_STRING:
- php_irssi_export_GList(val, (GSList*)args[i], PIAT_STRING TSRMLS_CC);
- break;
- default:
- ZVAL_NULL(val);
+ if (rec->sigargs) {
+ zargs = emalloc(rec->sigargs->argc * sizeof(zval **));
+
+ for (i = 0; i < rec->sigargs->argc; i++) {
+ /* TODO: would be nice to replace this with php_irssi_C_to_PHP(),
+ * but we need to make some assumptions and optimizations here
+ * for the NICK records */
+
+ zargs[i] = emalloc(sizeof(zval *));
+ MAKE_STD_ZVAL(*zargs[i]);
+ val = *zargs[i];
+ argc++;
+
+ switch(rec->sigargs->argtypes[i]) {
+ case PIAT_STRING:
+ ZVAL_STRING(val, (char *)args[i], 1);
+ break;
+ case PIAT_SERVER:
+ php_irssi_export_SERVER(val, (SERVER_REC*)args[i] TSRMLS_CC);
+ break;
+ case PIAT_CHANNEL:
+ php_irssi_export_CHANNEL(val, (CHANNEL_REC*)args[i] TSRMLS_CC);
+ break;
+ case PIAT_NICK:
+ /* a NICK only ever follows a channel */
+ 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]);
+ break;
+ case PIAT_ULONG:
+ ZVAL_LONG(val, *(ulong *)args[i]);
+ break;
+ case PIAT_WI_ITEM:
+ php_irssi_export_WI_ITEM(val, (WI_ITEM_REC*)args[i] TSRMLS_CC);
+ break;
+ case PIAT_WINDOW:
+ php_irssi_export_WINDOW(val, (WINDOW_REC*)args[i] TSRMLS_CC);
+ break;
+ case PIAT_ARRAY_OF_STRING:
+ php_irssi_export_GList(val, (GSList*)args[i], PIAT_STRING TSRMLS_CC);
+ break;
+ default:
+ ZVAL_NULL(val);
+ }
}
}
@@ -214,7 +214,7 @@
NULL,
func_name,
&retval,
- sigargs->argc,
+ argc,
zargs,
0, NULL TSRMLS_CC);
@@ -234,7 +234,7 @@
zval_ptr_dtor(&retval);
/* release those zvals */
- for (i = 0; i < sigargs->argc; i++) {
+ for (i = 0; i < argc; i++) {
zval_ptr_dtor(zargs[i]);
efree(zargs[i]);
}
@@ -456,6 +456,64 @@
RETURN_BOOL(signal_is_stopped(sigid));
}
+/* proto void irssi_command_bind(string command, mixed callback, [long priority, mixed cmdarg])
+ Binds a function to a command. priority is one of the IRSSI_PRIORITY_XXX constants */
+PHP_FUNCTION(irssi_command_bind)
+{
+ zval *sigarg = NULL, *funcname, *tmp;
+ char *signame;
+ long signame_len;
+ long priority = SIGNAL_PRIORITY_DEFAULT;
+ int sigid;
+ struct sig_record *rec;
+ char *sighash = NULL;
+ struct php_irssi_signal_args *sigargs;
+
+ if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|lz!",
+ &signame, &signame_len,
+ &funcname,
+ &priority,
+ &sigarg
+ )) {
+ return;
+ }
+
+ sigid = signal_get_uniq_id("default command");
+ sigargs = sigid_to_args(sigid);
+
+ sighash = signal_hash_key(signame, funcname, "command" TSRMLS_CC);
+ if (sighash == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to hash command handler");
+ }
+
+ rec = emalloc(sizeof(struct sig_record));
+ rec->type = SIG_REC_TYPE_COMMAND;
+ rec->v.cmd.command = estrdup(signame);
+
+ MAKE_STD_ZVAL(rec->handler);
+ *(rec->handler) = *funcname;
+ zval_copy_ctor(rec->handler);
+
+ if (sigarg) {
+ MAKE_STD_ZVAL(rec->arg);
+ *(rec->arg) = *sigarg;
+ zval_copy_ctor(rec->arg);
+ } else {
+ rec->arg = NULL;
+ }
+
+ rec->sigargs = sigargs;
+
+ if (sighash) {
+ zend_hash_update(bound_signals, sighash, strlen(sighash)+1, &rec, sizeof(rec), NULL);
+ efree(sighash);
+ } else {
+ zend_hash_next_index_insert(bound_signals, &rec, sizeof(rec), NULL);
+ }
+
+ command_bind_full(MODULE_NAME, priority, signame, -1, NULL, sig_func, rec);
+}
+
/* proto void irssi_signal_add(string signalname, mixed callback, [long priority, mixed sigarg])
Binds a function to a signal. priority is one of the IRSSI_PRIORITY_XXX constants */
PHP_FUNCTION(irssi_signal_add)
@@ -467,6 +525,7 @@
int sigid;
struct sig_record *rec;
char *sighash = NULL;
+ struct php_irssi_signal_args *sigargs;
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|lz!",
&signame, &signame_len,
@@ -477,7 +536,10 @@
return;
}
- sighash = signal_hash_key(signame, funcname TSRMLS_CC);
+ sigid = signal_get_uniq_id(signame);
+ sigargs = sigid_to_args(sigid);
+
+ sighash = signal_hash_key(signame, funcname, "signal" TSRMLS_CC);
if (sighash == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to hash signal handler");
}
@@ -485,8 +547,6 @@
rec = emalloc(sizeof(struct sig_record));
rec->type = SIG_REC_TYPE_SIGNAL;
- sigid = signal_get_uniq_id(signame);
-
MAKE_STD_ZVAL(rec->handler);
*(rec->handler) = *funcname;
zval_copy_ctor(rec->handler);
@@ -501,6 +561,8 @@
rec->arg = NULL;
}
+ rec->sigargs = sigargs;
+
if (sighash) {
zend_hash_update(bound_signals, sighash, strlen(sighash)+1, &rec, sizeof(rec), NULL);
efree(sighash);
@@ -606,7 +668,7 @@
return;
}
- sighash = signal_hash_key(signame, funcname TSRMLS_CC);
+ sighash = signal_hash_key(signame, funcname, "signal" TSRMLS_CC);
if (sighash == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to hash signal handler");
RETURN_FALSE;
@@ -624,14 +686,59 @@
RETURN_TRUE;
}
+PHP_FUNCTION(irssi_command_unbind)
+{
+ zval *sigarg = NULL, *funcname, *tmp;
+ char *signame;
+ long signame_len;
+ int sigid;
+ struct sig_record **rec;
+ char *sighash = NULL;
+
+ if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|z!",
+ &signame, &signame_len,
+ &funcname,
+ &sigarg
+ )) {
+ return;
+ }
+
+ sighash = signal_hash_key(signame, funcname, "command" TSRMLS_CC);
+ if (sighash == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to hash command handler");
+ RETURN_FALSE;
+ }
+
+ if (FAILURE == zend_hash_find(bound_signals, sighash, strlen(sighash)+1, (void**)&rec)) {
+ /* Could not find this handler in our list */
+ RETURN_FALSE;
+ }
+
+ zend_hash_del(bound_signals, sighash, strlen(sighash)+1);
+
+ efree(sighash);
+
+ RETURN_TRUE;
+}
+
+
+
+
static void sig_rec_dtor(void *pDest)
{
struct sig_record *rec = *(struct sig_record **)pDest;
-
- if (rec->type == SIG_REC_TYPE_SIGNAL) {
- signal_remove_id(rec->v.sig.signal_id, sig_func, rec);
- } else {
- g_source_remove(rec->v.timeout.tag);
+
+ switch(rec->type) {
+ case SIG_REC_TYPE_SIGNAL:
+ signal_remove_id(rec->v.sig.signal_id, sig_func, rec);
+ break;
+ case SIG_REC_TYPE_COMMAND:
+ command_unbind_full(rec->v.cmd.command, sig_func, rec);
+ efree(rec->v.cmd.command);
+ break;
+ case SIG_REC_TYPE_TIMEOUT:
+ g_source_remove(rec->v.timeout.tag);
+ break;
}
if (rec->handler) {
@@ -721,6 +828,8 @@
PHP_FE(irssi_timeout_remove, NULL)
PHP_FE(irssi_window_get_active, NULL)
PHP_FE(irssi_window_find_name, NULL)
+ PHP_FE(irssi_command_bind, NULL)
+ PHP_FE(irssi_command_unbind, NULL)
NULL, NULL, NULL
};
Index: embed/php-irssi/gensignals.php
diff -u embed/php-irssi/gensignals.php:1.3 embed/php-irssi/gensignals.php:1.4
--- embed/php-irssi/gensignals.php:1.3 Thu Jan 30 07:12:20 2003
+++ embed/php-irssi/gensignals.php Sun Feb 2 16:05:26 2003
@@ -15,7 +15,7 @@
+----------------------------------------------------------------------+
| Author: Wez Furlong <[email protected]> |
+----------------------------------------------------------------------+
- $Id: gensignals.php,v 1.3 2003/01/30 12:12:20 wez Exp $
+ $Id: gensignals.php,v 1.4 2003/02/02 21:05:26 wez Exp $
*/
/* Generate signal information from the signals.txt file in the docs
@@ -36,8 +36,8 @@
$signal = $matches[1];
$thing = $matches[2];
- if ($thing)
- return;
+// if ($thing)
+// return;
$args = explode(", ", $matches[3]);
Index: embed/php-irssi/nick.c
diff -u embed/php-irssi/nick.c:1.3 embed/php-irssi/nick.c:1.4
--- embed/php-irssi/nick.c:1.3 Thu Jan 30 10:42:47 2003
+++ embed/php-irssi/nick.c Sun Feb 2 16:05:26 2003
@@ -14,7 +14,7 @@
+----------------------------------------------------------------------+
| Author: Wez Furlong <[email protected]> |
+----------------------------------------------------------------------+
- $Id: nick.c,v 1.3 2003/01/30 15:42:47 wez Exp $
+ $Id: nick.c,v 1.4 2003/02/02 21:05:26 wez Exp $
*/
#include "php-irssi.h"
#define PHP_IRSSI_PROTOS_ONLY
@@ -73,6 +73,11 @@
{
struct php_irssi_obj_ref *ref;
+ if (nr == NULL) {
+ ZVAL_NULL(obj);
+ return;
+ }
+
php_irssi_create_wrapper(&ref, "NICK", obj TSRMLS_CC);
if (ref) {
ref->idents[IDX_SERVER] = estrdup(cr->server->tag);
Index: embed/php-irssi/php-core.c
diff -u embed/php-irssi/php-core.c:1.8 embed/php-irssi/php-core.c:1.9
--- embed/php-irssi/php-core.c:1.8 Sun Feb 2 14:18:27 2003
+++ embed/php-irssi/php-core.c Sun Feb 2 16:05:26 2003
@@ -14,7 +14,7 @@
+----------------------------------------------------------------------+
| Author: Wez Furlong <[email protected]> |
+----------------------------------------------------------------------+
- $Id: php-core.c,v 1.8 2003/02/02 19:18:27 wez Exp $
+ $Id: php-core.c,v 1.9 2003/02/02 21:05:26 wez Exp $
*/
#define MODULE_NAME "php/core"
#include "common.h"
@@ -134,7 +134,7 @@
}
/* Handler for "/php" command */
-static void cmd_php(const char *data, SERVER_REC *server, void *item)
+static void cmd_php(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
{
if (*data == '\0') {
data = "help";
Index: embed/php-irssi/server.c
diff -u embed/php-irssi/server.c:1.3 embed/php-irssi/server.c:1.4
--- embed/php-irssi/server.c:1.3 Sat Feb 1 22:27:16 2003
+++ embed/php-irssi/server.c Sun Feb 2 16:05:26 2003
@@ -14,7 +14,7 @@
+----------------------------------------------------------------------+
| Author: Wez Furlong <[email protected]> |
+----------------------------------------------------------------------+
- $Id: server.c,v 1.3 2003/02/02 03:27:16 wez Exp $
+ $Id: server.c,v 1.4 2003/02/02 21:05:26 wez Exp $
*/
#include "php-irssi.h"
@@ -28,6 +28,11 @@
{
struct php_irssi_obj_ref *ref;
+ if (srv == NULL) {
+ ZVAL_NULL(obj);
+ return;
+ }
+
php_irssi_create_wrapper(&ref, "SERVER", obj TSRMLS_CC);
if (ref) {
ref->idents[IDX_SERVER] = estrdup(srv->tag);
Index: embed/php-irssi/examples/command.php
+++ embed/php-irssi/examples/command.php
<?php
/* $Id: command.php,v 1.1 2003/02/02 21:05:26 wez Exp $
*
* Commands.
*
* This sample demonstrates how to map "/foo bar baz" as a valid
* irssi command and have your own PHP code handle it.
*
* Just like any callback made from irssi, you should not hang around for
* too long; long delays can cause irssi to drop network connections to
* your chatnets.
*/
/* $command_text is the text that the user typed after the command.
* so, for "/foo bar baz", $command_text will be "bar baz".
* $server is the server object associated with the window in which
* the user typed the command. It may be NULL if there is no server.
* $windowitem is the associated windowitem. It may be NULL, just
* like the server. Use get_class($windowitem) to determine which
* item it actually represents - it will typically be a channel object.
*/
function the_foo_command($command_text, $server, $windowitem)
{
echo "You typed $command_text";
}
irssi_command_bind("foo", "the_foo_command");
/* Load this script and then type "/foo bar baz" at the irssi prompt */
?>
--wez1044219926--