hirokawa Sun, 25 Sep 2011 08:01:54 +0000 Revision: http://svn.php.net/viewvc?view=revision&revision=317262
Log: added mb_ereg_replace_callback(). Changed paths: U php/php-src/trunk/ext/mbstring/mbstring.c U php/php-src/trunk/ext/mbstring/php_mbregex.c U php/php-src/trunk/ext/mbstring/php_mbregex.h Modified: php/php-src/trunk/ext/mbstring/mbstring.c =================================================================== --- php/php-src/trunk/ext/mbstring/mbstring.c 2011-09-25 07:23:54 UTC (rev 317261) +++ php/php-src/trunk/ext/mbstring/mbstring.c 2011-09-25 08:01:54 UTC (rev 317262) @@ -467,6 +467,13 @@ ZEND_ARG_INFO(0, string) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_ereg_replace_callback, 0, 0, 3) + ZEND_ARG_INFO(0, pattern) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(0, string) + ZEND_ARG_INFO(0, option) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_split, 0, 0, 2) ZEND_ARG_INFO(0, pattern) ZEND_ARG_INFO(0, string) Modified: php/php-src/trunk/ext/mbstring/php_mbregex.c =================================================================== --- php/php-src/trunk/ext/mbstring/php_mbregex.c 2011-09-25 07:23:54 UTC (rev 317261) +++ php/php-src/trunk/ext/mbstring/php_mbregex.c 2011-09-25 08:01:54 UTC (rev 317262) @@ -784,7 +784,7 @@ /* }}} */ /* {{{ _php_mb_regex_ereg_replace_exec */ -static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOptionType options) +static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOptionType options, int is_callable) { zval **arg_pattern_zval; @@ -793,9 +793,11 @@ char *replace; int replace_len; + zval **arg_replace_zval; char *string; int string_len; + zval **arg_string_zval; char *p; php_mb_regex_t *re; @@ -826,14 +828,20 @@ char *option_str = NULL; int option_str_len = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zss|s", - &arg_pattern_zval, - &replace, &replace_len, - &string, &string_len, - &option_str, &option_str_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZZ|s", + &arg_pattern_zval, + &arg_replace_zval, + &arg_string_zval, + &option_str, &option_str_len) == FAILURE) { RETURN_FALSE; } + replace = Z_STRVAL_PP(arg_replace_zval); + replace_len = Z_STRLEN_PP(arg_replace_zval); + + string = Z_STRVAL_PP(arg_string_zval); + string_len = Z_STRLEN_PP(arg_string_zval); + if (option_str != NULL) { _php_mb_regex_init_options(option_str, option_str_len, &options, &syntax, &eval); } else { @@ -859,7 +867,7 @@ RETURN_FALSE; } - if (eval) { + if (eval || is_callable) { pbuf = &eval_buf; description = zend_make_compiled_string_description("mbregex replace" TSRMLS_CC); } else { @@ -867,6 +875,22 @@ description = NULL; } + if (is_callable) { + char *callback_name; + if (!zend_is_callable(*arg_replace_zval, 0, &callback_name TSRMLS_CC)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Requires argument 2, '%s', to be a valid callback", callback_name); + efree(callback_name); + MAKE_COPY_ZVAL(arg_string_zval, return_value); + RETURN_FALSE; + } + efree(callback_name); + + if (eval) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Option 'e' cannot be used with replacement callback"); + RETURN_FALSE; + } + } + /* do the actual work */ err = 0; pos = (OnigUChar *)string; @@ -911,6 +935,8 @@ i += fwd; } } + + if (eval) { zval v; /* null terminate buffer */ @@ -928,7 +954,38 @@ /* Clean up */ eval_buf.len = 0; zval_dtor(&v); + } else if (is_callable) { + zval *retval_ptr; + zval **args[1]; + zval *subpats; + int i; + + MAKE_STD_ZVAL(subpats); + array_init(subpats); + + for (i = 0; i < regs->num_regs; i++) { + add_next_index_stringl(subpats, string + regs->beg[i], regs->end[i] - regs->beg[i], 1); + } + + args[0] = &subpats; + /* null terminate buffer */ + smart_str_0(&eval_buf); + + if (call_user_function_ex(EG(function_table), NULL, *arg_replace_zval, &retval_ptr, 1, args, 0, + NULL TSRMLS_CC) == SUCCESS && retval_ptr) { + convert_to_string_ex(&retval_ptr); + smart_str_appendl(&out_buf, Z_STRVAL_P(retval_ptr), Z_STRLEN_P(retval_ptr)); + eval_buf.len = 0; + zval_ptr_dtor(&retval_ptr); + } else { + efree(description); + if (!EG(exception)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call custom replacement function"); + } + } + zval_ptr_dtor(&subpats); } + n = regs->end[0]; if ((pos - (OnigUChar *)string) < n) { pos = (OnigUChar *)string + n; @@ -969,7 +1026,7 @@ Replace regular expression for multibyte string */ PHP_FUNCTION(mb_ereg_replace) { - _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); + _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 0); } /* }}} */ @@ -977,10 +1034,18 @@ Case insensitive replace regular expression for multibyte string */ PHP_FUNCTION(mb_eregi_replace) { - _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAM_PASSTHRU, ONIG_OPTION_IGNORECASE); + _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAM_PASSTHRU, ONIG_OPTION_IGNORECASE, 0); } /* }}} */ +/* {{{ proto string mb_ereg_replace_callback(string pattern, string callback, string string [, string option]) + regular expression for multibyte string using replacement callback */ +PHP_FUNCTION(mb_ereg_replace_callback) +{ + _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 1); +} +/* }}} */ + /* {{{ proto array mb_split(string pattern, string string [, int limit]) split multibyte string into array by regular expression */ PHP_FUNCTION(mb_split) Modified: php/php-src/trunk/ext/mbstring/php_mbregex.h =================================================================== --- php/php-src/trunk/ext/mbstring/php_mbregex.h 2011-09-25 07:23:54 UTC (rev 317261) +++ php/php-src/trunk/ext/mbstring/php_mbregex.h 2011-09-25 08:01:54 UTC (rev 317262) @@ -34,6 +34,7 @@ PHP_FE(mb_eregi, arginfo_mb_eregi) \ PHP_FE(mb_ereg_replace, arginfo_mb_ereg_replace) \ PHP_FE(mb_eregi_replace, arginfo_mb_eregi_replace) \ + PHP_FE(mb_ereg_replace_callback, arginfo_mb_ereg_replace_callback) \ PHP_FE(mb_split, arginfo_mb_split) \ PHP_FE(mb_ereg_match, arginfo_mb_ereg_match) \ PHP_FE(mb_ereg_search, arginfo_mb_ereg_search) \ @@ -81,6 +82,7 @@ PHP_FUNCTION(mb_eregi); PHP_FUNCTION(mb_ereg_replace); PHP_FUNCTION(mb_eregi_replace); +PHP_FUNCTION(mb_ereg_replace_callback); PHP_FUNCTION(mb_split); PHP_FUNCTION(mb_ereg_match); PHP_FUNCTION(mb_ereg_search);
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php