diff options
| author | Mark A. Hershberger <mah@debian.(none)> | 2009-03-25 00:37:27 -0400 |
|---|---|---|
| committer | Mark A. Hershberger <mah@debian.(none)> | 2009-03-25 00:37:27 -0400 |
| commit | 2d4e5b09576bb4f0ba716cc82cdf29ea04d9184b (patch) | |
| tree | 41ccc042009cba53e4ce43e727fcba4c1cfbf7f3 /ext/spl | |
| parent | d29a4fd2dd3b5d4cf6e80b602544d7b71d794e76 (diff) | |
| download | php-2d4e5b09576bb4f0ba716cc82cdf29ea04d9184b.tar.gz | |
Imported Upstream version 5.2.2upstream/5.2.2
Diffstat (limited to 'ext/spl')
45 files changed, 1304 insertions, 227 deletions
diff --git a/ext/spl/config.m4 b/ext/spl/config.m4 index 30f4f7806..0de013dc6 100755 --- a/ext/spl/config.m4 +++ b/ext/spl/config.m4 @@ -1,4 +1,4 @@ -dnl $Id: config.m4,v 1.13.2.4.2.1 2006/08/23 09:47:21 tony2001 Exp $ +dnl $Id: config.m4,v 1.13.2.4.2.3 2006/12/04 18:01:53 tony2001 Exp $ dnl config.m4 for extension SPL PHP_ARG_ENABLE(spl, enable SPL suppport, @@ -27,4 +27,6 @@ int main(int argc, char **argv) { AC_DEFINE_UNQUOTED(HAVE_PACKED_OBJECT_VALUE, $ac_result, [Whether struct _zend_object_value is packed]) AC_DEFINE(HAVE_SPL, 1, [Whether you want SPL (Standard PHP Library) support]) PHP_NEW_EXTENSION(spl, php_spl.c spl_functions.c spl_engine.c spl_iterators.c spl_array.c spl_directory.c spl_sxe.c spl_exceptions.c spl_observer.c, no) + PHP_INSTALL_HEADERS([ext/spl], [php_spl.h spl_array.h spl_directory.h spl_engine.h spl_exceptions.h spl_functions.h spl_iterators.h spl_observer.h spl_sxe.h]) + PHP_ADD_EXTENSION_DEP(spl, pcre, true) fi diff --git a/ext/spl/examples/callbackfilteriterator.inc b/ext/spl/examples/callbackfilteriterator.inc new file mode 100755 index 000000000..51757012e --- /dev/null +++ b/ext/spl/examples/callbackfilteriterator.inc @@ -0,0 +1,122 @@ +<?php + +/** @file callbackfilteriterator.inc + * @ingroup Examples + * @brief class CallbackFilterIterator + * @author Marcus Boerger + * @author Kevin McArthur + * @date 2006 - 2006 + * + * SPL - Standard PHP Library + */ + +/** @ingroup Examples + * @brief A non abstract FiletrIterator that uses a callback foreach element + * @author Marcus Boerger + * @author Kevin McArthur + * @version 1.0 + */ +class CallbackFilterIterator extends FilterIterator +{ + const USE_FALSE = 0; /**< mode: accept no elements, no callback */ + const USE_TRUE = 1; /**< mode: accept all elements, no callback */ + const USE_VALUE = 2; /**< mode: pass value to callback */ + const USE_KEY = 3; /**< mode: pass key to callback */ + const USE_BOTH = 4; /**< mode: pass value and key to callback */ + + const REPLACE = 0x00000001; /**< flag: pass key/value by reference */ + + private $callback; /**< callback to use */ + private $mode; /**< mode any of USE_VALUE, USE_KEY, USE_BOTH */ + private $flags; /**< flags (REPLACE) */ + private $key; /**< key value */ + private $current; /**< current value */ + + /** Construct a CallbackFilterIterator + * + * @param it inner iterator (iterator to filter) + * @param callback callback function + * @param mode any of USE_VALUE, USE_KEY, USE_BOTH + * @param flags any of 0, REPLACE + */ + public function __construct(Iterator $it, $callback, $mode = self::USE_VALUE, $flags = 0) + { + parent::__construct($it); + $this->callback = $callback; + $this->mode = $mode; + $this->flags = $flags; + } + + /** Call the filter callback + * @return result of filter callback + */ + public function accept() + { + $this->key = parent::key(); + $this->current = parent::current(); + + switch($this->mode) { + default: + case self::USE_FALSE; + return false; + case self::USE_TRUE: + return true; + case self::USE_VALUE: + if($this->flags & self::REPLACE) { + return (bool) call_user_func($this->callback, &$this->current); + } else { + return (bool) call_user_func($this->callback, $this->current); + } + case self::USE_KEY: + if($this->flags & self::REPLACE) { + return (bool) call_user_func($this->callback, &$this->key); + } else { + return (bool) call_user_func($this->callback, $this->key); + } + case SELF::USE_BOTH: + if($this->flags & self::REPLACE) { + return (bool) call_user_func($this->callback, &$this->key, &$this->current); + } else { + return (bool) call_user_func($this->callback, $this->key, $this->current); + } + } + } + + /** @return current key value */ + function key() + { + return $this->key; + } + + /** @return current value */ + function current() + { + return $this->current; + } + + /** @return operation mode */ + function getMode() + { + return $this->mode; + } + + /** @param $mode set new mode, @see mode */ + function setMode($mode) + { + $this->mode = $mode; + } + + /** @return operation flags */ + function getFlags() + { + return $this->flags; + } + + /** @param $flags set new flags, @see flags */ + function setFlags($flags) + { + $this->flags = $flags; + } +} + +?>
\ No newline at end of file diff --git a/ext/spl/examples/directoryfilterdots.inc b/ext/spl/examples/directoryfilterdots.inc index 740c2303c..aa4b6ddd6 100755 --- a/ext/spl/examples/directoryfilterdots.inc +++ b/ext/spl/examples/directoryfilterdots.inc @@ -4,7 +4,7 @@ * @ingroup Examples
* @brief class DirectoryFilterDots
* @author Marcus Boerger
- * @date 2003 - 2005
+ * @date 2003 - 2006
*
* SPL - Standard PHP Library
*/
@@ -12,9 +12,9 @@ /** @ingroup Examples
* @brief A filtered DirectoryIterator
* @author Marcus Boerger
- * @version 1.1
+ * @version 1.2
*
- * This Iteraotr takes a pathname from which it creates a DirectoryIterator
+ * This Iterator takes a pathname from which it creates a RecursiveDirectoryIterator
* and makes it recursive. Further more it filters the entries '.' and '..'.
*/
class DirectoryFilterDots extends RecursiveFilterIterator
@@ -24,7 +24,7 @@ class DirectoryFilterDots extends RecursiveFilterIterator */
function __construct($path)
{
- parent::__construct(new DirectoryIterator($path));
+ parent::__construct(new RecursiveDirectoryIterator($path));
}
/** @return whether the current entry is neither '.' nor '..'
@@ -42,4 +42,4 @@ class DirectoryFilterDots extends RecursiveFilterIterator }
}
-?>
\ No newline at end of file +?>
diff --git a/ext/spl/examples/dualiterator.inc b/ext/spl/examples/dualiterator.inc index 544034856..9d14328d7 100755 --- a/ext/spl/examples/dualiterator.inc +++ b/ext/spl/examples/dualiterator.inc @@ -12,7 +12,7 @@ /** @ingroup Examples * @brief Synchronous iteration over two iterators * @author Marcus Boerger - * @version 1.1 + * @version 1.3 */ class DualIterator implements Iterator { @@ -174,6 +174,7 @@ class DualIterator implements Iterator { $it = new RecursiveDualIterator($lhs, $rhs, self::CURRENT_0 | self::KEY_0); + $it = new RecursiveCompareDualIterator($it); } else { @@ -187,7 +188,7 @@ class DualIterator implements Iterator if ($identical) { - foreach(new RecursiveIteratorIterator($it) as $n) + foreach($it as $n) { if (!$it->areIdentical()) { diff --git a/ext/spl/examples/phar_from_dir.php b/ext/spl/examples/phar_from_dir.php new file mode 100755 index 000000000..2ee15ca1e --- /dev/null +++ b/ext/spl/examples/phar_from_dir.php @@ -0,0 +1,50 @@ +<?php + +/** @file phar_from_dir.php + * @brief Create phar archive from directory + * @ingroup examples + * @author Marcus Boerger + * @date 2003 - 2007 + * @version 1.0 + * + * Usage: php phar_create_from_dir.php \<archive\> \<directory\> [\<regex\>] + * + * Create phar archive \<archive\> using entries from \<directory\> that + * optionally match \<regex\>. + */ + +if ($argc < 3) +{ + echo <<<EOF +php phar_from_dir.php archive directory [regex] + +Packs files in a given directory into a phar archive. + +archive name of the archive to create +directory input directory to pack +regex optional expression to match files in directory + +EOF; + exit(1); +} + +$phar = new Phar($argv[1], 0, 'newphar'); + +$dir = new RecursiveDirectoryIterator($argv[2]); +$dir = new RecursiveIteratorIterator($dir); +if ($argc > 3) +{ + $dir = new RegexIterator($dir, '/'.$argv[3].'/'); +} + +$phar->begin(); + +foreach($dir as $file) +{ + echo "$file\n"; + copy($file, "phar://newphar/$file"); +} + +$phar->commit(); + +?>
\ No newline at end of file diff --git a/ext/spl/examples/recursivecomparedualiterator.inc b/ext/spl/examples/recursivecomparedualiterator.inc new file mode 100755 index 000000000..75265c1d5 --- /dev/null +++ b/ext/spl/examples/recursivecomparedualiterator.inc @@ -0,0 +1,69 @@ +<?php + +/** @file recursivecomparedualiterator.inc + * @ingroup Examples + * @brief class DualIterator + * @author Marcus Boerger + * @date 2003 - 2006 + * + * SPL - Standard PHP Library + */ + +/** @ingroup Examples + * @brief Recursive comparison iterator for a RecursiveDualIterator + * @author Marcus Boerger + * @version 1.0 + */ +class RecursiveCompareDualIterator extends RecursiveIteratorIterator +{ + /** Used to keep end of recursion equality. That is en leaving a nesting + * level we need to check whether both child iterators are at their end. + */ + protected $equal = false; + + /** Construct from RecursiveDualIterator + * + * @param $it RecursiveDualIterator + * @param $mode should be LEAVES_ONLY + * @param $flags should be 0 + */ + function __construct(RecursiveDualIterator $it, $mode = self::LEAVES_ONLY, $flags = 0) + { + parent::__construct($it); + } + + /** Rewind iteration andcomparison process. Starting with $equal = true. + */ + function rewind() + { + $this->equal = true; + parent::rewind(); + } + + /** Calculate $equal + * @see $equal + */ + function endChildren() + { + $this->equal &= !$this->getInnerIterator()->getLHS()->valid() + && !$this->getInnerIterator()->getRHS()->valid(); + } + + /** @return whether both inner iterators are valid and have identical + * current and key values or both are non valid. + */ + function areIdentical() + { + return $this->equal && $this->getInnerIterator()->areIdentical(); + } + + /** @return whether both inner iterators are valid and have equal current + * and key values or both are non valid. + */ + function areEqual() + { + return $this->equal && $this->getInnerIterator()->areEqual(); + } +} + +?> diff --git a/ext/spl/examples/recursivedualiterator.inc b/ext/spl/examples/recursivedualiterator.inc index 702e0cd74..cfa3bccbb 100755 --- a/ext/spl/examples/recursivedualiterator.inc +++ b/ext/spl/examples/recursivedualiterator.inc @@ -18,7 +18,7 @@ class RecursiveDualIterator extends DualIterator implements RecursiveIterator { private $ref; - /** construct iterator from two iterators + /** construct iterator from two RecursiveIterator instances * * @param lhs Left Hand Side Iterator * @param rhs Right Hand Side Iterator diff --git a/ext/spl/examples/tests/dualiterator_001.phpt b/ext/spl/examples/tests/dualiterator_001.phpt index 5577c4dc1..9150d76ae 100755 --- a/ext/spl/examples/tests/dualiterator_001.phpt +++ b/ext/spl/examples/tests/dualiterator_001.phpt @@ -33,6 +33,7 @@ test(array(1,array(21,22),3), array(1,array(21,"22"),3), true); ?> ===DONE=== +<?php exit(0); ?> --EXPECT-- bool(true) bool(false) diff --git a/ext/spl/internal/parentiterator.inc b/ext/spl/internal/parentiterator.inc index 9e0ebfa25..84c760d62 100755 --- a/ext/spl/internal/parentiterator.inc +++ b/ext/spl/internal/parentiterator.inc @@ -4,7 +4,7 @@ * @ingroup SPL * @brief class FilterIterator * @author Marcus Boerger - * @date 2003 - 2005 + * @date 2003 - 2006 * * SPL - Standard PHP Library */ @@ -21,26 +21,12 @@ */
class ParentIterator extends RecursiveFilterIterator
{
- /** @param $it the RecursiveIterator to filter
- */
- function __construct(RecursiveIterator $it)
- {
- parent::__construct($it);
- }
-
/** @return whetehr the current element has children
*/
function accept()
{
return $this->it->hasChildren();
}
-
- /** @return the ParentIterator for the current elements children
- */
- function getChildren()
- {
- return new ParentIterator($this->it->getChildren());
- }
}
?>
\ No newline at end of file diff --git a/ext/spl/internal/recursiveiterator.inc b/ext/spl/internal/recursiveiterator.inc index 063fc905c..07ffad7d1 100755 --- a/ext/spl/internal/recursiveiterator.inc +++ b/ext/spl/internal/recursiveiterator.inc @@ -15,7 +15,7 @@ * @version 1.0
* @since PHP 5.0
*/
-interface RecursiveIterator implements Iterator
+interface RecursiveIterator extends Iterator
{
/** @return whether the current element has children
*/
diff --git a/ext/spl/internal/recursiveiteratoriterator.inc b/ext/spl/internal/recursiveiteratoriterator.inc index ba32e4ee9..8bb657317 100755 --- a/ext/spl/internal/recursiveiteratoriterator.inc +++ b/ext/spl/internal/recursiveiteratoriterator.inc @@ -217,7 +217,7 @@ class RecursiveIteratorIterator implements OuterIterator if ($after_move)
{
if (($this->mode == self::SELF_FIRST && $this->callHasChildren())
- $this->mode == self::LEAVES_ONLY)
+ || $this->mode == self::LEAVES_ONLY)
$this->nextElement();
}
else
@@ -229,7 +229,9 @@ class RecursiveIteratorIterator implements OuterIterator /** Called when the next element is available
*/
- function nextElement();
+ function nextElement()
+ {
+ }
}
?>
\ No newline at end of file diff --git a/ext/spl/internal/seekableiterator.inc b/ext/spl/internal/seekableiterator.inc index af66c60c3..5ab6b9b4d 100755 --- a/ext/spl/internal/seekableiterator.inc +++ b/ext/spl/internal/seekableiterator.inc @@ -18,7 +18,7 @@ * to seek on an iterator LimitIterator can use this to efficiently rewind
* to offset.
*/
-interface SeekableIterator implements Iterator
+interface SeekableIterator extends Iterator
{
/** Seek to an absolute position
*
diff --git a/ext/spl/internal/splfileobject.inc b/ext/spl/internal/splfileobject.inc index 5f746ea2d..b78c71889 100755 --- a/ext/spl/internal/splfileobject.inc +++ b/ext/spl/internal/splfileobject.inc @@ -50,14 +50,6 @@ class SplFileObject extends SplFileInfo implements RecursiveIterator, SeekableIt }
/**
- * @return the filename as specified in the constructor
- */
- function getFilename()
- {
- return $this->fname;
- }
-
- /**
* @return whether the end of the stream is reached
*/
function eof()
diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c index 7991e4c76..5de79d47d 100755 --- a/ext/spl/php_spl.c +++ b/ext/spl/php_spl.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_spl.c,v 1.52.2.28.2.6 2006/08/07 09:49:53 tony2001 Exp $ */ +/* $Id: php_spl.c,v 1.52.2.28.2.15 2007/04/06 16:00:08 helly Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -24,6 +24,7 @@ #include "php.h" #include "php_ini.h" +#include "php_main.h" #include "ext/standard/info.h" #include "php_spl.h" #include "spl_functions.h" @@ -55,8 +56,10 @@ zend_function_entry spl_functions_none[] = { */ static PHP_GINIT_FUNCTION(spl) { - spl_globals->autoload_extensions = NULL; - spl_globals->autoload_functions = NULL; + spl_globals->autoload_extensions = NULL; + spl_globals->autoload_extensions_len = 0; + spl_globals->autoload_functions = NULL; + spl_globals->autoload_running = 0; } /* }}} */ @@ -205,7 +208,7 @@ PHP_FUNCTION(spl_classes) } /* }}} */ -int spl_autoload(const char *class_name, const char * lc_name, int class_name_len, const char * file_extension TSRMLS_DC) /* {{{ */ +static int spl_autoload(const char *class_name, const char * lc_name, int class_name_len, const char * file_extension TSRMLS_DC) /* {{{ */ { char *class_file; int class_file_len; @@ -213,23 +216,11 @@ int spl_autoload(const char *class_name, const char * lc_name, int class_name_le zend_file_handle file_handle; zend_op_array *new_op_array; zval *result = NULL; - zval err_mode; int ret; class_file_len = spprintf(&class_file, 0, "%s%s", lc_name, file_extension); - ZVAL_LONG(&err_mode, EG(error_reporting)); - if (Z_LVAL(err_mode)) { - php_alter_ini_entry("error_reporting", sizeof("error_reporting"), "0", 1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME); - } - - ret = zend_stream_open(class_file, &file_handle TSRMLS_CC); - - if (!EG(error_reporting) && Z_LVAL(err_mode) != EG(error_reporting)) { - convert_to_string(&err_mode); - zend_alter_ini_entry("error_reporting", sizeof("error_reporting"), Z_STRVAL(err_mode), Z_STRLEN(err_mode), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME); - zendi_zval_dtor(err_mode); - } + ret = php_stream_open_for_zend_ex(class_file, &file_handle, ENFORCE_SAFE_MODE|USE_PATH|STREAM_OPEN_FOR_INCLUDE TSRMLS_CC); if (ret == SUCCESS) { if (!file_handle.opened_path) { @@ -268,8 +259,8 @@ int spl_autoload(const char *class_name, const char * lc_name, int class_name_le Default implementation for __autoload() */ PHP_FUNCTION(spl_autoload) { - char *class_name, *lc_name, *file_exts; - int class_name_len, file_exts_len, found = 0; + char *class_name, *lc_name, *file_exts = SPL_G(autoload_extensions); + int class_name_len, file_exts_len = SPL_G(autoload_extensions_len), found = 0; char *copy, *pos1, *pos2; zval **original_return_value = EG(return_value_ptr_ptr); zend_op **original_opline_ptr = EG(opline_ptr); @@ -280,7 +271,7 @@ PHP_FUNCTION(spl_autoload) RETURN_FALSE; } - copy = pos1 = estrdup(ZEND_NUM_ARGS() > 1 ? file_exts : SPL_G(autoload_extensions)); + copy = pos1 = estrndup(file_exts, file_exts_len); lc_name = zend_str_tolower_dup(class_name, class_name_len); while(pos1 && *pos1 && !EG(exception)) { EG(return_value_ptr_ptr) = original_return_value; @@ -305,8 +296,16 @@ PHP_FUNCTION(spl_autoload) EG(active_op_array) = original_active_op_array; EG(function_state_ptr) = original_function_state_ptr; - if (!found) { - zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Class %s could not be loaded", class_name); + if (!found && !SPL_G(autoload_running)) { + /* For internal errors, we generate E_ERROR, for direct calls an exception is thrown. + * The "scope" is determined by an opcode, if it is ZEND_FETCH_CLASS we know function was called indirectly by + * the Zend engine. + */ + if (active_opline->opcode != ZEND_FETCH_CLASS) { + zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Class %s could not be loaded", class_name); + } else { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s could not be loaded", class_name); + } } } /* }}} */ @@ -325,10 +324,11 @@ PHP_FUNCTION(spl_autoload_extensions) if (SPL_G(autoload_extensions)) { efree(SPL_G(autoload_extensions)); } - SPL_G(autoload_extensions) = estrdup(file_exts); + SPL_G(autoload_extensions) = estrndup(file_exts, file_exts_len); + SPL_G(autoload_extensions_len) = file_exts_len; } - RETURN_STRING(SPL_G(autoload_extensions), 1); + RETURN_STRINGL(SPL_G(autoload_extensions), SPL_G(autoload_extensions_len), 1); } /* }}} */ typedef struct { @@ -361,6 +361,8 @@ PHP_FUNCTION(spl_autoload_call) } if (SPL_G(autoload_functions)) { + int l_autoload_running = SPL_G(autoload_running); + SPL_G(autoload_running) = 1; class_name_len = Z_STRLEN_P(class_name); lc_name = zend_str_tolower_dup(Z_STRVAL_P(class_name), class_name_len); zend_hash_internal_pointer_reset_ex(SPL_G(autoload_functions), &function_pos); @@ -377,6 +379,7 @@ PHP_FUNCTION(spl_autoload_call) zend_hash_move_forward_ex(SPL_G(autoload_functions), &function_pos); } efree(lc_name); + SPL_G(autoload_running) = l_autoload_running; } else { /* do not use or overwrite &EG(autoload_func) here */ zend_call_method_with_1_params(NULL, NULL, NULL, "spl_autoload", NULL, class_name); @@ -441,10 +444,19 @@ PHP_FUNCTION(spl_autoload_register) } } - lc_name = do_alloca(func_name_len + 1); + lc_name = safe_emalloc(func_name_len, 1, sizeof(long) + 1); zend_str_tolower_copy(lc_name, func_name, func_name_len); efree(func_name); + + if (SPL_G(autoload_functions) && zend_hash_exists(SPL_G(autoload_functions), (char*)lc_name, func_name_len+1)) { + goto skip; + } + if (obj_ptr && !(alfi.func_ptr->common.fn_flags & ZEND_ACC_STATIC)) { + /* add object id to the hash to ensure uniqueness, for more reference look at bug #40091 */ + memcpy(lc_name + func_name_len, &Z_OBJ_HANDLE_PP(obj_ptr), sizeof(zend_object_handle)); + func_name_len += sizeof(zend_object_handle); + lc_name[func_name_len] = '\0'; alfi.obj = *obj_ptr; alfi.obj->refcount++; } else { @@ -468,8 +480,8 @@ PHP_FUNCTION(spl_autoload_register) } zend_hash_add(SPL_G(autoload_functions), lc_name, func_name_len+1, &alfi.func_ptr, sizeof(autoload_func_info), NULL); - - free_alloca(lc_name); +skip: + efree(lc_name); } if (SPL_G(autoload_functions)) { @@ -489,12 +501,13 @@ PHP_FUNCTION(spl_autoload_unregister) zval *zcallable; int success = FAILURE; zend_function *spl_func_ptr; + zval **obj_ptr; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zcallable) == FAILURE) { return; } - if (!zend_is_callable_ex(zcallable, IS_CALLABLE_CHECK_SYNTAX_ONLY, &func_name, &func_name_len, NULL, NULL, NULL TSRMLS_CC)) { + if (!zend_is_callable_ex(zcallable, IS_CALLABLE_CHECK_SYNTAX_ONLY, &func_name, &func_name_len, NULL, NULL, &obj_ptr TSRMLS_CC)) { if (func_name) { efree(func_name); } @@ -514,6 +527,13 @@ PHP_FUNCTION(spl_autoload_unregister) } else { /* remove specific */ success = zend_hash_del(SPL_G(autoload_functions), func_name, func_name_len+1); + if (success != SUCCESS && obj_ptr) { + func_name = erealloc(func_name, func_name_len + 1 + sizeof(zend_object_handle)); + memcpy(func_name + func_name_len, &Z_OBJ_HANDLE_PP(obj_ptr), sizeof(zend_object_handle)); + func_name_len += sizeof(zend_object_handle); + func_name[func_name_len] = '\0'; + success = zend_hash_del(SPL_G(autoload_functions), func_name, func_name_len+1); + } } } else if (func_name_len == sizeof("spl_autoload")-1 && !strcmp(func_name, "spl_autoload")) { /* register single spl_autoload() */ @@ -641,6 +661,12 @@ PHP_MINFO_FUNCTION(spl) /* }}} */ static +ZEND_BEGIN_ARG_INFO_EX(arginfo_iterator_to_array, 0, 0, 1) + ZEND_ARG_OBJ_INFO(0, iterator, Traversable, 0) + ZEND_ARG_INFO(0, use_keys) +ZEND_END_ARG_INFO(); + +static ZEND_BEGIN_ARG_INFO(arginfo_iterator, 0) ZEND_ARG_OBJ_INFO(0, iterator, Traversable, 0) ZEND_END_ARG_INFO(); @@ -666,7 +692,7 @@ zend_function_entry spl_functions[] = { PHP_FE(class_implements, NULL) PHP_FE(spl_object_hash, NULL) #ifdef SPL_ITERATORS_H - PHP_FE(iterator_to_array, arginfo_iterator) + PHP_FE(iterator_to_array, arginfo_iterator_to_array) PHP_FE(iterator_count, arginfo_iterator) PHP_FE(iterator_apply, arginfo_iterator_apply) #endif /* SPL_ITERATORS_H */ @@ -692,6 +718,7 @@ PHP_MINIT_FUNCTION(spl) PHP_RINIT_FUNCTION(spl) /* {{{ */ { SPL_G(autoload_extensions) = estrndup(".inc,.php", sizeof(".inc,.php")-1); + SPL_G(autoload_extensions_len) = sizeof(".inc,.php")-1; SPL_G(autoload_functions) = NULL; return SUCCESS; } /* }}} */ @@ -701,6 +728,7 @@ PHP_RSHUTDOWN_FUNCTION(spl) /* {{{ */ if (SPL_G(autoload_extensions)) { efree(SPL_G(autoload_extensions)); SPL_G(autoload_extensions) = NULL; + SPL_G(autoload_extensions_len) = 0; } if (SPL_G(autoload_functions)) { zend_hash_destroy(SPL_G(autoload_functions)); diff --git a/ext/spl/php_spl.h b/ext/spl/php_spl.h index 4e8c9b3f7..7c44f5855 100755 --- a/ext/spl/php_spl.h +++ b/ext/spl/php_spl.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -58,6 +58,8 @@ PHP_MINFO_FUNCTION(spl); ZEND_BEGIN_MODULE_GLOBALS(spl) char * autoload_extensions; HashTable * autoload_functions; + int autoload_running; + int autoload_extensions_len; ZEND_END_MODULE_GLOBALS(spl) #ifdef ZTS diff --git a/ext/spl/spl.php b/ext/spl/spl.php index 2987024f2..bb6af7e05 100755 --- a/ext/spl/spl.php +++ b/ext/spl/spl.php @@ -6,7 +6,7 @@ * * SPL - Standard PHP Library * - * (c) Marcus Boerger, 2003 - 2006 + * (c) Marcus Boerger, 2003 - 2007 */ /** @mainpage SPL - Standard PHP Library @@ -32,12 +32,12 @@ * * SPL offers some advanced iterator algorithms: * - * - interface RecursiveIterator implements Iterator + * - interface RecursiveIterator extends Iterator * - interface OuterIterator extends Iterator * - class RecursiveIteratorIterator implements OuterIterator * - abstract class FilterIterator implements OuterIterator * - class ParentIterator extends FilterIterator implements RecursiveIterator - * - interface SeekableIterator implements Iterator + * - interface SeekableIterator extends Iterator * - class LimitIterator implements OuterIterator * - class CachingIterator implements OuterIterator * - class RecursiveCachingIterator extends CachingIterator implements RecursiveIterator @@ -118,20 +118,23 @@ * - <a href="http://www.phpriot.com/d/articles/php/oop/oop-with-spl-php-5-1/index.html">Advanced OOP with SPL in PHP 5</a> * - <a href="http://www.devshed.com/c/a/PHP/The-Standard-PHP-Library-Part-1/">The Standard PHP Library, Part 1</a> * - <a href="http://www.devshed.com/c/a/PHP/The-Standard-PHP-Library-Part-2/">The Standard PHP Library, Part 2</a> - * - <a href="http://www.wiki.cc/php/SPL">SPL on PHP Wiki</a> * - <a href="http://www.professionelle-softwareentwicklung-mit-php5.de/erste_auflage/oop.iterators.spl.html">Die Standard PHP Library (SPL) [german]</a> * * 10) Talks on SPL: - * - SPL for the masses <a href="http://somabo.de/talks/200504_php_quebec_spl_for_the_masses.pps">[pps]</a>, <a href="http://somabo.de/talks/200504_php_quebec_spl_for_the_masses.pdf">[pdf]</a> - * - From engine overloading to SPL <a href="http://somabo.de/talks/200505_cancun_from_engine_overloading_to_spl.pps">[pps]</a>, <a href="http://somabo.de/talks/200505_cancun_from_engine_overloading_to_spl.pdf">[pdf]</a> - * - Happy SPLing <a href="http://somabo.de/talks/200509_toronto_happy_spling.pps">[pps]</a>, <a href="http://somabo.de/talks/200509_toronto_happy_spling.pdf">[pdf]</a> - * - Debug session 1 <a href="http://somabo.de/talks/200509_toronto_iterator_debug_session_1.pps">[pps]</a>, <a href="http://somabo.de/talks/200509_toronto_iterator_debug_session_1.pdf">[pdf]</a> - * - Debug session 2 <a href="http://somabo.de/talks/200509_toronto_iterator_debug_session_2.pps">[pps]</a>, <a href="http://somabo.de/talks/200509_toronto_iterator_debug_session_2.pdf">[pdf]</a> + * - SPL Update <a href="http://talks.somabo.de/200702_vancouver_spl_update.pps">[pps]</a>, <a href="http://talks.somabo.de/200702_vancouver_spl_update.pdf">[pdf]</a> + * - Happy SPLing <a href="http://talks.somabo.de/200509_toronto_happy_spling.pps">[pps]</a>, <a href="http://talks.somabo.de/200509_toronto_happy_spling.pdf">[pdf]</a> + * - From engine overloading to SPL <a href="http://talks.somabo.de/200505_cancun_from_engine_overloading_to_spl.pps">[pps]</a>, <a href="http://talks.somabo.de/200505_cancun_from_engine_overloading_to_spl.pdf">[pdf]</a> + * - SPL for the masses <a href="http://talks.somabo.de/200504_php_quebec_spl_for_the_masses.pps">[pps]</a>, <a href="http://talks.somabo.de/200504_php_quebec_spl_for_the_masses.pdf">[pdf]</a> + * + * 11) Debug sessions: + * - Debug session 1 <a href="200407_oscon_introduction_to_iterators_debug.pps">[pps]</a>, <a href="200407_oscon_introduction_to_iterators_debug.pdf">[pdf]</a> + * - Debug session 2 <a href="http://talks.somabo.de/200509_toronto_iterator_debug_session_1.pps">[pps]</a>, <a href="http://talks.somabo.de/200509_toronto_iterator_debug_session_1.pdf">[pdf]</a>, <a href="http://taks.somabo.de/200411_php_conference_frankfrurt_iterator_debug_session.swf">[swf]</a> + * - Debug session 3 <a href="http://talks.somabo.de/200509_toronto_iterator_debug_session_2.pps">[pps]</a>, <a href="http://talks.somabo.de/200509_toronto_iterator_debug_session_2.pdf">[pdf]</a> * * You can download this documentation as a chm file * <a href="http://php.net/~helly/php/ext/spl/spl.chm">here</a>. * - * (c) Marcus Boerger, 2003 - 2006 + * (c) Marcus Boerger, 2003 - 2007 */ /** @defgroup ZendEngine Zend engine classes @@ -229,9 +232,10 @@ function iterator_count(Traversable $it) {/**/}; * @since PHP 5.1 * * @param it iterator to copy + * @param use_keys whether touse the keys * @return array with elements copied from the iterator */ -function iterator_to_array(Traversable $it) {/**/}; +function iterator_to_array(Traversable $it, $use_keys = true) {/**/}; /** @ingroup ZendEngine * @brief Basic Exception class. @@ -899,7 +903,7 @@ class SplFileInfo */ function getCTime() {/**/} - /** @return The current entry's size in bytes . + /** @return The current entry's file type. */ function getType() {/**/} @@ -927,6 +931,14 @@ class SplFileInfo */ function isLink() {/**/} + /** @return target of link. + */ + function getLinkTarget() {/**/} + + /** @return The resolved path + */ + function getRealPath() {/**/} + /** @return getPathname() */ function __toString() {/**/} diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index d025f3ffd..8079088d8 100755 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_array.c,v 1.71.2.17.2.4 2006/10/20 02:11:19 pollita Exp $ */ +/* $Id: spl_array.c,v 1.71.2.17.2.11 2007/04/06 17:57:10 helly Exp $ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -42,8 +42,6 @@ zend_object_handlers spl_handler_ArrayIterator; PHPAPI zend_class_entry *spl_ce_ArrayIterator; PHPAPI zend_class_entry *spl_ce_RecursiveArrayIterator; -PHPAPI zend_class_entry *spl_ce_Countable; - #define SPL_ARRAY_STD_PROP_LIST 0x00000001 #define SPL_ARRAY_ARRAY_AS_PROPS 0x00000002 #define SPL_ARRAY_OVERLOADED_REWIND 0x00010000 @@ -458,7 +456,7 @@ static int spl_array_has_dimension_ex(int check_inherited, zval *object, zval *o { spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC); long index; - zval *rv; + zval *rv, **tmp; if (check_inherited && intern->fptr_offset_has) { SEPARATE_ARG_IF_REF(offset); @@ -476,7 +474,14 @@ static int spl_array_has_dimension_ex(int check_inherited, zval *object, zval *o switch(Z_TYPE_P(offset)) { case IS_STRING: - return zend_symtable_exists(spl_array_get_hash_table(intern, 0 TSRMLS_CC), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); + if (check_empty) { + if (zend_symtable_find(spl_array_get_hash_table(intern, 0 TSRMLS_CC), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void **) &tmp) != FAILURE && zend_is_true(*tmp)) { + return 1; + } + return 0; + } else { + return zend_symtable_exists(spl_array_get_hash_table(intern, 0 TSRMLS_CC), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); + } case IS_DOUBLE: case IS_RESOURCE: case IS_BOOL: @@ -486,7 +491,15 @@ static int spl_array_has_dimension_ex(int check_inherited, zval *object, zval *o } else { index = Z_LVAL_P(offset); } - return zend_hash_index_exists(spl_array_get_hash_table(intern, 0 TSRMLS_CC), index); + if (check_empty) { + HashTable *ht = spl_array_get_hash_table(intern, 0 TSRMLS_CC); + if (zend_hash_index_find(ht, index, (void **)&tmp) != FAILURE && zend_is_true(*tmp)) { + return 1; + } + return 0; + } else { + return zend_hash_index_exists(spl_array_get_hash_table(intern, 0 TSRMLS_CC), index); + } default: zend_error(E_WARNING, "Illegal offset type"); } @@ -507,7 +520,7 @@ SPL_METHOD(Array, offsetExists) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &index) == FAILURE) { return; } - RETURN_BOOL(spl_array_has_dimension_ex(0, getThis(), index, 1 TSRMLS_CC)); + RETURN_BOOL(spl_array_has_dimension_ex(0, getThis(), index, 0 TSRMLS_CC)); } /* }}} */ /* {{{ proto mixed ArrayObject::offsetGet(mixed $index) @@ -1022,7 +1035,7 @@ SPL_METHOD(Array, exchangeArray) zend_hash_copy(HASH_OF(return_value), spl_array_get_hash_table(intern, 0 TSRMLS_CC), (copy_ctor_func_t) zval_add_ref, &tmp, sizeof(zval*)); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &array) == FAILURE) { - WRONG_PARAM_COUNT; + return; } if (Z_TYPE_PP(array) == IS_OBJECT && intern == (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC)) { zval_ptr_dtor(&intern->array); @@ -1477,11 +1490,6 @@ static zend_function_entry spl_funcs_RecursiveArrayIterator[] = { {NULL, NULL, NULL} }; -static zend_function_entry spl_funcs_Countable[] = { - SPL_ABSTRACT_ME(Countable, count, NULL) - {NULL, NULL, NULL} -}; - /* {{{ PHP_MINIT_FUNCTION(spl_array) */ PHP_MINIT_FUNCTION(spl_array) { @@ -1515,8 +1523,6 @@ PHP_MINIT_FUNCTION(spl_array) REGISTER_SPL_IMPLEMENTS(RecursiveArrayIterator, RecursiveIterator); spl_ce_RecursiveArrayIterator->get_iterator = spl_array_get_iterator; - REGISTER_SPL_INTERFACE(Countable); - REGISTER_SPL_IMPLEMENTS(ArrayObject, Countable); REGISTER_SPL_IMPLEMENTS(ArrayIterator, Countable); diff --git a/ext/spl/spl_array.h b/ext/spl/spl_array.h index 2e8519557..0dc6d0073 100755 --- a/ext/spl/spl_array.h +++ b/ext/spl/spl_array.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -16,18 +16,18 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_array.h,v 1.13.2.2.2.1 2006/05/10 00:03:38 helly Exp $ */ +/* $Id: spl_array.h,v 1.13.2.2.2.4 2007/02/08 22:54:34 helly Exp $ */ #ifndef SPL_ARRAY_H #define SPL_ARRAY_H #include "php.h" #include "php_spl.h" +#include "spl_iterators.h" extern PHPAPI zend_class_entry *spl_ce_ArrayObject; extern PHPAPI zend_class_entry *spl_ce_ArrayIterator; extern PHPAPI zend_class_entry *spl_ce_RecursiveArrayIterator; -extern PHPAPI zend_class_entry *spl_ce_Countable; PHP_MINIT_FUNCTION(spl_array); diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index a5b9a11cf..3d8fe6dc2 100755 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_directory.c,v 1.45.2.27.2.8 2006/09/29 13:11:28 bjori Exp $ */ +/* $Id: spl_directory.c,v 1.45.2.27.2.20 2007/04/09 15:34:55 dmitry Exp $ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -319,14 +319,23 @@ static spl_filesystem_object * spl_filesystem_object_create_info(spl_filesystem_ { spl_filesystem_object *intern; zval *arg1; - + if (!file_path || !file_path_len) { +#if defined(PHP_WIN32) zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot create SplFileInfo for empty path"); if (file_path && !use_copy) { efree(file_path); } return NULL; +#else + if (file_path && !use_copy) { + efree(file_path); + } + use_copy = 1; + file_path_len = 1; + file_path = "/"; +#endif } php_set_error_handling(EH_THROW, spl_ce_RuntimeException TSRMLS_CC); @@ -406,6 +415,8 @@ static spl_filesystem_object * spl_filesystem_object_create_type(int ht, spl_fil } else { intern->file_name = source->file_name; intern->file_name_len = source->file_name_len; + intern->path = estrndup(source->path, source->path_len); + intern->path_len = source->path_len; intern->u.file.open_mode = "r"; intern->u.file.open_mode_len = 1; @@ -437,6 +448,18 @@ static spl_filesystem_object * spl_filesystem_object_create_type(int ht, spl_fil return NULL; } /* }}} */ +static inline int spl_filesystem_is_dot(const char * d_name) /* {{{ */ +{ + return !strcmp(d_name, ".") || !strcmp(d_name, ".."); +} +/* }}} */ + +static int spl_filesystem_is_invalid_or_dot(const char * d_name) /* {{{ */ +{ + return d_name[0] == '\0' || spl_filesystem_is_dot(d_name); +} +/* }}} */ + /* {{{ proto void DirectoryIterator::__construct(string path) Cronstructs a new dir iterator from a path. */ SPL_METHOD(DirectoryIterator, __construct) @@ -548,7 +571,7 @@ SPL_METHOD(SplFileInfo, getFilename) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - if (intern->path_len) { + if (intern->path_len && intern->path_len < intern->file_name_len) { RETURN_STRINGL(intern->file_name + intern->path_len + 1, intern->file_name_len - (intern->path_len + 1), 1); } else { RETURN_STRINGL(intern->file_name, intern->file_name_len, 1); @@ -566,6 +589,52 @@ SPL_METHOD(DirectoryIterator, getFilename) } /* }}} */ +/* {{{ proto string SplFileInfo::getBasename([string $suffix]) U + Returns filename component of path */ +SPL_METHOD(SplFileInfo, getBasename) +{ + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + char *fname, *suffix = 0; + size_t flen; + int slen = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &suffix, &slen) == FAILURE) { + return; + } + + if (intern->path_len && intern->path_len < intern->file_name_len) { + fname = intern->file_name + intern->path_len + 1; + flen = intern->file_name_len - (intern->path_len + 1); + } else { + fname = intern->file_name; + flen = intern->file_name_len; + } + + php_basename(fname, flen, suffix, slen, &fname, &flen TSRMLS_CC); + + RETURN_STRINGL(fname, flen, 0); +} +/* }}}*/ + +/* {{{ proto string DirectoryIterator::getBasename([string $suffix]) U + Returns filename component of current dir entry */ +SPL_METHOD(DirectoryIterator, getBasename) +{ + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + char *suffix = 0, *fname; + int slen = 0; + size_t flen; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &suffix, &slen) == FAILURE) { + return; + } + + php_basename(intern->u.dir.entry.d_name, strlen(intern->u.dir.entry.d_name), suffix, slen, &fname, &flen TSRMLS_CC); + + RETURN_STRINGL(fname, flen, 0); +} +/* }}} */ + /* {{{ proto string SplFileInfo::getPathname() Return path and filename */ SPL_METHOD(SplFileInfo, getPathname) @@ -626,7 +695,7 @@ SPL_METHOD(DirectoryIterator, isDot) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - RETURN_BOOL(!strcmp(intern->u.dir.entry.d_name, ".") || !strcmp(intern->u.dir.entry.d_name, "..")); + RETURN_BOOL(spl_filesystem_is_dot(intern->u.dir.entry.d_name)); } /* }}} */ @@ -668,8 +737,10 @@ SPL_METHOD(SplFileInfo, func_name) \ { \ spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); \ \ + php_set_error_handling(EH_THROW, spl_ce_RuntimeException TSRMLS_CC);\ spl_filesystem_object_get_file_name(intern TSRMLS_CC); \ php_stat(intern->file_name, intern->file_name_len, func_num, return_value TSRMLS_CC); \ + php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);\ } /* }}} */ @@ -748,6 +819,56 @@ FileInfoFunction(isDir, FS_IS_DIR) FileInfoFunction(isLink, FS_IS_LINK) /* }}} */ +/* {{{ proto string SplFileInfo::getLinkTarget() U + Return the target of a symbolic link */ +SPL_METHOD(SplFileInfo, getLinkTarget) +{ + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + int ret; + char buff[MAXPATHLEN]; + + php_set_error_handling(EH_THROW, spl_ce_RuntimeException TSRMLS_CC); + + ret = readlink(intern->file_name, buff, MAXPATHLEN-1); + + if (ret == -1) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Unable to read link %s, error: %s", intern->file_name, strerror(errno)); + RETVAL_FALSE; + } else { + /* Append NULL to the end of the string */ + buff[ret] = '\0'; + + RETVAL_STRINGL(buff, ret, 1); + } + php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); +} +/* }}} */ + +#if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) +/* {{{ proto string SplFileInfo::getRealPath() + Return the resolved path */ +SPL_METHOD(SplFileInfo, getRealPath) +{ + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + char buff[MAXPATHLEN]; + + php_set_error_handling(EH_THROW, spl_ce_RuntimeException TSRMLS_CC); + + if (VCWD_REALPATH(intern->file_name, buff)) { +#ifdef ZTS + if (VCWD_ACCESS(buff, F_OK)) { + RETVAL_FALSE; + } else +#endif + RETVAL_STRING(buff, 1); + } else { + RETVAL_FALSE; + } + php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); +} +/* }}} */ +#endif + /* {{{ proto SplFileObject SplFileInfo::openFile([string mode = 'r' [, bool use_include_path [, resource context]]]) Open the current file */ SPL_METHOD(SplFileInfo, openFile) @@ -865,7 +986,7 @@ SPL_METHOD(RecursiveDirectoryIterator, rewind) if (!intern->u.dir.dirp || !php_stream_readdir(intern->u.dir.dirp, &intern->u.dir.entry)) { intern->u.dir.entry.d_name[0] = '\0'; } - } while (!strcmp(intern->u.dir.entry.d_name, ".") || !strcmp(intern->u.dir.entry.d_name, "..")); + } while (spl_filesystem_is_dot(intern->u.dir.entry.d_name)); } /* }}} */ @@ -880,7 +1001,7 @@ SPL_METHOD(RecursiveDirectoryIterator, next) if (!intern->u.dir.dirp || !php_stream_readdir(intern->u.dir.dirp, &intern->u.dir.entry)) { intern->u.dir.entry.d_name[0] = '\0'; } - } while (!strcmp(intern->u.dir.entry.d_name, ".") || !strcmp(intern->u.dir.entry.d_name, "..")); + } while (spl_filesystem_is_dot(intern->u.dir.entry.d_name)); if (intern->file_name) { efree(intern->file_name); intern->file_name = NULL; @@ -895,7 +1016,7 @@ SPL_METHOD(RecursiveDirectoryIterator, hasChildren) zend_bool allow_links = 0; spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - if (!strcmp(intern->u.dir.entry.d_name, ".") || !strcmp(intern->u.dir.entry.d_name, "..")) { + if (spl_filesystem_is_invalid_or_dot(intern->u.dir.entry.d_name)) { RETURN_BOOL(0); } else { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &allow_links) == FAILURE) { @@ -1167,7 +1288,7 @@ static void spl_filesystem_tree_it_move_forward(zend_object_iterator *iter TSRML if (!object->u.dir.dirp || !php_stream_readdir(object->u.dir.dirp, &object->u.dir.entry)) { object->u.dir.entry.d_name[0] = '\0'; } - } while (!strcmp(object->u.dir.entry.d_name, ".") || !strcmp(object->u.dir.entry.d_name, "..")); + } while (spl_filesystem_is_dot(object->u.dir.entry.d_name)); if (object->file_name) { efree(object->file_name); object->file_name = NULL; @@ -1193,7 +1314,7 @@ static void spl_filesystem_tree_it_rewind(zend_object_iterator *iter TSRMLS_DC) if (!object->u.dir.dirp || !php_stream_readdir(object->u.dir.dirp, &object->u.dir.entry)) { object->u.dir.entry.d_name[0] = '\0'; } - } while (!strcmp(object->u.dir.entry.d_name, ".") || !strcmp(object->u.dir.entry.d_name, "..")); + } while (spl_filesystem_is_dot(object->u.dir.entry.d_name)); if (iterator->current) { zval_ptr_dtor(&iterator->current); iterator->current = NULL; @@ -1273,12 +1394,18 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_info_optinalFileClass, 0, 0, 0) ZEND_ARG_INFO(0, class_name) ZEND_END_ARG_INFO() +static +ZEND_BEGIN_ARG_INFO_EX(arginfo_optinalSuffix, 0, 0, 0) + ZEND_ARG_INFO(0, suffix) +ZEND_END_ARG_INFO() + /* the method table */ /* each method can have its own parameters and visibility */ static zend_function_entry spl_SplFileInfo_functions[] = { SPL_ME(SplFileInfo, __construct, arginfo_info___construct, ZEND_ACC_PUBLIC) SPL_ME(SplFileInfo, getPath, NULL, ZEND_ACC_PUBLIC) SPL_ME(SplFileInfo, getFilename, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, getBasename, arginfo_optinalSuffix, ZEND_ACC_PUBLIC) SPL_ME(SplFileInfo, getPathname, NULL, ZEND_ACC_PUBLIC) SPL_ME(SplFileInfo, getPerms, NULL, ZEND_ACC_PUBLIC) SPL_ME(SplFileInfo, getInode, NULL, ZEND_ACC_PUBLIC) @@ -1295,6 +1422,10 @@ static zend_function_entry spl_SplFileInfo_functions[] = { SPL_ME(SplFileInfo, isFile, NULL, ZEND_ACC_PUBLIC) SPL_ME(SplFileInfo, isDir, NULL, ZEND_ACC_PUBLIC) SPL_ME(SplFileInfo, isLink, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, getLinkTarget, NULL, ZEND_ACC_PUBLIC) +#if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) + SPL_ME(SplFileInfo, getRealPath, NULL, ZEND_ACC_PUBLIC) +#endif SPL_ME(SplFileInfo, getFileInfo, arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC) SPL_ME(SplFileInfo, getPathInfo, arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC) SPL_ME(SplFileInfo, openFile, arginfo_info_openFile, ZEND_ACC_PUBLIC) @@ -1314,6 +1445,7 @@ ZEND_END_ARG_INFO() static zend_function_entry spl_DirectoryIterator_functions[] = { SPL_ME(DirectoryIterator, __construct, arginfo_dir___construct, ZEND_ACC_PUBLIC) SPL_ME(DirectoryIterator, getFilename, NULL, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, getBasename, arginfo_optinalSuffix, ZEND_ACC_PUBLIC) SPL_ME(DirectoryIterator, isDot, NULL, ZEND_ACC_PUBLIC) SPL_ME(DirectoryIterator, rewind, NULL, ZEND_ACC_PUBLIC) SPL_ME(DirectoryIterator, valid, NULL, ZEND_ACC_PUBLIC) @@ -1325,18 +1457,23 @@ static zend_function_entry spl_DirectoryIterator_functions[] = { }; static -ZEND_BEGIN_ARG_INFO(arginfo_r_dir___construct, 0) +ZEND_BEGIN_ARG_INFO_EX(arginfo_r_dir___construct, 0, 0, 1) ZEND_ARG_INFO(0, path) ZEND_ARG_INFO(0, flags) ZEND_END_ARG_INFO() +static +ZEND_BEGIN_ARG_INFO_EX(arginfo_r_dir_hasChildren, 0, 0, 0) + ZEND_ARG_INFO(0, allow_links) +ZEND_END_ARG_INFO() + static zend_function_entry spl_RecursiveDirectoryIterator_functions[] = { SPL_ME(RecursiveDirectoryIterator, __construct, arginfo_r_dir___construct, ZEND_ACC_PUBLIC) SPL_ME(RecursiveDirectoryIterator, rewind, NULL, ZEND_ACC_PUBLIC) SPL_ME(RecursiveDirectoryIterator, next, NULL, ZEND_ACC_PUBLIC) SPL_ME(RecursiveDirectoryIterator, key, NULL, ZEND_ACC_PUBLIC) SPL_ME(RecursiveDirectoryIterator, current, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveDirectoryIterator, hasChildren, NULL, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveDirectoryIterator, hasChildren, arginfo_r_dir_hasChildren, ZEND_ACC_PUBLIC) SPL_ME(RecursiveDirectoryIterator, getChildren, NULL, ZEND_ACC_PUBLIC) SPL_ME(RecursiveDirectoryIterator, getSubPath, NULL, ZEND_ACC_PUBLIC) SPL_ME(RecursiveDirectoryIterator, getSubPathname,NULL, ZEND_ACC_PUBLIC) @@ -1360,7 +1497,7 @@ static int spl_filesystem_file_read(spl_filesystem_object *intern, int silent TS } if (intern->u.file.max_line_len > 0) { - buf = emalloc((intern->u.file.max_line_len + 1) * sizeof(char)); + buf = safe_emalloc((intern->u.file.max_line_len + 1), sizeof(char), 0); if (php_stream_get_line(intern->u.file.stream, buf, intern->u.file.max_line_len, &line_len) == NULL) { efree(buf); buf = NULL; @@ -1624,7 +1761,7 @@ SPL_METHOD(SplTempFileObject, __construct) intern->file_name = "php://memory"; intern->file_name_len = 12; } else if (ZEND_NUM_ARGS()) { - intern->file_name_len = snprintf(tmp_fname, sizeof(tmp_fname), "php://temp/maxmemory:%ld", max_memory); + intern->file_name_len = slprintf(tmp_fname, sizeof(tmp_fname), "php://temp/maxmemory:%ld", max_memory); intern->file_name = tmp_fname; } else { intern->file_name = "php://temp"; @@ -1651,15 +1788,6 @@ SPL_METHOD(SplFileObject, rewind) spl_filesystem_file_rewind(getThis(), intern TSRMLS_CC); } /* }}} */ -/* {{{ proto string SplFileObject::getFilename() - Return the filename */ -SPL_METHOD(SplFileObject, getFilename) -{ - spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - - RETURN_STRINGL(intern->file_name, intern->file_name_len, 1); -} /* }}} */ - /* {{{ proto void SplFileObject::eof() Return whether end of file is reached */ SPL_METHOD(SplFileObject, eof) @@ -2146,7 +2274,6 @@ ZEND_END_ARG_INFO() static zend_function_entry spl_SplFileObject_functions[] = { SPL_ME(SplFileObject, __construct, arginfo_file_object___construct, ZEND_ACC_PUBLIC) - SPL_ME(SplFileObject, getFilename, NULL, ZEND_ACC_PUBLIC) SPL_ME(SplFileObject, rewind, NULL, ZEND_ACC_PUBLIC) SPL_ME(SplFileObject, eof, NULL, ZEND_ACC_PUBLIC) SPL_ME(SplFileObject, valid, NULL, ZEND_ACC_PUBLIC) diff --git a/ext/spl/spl_directory.h b/ext/spl/spl_directory.h index 9a29c9b82..222ac5b59 100755 --- a/ext/spl/spl_directory.h +++ b/ext/spl/spl_directory.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_directory.h,v 1.12.2.5.2.2 2006/07/15 15:08:41 helly Exp $ */ +/* $Id: spl_directory.h,v 1.12.2.5.2.4 2007/01/01 09:36:07 sebastian Exp $ */ #ifndef SPL_DIRECTORY_H #define SPL_DIRECTORY_H @@ -95,10 +95,10 @@ struct _spl_filesystem_object { #define SPL_FILE_DIR_CURRENT_AS_FILEINFO 0x00000010 /* make RecursiveDirectoryTree::current() return SplFileInfo */ #define SPL_FILE_DIR_CURRENT_AS_PATHNAME 0x00000020 /* make RecursiveDirectoryTree::current() return getPathname() */ -#define SPL_FILE_DIR_CURRENT_MODE_MASK 0x000000F0 /* make RecursiveDirectoryTree::key() return getFilename() */ +#define SPL_FILE_DIR_CURRENT_MODE_MASK 0x000000F0 /* mask RecursiveDirectoryTree::current() */ #define SPL_FILE_DIR_KEY_AS_FILENAME 0x00000100 /* make RecursiveDirectoryTree::key() return getFilename() */ -#define SPL_FILE_DIR_KEY_MODE_MASK 0x00000F00 /* make RecursiveDirectoryTree::key() return getFilename() */ +#define SPL_FILE_DIR_KEY_MODE_MASK 0x00000F00 /* mask RecursiveDirectoryTree::key() */ #endif /* SPL_DIRECTORY_H */ diff --git a/ext/spl/spl_engine.c b/ext/spl/spl_engine.c index dcc9af3c6..9404e8e24 100755 --- a/ext/spl/spl_engine.c +++ b/ext/spl/spl_engine.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | diff --git a/ext/spl/spl_engine.h b/ext/spl/spl_engine.h index 06a77942f..ecb42d304 100755 --- a/ext/spl/spl_engine.h +++ b/ext/spl/spl_engine.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_engine.h,v 1.19.2.3 2006/03/14 18:07:51 fmk Exp $ */ +/* $Id: spl_engine.h,v 1.19.2.3.2.1 2007/01/01 09:36:07 sebastian Exp $ */ #ifndef SPL_ENGINE_H #define SPL_ENGINE_H diff --git a/ext/spl/spl_exceptions.c b/ext/spl/spl_exceptions.c index 0688fbc34..081341312 100755 --- a/ext/spl/spl_exceptions.c +++ b/ext/spl/spl_exceptions.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_exceptions.c,v 1.6.2.1.2.1 2006/05/10 00:03:38 helly Exp $ */ +/* $Id: spl_exceptions.c,v 1.6.2.1.2.2 2007/01/01 09:36:07 sebastian Exp $ */ #ifdef HAVE_CONFIG_H # include "config.h" diff --git a/ext/spl/spl_exceptions.h b/ext/spl/spl_exceptions.h index 581aace3c..34811f876 100755 --- a/ext/spl/spl_exceptions.h +++ b/ext/spl/spl_exceptions.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_exceptions.h,v 1.5.2.1 2006/01/01 12:50:13 sniper Exp $ */ +/* $Id: spl_exceptions.h,v 1.5.2.1.2.1 2007/01/01 09:36:07 sebastian Exp $ */ #ifndef SPL_EXCEPTIONS_H #define SPL_EXCEPTIONS_H diff --git a/ext/spl/spl_functions.c b/ext/spl/spl_functions.c index b0936ea09..e1fedcb0f 100755 --- a/ext/spl/spl_functions.c +++ b/ext/spl/spl_functions.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_functions.c,v 1.28.2.3.2.2 2006/07/20 22:54:21 helly Exp $ */ +/* $Id: spl_functions.c,v 1.28.2.3.2.3 2007/01/01 09:36:07 sebastian Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/spl/spl_functions.h b/ext/spl/spl_functions.h index 557215719..0a82a74da 100755 --- a/ext/spl/spl_functions.h +++ b/ext/spl/spl_functions.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_functions.h,v 1.19.2.3.2.1 2006/07/20 22:54:21 helly Exp $ */ +/* $Id: spl_functions.h,v 1.19.2.3.2.2 2007/01/01 09:36:07 sebastian Exp $ */ #ifndef PHP_FUNCTIONS_H #define PHP_FUNCTIONS_H diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index 58853c6f5..8534d313b 100755 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_iterators.c,v 1.73.2.30.2.17 2006/07/21 21:26:11 helly Exp $ */ +/* $Id: spl_iterators.c,v 1.73.2.30.2.27 2007/03/04 14:01:06 helly Exp $ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -57,6 +57,7 @@ PHPAPI zend_class_entry *spl_ce_EmptyIterator; PHPAPI zend_class_entry *spl_ce_AppendIterator; PHPAPI zend_class_entry *spl_ce_RegexIterator; PHPAPI zend_class_entry *spl_ce_RecursiveRegexIterator; +PHPAPI zend_class_entry *spl_ce_Countable; zend_function_entry spl_funcs_RecursiveIterator[] = { SPL_ABSTRACT_ME(RecursiveIterator, hasChildren, NULL) @@ -748,18 +749,19 @@ static zend_object_value spl_RecursiveIteratorIterator_new(zend_class_entry *cla /* }}} */ static -ZEND_BEGIN_ARG_INFO(arginfo_recursive_it___construct, 0) +ZEND_BEGIN_ARG_INFO_EX(arginfo_recursive_it___construct, 0, 0, 1) ZEND_ARG_OBJ_INFO(0, iterator, Traversable, 0) ZEND_ARG_INFO(0, mode) + ZEND_ARG_INFO(0, flags) ZEND_END_ARG_INFO(); static -ZEND_BEGIN_ARG_INFO(arginfo_recursive_it_getSubIterator, 0) +ZEND_BEGIN_ARG_INFO_EX(arginfo_recursive_it_getSubIterator, 0, 0, 0) ZEND_ARG_INFO(0, level) ZEND_END_ARG_INFO(); static -ZEND_BEGIN_ARG_INFO(arginfo_recursive_it_setMaxDepth, 0) +ZEND_BEGIN_ARG_INFO_EX(arginfo_recursive_it_setMaxDepth, 0, 0, 0) ZEND_ARG_INFO(0, max_depth) ZEND_END_ARG_INFO(); @@ -1012,8 +1014,13 @@ static spl_dual_it_object* spl_dual_it_construct(INTERNAL_FUNCTION_PARAMETERS, z intern->u.regex.mode = mode; intern->u.regex.regex = estrndup(regex, regex_len); intern->u.regex.pce = pcre_get_compiled_regex_cache(regex, regex_len TSRMLS_CC); + if (intern->u.regex.pce == NULL) { + /* pcre_get_compiled_regex_cache has already sent error */ + php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); + return NULL; + } intern->u.regex.pce->refcount++; - break;; + break; } #endif default: @@ -1329,41 +1336,6 @@ SPL_METHOD(ParentIterator, __construct) spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, spl_ce_ParentIterator, spl_ce_RecursiveIterator, DIT_ParentIterator); } /* }}} */ -/* {{{ proto bool ParentIterator::hasChildren() - Check whether the inner iterator's current element has children */ -SPL_METHOD(ParentIterator, hasChildren) -{ - spl_dual_it_object *intern; - zval *retval; - - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - - zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "haschildren", &retval); - if (retval) { - RETURN_ZVAL(retval, 0, 1); - } else { - RETURN_FALSE; - } -} /* }}} */ - -/* {{{ proto ParentIterator ParentIterator::getChildren() - Return the inner iterator's children contained in a ParentIterator */ -SPL_METHOD(ParentIterator, getChildren) -{ - spl_dual_it_object *intern; - zval *retval; - - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - - zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &retval); - if (!EG(exception) && retval) { - spl_instantiate_arg_ex1(Z_OBJCE_P(getThis()), &return_value, 0, retval TSRMLS_CC); - } - if (retval) { - zval_ptr_dtor(&retval); - } -} /* }}} */ - #if HAVE_PCRE || HAVE_BUNDLED_PCRE /* {{{ proto void RegexIterator::__construct(Iterator it, string regex [, int mode [, int flags [, int preg_flags]]]) Create an RegexIterator from another iterator and a regular expression */ @@ -1383,7 +1355,7 @@ SPL_METHOD(RegexIterator, accept) if (intern->u.regex.flags & REGIT_USE_KEY) { if (intern->current.key_type == HASH_KEY_IS_LONG) { - subject_len = snprintf(tmp, sizeof(tmp), "%ld", intern->current.int_key); + subject_len = slprintf(tmp, sizeof(tmp), "%ld", intern->current.int_key); subject = &tmp[0]; use_copy = 0; } else { @@ -1481,7 +1453,7 @@ SPL_METHOD(RegexIterator, setMode) if (mode < 0 || mode >= REGIT_MODE_MAX) { zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Illegal mode %ld", mode); - return;// NULL + return;/* NULL */ } intern->u.regex.mode = mode; @@ -1523,7 +1495,7 @@ SPL_METHOD(RegexIterator, getPregFlags) } } /* }}} */ -/* {{{ proto bool RegexIterator::setFlags(int new_flags) +/* {{{ proto bool RegexIterator::setPregFlags(int new_flags) Set PREG flags */ SPL_METHOD(RegexIterator, setPregFlags) { @@ -1658,7 +1630,6 @@ ZEND_END_ARG_INFO(); static zend_function_entry spl_funcs_RecursiveFilterIterator[] = { SPL_ME(RecursiveFilterIterator, __construct, arginfo_parent_it___construct, ZEND_ACC_PUBLIC) - SPL_MA(ParentIterator, accept, RecursiveFilterIterator, hasChildren, NULL, ZEND_ACC_PUBLIC) SPL_ME(RecursiveFilterIterator, hasChildren, NULL, ZEND_ACC_PUBLIC) SPL_ME(RecursiveFilterIterator, getChildren, NULL, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} @@ -1666,10 +1637,7 @@ static zend_function_entry spl_funcs_RecursiveFilterIterator[] = { static zend_function_entry spl_funcs_ParentIterator[] = { SPL_ME(ParentIterator, __construct, arginfo_parent_it___construct, ZEND_ACC_PUBLIC) - SPL_MA(ParentIterator, accept, ParentIterator, hasChildren, NULL, ZEND_ACC_PUBLIC) - SPL_ME(ParentIterator, hasChildren, NULL, ZEND_ACC_PUBLIC) - SPL_ME(ParentIterator, getChildren, NULL, ZEND_ACC_PUBLIC) - SPL_ME(dual_it, getInnerIterator, NULL, ZEND_ACC_PUBLIC) + SPL_MA(ParentIterator, accept, RecursiveFilterIterator, hasChildren, NULL, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; @@ -1720,9 +1688,9 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_rec_regex_it___construct, 0, 0, 2) ZEND_END_ARG_INFO(); static zend_function_entry spl_funcs_RecursiveRegexIterator[] = { - SPL_ME(RecursiveRegexIterator, __construct, arginfo_rec_regex_it___construct, ZEND_ACC_PUBLIC) - SPL_ME(ParentIterator, hasChildren, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveRegexIterator, getChildren, NULL, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveRegexIterator, __construct, arginfo_rec_regex_it___construct, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveFilterIterator, hasChildren, NULL, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveRegexIterator, getChildren, NULL, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; #endif @@ -1857,7 +1825,7 @@ static zend_function_entry spl_funcs_SeekableIterator[] = { }; static -ZEND_BEGIN_ARG_INFO(arginfo_limit_it___construct, 0) +ZEND_BEGIN_ARG_INFO_EX(arginfo_limit_it___construct, 0, 0, 1) ZEND_ARG_OBJ_INFO(0, iterator, Iterator, 0) ZEND_ARG_INFO(0, offset) ZEND_ARG_INFO(0, count) @@ -2192,7 +2160,7 @@ SPL_METHOD(CachingIterator, getFlags) } /* }}} */ -/* {{{ proto void CachingIterator::setFlags() +/* {{{ proto void CachingIterator::setFlags(int flags) Set the internal flags */ SPL_METHOD(CachingIterator, setFlags) { @@ -2225,8 +2193,25 @@ SPL_METHOD(CachingIterator, setFlags) } /* }}} */ +/* {{{ proto void CachingIterator::count() + Number of cached elements */ +SPL_METHOD(CachingIterator, count) +{ + spl_dual_it_object *intern; + + intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + + if (!(intern->u.caching.flags & CIT_FULL_CACHE)) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "%v does not use a full cache (see CachingIterator::__construct)", Z_OBJCE_P(getThis())->name); + return; + } + + RETURN_LONG(zend_hash_num_elements(HASH_OF(intern->u.caching.zcache))); +} +/* }}} */ + static -ZEND_BEGIN_ARG_INFO(arginfo_caching_it___construct, 0) +ZEND_BEGIN_ARG_INFO_EX(arginfo_caching_it___construct, 0, 0, 1) ZEND_ARG_OBJ_INFO(0, iterator, Iterator, 0) ZEND_ARG_INFO(0, flags) ZEND_END_ARG_INFO(); @@ -2237,12 +2222,12 @@ ZEND_BEGIN_ARG_INFO(arginfo_caching_it_setFlags, 0) ZEND_END_ARG_INFO(); static -ZEND_BEGIN_ARG_INFO_EX(arginfo_caching_it_offsetGet, 0, 0, 1) +ZEND_BEGIN_ARG_INFO(arginfo_caching_it_offsetGet, 0) ZEND_ARG_INFO(0, index) ZEND_END_ARG_INFO(); static -ZEND_BEGIN_ARG_INFO_EX(arginfo_caching_it_offsetSet, 0, 0, 2) +ZEND_BEGIN_ARG_INFO(arginfo_caching_it_offsetSet, 0) ZEND_ARG_INFO(0, index) ZEND_ARG_INFO(0, newval) ZEND_END_ARG_INFO(); @@ -2264,6 +2249,7 @@ static zend_function_entry spl_funcs_CachingIterator[] = { SPL_ME(CachingIterator, offsetUnset, arginfo_caching_it_offsetGet, ZEND_ACC_PUBLIC) SPL_ME(CachingIterator, offsetExists, arginfo_caching_it_offsetGet, ZEND_ACC_PUBLIC) SPL_ME(CachingIterator, getCache, NULL, ZEND_ACC_PUBLIC) + SPL_ME(CachingIterator, count, NULL, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; @@ -2301,7 +2287,7 @@ SPL_METHOD(RecursiveCachingIterator, getChildren) } /* }}} */ static -ZEND_BEGIN_ARG_INFO_EX(arginfo_caching_rec_it___construct, 0, ZEND_RETURN_VALUE, 2) +ZEND_BEGIN_ARG_INFO_EX(arginfo_caching_rec_it___construct, 0, ZEND_RETURN_VALUE, 1) ZEND_ARG_OBJ_INFO(0, iterator, Iterator, 0) ZEND_ARG_INFO(0, flags) ZEND_END_ARG_INFO(); @@ -2728,23 +2714,38 @@ static int spl_iterator_to_array_apply(zend_object_iterator *iter, void *puser T } /* }}} */ -/* {{{ proto array iterator_to_array(Traversable it) +static int spl_iterator_to_values_apply(zend_object_iterator *iter, void *puser TSRMLS_DC) /* {{{ */ +{ + zval **data, *return_value = (zval*)puser; + + iter->funcs->get_current_data(iter, &data TSRMLS_CC); + if (EG(exception)) { + return ZEND_HASH_APPLY_STOP; + } + (*data)->refcount++; + add_next_index_zval(return_value, *data); + return ZEND_HASH_APPLY_KEEP; +} +/* }}} */ + +/* {{{ proto array iterator_to_array(Traversable it [, bool use_keys = true]) Copy the iterator into an array */ PHP_FUNCTION(iterator_to_array) { zval *obj; + zend_bool use_keys = 1; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &obj, zend_ce_traversable) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|b", &obj, zend_ce_traversable, &use_keys) == FAILURE) { RETURN_FALSE; } array_init(return_value); - - if (spl_iterator_apply(obj, spl_iterator_to_array_apply, (void*)return_value TSRMLS_CC) != SUCCESS) { + + if (spl_iterator_apply(obj, use_keys ? spl_iterator_to_array_apply : spl_iterator_to_values_apply, (void*)return_value TSRMLS_CC) != SUCCESS) { zval_dtor(return_value); RETURN_NULL(); } -} +} /* }}} */ static int spl_iterator_count_apply(zend_object_iterator *iter, void *puser TSRMLS_DC) /* {{{ */ { @@ -2823,6 +2824,11 @@ static zend_function_entry spl_funcs_OuterIterator[] = { {NULL, NULL, NULL} }; +static zend_function_entry spl_funcs_Countable[] = { + SPL_ABSTRACT_ME(Countable, count, NULL) + {NULL, NULL, NULL} +}; + /* {{{ PHP_MINIT_FUNCTION(spl_iterators) */ PHP_MINIT_FUNCTION(spl_iterators) @@ -2865,6 +2871,7 @@ PHP_MINIT_FUNCTION(spl_iterators) REGISTER_SPL_SUB_CLASS_EX(ParentIterator, RecursiveFilterIterator, spl_dual_it_new, spl_funcs_ParentIterator); + REGISTER_SPL_INTERFACE(Countable); REGISTER_SPL_INTERFACE(SeekableIterator); REGISTER_SPL_ITERATOR(SeekableIterator); @@ -2872,6 +2879,7 @@ PHP_MINIT_FUNCTION(spl_iterators) REGISTER_SPL_SUB_CLASS_EX(CachingIterator, IteratorIterator, spl_dual_it_new, spl_funcs_CachingIterator); REGISTER_SPL_IMPLEMENTS(CachingIterator, ArrayAccess); + REGISTER_SPL_IMPLEMENTS(CachingIterator, Countable); REGISTER_SPL_CLASS_CONST_LONG(CachingIterator, "CALL_TOSTRING", CIT_CALL_TOSTRING); REGISTER_SPL_CLASS_CONST_LONG(CachingIterator, "CATCH_GET_CHILD", CIT_CATCH_GET_CHILD); diff --git a/ext/spl/spl_iterators.h b/ext/spl/spl_iterators.h index c434f4264..7c5031241 100755 --- a/ext/spl/spl_iterators.h +++ b/ext/spl/spl_iterators.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_iterators.h,v 1.18.2.7.2.9 2006/09/28 22:33:06 tony2001 Exp $ */ +/* $Id: spl_iterators.h,v 1.18.2.7.2.11 2007/02/08 22:17:40 helly Exp $ */ #ifndef SPL_ITERATORS_H #define SPL_ITERATORS_H @@ -50,6 +50,7 @@ extern PHPAPI zend_class_entry *spl_ce_EmptyIterator; extern PHPAPI zend_class_entry *spl_ce_AppendIterator; extern PHPAPI zend_class_entry *spl_ce_RegexIterator; extern PHPAPI zend_class_entry *spl_ce_RecursiveRegexIterator; +extern PHPAPI zend_class_entry *spl_ce_Countable; PHP_MINIT_FUNCTION(spl_iterators); diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c index c13d3620a..27903e504 100755 --- a/ext/spl/spl_observer.c +++ b/ext/spl/spl_observer.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is SplSubject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_observer.c,v 1.2.2.6.2.1 2006/08/23 09:32:24 bjori Exp $ */ +/* $Id: spl_observer.c,v 1.2.2.6.2.3 2007/02/08 22:14:25 helly Exp $ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -25,6 +25,8 @@ #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" +#include "ext/standard/php_var.h" +#include "ext/standard/php_smart_str.h" #include "zend_interfaces.h" #include "zend_exceptions.h" @@ -34,6 +36,7 @@ #include "spl_observer.h" #include "spl_iterators.h" #include "spl_array.h" +#include "spl_exceptions.h" SPL_METHOD(SplObserver, update); SPL_METHOD(SplSubject, attach); @@ -121,18 +124,8 @@ static zend_object_value spl_SplObjectStorage_new(zend_class_entry *class_type T } /* }}} */ -/* {{{ proto void SplObjectStorage::attach($obj) - Attaches an object to the storage if not yet contained */ -SPL_METHOD(SplObjectStorage, attach) +void spl_object_storage_attach(spl_SplObjectStorage *intern, zval *obj TSRMLS_DC) /* {{{ */ { - zval *obj; - - spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) { - return; - } - #if HAVE_PACKED_OBJECT_VALUE zend_hash_update(&intern->storage, (char*)&Z_OBJVAL_P(obj), sizeof(zend_object_value), &obj, sizeof(zval*), NULL); #else @@ -148,6 +141,20 @@ SPL_METHOD(SplObjectStorage, attach) obj->refcount++; } /* }}} */ +/* {{{ proto void SplObjectStorage::attach($obj) + Attaches an object to the storage if not yet contained */ +SPL_METHOD(SplObjectStorage, attach) +{ + zval *obj; + + spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) { + return; + } + spl_object_storage_attach(intern, obj TSRMLS_CC); +} /* }}} */ + /* {{{ proto void SplObjectStorage::detach($obj) Detaches an object from the storage */ SPL_METHOD(SplObjectStorage, detach) @@ -259,11 +266,154 @@ SPL_METHOD(SplObjectStorage, next) intern->index++; } /* }}} */ +/* {{{ proto string SplObjectStorage::serialize() + */ +SPL_METHOD(SplObjectStorage, serialize) +{ + spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); + + zval **entry, members, *pmembers; + HashPosition pos; + php_serialize_data_t var_hash; + smart_str buf = {0}; + + PHP_VAR_SERIALIZE_INIT(var_hash); + + /* storage */ + smart_str_appendl(&buf, "x:i:", 4); + smart_str_append_long(&buf, zend_hash_num_elements(&intern->storage)); + smart_str_appendc(&buf, ';'); + + zend_hash_internal_pointer_reset_ex(&intern->storage, &pos); + + while(zend_hash_has_more_elements_ex(&intern->storage, &pos) == SUCCESS) { + if (zend_hash_get_current_data_ex(&intern->storage, (void**)&entry, &pos) == FAILURE) { + smart_str_free(&buf); + PHP_VAR_SERIALIZE_DESTROY(var_hash); + RETURN_NULL(); + } + php_var_serialize(&buf, entry, &var_hash TSRMLS_CC); + smart_str_appendc(&buf, ';'); + zend_hash_move_forward_ex(&intern->storage, &pos); + } + + /* members */ + smart_str_appendl(&buf, "m:", 2); + INIT_PZVAL(&members); + Z_ARRVAL(members) = intern->std.properties; + Z_TYPE(members) = IS_ARRAY; + pmembers = &members; + php_var_serialize(&buf, &pmembers, &var_hash TSRMLS_CC); /* finishes the string */ + + /* done */ + PHP_VAR_SERIALIZE_DESTROY(var_hash); + + if (buf.c) { + RETURN_STRINGL(buf.c, buf.len, 0); + } else { + RETURN_NULL(); + } + +} /* }}} */ + +/* {{{ proto void SplObjectStorage::unserialize(string serialized) + */ +SPL_METHOD(SplObjectStorage, unserialize) +{ + spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); + + char *buf; + int buf_len; + const unsigned char *p, *s; + php_unserialize_data_t var_hash; + zval *pentry, *pmembers, *pcount = NULL; + long count; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buf, &buf_len) == FAILURE) { + return; + } + + if (buf_len == 0) { + zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Empty serialized string cannot be empty"); + return; + } + + /* storage */ + s = p = (const unsigned char*)buf; + PHP_VAR_UNSERIALIZE_INIT(var_hash); + + if (*p!= 'x' || *++p != ':') { + goto outexcept; + } + ++p; + + ALLOC_INIT_ZVAL(pcount); + if (!php_var_unserialize(&pcount, &p, s + buf_len, &var_hash TSRMLS_CC) || Z_TYPE_P(pcount) != IS_LONG) { + zval_ptr_dtor(&pcount); + goto outexcept; + } + + --p; /* for ';' */ + count = Z_LVAL_P(pcount); + zval_ptr_dtor(&pcount); + + while(count-- > 0) { + if (*p != ';') { + goto outexcept; + } + ++p; + ALLOC_INIT_ZVAL(pentry); + if (!php_var_unserialize(&pentry, &p, s + buf_len, &var_hash TSRMLS_CC)) { + zval_ptr_dtor(&pentry); + goto outexcept; + } + spl_object_storage_attach(intern, pentry TSRMLS_CC); + zval_ptr_dtor(&pentry); + } + + if (*p != ';') { + goto outexcept; + } + ++p; + + /* members */ + if (*p!= 'm' || *++p != ':') { + goto outexcept; + } + ++p; + + ALLOC_INIT_ZVAL(pmembers); + if (!php_var_unserialize(&pmembers, &p, s + buf_len, &var_hash TSRMLS_CC)) { + zval_ptr_dtor(&pmembers); + goto outexcept; + } + + /* copy members */ + zend_hash_copy(intern->std.properties, Z_ARRVAL_P(pmembers), (copy_ctor_func_t) zval_add_ref, (void *) NULL, sizeof(zval *)); + zval_ptr_dtor(&pmembers); + + /* done reading $serialized */ + + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + return; + +outexcept: + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Error at offset %ld of %d bytes", (long)((char*)p - buf), buf_len); + return; + +} /* }}} */ + static ZEND_BEGIN_ARG_INFO(arginfo_Object, 0) ZEND_ARG_INFO(0, object) ZEND_END_ARG_INFO(); +static +ZEND_BEGIN_ARG_INFO(arginfo_Serialized, 0) + ZEND_ARG_INFO(0, serialized) +ZEND_END_ARG_INFO(); + static zend_function_entry spl_funcs_SplObjectStorage[] = { SPL_ME(SplObjectStorage, attach, arginfo_Object, 0) SPL_ME(SplObjectStorage, detach, arginfo_Object, 0) @@ -274,6 +424,8 @@ static zend_function_entry spl_funcs_SplObjectStorage[] = { SPL_ME(SplObjectStorage, key, NULL, 0) SPL_ME(SplObjectStorage, current, NULL, 0) SPL_ME(SplObjectStorage, next, NULL, 0) + SPL_ME(SplObjectStorage, unserialize, arginfo_Serialized, 0) + SPL_ME(SplObjectStorage, serialize, NULL, 0) {NULL, NULL, NULL} }; @@ -288,7 +440,8 @@ PHP_MINIT_FUNCTION(spl_observer) REGISTER_SPL_IMPLEMENTS(SplObjectStorage, Countable); REGISTER_SPL_IMPLEMENTS(SplObjectStorage, Iterator); - + REGISTER_SPL_IMPLEMENTS(SplObjectStorage, Serializable); + return SUCCESS; } /* }}} */ diff --git a/ext/spl/spl_observer.h b/ext/spl/spl_observer.h index 798d0fc91..b6924ebd8 100755 --- a/ext/spl/spl_observer.h +++ b/ext/spl/spl_observer.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_observer.h,v 1.2.2.2 2006/01/01 12:50:14 sniper Exp $ */ +/* $Id: spl_observer.h,v 1.2.2.2.2.1 2007/01/01 09:36:07 sebastian Exp $ */ #ifndef SPL_OBSERVER_H #define SPL_OBSERVER_H diff --git a/ext/spl/spl_sxe.c b/ext/spl/spl_sxe.c index 5f9a98ee5..419ca5b46 100755 --- a/ext/spl/spl_sxe.c +++ b/ext/spl/spl_sxe.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_sxe.c,v 1.8.2.5 2006/03/06 09:50:44 helly Exp $ */ +/* $Id: spl_sxe.c,v 1.8.2.5.2.1 2007/01/01 09:36:07 sebastian Exp $ */ #ifdef HAVE_CONFIG_H # include "config.h" diff --git a/ext/spl/spl_sxe.h b/ext/spl/spl_sxe.h index 12b2bb4e7..c7c77392e 100755 --- a/ext/spl/spl_sxe.h +++ b/ext/spl/spl_sxe.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_sxe.h,v 1.4.2.1 2006/01/01 12:50:14 sniper Exp $ */ +/* $Id: spl_sxe.h,v 1.4.2.1.2.1 2007/01/01 09:36:07 sebastian Exp $ */ #ifndef SPL_SXE_H #define SPL_SXE_H diff --git a/ext/spl/tests/bug38325.phpt b/ext/spl/tests/bug38325.phpt new file mode 100644 index 000000000..126e1f3c0 --- /dev/null +++ b/ext/spl/tests/bug38325.phpt @@ -0,0 +1,11 @@ +--TEST-- +Bug #38325 (spl_autoload_register() gaves wrong line for "class not found") +--SKIPIF-- +<?php if (!extension_loaded("spl")) print "skip"; ?> +--FILE-- +<?php +spl_autoload_register(); +new Foo(); +?> +--EXPECTF-- +Fatal error: spl_autoload(): Class Foo could not be loaded in %s on line 3 diff --git a/ext/spl/tests/bug40036.phpt b/ext/spl/tests/bug40036.phpt new file mode 100644 index 000000000..8569629d3 --- /dev/null +++ b/ext/spl/tests/bug40036.phpt @@ -0,0 +1,34 @@ +--TEST-- +Bug #40036 (empty() does not work correctly with ArrayObject when using ARRAY_AS_PROPS) +--SKIPIF-- +<?php if (!extension_loaded("spl")) print "skip"; ?> +--FILE-- +<?php +class View extends ArrayObject +{ + public function __construct(array $array = array()) + { + parent::__construct($array, ArrayObject::ARRAY_AS_PROPS); + } +} + +$view = new View(); +$view->foo = false; +$view->bar = null; +$view->baz = ''; +if (empty($view['foo']) || empty($view->foo)) { + echo "View::foo empty\n"; +} +if (empty($view['bar']) || empty($view->bar)) { + echo "View::bar empty\n"; +} +if (empty($view['baz']) || empty($view->baz)) { + echo "View::baz empty\n"; +} +?> +===DONE=== +--EXPECT-- +View::foo empty +View::bar empty +View::baz empty +===DONE=== diff --git a/ext/spl/tests/bug40091.phpt b/ext/spl/tests/bug40091.phpt new file mode 100644 index 000000000..7d6210b8b --- /dev/null +++ b/ext/spl/tests/bug40091.phpt @@ -0,0 +1,39 @@ +--TEST-- +Bug #40091 (issue with spl_autoload_register() and 2 instances of the same class) +--SKIPIF-- +<?php if (!extension_loaded("spl")) print "skip"; ?> +--FILE-- +<?php +class MyAutoloader { + function __construct($directory_to_use) {} + function autoload($class_name) { + // code to autoload based on directory + } +} + +$autloader1 = new MyAutoloader('dir1'); +spl_autoload_register(array($autloader1, 'autoload')); + +$autloader2 = new MyAutoloader('dir2'); +spl_autoload_register(array($autloader2, 'autoload')); + +print_r(spl_autoload_functions()); +?> +===DONE=== +--EXPECT-- +Array +( + [0] => Array + ( + [0] => MyAutoloader + [1] => autoload + ) + + [1] => Array + ( + [0] => MyAutoloader + [1] => autoload + ) + +) +===DONE=== diff --git a/ext/spl/tests/bug40442.phpt b/ext/spl/tests/bug40442.phpt new file mode 100755 index 000000000..fbeb22d2b --- /dev/null +++ b/ext/spl/tests/bug40442.phpt @@ -0,0 +1,12 @@ +--TEST-- +Bug #40442 (ArrayObject::offsetExists broke in 5.2.1, works in 5.2.0) +--FILE-- +<?php +$a = new ArrayObject(); +$a->offsetSet('property', 0); +var_dump($a->offsetExists('property')); +?> +===DONE=== +--EXPECT-- +bool(true) +===DONE=== diff --git a/ext/spl/tests/bug40872.phpt b/ext/spl/tests/bug40872.phpt new file mode 100755 index 000000000..a48fe74fe --- /dev/null +++ b/ext/spl/tests/bug40872.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #40872 (inconsistency in offsetSet, offsetExists treatment of string enclosed integers) +--FILE-- +<?php + class Project { + public $id; + + function __construct($id) { + $this->id = $id; + } + } + + class ProjectsList extends ArrayIterator { + public function add(Project $item) { + $this->offsetSet($item->id, $item); + } + } + + $projects = new ProjectsList(); + $projects->add(new Project('1')); + $projects->add(new Project(2)); + + var_dump($projects->offsetExists(1)); + var_dump($projects->offsetExists('2')); +?> +===DONE=== +--EXPECT-- +bool(true) +bool(true) +===DONE=== diff --git a/ext/spl/tests/fileobject_003.phpt b/ext/spl/tests/fileobject_003.phpt index 74f2002d0..0b19ad7fb 100755 --- a/ext/spl/tests/fileobject_003.phpt +++ b/ext/spl/tests/fileobject_003.phpt @@ -31,6 +31,9 @@ function test($name, $lc, $lp) var_dump($f->getPath()); $l = substr($f->getPath(), -1); var_dump($l != '/' && $l != '\\' && $l == $lp); + + $fo = $o->openFile(); + var_dump($fo->getPathName(), $fo->getFileName(), $fo->getPath()); } test(dirname(__FILE__) . '/' . 'fileobject_001a.txt', 't', substr(dirname(__FILE__),-1)); @@ -52,10 +55,13 @@ bool(true) string(%d) "%sfileobject_001a.txt" string(%d) "%sfileobject_001a.txt" bool(true) -string(%d) "%sfileobject_001a.txt" +string(19) "fileobject_001a.txt" bool(true) string(%d) "%stests" bool(true) +string(%d) "%sfileobject_001a.txt" +string(19) "fileobject_001a.txt" +string(%d) "%stests" ===1=== object(SplFileInfo)#%d (0) { } @@ -67,10 +73,13 @@ bool(true) string(%d) "%stests/" string(%d) "%stests" bool(true) -string(%d) "%stests" +string(5) "tests" bool(true) string(%d) "%sspl" bool(true) +string(%d) "%stests" +string(%d) "%stests" +string(%d) "%stests" ===2=== object(SplFileInfo)#1 (0) { } @@ -82,8 +91,11 @@ bool(true) string(%d) "%stests" string(%d) "%stests" bool(true) -string(%d) "%stests" +string(%d) "tests" bool(true) string(%d) "%sspl" bool(true) +string(%d) "%stests" +string(5) "tests" +string(%d) "%sspl" ===DONE=== diff --git a/ext/spl/tests/iterator_044.phpt b/ext/spl/tests/iterator_044.phpt index e25e0d1dd..d3c625314 100755 --- a/ext/spl/tests/iterator_044.phpt +++ b/ext/spl/tests/iterator_044.phpt @@ -76,10 +76,10 @@ Exception: MyCachingIterator does not use a full cache (see CachingIterator::__c Notice: Undefined index: 0 in %siterator_044.php on line %d Exception: MyCachingIterator does not use a full cache (see CachingIterator::__construct) -Warning: CachingIterator::offsetExists() expects exactly 1 parameter, 0 given in %s/iterator_044.php on line %d +Warning: CachingIterator::offsetExists() expects exactly 1 parameter, 0 given in %siterator_044.php on line %d NULL -Warning: CachingIterator::offsetGet() expects exactly 1 parameter, 0 given in %s/iterator_044.php on line %d +Warning: CachingIterator::offsetGet() expects exactly 1 parameter, 0 given in %siterator_044.php on line %d NULL ===0=== int(0) diff --git a/ext/spl/tests/observer_003.phpt b/ext/spl/tests/observer_003.phpt new file mode 100755 index 000000000..79df8cf96 --- /dev/null +++ b/ext/spl/tests/observer_003.phpt @@ -0,0 +1,60 @@ +--TEST-- +SPL: SplObjectStorage serialization +--SKIPIF-- +<?php if (!extension_loaded("spl")) print "skip"; ?> +--FILE-- +<?php + +class TestClass +{ + public $test = 25; + + public function __construct($test = 42) + { + $this->test = $test; + } +} + +$storage = new SplObjectStorage(); + +foreach(array(1,"2","foo",true) as $value) +{ + $storage->attach(new TestClass($value)); +} + +var_dump(count($storage)); + +foreach($storage as $object) +{ + var_dump($object->test); +} + +var_dump(serialize($storage)); +echo "===UNSERIALIZE===\n"; + +$storage2 = unserialize(serialize($storage)); + +var_dump(count($storage2)); + +foreach($storage2 as $object) +{ + var_dump($object->test); +} + +?> +===DONE=== +<?php exit(0); ?> +--EXPECTF-- +int(4) +int(1) +string(1) "2" +string(3) "foo" +bool(true) +string(%d) "%s" +===UNSERIALIZE=== +int(4) +int(1) +string(1) "2" +string(3) "foo" +bool(true) +===DONE=== diff --git a/ext/spl/tests/observer_004.phpt b/ext/spl/tests/observer_004.phpt new file mode 100755 index 000000000..78b480ab1 --- /dev/null +++ b/ext/spl/tests/observer_004.phpt @@ -0,0 +1,78 @@ +--TEST-- +SPL: SplObjectStorage serialization & overloading +--SKIPIF-- +<?php if (!extension_loaded("spl")) print "skip"; ?> +--FILE-- +<?php + +class TestClass +{ + public $test = 25; + + public function __construct($test = 42) + { + $this->test = $test; + } +} + +class MyStorage extends SplObjectStorage +{ + public $bla = 25; + + public function __construct($bla = 26) + { + $this->bla = $bla; + } +} + +$storage = new MyStorage(); + +foreach(array(1,2) as $value) +{ + $storage->attach(new TestClass($value)); +} + +var_dump(count($storage)); + +foreach($storage as $object) +{ + var_dump($object->test); +} + +var_dump($storage); + +var_dump(serialize($storage)); +echo "===UNSERIALIZE===\n"; + +$storage2 = unserialize(serialize($storage)); + +var_dump(count($storage2)); + +foreach($storage2 as $object) +{ + var_dump($object->test); +} + +var_dump($storage2); + +?> +===DONE=== +<?php exit(0); ?> +--EXPECTF-- +int(2) +int(1) +int(2) +object(MyStorage)#%d (1) { + ["bla"]=> + int(26) +} +string(%d) "%s" +===UNSERIALIZE=== +int(2) +int(1) +int(2) +object(MyStorage)#%d (1) { + ["bla"]=> + int(26) +} +===DONE=== diff --git a/ext/spl/tests/observer_005.phpt b/ext/spl/tests/observer_005.phpt new file mode 100755 index 000000000..46971cc2d --- /dev/null +++ b/ext/spl/tests/observer_005.phpt @@ -0,0 +1,144 @@ +--TEST-- +SPL: SplObjectStorage serialization & visibility +--SKIPIF-- +<?php if (!extension_loaded("spl")) print "skip"; ?> +--FILE-- +<?php + +class TestClass +{ + public $def = 24; + public $pub = 25; + protected $pro = 26; + private $pri = 27; + + public function __construct($pub = 42, $pro = 43, $pri = 44) + { + $this->pub = $pub; + $this->pro = $pro; + $this->pri = $pri; + } +} + +class ExtTestClass +{ +} + +class MyStorage extends SplObjectStorage +{ + public $def = 24; + public $pub = 25; + protected $pro = 26; + private $pri = 27; + + public function __construct($pub = 52, $pro = 53, $pri = 54) + { + $this->pub = $pub; + $this->pro = $pro; + $this->pri = $pri; + } +} + +class ExtStorage extends MyStorage +{ +} + +$storage = new MyStorage(1,2,3); + +foreach(array(array(4,5,6),array(7,8,9)) as $value) +{ + $storage->attach(new TestClass($value[0], $value[1], $value[2])); +} + +var_dump(count($storage)); + +foreach($storage as $object) +{ + var_dump($object); +} + +var_dump($storage); + +var_dump(serialize($storage)); +echo "===UNSERIALIZE===\n"; + +$storage2 = unserialize(serialize($storage)); + +var_dump(count($storage2)); + +foreach($storage2 as $object) +{ + var_dump($object); +} + +var_dump($storage2); + +?> +===DONE=== +<?php exit(0); ?> +--EXPECTF-- +int(2) +object(TestClass)#%d (4) { + ["def"]=> + int(24) + ["pub"]=> + int(4) + ["pro:protected"]=> + int(5) + ["pri:private"]=> + int(6) +} +object(TestClass)#%d (4) { + ["def"]=> + int(24) + ["pub"]=> + int(7) + ["pro:protected"]=> + int(8) + ["pri:private"]=> + int(9) +} +object(MyStorage)#%d (4) { + ["def"]=> + int(24) + ["pub"]=> + int(1) + ["pro:protected"]=> + int(2) + ["pri:private"]=> + int(3) +} +string(%d) "%s" +===UNSERIALIZE=== +int(2) +object(TestClass)#%d (4) { + ["def"]=> + int(24) + ["pub"]=> + int(4) + ["pro:protected"]=> + int(5) + ["pri:private"]=> + int(6) +} +object(TestClass)#%d (4) { + ["def"]=> + int(24) + ["pub"]=> + int(7) + ["pro:protected"]=> + int(8) + ["pri:private"]=> + int(9) +} +object(MyStorage)#%d (4) { + ["def"]=> + int(24) + ["pub"]=> + int(1) + ["pro:protected"]=> + int(2) + ["pri:private"]=> + int(3) +} +===DONE=== diff --git a/ext/spl/tests/spl_006.phpt b/ext/spl/tests/spl_006.phpt new file mode 100755 index 000000000..89859624d --- /dev/null +++ b/ext/spl/tests/spl_006.phpt @@ -0,0 +1,41 @@ +--TEST-- +SPL: iterator_to_array() without keys +--SKIPIF-- +<?php if (!extension_loaded("spl")) print "skip"; ?> +--FILE-- +<?php + +$it = new AppendIterator(); +$it->append(new ArrayIterator(array(1,2))); +$it->append(new ArrayIterator(array(2,3))); + +var_dump(iterator_to_array($it)); +var_dump(iterator_to_array($it, false)); +var_dump(iterator_to_array($it, true)); + +?> +===DONE=== +--EXPECT-- +array(2) { + [0]=> + int(2) + [1]=> + int(3) +} +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(2) + [3]=> + int(3) +} +array(2) { + [0]=> + int(2) + [1]=> + int(3) +} +===DONE=== diff --git a/ext/spl/tests/spl_007.phpt b/ext/spl/tests/spl_007.phpt new file mode 100755 index 000000000..dcd63f9b5 --- /dev/null +++ b/ext/spl/tests/spl_007.phpt @@ -0,0 +1,26 @@ +--TEST-- +SPL: iterator_apply() with callback using __call() +--SKIPIF-- +<?php if (!extension_loaded("spl")) print "skip"; ?> +--FILE-- +<?php + +class Foo { + public function __call($name, $params) { + echo "Called $name.\n"; + return true; + } +} + +$it = new ArrayIterator(array(1, 2, 3)); + +iterator_apply($it, array(new Foo, "foobar")); + +?> +===DONE=== +<?php exit(0); ?> +--EXPECT-- +Called foobar. +Called foobar. +Called foobar. +===DONE=== diff --git a/ext/spl/tests/spl_autoload_009.phpt b/ext/spl/tests/spl_autoload_009.phpt new file mode 100755 index 000000000..057e96616 --- /dev/null +++ b/ext/spl/tests/spl_autoload_009.phpt @@ -0,0 +1,28 @@ +--TEST--
+SPL: spl_autoload() and friends
+--SKIPIF--
+<?php if (!extension_loaded("spl")) print "skip"; ?>
+--INI--
+include_path=.
+--FILE--
+<?php
+
+function my_autoload($name)
+{
+ require $name . '.class.inc';
+ var_dump(class_exists($name));
+}
+
+spl_autoload_register("spl_autoload");
+spl_autoload_register("my_autoload");
+
+$obj = new testclass;
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+%stestclass.inc
+%stestclass.class.inc
+bool(true)
+===DONE===
|
