summaryrefslogtreecommitdiff
path: root/ext/spl
diff options
context:
space:
mode:
authorMark A. Hershberger <mah@debian.(none)>2009-03-25 00:37:27 -0400
committerMark A. Hershberger <mah@debian.(none)>2009-03-25 00:37:27 -0400
commit2d4e5b09576bb4f0ba716cc82cdf29ea04d9184b (patch)
tree41ccc042009cba53e4ce43e727fcba4c1cfbf7f3 /ext/spl
parentd29a4fd2dd3b5d4cf6e80b602544d7b71d794e76 (diff)
downloadphp-2d4e5b09576bb4f0ba716cc82cdf29ea04d9184b.tar.gz
Imported Upstream version 5.2.2upstream/5.2.2
Diffstat (limited to 'ext/spl')
-rwxr-xr-xext/spl/config.m44
-rwxr-xr-xext/spl/examples/callbackfilteriterator.inc122
-rwxr-xr-xext/spl/examples/directoryfilterdots.inc10
-rwxr-xr-xext/spl/examples/dualiterator.inc5
-rwxr-xr-xext/spl/examples/phar_from_dir.php50
-rwxr-xr-xext/spl/examples/recursivecomparedualiterator.inc69
-rwxr-xr-xext/spl/examples/recursivedualiterator.inc2
-rwxr-xr-xext/spl/examples/tests/dualiterator_001.phpt1
-rwxr-xr-xext/spl/internal/parentiterator.inc16
-rwxr-xr-xext/spl/internal/recursiveiterator.inc2
-rwxr-xr-xext/spl/internal/recursiveiteratoriterator.inc6
-rwxr-xr-xext/spl/internal/seekableiterator.inc2
-rwxr-xr-xext/spl/internal/splfileobject.inc8
-rwxr-xr-xext/spl/php_spl.c88
-rwxr-xr-xext/spl/php_spl.h4
-rwxr-xr-xext/spl/spl.php36
-rwxr-xr-xext/spl/spl_array.c38
-rwxr-xr-xext/spl/spl_array.h6
-rwxr-xr-xext/spl/spl_directory.c175
-rwxr-xr-xext/spl/spl_directory.h8
-rwxr-xr-xext/spl/spl_engine.c2
-rwxr-xr-xext/spl/spl_engine.h4
-rwxr-xr-xext/spl/spl_exceptions.c4
-rwxr-xr-xext/spl/spl_exceptions.h4
-rwxr-xr-xext/spl/spl_functions.c4
-rwxr-xr-xext/spl/spl_functions.h4
-rwxr-xr-xext/spl/spl_iterators.c134
-rwxr-xr-xext/spl/spl_iterators.h5
-rwxr-xr-xext/spl/spl_observer.c181
-rwxr-xr-xext/spl/spl_observer.h4
-rwxr-xr-xext/spl/spl_sxe.c4
-rwxr-xr-xext/spl/spl_sxe.h4
-rw-r--r--ext/spl/tests/bug38325.phpt11
-rw-r--r--ext/spl/tests/bug40036.phpt34
-rw-r--r--ext/spl/tests/bug40091.phpt39
-rwxr-xr-xext/spl/tests/bug40442.phpt12
-rwxr-xr-xext/spl/tests/bug40872.phpt30
-rwxr-xr-xext/spl/tests/fileobject_003.phpt18
-rwxr-xr-xext/spl/tests/iterator_044.phpt4
-rwxr-xr-xext/spl/tests/observer_003.phpt60
-rwxr-xr-xext/spl/tests/observer_004.phpt78
-rwxr-xr-xext/spl/tests/observer_005.phpt144
-rwxr-xr-xext/spl/tests/spl_006.phpt41
-rwxr-xr-xext/spl/tests/spl_007.phpt26
-rwxr-xr-xext/spl/tests/spl_autoload_009.phpt28
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===