cvs: embed /php-irssi ext-irssi.c

From: Date: Sat, 01 Feb 2003 04:46:56 +0000
Subject: cvs: embed /php-irssi ext-irssi.c
Groups: php.embed.cvs 
Request: Send a blank email to php-embed-cvs+get-10@lists.php.net to get a copy of this message
wez Fri Jan 31 23:46:56 2003 EDT Modified files: /embed/php-irssi ext-irssi.c Log: Implement irssi_signal_remove(). Index: embed/php-irssi/ext-irssi.c diff -u embed/php-irssi/ext-irssi.c:1.5 embed/php-irssi/ext-irssi.c:1.6 --- embed/php-irssi/ext-irssi.c:1.5 Fri Jan 31 13:11:56 2003 +++ embed/php-irssi/ext-irssi.c Fri Jan 31 23:46:56 2003 @@ -14,7 +14,7 @@ +----------------------------------------------------------------------+ | Author: Wez Furlong <wez@php.net> | +----------------------------------------------------------------------+ - $Id: ext-irssi.c,v 1.5 2003/01/31 18:11:56 tal Exp $ + $Id: ext-irssi.c,v 1.6 2003/02/01 04:46:56 wez Exp $ */ #include "php-irssi.h" #include "php-signals-list.h" /* generated by php during make */ @@ -24,12 +24,6 @@ * Avoid stale pointer mess by keeping a copy of identifiers rather than * pointers to the actual records. This may be slightly slower than holding * pointers, but at least it is safe. - * - * Make sure the OO works without needing (PHP) references as this causes - * headaches. - * - * Use accessor functions rather than properties. - * Could write overloaded objects where a property make sense. * */ struct sig_record { @@ -180,6 +174,39 @@ } } +static char * signal_hash_key(char *signame, zval *callback TSRMLS_DC) +{ + char *key = NULL; + + if (Z_TYPE_P(callback) == IS_ARRAY) { + zval **obj = NULL, **func = NULL; + + zend_hash_index_find(Z_ARRVAL_P(callback), 0, (void**)&obj); + zend_hash_index_find(Z_ARRVAL_P(callback), 1, (void**)&func); + + if (obj == NULL || func == NULL) { + return NULL; + } + + 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)); + return key; + } + + /* class name */ + convert_to_string_ex(obj); + spprintf(&key, 0, "%s@%s@%s", 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)); + return key; + } + return NULL; +} + /* 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) @@ -190,7 +217,8 @@ long priority = SIGNAL_PRIORITY_DEFAULT; int sigid; struct sig_record *rec; - + char *sighash = NULL; + if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|lz!", &signame, &signame_len, &funcname, @@ -200,6 +228,11 @@ return; } + sighash = signal_hash_key(signame, funcname TSRMLS_CC); + if (sighash == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to hash signal handler"); + } + rec = emalloc(sizeof(struct sig_record)); sigid = signal_get_uniq_id(signame); @@ -218,10 +251,16 @@ rec->arg = NULL; } - zend_hash_next_index_insert(bound_signals, &rec, sizeof(rec), NULL); + 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); + } signal_add_full_id(MODULE_NAME, priority, sigid, sig_func, rec); + } /* fetches the optional arg registered when an event handler was bound */ @@ -242,6 +281,7 @@ } +/* Trigger a signal */ PHP_FUNCTION(irssi_signal_emit) { const void *args[6]; @@ -287,7 +327,7 @@ args[i] = &Z_LVAL_PP(zargs[i+1]); break; case PIAT_ARRAY_OF_STRING: - /* make it into a GSList of char * */ + /* TODO: make it into a GSList of char * */ default: args[i] = NULL; } @@ -296,16 +336,49 @@ args[2], args[3], args[4], args[5]); } + + +/* Un-bind a signal */ PHP_FUNCTION(irssi_signal_remove) { + 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 TSRMLS_CC); + if (sighash == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to hash signal 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; + } -} + signal_remove_id((*rec)->signal_id, sig_func, rec); + 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; + struct sig_record *rec = *(struct sig_record **)pDest; if (rec->handler) { zval_ptr_dtor(&rec->handler); @@ -318,6 +391,7 @@ efree(rec); } + PHP_MINIT_FUNCTION(irssi) { ALLOC_HASHTABLE(bound_signals); @@ -360,6 +434,7 @@ REGISTER_LONG_CONSTANT("IRSSI_SIGNAL_PRIORITY_DEFAULT", SIGNAL_PRIORITY_DEFAULT, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IRSSI_SIGNAL_PRIORITY_LOW", SIGNAL_PRIORITY_LOW, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IRSSI_SIGNAL_PRIORITY_HIGH", SIGNAL_PRIORITY_HIGH, CONST_CS|CONST_PERSISTENT); + REGISTER_STRING_CONSTANT("PHP_IRSSI_VERSION", PHP_IRSSI_VERSION, CONST_CS|CONST_PERSISTENT); return SUCCESS;

« previous php.embed.cvs (#10) next »