colder          Sun May 18 12:17:43 2008 UTC

  Added files:                 (Branch: PHP_5_3)
    /php-src/ext/spl/tests      dit_004.phpt dit_005.phpt 

  Modified files:              
    /php-src/ext/spl    spl_directory.c spl_directory.h 
  Log:
  MFH: Fix filesystemiterator with ./.. + add cloning tests
  
http://cvs.php.net/viewvc.cgi/php-src/ext/spl/spl_directory.c?r1=1.45.2.27.2.23.2.19&r2=1.45.2.27.2.23.2.20&diff_format=u
Index: php-src/ext/spl/spl_directory.c
diff -u php-src/ext/spl/spl_directory.c:1.45.2.27.2.23.2.19 
php-src/ext/spl/spl_directory.c:1.45.2.27.2.23.2.20
--- php-src/ext/spl/spl_directory.c:1.45.2.27.2.23.2.19 Wed Apr  9 19:01:12 2008
+++ php-src/ext/spl/spl_directory.c     Sun May 18 12:17:43 2008
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: spl_directory.c,v 1.45.2.27.2.23.2.19 2008/04/09 19:01:12 colder Exp $ 
*/
+/* $Id: spl_directory.c,v 1.45.2.27.2.23.2.20 2008/05/18 12:17:43 colder Exp $ 
*/
 
 #ifdef HAVE_CONFIG_H
 # include "config.h"
@@ -200,10 +200,18 @@
 
 #define IS_SLASH_AT(zs, pos) (IS_SLASH(zs[pos]))
 
+static inline int spl_filesystem_is_dot(const char * d_name) /* {{{ */
+{
+       return !strcmp(d_name, ".") || !strcmp(d_name, "..");
+}
+/* }}} */
+
 /* {{{ spl_filesystem_dir_open */
 /* open a directory resource */
 static void spl_filesystem_dir_open(spl_filesystem_object* intern, char *path 
TSRMLS_DC)
 {
+       int skip_dots = intern->flags & SPL_FILE_DIR_SKIPDOTS;
+
        intern->type = SPL_FS_DIR;
        intern->_path_len = strlen(path);
        intern->u.dir.dirp = php_stream_opendir(path, 
ENFORCE_SAFE_MODE|REPORT_ERRORS, NULL);
@@ -219,7 +227,9 @@
                /* throw exception: should've been already happened */
                intern->u.dir.entry.d_name[0] = '\0';
        } else {
-               spl_filesystem_dir_read(intern TSRMLS_CC);
+               do {
+                       spl_filesystem_dir_read(intern TSRMLS_CC);
+               } while (skip_dots && 
spl_filesystem_is_dot(intern->u.dir.entry.d_name));
        }
 }
 /* }}} */
@@ -277,6 +287,7 @@
        zend_object_handle handle = Z_OBJ_HANDLE_P(zobject);
        spl_filesystem_object *intern;
        spl_filesystem_object *source;
+       int index, skip_dots;
 
        old_object = zend_objects_get_address(zobject TSRMLS_CC);
        source = (spl_filesystem_object*)old_object;
@@ -284,6 +295,8 @@
        new_obj_val = spl_filesystem_object_new_ex(old_object->ce, &intern 
TSRMLS_CC);
        new_object = &intern->std;
 
+       intern->flags = source->flags;
+
        switch (source->type) {
        case SPL_FS_INFO:
                intern->_path_len = source->_path_len;
@@ -293,6 +306,14 @@
                break;
        case SPL_FS_DIR:
                spl_filesystem_dir_open(intern, source->_path TSRMLS_CC);
+               /* read until we hit the position in which we were before */
+               skip_dots = source->flags & SPL_FILE_DIR_SKIPDOTS;
+               for(index = 0; index < source->u.dir.index; ++index) {
+                       do {
+                               spl_filesystem_dir_read(intern TSRMLS_CC);
+                       } while (skip_dots && 
spl_filesystem_is_dot(intern->u.dir.entry.d_name));
+               }
+               intern->u.dir.index = index;
                break;
        case SPL_FS_FILE:
                php_error_docref(NULL TSRMLS_CC, E_ERROR, "An object of class 
%s cannot be cloned", old_object->ce->name);
@@ -301,7 +322,6 @@
        
        intern->file_class = source->file_class;
        intern->info_class = source->info_class;
-       intern->flags = source->flags;
        intern->oth = source->oth;
        intern->oth_handler = source->oth_handler;
 
@@ -468,12 +488,6 @@
        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);
@@ -562,6 +576,9 @@
                flags = 
SPL_FILE_DIR_KEY_AS_PATHNAME|SPL_FILE_DIR_CURRENT_AS_SELF;
                parsed = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", 
&path, &len);
        }
+       if (ctor_flags & SPL_FILE_DIR_SKIPDOTS) {
+               flags |= SPL_FILE_DIR_SKIPDOTS;
+       }
        if (parsed == FAILURE) {
                php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
                return;
@@ -573,6 +590,7 @@
        }
 
        intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() 
TSRMLS_CC);
+       intern->flags = flags;
        if ((ctor_flags & DIT_CTOR_GLOB) && strstr(path, "glob://") != path) {
                spprintf(&path, 0, "glob://%s", path);
                spl_filesystem_dir_open(intern, path TSRMLS_CC);
@@ -582,7 +600,6 @@
        }
 
        intern->u.dir.is_recursive = instanceof_function(intern->std.ce, 
spl_ce_RecursiveDirectoryIterator TSRMLS_CC) ? 1 : 0;
-       intern->flags = flags;
 
        php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
 }
@@ -637,9 +654,12 @@
 SPL_METHOD(DirectoryIterator, next)
 {
        spl_filesystem_object *intern = 
(spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       int skip_dots = intern->flags & SPL_FILE_DIR_SKIPDOTS;
 
        intern->u.dir.index++;
-       spl_filesystem_dir_read(intern TSRMLS_CC);
+       do {
+               spl_filesystem_dir_read(intern TSRMLS_CC);
+       } while (skip_dots && 
spl_filesystem_is_dot(intern->u.dir.entry.d_name));
        if (intern->file_name) {
                efree(intern->file_name);
                intern->file_name = NULL;
@@ -1071,7 +1091,7 @@
  Cronstructs a new dir iterator from a path. */
 SPL_METHOD(FilesystemIterator, __construct)
 {
-       spl_filesystem_object_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
DIT_CTOR_FLAGS);
+       spl_filesystem_object_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, 
DIT_CTOR_FLAGS | SPL_FILE_DIR_SKIPDOTS);
 }
 /* }}} */
 
@@ -1091,30 +1111,13 @@
 }
 /* }}} */
 
-/* {{{ proto void FilesystemIterator::next()
-   Move to next entry */
-SPL_METHOD(FilesystemIterator, next)
-{
-       spl_filesystem_object *intern = 
(spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
-
-       intern->u.dir.index++;
-       do {
-               spl_filesystem_dir_read(intern TSRMLS_CC);
-       } while (spl_filesystem_is_dot(intern->u.dir.entry.d_name));
-       if (intern->file_name) {
-               efree(intern->file_name);
-               intern->file_name = NULL;
-       }
-}
-/* }}} */
-
 /* {{{ proto int FilesystemIterator::getFlags()
    Get handling flags */
 SPL_METHOD(FilesystemIterator, getFlags)
 {
        spl_filesystem_object *intern = 
(spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
 
-       RETURN_LONG(intern->flags);
+       RETURN_LONG(intern->flags & (SPL_FILE_DIR_KEY_MODE_MASK | 
SPL_FILE_DIR_CURRENT_MODE_MASK));
 } /* }}} */
 
 /* {{{ proto void FilesystemIterator::setFlags(long $flags)
@@ -1609,7 +1612,7 @@
 static const zend_function_entry spl_FilesystemIterator_functions[] = {
        SPL_ME(FilesystemIterator, __construct,   arginfo_r_dir___construct, 
ZEND_ACC_PUBLIC)
        SPL_ME(FilesystemIterator, rewind,        NULL, ZEND_ACC_PUBLIC)
-       SPL_ME(FilesystemIterator, next,          NULL, ZEND_ACC_PUBLIC)
+       SPL_ME(DirectoryIterator,  next,          NULL, ZEND_ACC_PUBLIC)
        SPL_ME(FilesystemIterator, key,           NULL, ZEND_ACC_PUBLIC)
        SPL_ME(FilesystemIterator, current,       NULL, ZEND_ACC_PUBLIC)
        SPL_ME(FilesystemIterator, getFlags,      NULL, ZEND_ACC_PUBLIC)
@@ -2033,7 +2036,7 @@
 {
        spl_filesystem_object *intern = 
(spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
 
-       RETURN_LONG(intern->flags);
+       RETURN_LONG(intern->flags & SPL_FILE_OBJECT_MASK);
 } /* }}} */
 
 /* {{{ proto void SplFileObject::setMaxLineLen(int max_len)
http://cvs.php.net/viewvc.cgi/php-src/ext/spl/spl_directory.h?r1=1.12.2.5.2.4.2.8&r2=1.12.2.5.2.4.2.9&diff_format=u
Index: php-src/ext/spl/spl_directory.h
diff -u php-src/ext/spl/spl_directory.h:1.12.2.5.2.4.2.8 
php-src/ext/spl/spl_directory.h:1.12.2.5.2.4.2.9
--- php-src/ext/spl/spl_directory.h:1.12.2.5.2.4.2.8    Wed Feb 13 12:05:34 2008
+++ php-src/ext/spl/spl_directory.h     Sun May 18 12:17:43 2008
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: spl_directory.h,v 1.12.2.5.2.4.2.8 2008/02/13 12:05:34 helly Exp $ */
+/* $Id: spl_directory.h,v 1.12.2.5.2.4.2.9 2008/05/18 12:17:43 colder Exp $ */
 
 #ifndef SPL_DIRECTORY_H
 #define SPL_DIRECTORY_H
@@ -115,6 +115,7 @@
 #define SPL_FILE_OBJECT_READ_AHEAD         0x00000002 /* read on rewind/next */
 #define SPL_FILE_OBJECT_SKIP_EMPTY         0x00000006 /* skip empty lines */
 #define SPL_FILE_OBJECT_READ_CSV           0x00000008 /* read via fgetcsv */
+#define SPL_FILE_OBJECT_MASK               0x0000000F /* read via fgetcsv */
 
 #define SPL_FILE_DIR_CURRENT_AS_FILEINFO   0x00000000 /* make 
RecursiveDirectoryTree::current() return SplFileInfo */
 #define SPL_FILE_DIR_CURRENT_AS_SELF       0x00000010 /* make 
RecursiveDirectoryTree::current() return getSelf() */
@@ -127,6 +128,8 @@
 #define SPL_FILE_DIR_KEY_MODE_MASK         0x00000F00 /* mask 
RecursiveDirectoryTree::key() */
 #define SPL_FILE_DIR_KEY(intern,mode)      
((intern->flags&SPL_FILE_DIR_KEY_MODE_MASK)==mode)
 
+#define SPL_FILE_DIR_SKIPDOTS              0x00001000 /* Tells whether it 
should skip dots or not */
+
 #endif /* SPL_DIRECTORY_H */
 
 /*

http://cvs.php.net/viewvc.cgi/php-src/ext/spl/tests/dit_004.phpt?view=markup&rev=1.1
Index: php-src/ext/spl/tests/dit_004.phpt
+++ php-src/ext/spl/tests/dit_004.phpt
--TEST--
SPL: DirectoryIterator and clone
--SKIPIF--
<?php if (!extension_loaded("spl")) print "skip"; ?>
--FILE--
<?php
$a = new DirectoryIterator(__DIR__);
$b = clone $a;
var_dump((string)$b == (string)$a);
var_dump($a->key(), $b->key());
$a->next();
$a->next();
$a->next();
$c = clone $a;
var_dump((string)$c == (string)$a);
var_dump($a->key(), $c->key());
?>
===DONE===
--EXPECTF--
bool(true)
int(0)
int(0)
bool(true)
int(3)
int(3)
===DONE===

http://cvs.php.net/viewvc.cgi/php-src/ext/spl/tests/dit_005.phpt?view=markup&rev=1.1
Index: php-src/ext/spl/tests/dit_005.phpt
+++ php-src/ext/spl/tests/dit_005.phpt
--TEST--
SPL: FilesystemIterator and clone
--SKIPIF--
<?php if (!extension_loaded("spl")) print "skip"; ?>
--FILE--
<?php
$a = new FileSystemIterator(__DIR__);
$b = clone $a;
var_dump((string)$b == (string)$a);
var_dump($a->key() == $b->key());
$a->next();
$a->next();
$a->next();
$c = clone $a;
var_dump((string)$c == (string)$a);
var_dump($a->key() == $c->key());
?>
===DONE===
--EXPECTF--
bool(true)
bool(true)
bool(true)
bool(true)
===DONE===

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to