diff options
author | Jani Taskinen <jani@php.net> | 2007-11-02 19:40:39 +0000 |
---|---|---|
committer | Jani Taskinen <jani@php.net> | 2007-11-02 19:40:39 +0000 |
commit | b48925117750da2a7fb7cff629e3852d13917f2f (patch) | |
tree | 44671e4afbcd83803757998784821a6cc19007b5 /ext/spl | |
parent | 0d7479891444f46d1c30cf875037e5099f8f782b (diff) | |
download | php-git-b48925117750da2a7fb7cff629e3852d13917f2f.tar.gz |
- MFH from HEAD:
. Folding tags
. Parameter parsing
. SPL debug info
. array function improvements (not all yet)
. Improvements to function calling with call_user_* functions
. Improvements to debugging info in var_dump/print_r
# I propably forgot already something but this all was pretty close tied
# to each other so it wasn't possible to do it in parts.
Diffstat (limited to 'ext/spl')
-rwxr-xr-x | ext/spl/php_spl.c | 28 | ||||
-rwxr-xr-x | ext/spl/php_spl.h | 2 | ||||
-rwxr-xr-x | ext/spl/spl_array.c | 34 | ||||
-rwxr-xr-x | ext/spl/spl_directory.c | 52 | ||||
-rwxr-xr-x | ext/spl/spl_functions.c | 29 | ||||
-rwxr-xr-x | ext/spl/spl_functions.h | 5 | ||||
-rwxr-xr-x | ext/spl/spl_iterators.c | 29 | ||||
-rwxr-xr-x | ext/spl/spl_observer.c | 38 |
8 files changed, 186 insertions, 31 deletions
diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c index cc88d91906..b4cd28144b 100755 --- a/ext/spl/php_spl.c +++ b/ext/spl/php_spl.c @@ -19,7 +19,7 @@ /* $Id$ */ #ifdef HAVE_CONFIG_H - #include "config.h" +#include "config.h" #endif #include "php.h" @@ -153,7 +153,7 @@ PHP_FUNCTION(class_implements) /* }}} */ #define SPL_ADD_CLASS(class_name, z_list, sub, allow, ce_flags) \ - spl_add_classes(&spl_ce_ ## class_name, z_list, sub, allow, ce_flags TSRMLS_CC) + spl_add_classes(spl_ce_ ## class_name, z_list, sub, allow, ce_flags TSRMLS_CC) #define SPL_LIST_CLASSES(z_list, sub, allow, ce_flags) \ SPL_ADD_CLASS(AppendIterator, z_list, sub, allow, ce_flags); \ @@ -607,26 +607,36 @@ PHP_FUNCTION(spl_autoload_functions) PHP_FUNCTION(spl_object_hash) { zval *obj; - int len; - char *hash; - char md5str[33]; - PHP_MD5_CTX context; - unsigned char digest[16]; + char* md5str; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) { return; } + + md5str = emalloc(33); + php_spl_object_hash(obj, md5str TSRMLS_CC); + + RETVAL_STRING(md5str, 0); +} +/* }}} */ + +PHPAPI void php_spl_object_hash(zval *obj, char *md5str TSRMLS_DC) /* {{{*/ +{ + int len; + char *hash; + PHP_MD5_CTX context; + unsigned char digest[16]; len = spprintf(&hash, 0, "%p:%d", Z_OBJ_HT_P(obj), Z_OBJ_HANDLE_P(obj)); - + md5str[0] = '\0'; PHP_MD5Init(&context); PHP_MD5Update(&context, (unsigned char*)hash, len); PHP_MD5Final(digest, &context); make_digest(md5str, digest); - RETVAL_STRING(md5str, 1); efree(hash); } +/* }}} */ int spl_build_class_list_string(zval **entry, char **list TSRMLS_DC) /* {{{ */ { diff --git a/ext/spl/php_spl.h b/ext/spl/php_spl.h index 7c44f58550..e28578dcc1 100755 --- a/ext/spl/php_spl.h +++ b/ext/spl/php_spl.h @@ -74,6 +74,8 @@ PHP_FUNCTION(spl_classes); PHP_FUNCTION(class_parents); PHP_FUNCTION(class_implements); +PHPAPI void php_spl_object_hash(zval *obj, char* md5str TSRMLS_DC); + #endif /* PHP_SPL_H */ /* diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index d9d7cd7e27..74e0999687 100755 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -614,6 +614,39 @@ static HashTable *spl_array_get_properties(zval *object TSRMLS_DC) /* {{{ */ return spl_array_get_hash_table(intern, 1 TSRMLS_CC); } /* }}} */ +static HashTable* spl_array_get_debug_info(zval *obj, int *is_temp TSRMLS_DC) /* {{{ */ +{ + spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(obj TSRMLS_CC); + HashTable *rv; + zval *tmp, *storage; + int name_len; + char *zname; + zend_class_entry *base; + + if (HASH_OF(intern->array) == intern->std.properties) { + *is_temp = 0; + return intern->std.properties; + } else { + *is_temp = 1; + + ALLOC_HASHTABLE(rv); + ZEND_INIT_SYMTABLE_EX(rv, zend_hash_num_elements(intern->std.properties) + 1, 0); + + zend_hash_copy(rv, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + + storage = intern->array; + zval_add_ref(&storage); + + base = (Z_OBJ_HT_P(obj) == &spl_handler_ArrayIterator) ? spl_ce_ArrayIterator : spl_ce_ArrayObject; + zname = spl_gen_private_prop_name(base, "storage", sizeof("storage")-1, &name_len TSRMLS_CC); + zend_symtable_update(rv, zname, name_len+1, &storage, sizeof(zval *), NULL); + efree(zname); + + return rv; + } +} +/* }}} */ + static zval *spl_array_read_property(zval *object, zval *member, int type TSRMLS_DC) /* {{{ */ { spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC); @@ -1514,6 +1547,7 @@ PHP_MINIT_FUNCTION(spl_array) spl_handler_ArrayObject.count_elements = spl_array_object_count_elements; spl_handler_ArrayObject.get_properties = spl_array_get_properties; + spl_handler_ArrayObject.get_debug_info = spl_array_get_debug_info; spl_handler_ArrayObject.read_property = spl_array_read_property; spl_handler_ArrayObject.write_property = spl_array_write_property; spl_handler_ArrayObject.get_property_ptr_ptr = spl_array_get_property_ptr_ptr; diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index bf3eb83f5a..6ee18d335c 100755 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -459,6 +459,57 @@ static int spl_filesystem_is_invalid_or_dot(const char * d_name) /* {{{ */ } /* }}} */ +static HashTable* spl_filesystem_object_get_debug_info(zval *obj, int *is_temp TSRMLS_DC) /* {{{{ */ +{ + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(obj TSRMLS_CC); + HashTable *rv; + zval *tmp, zrv; + char *pnstr; + int pnlen; + char stmp[2]; + + *is_temp = 1; + + ALLOC_HASHTABLE(rv); + ZEND_INIT_SYMTABLE_EX(rv, zend_hash_num_elements(intern->std.properties) + 3, 0); + + INIT_PZVAL(&zrv); + Z_ARRVAL(zrv) = rv; + + zend_hash_copy(rv, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + + pnstr = spl_gen_private_prop_name(spl_ce_SplFileInfo, "pathName", sizeof("pathName")-1, &pnlen TSRMLS_CC); + add_assoc_stringl_ex(&zrv, pnstr, pnlen+1, intern->path, intern->path_len, 1); + efree(pnstr); + if (intern->file_name) { + pnstr = spl_gen_private_prop_name(spl_ce_SplFileInfo, "fileName", sizeof("fileName")-1, &pnlen TSRMLS_CC); + add_assoc_stringl_ex(&zrv, pnstr, pnlen+1, intern->file_name, intern->file_name_len, 1); + efree(pnstr); + } + if (intern->type == SPL_FS_DIR && intern->u.dir.sub_path) { + pnstr = spl_gen_private_prop_name(spl_ce_RecursiveDirectoryIterator, "subPathName", sizeof("subPathName")-1, &pnlen TSRMLS_CC); + add_assoc_stringl_ex(&zrv, pnstr, pnlen+1, intern->u.dir.sub_path, intern->u.dir.sub_path_len, 1); + efree(pnstr); + } + if (intern->type == SPL_FS_FILE) { + pnstr = spl_gen_private_prop_name(spl_ce_SplFileObject, "openMode", sizeof("openMode")-1, &pnlen TSRMLS_CC); + add_assoc_stringl_ex(&zrv, pnstr, pnlen+1, intern->u.file.open_mode, intern->u.file.open_mode_len, 1); + efree(pnstr); + stmp[1] = '\0'; + stmp[0] = intern->u.file.delimiter; + pnstr = spl_gen_private_prop_name(spl_ce_SplFileObject, "delimiter", sizeof("delimiter")-1, &pnlen TSRMLS_CC); + add_assoc_stringl_ex(&zrv, pnstr, pnlen+1, stmp, 1, 1); + efree(pnstr); + stmp[0] = intern->u.file.enclosure; + pnstr = spl_gen_private_prop_name(spl_ce_SplFileObject, "enclosure", sizeof("enclosure")-1, &pnlen TSRMLS_CC); + add_assoc_stringl_ex(&zrv, pnstr, pnlen+1, stmp, 1, 1); + efree(pnstr); + } + + return rv; +} +/* }}}} */ + /* {{{ proto void DirectoryIterator::__construct(string path) Cronstructs a new dir iterator from a path. */ SPL_METHOD(DirectoryIterator, __construct) @@ -2349,6 +2400,7 @@ PHP_MINIT_FUNCTION(spl_directory) memcpy(&spl_filesystem_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); spl_filesystem_object_handlers.clone_obj = spl_filesystem_object_clone; spl_filesystem_object_handlers.cast_object = spl_filesystem_object_cast; + spl_filesystem_object_handlers.get_debug_info = spl_filesystem_object_get_debug_info; REGISTER_SPL_SUB_CLASS_EX(DirectoryIterator, SplFileInfo, spl_filesystem_object_new, spl_DirectoryIterator_functions); zend_class_implements(spl_ce_DirectoryIterator TSRMLS_CC, 1, zend_ce_iterator); diff --git a/ext/spl/spl_functions.c b/ext/spl/spl_functions.c index 31acfee436..16bda2fcec 100755 --- a/ext/spl/spl_functions.c +++ b/ext/spl/spl_functions.c @@ -40,8 +40,7 @@ void spl_register_interface(zend_class_entry ** ppce, char * class_name, const z { zend_class_entry ce; - INIT_CLASS_ENTRY(ce, class_name, functions); - ce.name_length = strlen(class_name); + INIT_CLASS_ENTRY_EX(ce, class_name, strlen(class_name), functions); *ppce = zend_register_internal_interface(&ce TSRMLS_CC); } /* }}} */ @@ -51,8 +50,7 @@ PHPAPI void spl_register_std_class(zend_class_entry ** ppce, char * class_name, { zend_class_entry ce; - INIT_CLASS_ENTRY(ce, class_name, function_list); - ce.name_length = strlen(class_name); + INIT_CLASS_ENTRY_EX(ce, class_name, strlen(class_name), function_list); *ppce = zend_register_internal_class(&ce TSRMLS_CC); /* entries changed by initialize */ @@ -67,8 +65,7 @@ PHPAPI void spl_register_sub_class(zend_class_entry ** ppce, zend_class_entry * { zend_class_entry ce; - INIT_CLASS_ENTRY(ce, class_name, function_list); - ce.name_length = strlen(class_name); + INIT_CLASS_ENTRY_EX(ce, class_name, strlen(class_name), function_list); *ppce = zend_register_internal_class_ex(&ce, parent_ce, NULL TSRMLS_CC); /* entries changed by initialize */ @@ -105,12 +102,12 @@ void spl_register_property( zend_class_entry * class_entry, char *prop_name, int void spl_add_class_name(zval *list, zend_class_entry * pce, int allow, int ce_flags TSRMLS_DC) { if (!allow || (allow > 0 && pce->ce_flags & ce_flags) || (allow < 0 && !(pce->ce_flags & ce_flags))) { - size_t len = strlen(pce->name); + size_t len = pce->name_length; zval *tmp; if (zend_hash_find(Z_ARRVAL_P(list), pce->name, len+1, (void*)&tmp) == FAILURE) { MAKE_STD_ZVAL(tmp); - ZVAL_STRING(tmp, pce->name, 1); + ZVAL_STRINGL(tmp, pce->name, pce->name_length, 1); zend_hash_add(Z_ARRVAL_P(list), pce->name, len+1, &tmp, sizeof(zval *), NULL); } } @@ -129,10 +126,8 @@ void spl_add_interfaces(zval *list, zend_class_entry * pce, int allow, int ce_fl /* }}} */ /* {{{ spl_add_classes */ -int spl_add_classes(zend_class_entry ** ppce, zval *list, int sub, int allow, int ce_flags TSRMLS_DC) +int spl_add_classes(zend_class_entry *pce, zval *list, int sub, int allow, int ce_flags TSRMLS_DC) { - zend_class_entry *pce = *ppce; - if (!pce) { return 0; } @@ -141,13 +136,23 @@ int spl_add_classes(zend_class_entry ** ppce, zval *list, int sub, int allow, in spl_add_interfaces(list, pce, allow, ce_flags TSRMLS_CC); while (pce->parent) { pce = pce->parent; - spl_add_classes(&pce, list, sub, allow, ce_flags TSRMLS_CC); + spl_add_classes(pce, list, sub, allow, ce_flags TSRMLS_CC); } } return 0; } /* }}} */ +char * spl_gen_private_prop_name(zend_class_entry *ce, char *prop_name, int prop_len, int *name_len TSRMLS_DC) /* {{{ */ +{ + char *rv; + + zend_mangle_property_name(&rv, name_len, ce->name, ce->name_length, prop_name, prop_len, 0); + + return rv; +} +/* }}} */ + /* * Local variables: * tab-width: 4 diff --git a/ext/spl/spl_functions.h b/ext/spl/spl_functions.h index 0db207b754..5eab7f9f7c 100755 --- a/ext/spl/spl_functions.h +++ b/ext/spl/spl_functions.h @@ -73,7 +73,10 @@ void spl_register_property( zend_class_entry * class_entry, char *prop_name, int */ void spl_add_class_name(zval * list, zend_class_entry * pce, int allow, int ce_flags TSRMLS_DC); void spl_add_interfaces(zval * list, zend_class_entry * pce, int allow, int ce_flags TSRMLS_DC); -int spl_add_classes(zend_class_entry ** ppce, zval *list, int sub, int allow, int ce_flags TSRMLS_DC); +int spl_add_classes(zend_class_entry *pce, zval *list, int sub, int allow, int ce_flags TSRMLS_DC); + +/* caller must efree(return) */ +char * spl_gen_private_prop_name(zend_class_entry *ce, char *prop_name, int prop_len, int *name_len TSRMLS_DC); #define SPL_ME(class_name, function_name, arg_info, flags) \ PHP_ME( spl_ ## class_name, function_name, arg_info, flags) diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index 58bf8144f6..d806642132 100755 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -517,10 +517,16 @@ SPL_METHOD(RecursiveIteratorIterator, key) char *str_key; uint str_key_len; ulong int_key; - if (iterator->funcs->get_current_key(iterator, &str_key, &str_key_len, &int_key TSRMLS_CC) == HASH_KEY_IS_LONG) { - RETURN_LONG(int_key); - } else { - RETURN_STRINGL(str_key, str_key_len-1, 0); + + switch (iterator->funcs->get_current_key(iterator, &str_key, &str_key_len, &int_key TSRMLS_CC)) { + case HASH_KEY_IS_LONG: + RETURN_LONG(int_key); + break; + case HASH_KEY_IS_STRING: + RETURN_STRINGL(str_key, str_key_len-1, 0); + break; + default: + RETURN_NULL(); } } else { RETURN_NULL(); @@ -1126,7 +1132,7 @@ static inline int spl_dual_it_fetch(spl_dual_it_object *intern, int check_more T intern->inner.iterator->funcs->get_current_data(intern->inner.iterator, &data TSRMLS_CC); if (data && *data) { intern->current.data = *data; - Z_ADDREF_P(intern->current.data); + Z_ADDREF_P(intern->current.data); } if (intern->inner.iterator->funcs->get_current_key) { intern->current.key_type = intern->inner.iterator->funcs->get_current_key(intern->inner.iterator, &intern->current.str_key, &intern->current.str_key_len, &intern->current.int_key TSRMLS_CC); @@ -2364,10 +2370,15 @@ SPL_METHOD(NoRewindIterator, key) char *str_key; uint str_key_len; ulong int_key; - if (intern->inner.iterator->funcs->get_current_key(intern->inner.iterator, &str_key, &str_key_len, &int_key TSRMLS_CC) == HASH_KEY_IS_LONG) { - RETURN_LONG(int_key); - } else { - RETURN_STRINGL(str_key, str_key_len-1, 0); + switch (intern->inner.iterator->funcs->get_current_key(intern->inner.iterator, &str_key, &str_key_len, &int_key TSRMLS_CC)) { + case HASH_KEY_IS_LONG: + RETURN_LONG(int_key); + break; + case HASH_KEY_IS_STRING: + RETURN_STRINGL(str_key, str_key_len-1, 0); + break; + default: + RETURN_NULL(); } } else { RETURN_NULL(); diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c index eeaac42bb8..f96e42b7e4 100755 --- a/ext/spl/spl_observer.c +++ b/ext/spl/spl_observer.c @@ -116,6 +116,43 @@ static zend_object_value spl_object_storage_new_ex(zend_class_entry *class_type, } /* }}} */ +static HashTable* spl_object_storage_debug_info(zval *obj, int *is_temp TSRMLS_DC) /* {{{ */ +{ + spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(obj TSRMLS_CC); + HashTable *rv, *props; + HashPosition pos; + zval *tmp, *storage, **entry; + char md5str[33]; + int name_len; + char *zname; + + *is_temp = 1; + + props = Z_OBJPROP_P(obj); + ALLOC_HASHTABLE(rv); + ZEND_INIT_SYMTABLE_EX(rv, zend_hash_num_elements(props) + 1, 0); + + zend_hash_copy(rv, props, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + + MAKE_STD_ZVAL(storage); + array_init(storage); + + zend_hash_internal_pointer_reset_ex(&intern->storage, &pos); + while (zend_hash_get_current_data_ex(&intern->storage, (void **)&entry, &pos) == SUCCESS) { + php_spl_object_hash(*entry, md5str TSRMLS_CC); + zval_add_ref(entry); + add_assoc_zval_ex(storage, md5str, 33, *entry); + zend_hash_move_forward_ex(&intern->storage, &pos); + } + + zname = spl_gen_private_prop_name(spl_ce_SplObjectStorage, "storage", sizeof("storage")-1, &name_len TSRMLS_CC); + zend_symtable_update(rv, zname, name_len+1, &storage, sizeof(zval *), NULL); + efree(zname); + + return rv; +} +/* }}} */ + /* {{{ spl_array_object_new */ static zend_object_value spl_SplObjectStorage_new(zend_class_entry *class_type TSRMLS_DC) { @@ -437,6 +474,7 @@ PHP_MINIT_FUNCTION(spl_observer) REGISTER_SPL_STD_CLASS_EX(SplObjectStorage, spl_SplObjectStorage_new, spl_funcs_SplObjectStorage); memcpy(&spl_handler_SplObjectStorage, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + spl_handler_SplObjectStorage.get_debug_info = spl_object_storage_debug_info; REGISTER_SPL_IMPLEMENTS(SplObjectStorage, Countable); REGISTER_SPL_IMPLEMENTS(SplObjectStorage, Iterator); |