diff options
-rwxr-xr-x | ext/spl/doxygen.cfg | 4 | ||||
-rwxr-xr-x | ext/spl/internal/regexiterator.inc | 3 | ||||
-rwxr-xr-x | ext/spl/spl_functions.c | 9 | ||||
-rwxr-xr-x | ext/spl/spl_functions.h | 6 | ||||
-rwxr-xr-x | ext/spl/spl_iterators.c | 48 | ||||
-rwxr-xr-x | ext/spl/spl_iterators.h | 2 | ||||
-rwxr-xr-x | ext/spl/tests/iterator_052.phpt | 233 | ||||
-rwxr-xr-x | ext/spl/tests/iterator_053.phpt | 355 |
8 files changed, 473 insertions, 187 deletions
diff --git a/ext/spl/doxygen.cfg b/ext/spl/doxygen.cfg index d58017a6ad..4b71787238 100755 --- a/ext/spl/doxygen.cfg +++ b/ext/spl/doxygen.cfg @@ -194,10 +194,10 @@ PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- CLASS_DIAGRAMS = YES HIDE_UNDOC_RELATIONS = YES -HAVE_DOT = NO +HAVE_DOT = YES CLASS_GRAPH = YES COLLABORATION_GRAPH = YES -UML_LOOK = NO +UML_LOOK = YES TEMPLATE_RELATIONS = NO INCLUDE_GRAPH = YES INCLUDED_BY_GRAPH = YES diff --git a/ext/spl/internal/regexiterator.inc b/ext/spl/internal/regexiterator.inc index 8c38dcc562..bdbf39f548 100755 --- a/ext/spl/internal/regexiterator.inc +++ b/ext/spl/internal/regexiterator.inc @@ -12,7 +12,7 @@ /** * @brief Regular expression filter for iterators * @author Marcus Boerger - * @version 1.1 + * @version 1.0 * @since PHP 5.1 * * This filter iterator assumes that the inner iterator @@ -26,6 +26,7 @@ class RegexIterator implements FilterIterator const GET_MATCH = 1; /**< Mode: Return the first matche (if any) */ const ALL_MATCHES = 2; /**< Mode: Return all matches (if any) */ const SPLIT = 3; /**< Mode: Return the split values (if any) */ + const REPLACE = 4; /**< Mode: Replace the input key or current */ private $regex; /**< the regular expression to match against */ private $flags; /**< special flags (self::USE_KEY) */ diff --git a/ext/spl/spl_functions.c b/ext/spl/spl_functions.c index c1beb5867c..231646cc85 100755 --- a/ext/spl/spl_functions.c +++ b/ext/spl/spl_functions.c @@ -95,14 +95,9 @@ void spl_register_functions(zend_class_entry * class_entry, zend_function_entry /* }}} */ /* {{{ spl_register_property */ -void spl_register_property( zend_class_entry * class_entry, char *prop_name, zval *prop_val, int prop_flags TSRMLS_DC) +void spl_register_property( zend_class_entry * class_entry, char *prop_name, int prop_name_len, int prop_flags TSRMLS_DC) { - if (!prop_val) { - INIT_PZVAL(prop_val); - prop_val->type = IS_NULL; - } - - zend_declare_property(class_entry, prop_name, strlen(prop_name), prop_val, prop_flags TSRMLS_CC); + zend_declare_property_null(class_entry, prop_name, prop_name_len, prop_flags TSRMLS_CC); } /* }}} */ diff --git a/ext/spl/spl_functions.h b/ext/spl/spl_functions.h index a36fa6e808..04b8603732 100755 --- a/ext/spl/spl_functions.h +++ b/ext/spl/spl_functions.h @@ -49,8 +49,8 @@ typedef zend_object_value (*create_object_func_t)(zend_class_entry *class_type T #define REGISTER_SPL_FUNCTIONS(class_name, function_list) \ spl_register_functions(spl_ce_ ## class_name, function_list TSRMLS_CC); -#define REGISTER_SPL_PROPERTY(class_name, prop_name) \ - spl_register_property(spl_ce_ ## class_name, prop_name, prop_val, prop_flags TSRMLS_CC); +#define REGISTER_SPL_PROPERTY(class_name, prop_name, prop_flags) \ + spl_register_property(spl_ce_ ## class_name, prop_name, sizeof(prop_name)-1, prop_flags TSRMLS_CC); #define REGISTER_SPL_CLASS_CONST_LONG(class_name, const_name, value) \ zend_declare_class_constant_long(spl_ce_ ## class_name, const_name, sizeof(const_name)-1, (long)value TSRMLS_CC); @@ -64,7 +64,7 @@ void spl_register_interface(zend_class_entry ** ppce, char * class_name, zend_fu void spl_register_parent_ce(zend_class_entry * class_entry, zend_class_entry * parent_class TSRMLS_DC); void spl_register_functions(zend_class_entry * class_entry, zend_function_entry * function_list TSRMLS_DC); -void spl_register_property( zend_class_entry * class_entry, char *prop_name, zval *prop_val, int prop_flags TSRMLS_DC); +void spl_register_property( zend_class_entry * class_entry, char *prop_name, int prop_name_len, int prop_flags TSRMLS_DC); /* sub: whether to allow subclasses/interfaces allow = 0: allow all classes and interfaces diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index 34886970da..88b27c2ea1 100755 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -1003,13 +1003,13 @@ static spl_dual_it_object* spl_dual_it_construct(INTERNAL_FUNCTION_PARAMETERS, z case DIT_RegexIterator: case DIT_RecursiveRegexIterator: { char *regex; - int len, poptions, coptions; - pcre_extra *extra = NULL; + int regex_len; long mode = REGIT_MODE_MATCH; + intern->u.regex.use_flags = ZEND_NUM_ARGS() >= 5; intern->u.regex.flags = 0; intern->u.regex.preg_flags = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os|lll", &zobject, ce_inner, ®ex, &len, &intern->u.regex.flags, &mode, &intern->u.regex.preg_flags) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Os|lll", &zobject, ce_inner, ®ex, ®ex_len, &intern->u.regex.flags, &mode, &intern->u.regex.preg_flags) == FAILURE) { php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); return NULL; } @@ -1019,8 +1019,8 @@ static spl_dual_it_object* spl_dual_it_construct(INTERNAL_FUNCTION_PARAMETERS, z return NULL; } intern->u.regex.mode = mode; - intern->u.regex.regex = estrndup(regex, len); - intern->u.regex.pce = pcre_get_compiled_regex_cache(regex, len, &extra, &poptions, &coptions TSRMLS_CC); + intern->u.regex.regex = estrndup(regex, regex_len); + intern->u.regex.pce = pcre_get_compiled_regex_cache(regex, regex_len TSRMLS_CC); intern->u.regex.pce->refcount++; break;; } @@ -1388,11 +1388,9 @@ SPL_METHOD(RegexIterator, __construct) SPL_METHOD(RegexIterator, accept) { spl_dual_it_object *intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - char *subject, tmp[32]; - int subject_len, use_copy, count; - zval subject_copy, zcount; - pcre *regex = intern->u.regex.pce->re; - pcre_extra *extra = intern->u.regex.pce->extra; + char *subject, tmp[32], *result; + int subject_len, use_copy, count, result_len; + zval subject_copy, zcount, *replacement; if (intern->u.regex.flags & REGIT_USE_KEY) { if (intern->current.key_type == HASH_KEY_IS_LONG) { @@ -1433,7 +1431,7 @@ SPL_METHOD(RegexIterator, accept) { case REGIT_MODE_MAX: /* won't happen but makes compiler happy */ case REGIT_MODE_MATCH: - count = pcre_exec(regex, extra, subject, subject_len, 0, 0, NULL, 0); + count = pcre_exec(intern->u.regex.pce->re, intern->u.regex.pce->extra, subject, subject_len, 0, 0, NULL, 0); RETVAL_BOOL(count >= 0); break; @@ -1445,8 +1443,13 @@ SPL_METHOD(RegexIterator, accept) } zval_ptr_dtor(&intern->current.data); MAKE_STD_ZVAL(intern->current.data); +<<<<<<< spl_iterators.c + php_pcre_match_impl(intern->u.regex.pce, subject, subject_len, &zcount, + intern->current.data, intern->u.regex.mode == REGIT_MODE_ALL_MATCHES, intern->u.regex.use_flags, intern->u.regex.preg_flags, 0 TSRMLS_CC); +======= php_pcre_match(regex, extra, subject, subject_len, &zcount, intern->current.data, intern->u.regex.mode == REGIT_MODE_ALL_MATCHES, 0, 0, 0, 0 TSRMLS_CC); +>>>>>>> 1.141 count = zend_hash_num_elements(Z_ARRVAL_P(intern->current.data)); RETVAL_BOOL(count > 0); break; @@ -1458,10 +1461,31 @@ SPL_METHOD(RegexIterator, accept) } zval_ptr_dtor(&intern->current.data); MAKE_STD_ZVAL(intern->current.data); +<<<<<<< spl_iterators.c + php_pcre_split_impl(intern->u.regex.pce, subject, subject_len, intern->current.data, -1, intern->u.regex.preg_flags TSRMLS_CC); +======= php_pcre_split(regex, extra, subject, subject_len, intern->current.data, 0, -1, 0, 0, 0 TSRMLS_CC); +>>>>>>> 1.141 count = zend_hash_num_elements(Z_ARRVAL_P(intern->current.data)); RETVAL_BOOL(count > 1); break; + + case REGIT_MODE_REPLACE: + replacement = zend_read_property(intern->std.ce, getThis(), "replacement", sizeof("replacement")-1, 1 TSRMLS_CC); + result = php_pcre_replace_impl(intern->u.regex.pce, subject, subject_len, replacement, 0, &result_len, 0, NULL TSRMLS_CC); + + if (intern->u.regex.flags & REGIT_USE_KEY) { + if (intern->current.key_type != HASH_KEY_IS_LONG) { + efree(intern->current.str_key.v); + } + intern->current.key_type = HASH_KEY_IS_STRING; + intern->current.str_key.s = result; + intern->current.str_key_len = result_len + 1; + } else { + zval_ptr_dtor(&intern->current.data); + MAKE_STD_ZVAL(intern->current.data); + ZVAL_STRINGL(intern->current.data, result, result_len, 0); + } } if (use_copy) { @@ -2830,6 +2854,8 @@ PHP_MINIT_FUNCTION(spl_iterators) REGISTER_SPL_CLASS_CONST_LONG(RegexIterator, "GET_MATCH", REGIT_MODE_GET_MATCH); REGISTER_SPL_CLASS_CONST_LONG(RegexIterator, "ALL_MATCHES", REGIT_MODE_ALL_MATCHES); REGISTER_SPL_CLASS_CONST_LONG(RegexIterator, "SPLIT", REGIT_MODE_SPLIT); + REGISTER_SPL_CLASS_CONST_LONG(RegexIterator, "REPLACE", REGIT_MODE_REPLACE); + REGISTER_SPL_PROPERTY(RegexIterator, "replacement", 0); REGISTER_SPL_SUB_CLASS_EX(RecursiveRegexIterator, RegexIterator, spl_dual_it_new, spl_funcs_RecursiveRegexIterator); REGISTER_SPL_IMPLEMENTS(RecursiveRegexIterator, RecursiveIterator); #else diff --git a/ext/spl/spl_iterators.h b/ext/spl/spl_iterators.h index 20ab0c7fd0..4b0528ebc2 100755 --- a/ext/spl/spl_iterators.h +++ b/ext/spl/spl_iterators.h @@ -100,6 +100,7 @@ typedef enum { REGIT_MODE_GET_MATCH, REGIT_MODE_ALL_MATCHES, REGIT_MODE_SPLIT, + REGIT_MODE_REPLACE, REGIT_MODE_MAX, } regex_mode; @@ -137,6 +138,7 @@ typedef struct _spl_dual_it_object { } append; #if HAVE_PCRE || HAVE_BUNDLED_PCRE struct { + int use_flags; int flags; regex_mode mode; long preg_flags; diff --git a/ext/spl/tests/iterator_052.phpt b/ext/spl/tests/iterator_052.phpt index 574868bd65..827c8f00ac 100755 --- a/ext/spl/tests/iterator_052.phpt +++ b/ext/spl/tests/iterator_052.phpt @@ -7,6 +7,15 @@ SPL: RegexIterator::ALL_MATCHES class MyRegexIterator extends RegexIterator { + public $uk, $re; + + function __construct($it, $re, $flags, $mode) + { + $this->uk = $flags & self::USE_KEY; + $this->re = $re; + parent::__construct($it, $re, $flags, $mode); + } + function show() { foreach($this as $k => $v) @@ -15,6 +24,14 @@ class MyRegexIterator extends RegexIterator var_dump($v); } } + + function accept() + { + @preg_match_all($this->re, (string)($this->uk ? $this->key() : $this->current()), $sub); + $ret = parent::accept(); + var_dump($sub == $this->current()); + return $ret; + } } $ar = new ArrayIterator(array('1','1,2','1,2,3','',NULL,array(),'FooBar',',',',,')); @@ -30,40 +47,150 @@ var_dump($ar); ===DONE=== <?php exit(0); ?> --EXPECTF-- +bool(true) +int(0) +array(3) { + [0]=> + array(0) { + } + [1]=> + array(0) { + } + [2]=> + array(0) { + } +} +bool(true) int(1) -array(1) { +array(3) { [0]=> - array(3) { + array(1) { [0]=> string(3) "1,2" - [1]=> + } + [1]=> + array(1) { + [0]=> string(1) "1" - [2]=> + } + [2]=> + array(1) { + [0]=> string(1) "2" } } +bool(true) int(2) -array(1) { +array(3) { [0]=> - array(3) { + array(1) { [0]=> string(3) "1,2" - [1]=> + } + [1]=> + array(1) { + [0]=> string(1) "1" - [2]=> + } + [2]=> + array(1) { + [0]=> string(1) "2" } } +bool(true) +int(3) +array(3) { + [0]=> + array(0) { + } + [1]=> + array(0) { + } + [2]=> + array(0) { + } +} +bool(true) +int(4) +array(3) { + [0]=> + array(0) { + } + [1]=> + array(0) { + } + [2]=> + array(0) { + } +} +bool(true) +int(5) +array(3) { + [0]=> + array(0) { + } + [1]=> + array(0) { + } + [2]=> + array(0) { + } +} +bool(true) +int(6) +array(3) { + [0]=> + array(0) { + } + [1]=> + array(0) { + } + [2]=> + array(0) { + } +} +bool(true) +int(7) +array(3) { + [0]=> + array(0) { + } + [1]=> + array(0) { + } + [2]=> + array(0) { + } +} +bool(true) +int(8) +array(3) { + [0]=> + array(0) { + } + [1]=> + array(0) { + } + [2]=> + array(0) { + } +} +bool(true) int(0) -array(1) { +array(2) { [0]=> - array(2) { + array(1) { [0]=> string(1) "1" - [1]=> + } + [1]=> + array(1) { + [0]=> string(1) "1" } } +bool(true) int(1) array(2) { [0]=> @@ -71,40 +198,98 @@ array(2) { [0]=> string(1) "1" [1]=> - string(1) "1" + string(1) "2" } [1]=> array(2) { [0]=> - string(1) "2" + string(1) "1" [1]=> string(1) "2" } } +bool(true) int(2) -array(3) { +array(2) { [0]=> - array(2) { + array(3) { [0]=> string(1) "1" [1]=> - string(1) "1" + string(1) "2" + [2]=> + string(1) "3" } [1]=> - array(2) { + array(3) { [0]=> - string(1) "2" + string(1) "1" [1]=> string(1) "2" - } - [2]=> - array(2) { - [0]=> - string(1) "3" - [1]=> + [2]=> string(1) "3" } } +bool(true) +int(3) +array(2) { + [0]=> + array(0) { + } + [1]=> + array(0) { + } +} +bool(true) +int(4) +array(2) { + [0]=> + array(0) { + } + [1]=> + array(0) { + } +} +bool(true) +int(5) +array(2) { + [0]=> + array(0) { + } + [1]=> + array(0) { + } +} +bool(true) +int(6) +array(2) { + [0]=> + array(0) { + } + [1]=> + array(0) { + } +} +bool(true) +int(7) +array(2) { + [0]=> + array(0) { + } + [1]=> + array(0) { + } +} +bool(true) +int(8) +array(2) { + [0]=> + array(0) { + } + [1]=> + array(0) { + } +} object(ArrayIterator)#%d (9) { [0]=> %s(1) "1" diff --git a/ext/spl/tests/iterator_053.phpt b/ext/spl/tests/iterator_053.phpt index bc4b1440d6..c4d7418aaf 100755 --- a/ext/spl/tests/iterator_053.phpt +++ b/ext/spl/tests/iterator_053.phpt @@ -1,5 +1,5 @@ --TEST-- -SPL: RegexIterator::ALL_MATCHES, USE_KEY +SPL: RegexIterator::ALL_MATCHES --SKIPIF-- <?php if (!extension_loaded("spl")) print "skip"; ?> --FILE-- @@ -7,6 +7,15 @@ SPL: RegexIterator::ALL_MATCHES, USE_KEY class MyRegexIterator extends RegexIterator { + public $uk, $re; + + function __construct($it, $re, $flags, $mode) + { + $this->uk = $flags & self::USE_KEY; + $this->re = $re; + parent::__construct($it, $re, $flags, $mode); + } + function show() { foreach($this as $k => $v) @@ -15,9 +24,17 @@ class MyRegexIterator extends RegexIterator var_dump($v); } } + + function accept() + { + @preg_match_all($this->re, (string)($this->uk ? $this->key() : $this->current()), $sub); + $ret = parent::accept(); + var_dump($sub == $this->current()); + return $ret; + } } -$ar = new ArrayIterator(array('1'=>0,'1,2'=>1,'1,2,3'=>2,0=>3,'FooBar'=>4,','=>5,',,'=>6)); +$ar = new ArrayIterator(array('1','1,2','1,2,3','',NULL,array(),'FooBar',',',',,')); $it = new MyRegexIterator($ar, '/(\d),(\d)/', RegexIterator::USE_KEY, RegexIterator::ALL_MATCHES); $it->show(); @@ -30,208 +47,268 @@ var_dump($ar); ===DONE=== <?php exit(0); ?> --EXPECTF-- -string(3) "1,2" -array(1) { +bool(true) +int(0) +array(3) { [0]=> - array(3) { - [0]=> - string(3) "1,2" - [1]=> - string(1) "1" - [2]=> - string(1) "2" + array(0) { + } + [1]=> + array(0) { + } + [2]=> + array(0) { } } -string(5) "1,2,3" -array(1) { +bool(true) +int(1) +array(3) { [0]=> - array(3) { - [0]=> - string(3) "1,2" - [1]=> - string(1) "1" - [2]=> - string(1) "2" + array(0) { + } + [1]=> + array(0) { + } + [2]=> + array(0) { } } -int(1) -array(1) { +bool(true) +int(2) +array(3) { [0]=> - array(2) { - [0]=> - string(1) "1" - [1]=> - string(1) "1" + array(0) { + } + [1]=> + array(0) { + } + [2]=> + array(0) { } } -string(3) "1,2" -array(2) { +bool(true) +int(3) +array(3) { [0]=> - array(2) { - [0]=> - string(1) "1" - [1]=> - string(1) "1" + array(0) { } [1]=> - array(2) { - [0]=> - string(1) "2" - [1]=> - string(1) "2" + array(0) { + } + [2]=> + array(0) { } } -string(5) "1,2,3" +bool(true) +int(4) array(3) { [0]=> - array(2) { - [0]=> - string(1) "1" - [1]=> - string(1) "1" + array(0) { } [1]=> - array(2) { - [0]=> - string(1) "2" - [1]=> - string(1) "2" + array(0) { } [2]=> - array(2) { - [0]=> - string(1) "3" - [1]=> - string(1) "3" + array(0) { } } -int(0) -array(1) { +bool(true) +int(5) +array(3) { [0]=> - array(2) { - [0]=> - string(1) "0" - [1]=> - string(1) "0" + array(0) { + } + [1]=> + array(0) { + } + [2]=> + array(0) { } } -object(ArrayIterator)#%d (7) { +bool(true) +int(6) +array(3) { + [0]=> + array(0) { + } [1]=> - int(0) - ["1,2"]=> - int(1) - ["1,2,3"]=> - int(2) + array(0) { + } + [2]=> + array(0) { + } +} +bool(true) +int(7) +array(3) { [0]=> - int(3) - ["FooBar"]=> - int(4) - [","]=> - int(5) - [",,"]=> - int(6) + array(0) { + } + [1]=> + array(0) { + } + [2]=> + array(0) { + } } -===DONE=== ---UEXPECTF-- -unicode(3) "1,2" -array(1) { +bool(true) +int(8) +array(3) { [0]=> - array(3) { - [0]=> - string(3) "1,2" - [1]=> - string(1) "1" - [2]=> - string(1) "2" + array(0) { + } + [1]=> + array(0) { + } + [2]=> + array(0) { } } -unicode(5) "1,2,3" -array(1) { +bool(true) +int(0) +array(2) { [0]=> - array(3) { + array(1) { [0]=> - string(3) "1,2" - [1]=> - string(1) "1" - [2]=> - string(1) "2" + string(1) "0" + } + [1]=> + array(1) { + [0]=> + string(1) "0" } } +bool(true) int(1) -array(1) { +array(2) { [0]=> - array(2) { + array(1) { [0]=> string(1) "1" - [1]=> + } + [1]=> + array(1) { + [0]=> string(1) "1" } } -unicode(3) "1,2" +bool(true) +int(2) array(2) { [0]=> - array(2) { + array(1) { [0]=> - string(1) "1" - [1]=> - string(1) "1" + string(1) "2" } [1]=> - array(2) { + array(1) { [0]=> string(1) "2" - [1]=> - string(1) "2" } } -unicode(5) "1,2,3" -array(3) { +bool(true) +int(3) +array(2) { [0]=> - array(2) { + array(1) { [0]=> - string(1) "1" - [1]=> - string(1) "1" + string(1) "3" } [1]=> - array(2) { + array(1) { [0]=> - string(1) "2" - [1]=> - string(1) "2" + string(1) "3" } - [2]=> - array(2) { +} +bool(true) +int(4) +array(2) { + [0]=> + array(1) { [0]=> - string(1) "3" - [1]=> - string(1) "3" + string(1) "4" + } + [1]=> + array(1) { + [0]=> + string(1) "4" } } -int(0) -array(1) { +bool(true) +int(5) +array(2) { [0]=> - array(2) { + array(1) { [0]=> - string(1) "0" - [1]=> - string(1) "0" + string(1) "5" + } + [1]=> + array(1) { + [0]=> + string(1) "5" } } -object(ArrayIterator)#%d (7) { +bool(true) +int(6) +array(2) { + [0]=> + array(1) { + [0]=> + string(1) "6" + } [1]=> - int(0) - [u"1,2"]=> - int(1) - [u"1,2,3"]=> - int(2) + array(1) { + [0]=> + string(1) "6" + } +} +bool(true) +int(7) +array(2) { [0]=> - int(3) - [u"FooBar"]=> - int(4) - [u","]=> - int(5) - [u",,"]=> - int(6) + array(1) { + [0]=> + string(1) "7" + } + [1]=> + array(1) { + [0]=> + string(1) "7" + } +} +bool(true) +int(8) +array(2) { + [0]=> + array(1) { + [0]=> + string(1) "8" + } + [1]=> + array(1) { + [0]=> + string(1) "8" + } +} +object(ArrayIterator)#%d (9) { + [0]=> + %s(1) "1" + [1]=> + %s(3) "1,2" + [2]=> + %s(5) "1,2,3" + [3]=> + %s(0) "" + [4]=> + NULL + [5]=> + array(0) { + } + [6]=> + %s(6) "FooBar" + [7]=> + %s(1) "," + [8]=> + %s(2) ",," } ===DONE=== |