andrei Mon Oct 9 19:48:32 2006 UTC Modified files: /php-src/ext/standard basic_functions.c Log: Unicode support for call_user_* functions.
http://cvs.php.net/viewvc.cgi/php-src/ext/standard/basic_functions.c?r1=1.811&r2=1.812&diff_format=u Index: php-src/ext/standard/basic_functions.c diff -u php-src/ext/standard/basic_functions.c:1.811 php-src/ext/standard/basic_functions.c:1.812 --- php-src/ext/standard/basic_functions.c:1.811 Mon Oct 9 02:48:06 2006 +++ php-src/ext/standard/basic_functions.c Mon Oct 9 19:48:32 2006 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: basic_functions.c,v 1.811 2006/10/09 02:48:06 pollita Exp $ */ +/* $Id: basic_functions.c,v 1.812 2006/10/09 19:48:32 andrei Exp $ */ #include "php.h" #include "php_streams.h" @@ -5001,197 +5001,162 @@ } /* }}} */ -/* {{{ proto mixed call_user_func(string function_name [, mixed parmeter] [, mixed ...]) +/* {{{ proto mixed call_user_func(string function_name [, mixed parmeter] [, mixed ...]) U Call a user function which is the first parameter */ PHP_FUNCTION(call_user_func) { - zval ***params; + zval ***params = NULL; + int n_params = 0; zval *retval_ptr; - zval name; - int argc = ZEND_NUM_ARGS(); - - if (argc < 1) { - WRONG_PARAM_COUNT; - } - - params = safe_emalloc(sizeof(zval **), argc, 0); + zval *callback, name; + zend_fcall_info fci; + zend_fcall_info_cache fci_cache = empty_fcall_info_cache; - if (zend_get_parameters_array_ex(1, params) == FAILURE) { - efree(params); - RETURN_FALSE; - } - - if (Z_TYPE_PP(params[0]) != IS_STRING && - Z_TYPE_PP(params[0]) != IS_UNICODE && - Z_TYPE_PP(params[0]) != IS_ARRAY) { - SEPARATE_ZVAL(params[0]); - convert_to_string_ex(params[0]); + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z*", &callback, ¶ms, &n_params) == FAILURE) { + return; } - if (!zend_is_callable(*params[0], 0, &name)) { - convert_to_string(&name); - php_error_docref1(NULL TSRMLS_CC, Z_STRVAL(name), E_WARNING, "First argument is expected to be a valid callback"); - zval_dtor(&name); - efree(params); - RETURN_NULL(); + if (zend_fcall_info_init(callback, &fci, &fci_cache TSRMLS_CC) == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "first parameter is expected to be a valid callback"); + return; } - if (zend_get_parameters_array_ex(argc, params) == FAILURE) { - efree(params); - RETURN_FALSE; - } + fci.retval_ptr_ptr = &retval_ptr; + fci.params = params; + fci.param_count = n_params; + fci.no_separation = 0; - if (call_user_function_ex(EG(function_table), NULL, *params[0], &retval_ptr, argc-1, params+1, 0, NULL TSRMLS_CC) == SUCCESS) { + if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS) { if (retval_ptr) { COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr); } } else { - convert_to_string(&name); - if (argc > 1) { - SEPARATE_ZVAL(params[1]); - convert_to_string_ex(params[1]); - if (argc > 2) { - SEPARATE_ZVAL(params[2]); - convert_to_string_ex(params[2]); - php_error_docref1(NULL TSRMLS_CC, Z_STRVAL(name), E_WARNING, "Unable to call %R(%s,%s)", Z_TYPE(name), Z_UNIVAL(name), Z_STRVAL_PP(params[1]), Z_STRVAL_PP(params[2])); - } else { - php_error_docref1(NULL TSRMLS_CC, Z_STRVAL(name), E_WARNING, "Unable to call %R(%s)", Z_TYPE(name), Z_UNIVAL(name), Z_STRVAL_PP(params[1])); - } - } else { - php_error_docref1(NULL TSRMLS_CC, Z_STRVAL(name), E_WARNING, "Unable to call %R()", Z_TYPE(name), Z_UNIVAL(name)); - } + zend_is_callable(callback, IS_CALLABLE_CHECK_SYNTAX_ONLY, &name); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %R()", Z_TYPE(name), Z_UNIVAL(name)); + zval_dtor(&name); } - zval_dtor(&name); - efree(params); + if (params) { + efree(params); + } } /* }}} */ -/* {{{ proto mixed call_user_func_array(string function_name, array parameters) +/* {{{ proto mixed call_user_func_array(string function_name, array parameters) U Call a user function which is the first parameter with the arguments contained in array */ PHP_FUNCTION(call_user_func_array) { - zval ***func_params, **func, **params; + zval ***func_params, *callback, *params; zval *retval_ptr; HashTable *func_params_ht; zval name; + zend_fcall_info fci; + zend_fcall_info_cache fci_cache = empty_fcall_info_cache; int count; int current = 0; - if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &func, ¶ms) == FAILURE) { - WRONG_PARAM_COUNT; - } - - SEPARATE_ZVAL(params); - convert_to_array_ex(params); - - if (Z_TYPE_PP(func) != IS_STRING && - Z_TYPE_PP(func) != IS_UNICODE && - Z_TYPE_PP(func) != IS_ARRAY) { - SEPARATE_ZVAL(func); - convert_to_string_ex(func); + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "za/", &callback, ¶ms) == FAILURE) { + return; } - if (!zend_is_callable(*func, 0, &name)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "First argument is expected to be a valid callback, '%R' was given", Z_TYPE(name), Z_UNIVAL(name)); - zval_dtor(&name); - RETURN_NULL(); + if (zend_fcall_info_init(callback, &fci, &fci_cache TSRMLS_CC) == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "first parameter is expected to be a valid callback"); + return; } - func_params_ht = Z_ARRVAL_PP(params); + func_params_ht = Z_ARRVAL_P(params); count = zend_hash_num_elements(func_params_ht); if (count) { func_params = safe_emalloc(sizeof(zval **), count, 0); for (zend_hash_internal_pointer_reset(func_params_ht); - zend_hash_get_current_data(func_params_ht, (void **) &func_params[current]) == SUCCESS; - zend_hash_move_forward(func_params_ht) - ) { + zend_hash_get_current_data(func_params_ht, (void **) &func_params[current]) == SUCCESS; + zend_hash_move_forward(func_params_ht)) + { current++; } } else { func_params = NULL; } - if (call_user_function_ex(EG(function_table), NULL, *func, &retval_ptr, count, func_params, 0, NULL TSRMLS_CC) == SUCCESS) { + fci.retval_ptr_ptr = &retval_ptr; + fci.params = func_params; + fci.param_count = count; + fci.no_separation = 0; + + if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS) { if (retval_ptr) { COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr); } } else { + zend_is_callable(callback, IS_CALLABLE_CHECK_SYNTAX_ONLY, &name); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %R()", Z_TYPE(name), Z_UNIVAL(name)); + zval_dtor(&name); } - zval_dtor(&name); if (func_params) { efree(func_params); } } /* }}} */ -/* {{{ proto mixed call_user_method(string method_name, mixed object [, mixed parameter] [, mixed ...]) +/* {{{ proto mixed call_user_method(string method_name, mixed object [, mixed parameter] [, mixed ...]) U Call a user method on a specific object or class */ PHP_FUNCTION(call_user_method) { - zval ***params; + zval ***params = NULL; + int n_params = 0; zval *retval_ptr; - int arg_count = ZEND_NUM_ARGS(); + zval *callback, *object; - if (arg_count < 2) { - WRONG_PARAM_COUNT; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/z*", &callback, &object, ¶ms, &n_params) == FAILURE) { + return; } - params = (zval ***) safe_emalloc(sizeof(zval **), arg_count, 0); - if (zend_get_parameters_array_ex(arg_count, params) == FAILURE) { - efree(params); - RETURN_FALSE; - } - if (Z_TYPE_PP(params[1]) != IS_OBJECT && - Z_TYPE_PP(params[1]) != IS_STRING && - Z_TYPE_PP(params[1]) != IS_UNICODE) { + if (Z_TYPE_P(object) != IS_OBJECT && + Z_TYPE_P(object) != IS_STRING && + Z_TYPE_P(object) != IS_UNICODE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Second argument is not an object or class name"); efree(params); RETURN_FALSE; } - SEPARATE_ZVAL(params[0]); - convert_to_string(*params[0]); + convert_to_text(callback); - if (call_user_function_ex(EG(function_table), params[1], *params[0], &retval_ptr, arg_count-2, params+2, 0, NULL TSRMLS_CC) == SUCCESS && retval_ptr) { + if (call_user_function_ex(EG(function_table), &object, callback, &retval_ptr, n_params, params, 0, NULL TSRMLS_CC) == SUCCESS && retval_ptr) { COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr); } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s()", Z_STRVAL_PP(params[0])); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %R()", Z_TYPE_P(callback), Z_UNIVAL_P(callback)); } efree(params); } /* }}} */ -/* {{{ proto mixed call_user_method_array(string method_name, mixed object, array params) +/* {{{ proto mixed call_user_method_array(string method_name, mixed object, array params) U Call a user method on a specific object or class using a parameter array */ PHP_FUNCTION(call_user_method_array) { - zval **method_name, **obj, **params, ***method_args = NULL, *retval_ptr; + zval *params, ***method_args = NULL, *retval_ptr; + zval *callback, *object; HashTable *params_ar; int num_elems, element = 0; - if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &method_name, &obj, ¶ms) == FAILURE) { - WRONG_PARAM_COUNT; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/za/", &callback, &object, ¶ms) == FAILURE) { + return; } - if (Z_TYPE_PP(obj) != IS_OBJECT && - Z_TYPE_PP(obj) != IS_STRING && - Z_TYPE_PP(obj) != IS_UNICODE) { + if (Z_TYPE_P(object) != IS_OBJECT && + Z_TYPE_P(object) != IS_STRING && + Z_TYPE_P(object) != IS_UNICODE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Second argument is not an object or class name"); RETURN_FALSE; } - SEPARATE_ZVAL(method_name); - SEPARATE_ZVAL(params); - convert_to_string_ex(method_name); - convert_to_array_ex(params); + convert_to_text(callback); - params_ar = HASH_OF(*params); + params_ar = HASH_OF(params); num_elems = zend_hash_num_elements(params_ar); method_args = (zval ***) safe_emalloc(sizeof(zval **), num_elems, 0); @@ -5202,10 +5167,10 @@ element++; } - if (call_user_function_ex(EG(function_table), obj, *method_name, &retval_ptr, num_elems, method_args, 0, NULL TSRMLS_CC) == SUCCESS && retval_ptr) { + if (call_user_function_ex(EG(function_table), &object, callback, &retval_ptr, num_elems, method_args, 0, NULL TSRMLS_CC) == SUCCESS && retval_ptr) { COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr); } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s()", Z_STRVAL_PP(method_name)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %R()", Z_TYPE_P(callback), Z_UNIVAL_P(callback)); } efree(method_args);
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php