colder Fri May 16 13:22:02 2008 UTC Added files: /php-src/ext/spl/tests dit_004.phpt dit_005.phpt
Modified files: /php-src/ext/spl spl_directory.c spl_directory.h Log: Fix FilesystemIterator with ./..
http://cvs.php.net/viewvc.cgi/php-src/ext/spl/spl_directory.c?r1=1.153&r2=1.154&diff_format=u Index: php-src/ext/spl/spl_directory.c diff -u php-src/ext/spl/spl_directory.c:1.153 php-src/ext/spl/spl_directory.c:1.154 --- php-src/ext/spl/spl_directory.c:1.153 Thu May 15 17:22:03 2008 +++ php-src/ext/spl/spl_directory.c Fri May 16 13:22:02 2008 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_directory.c,v 1.153 2008/05/15 17:22:03 colder Exp $ */ +/* $Id: spl_directory.c,v 1.154 2008/05/16 13:22:02 colder Exp $ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -212,11 +212,18 @@ #define IS_SLASH_AT(type, zs, pos) (type == IS_UNICODE ? IS_U_SLASH(zs.u[pos]) : IS_SLASH(zs.s[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, zend_uchar type, zstr path, int path_len TSRMLS_DC) { int options = REPORT_ERRORS; + int skip_dots = intern->flags & SPL_FILE_DIR_SKIPDOTS; #if HELLY_0 if (php_stream_is(intern->u.dir.dirp, &php_glob_stream_ops)) { @@ -240,7 +247,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)); } } /* }}} */ @@ -299,13 +308,18 @@ spl_filesystem_object *intern; spl_filesystem_object *source; int index; + int skip_dots; old_object = zend_objects_get_address(zobject TSRMLS_CC); source = (spl_filesystem_object*)old_object; + skip_dots = source->flags & SPL_FILE_DIR_SKIPDOTS; + 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_type = source->_path_type; @@ -319,7 +333,9 @@ spl_filesystem_dir_open(intern, source->_path_type, source->_path, source->_path_len TSRMLS_CC); /* read until we hit the position in which we were before */ for(index = 0; index < source->u.dir.index; ++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)); } intern->u.dir.index = index; break; @@ -330,7 +346,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; @@ -514,12 +529,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); @@ -614,6 +623,11 @@ flags = SPL_FILE_DIR_KEY_AS_PATHNAME|SPL_FILE_DIR_CURRENT_AS_SELF; parsed = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "t", &path, &len, &path_type); } + + 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; @@ -625,6 +639,8 @@ } intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + intern->flags = flags; + if ((ctor_flags & DIT_CTOR_GLOB) && ( (path_type == IS_STRING && strstr(path.s, "glob://") != path.s) || (path_type == IS_UNICODE && u_strstr(path.u, u_glob) != path.u) @@ -637,7 +653,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); } @@ -692,9 +707,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.v) { efree(intern->file_name.v); intern->file_name = NULL_ZSTR; @@ -1183,7 +1201,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); } /* }}} */ @@ -1203,30 +1221,13 @@ } /* }}} */ -/* {{{ proto void FilesystemIterator::next() U - 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.v) { - efree(intern->file_name.v); - intern->file_name = NULL_ZSTR; - } -} -/* }}} */ - /* {{{ proto int FilesystemIterator::getFlags() U 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) U @@ -1743,7 +1744,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) @@ -2180,7 +2181,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) U http://cvs.php.net/viewvc.cgi/php-src/ext/spl/spl_directory.h?r1=1.42&r2=1.43&diff_format=u Index: php-src/ext/spl/spl_directory.h diff -u php-src/ext/spl/spl_directory.h:1.42 php-src/ext/spl/spl_directory.h:1.43 --- php-src/ext/spl/spl_directory.h:1.42 Wed Feb 13 12:01:16 2008 +++ php-src/ext/spl/spl_directory.h Fri May 16 13:22:02 2008 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_directory.h,v 1.42 2008/02/13 12:01:16 helly Exp $ */ +/* $Id: spl_directory.h,v 1.43 2008/05/16 13:22:02 colder Exp $ */ #ifndef SPL_DIRECTORY_H #define SPL_DIRECTORY_H @@ -117,6 +117,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 /* mask */ #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() */ @@ -129,6 +130,9 @@ #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