From: Andrei Zmievski Date: Tue, 9 May 2006 18:21:27 +0000 (+0000) Subject: Add char_enum_types(). X-Git-Tag: BEFORE_NEW_OUTPUT_API~261 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e2a1d7a3e1e1ba1277eadc0fef156cf7ee12377c;p=php Add char_enum_types(). --- diff --git a/ext/unicode/php_property.h b/ext/unicode/php_property.h index b28e402137..828910828d 100644 --- a/ext/unicode/php_property.h +++ b/ext/unicode/php_property.h @@ -84,6 +84,7 @@ PHP_FUNCTION(char_get_property_value_name); PHP_FUNCTION(char_get_property_value_from_name); PHP_FUNCTION(char_enum_names); +PHP_FUNCTION(char_enum_types); #endif /* PHP_PROPERTY_H */ diff --git a/ext/unicode/property.c b/ext/unicode/property.c index ddce71a3d5..bd4fc36ccb 100644 --- a/ext/unicode/property.c +++ b/ext/unicode/property.c @@ -51,7 +51,6 @@ static void check_property_impl(INTERNAL_FUNCTION_PARAMETERS, prop_check_func_t RETURN_BOOL(result); } - /* {{{ C/POSIX migration functions */ PHP_FUNCTION(char_is_lower) @@ -645,7 +644,7 @@ PHP_FUNCTION(char_get_property_value_from_name) /* {{{ Enumerator functions */ -static UBool php_enum_char_names(void *context, +static UBool php_enum_char_names(const void *context, UChar32 code, UCharNameChoice nameChoice, const char *name, @@ -687,6 +686,44 @@ static UBool php_enum_char_names(void *context, return result; } +static UBool php_enum_char_type_range(const void *context, + UChar32 start, + UChar32 limit, + UCharCategory type) +{ + char_enum_context_t *ctx = (char_enum_context_t *)context; + zval *retval_ptr = NULL; + int status; + UBool result = FALSE; + TSRMLS_FETCH_FROM_CTX(ctx->thread_ctx); + + convert_to_long_ex(ctx->args[0]); + convert_to_long_ex(ctx->args[1]); + convert_to_long_ex(ctx->args[2]); + + ZVAL_LONG(*ctx->args[0], start); + ZVAL_LONG(*ctx->args[1], limit); + ZVAL_LONG(*ctx->args[2], type); + + ctx->fci.retval_ptr_ptr = &retval_ptr; + + status = zend_call_function(&ctx->fci, &ctx->fci_cache TSRMLS_CC); + + if (status == SUCCESS && retval_ptr && !EG(exception)) { + convert_to_boolean(retval_ptr); + result = (UBool)Z_BVAL_P(retval_ptr); + } else { + if (!EG(exception)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Enumeration callback encountered an error"); + } + result = FALSE; + } + if (retval_ptr) { + zval_ptr_dtor(&retval_ptr); + } + return result; +} + PHP_FUNCTION(char_enum_names) { zval *callback; @@ -747,6 +784,52 @@ PHP_FUNCTION(char_enum_names) } } +PHP_FUNCTION(char_enum_types) +{ + zval *callback; + zval *zstart, *zlimit, *ztype; + char_enum_context_t ectx; + + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "z", &callback)) { + return; + } + + if (!zend_is_callable(callback, 0, NULL)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid enumeration callback"); + return; + } + + /* Do all the heavy lifing once, instead of in the callback */ + MAKE_STD_ZVAL(zstart); + MAKE_STD_ZVAL(zlimit); + MAKE_STD_ZVAL(ztype); + + ZVAL_LONG(zstart, 0); + ZVAL_LONG(zlimit, 0); + ZVAL_LONG(ztype, 0); + + memset(&ectx, 0, sizeof(char_enum_context_t)); + ectx.fci.size = sizeof(ectx.fci); + ectx.fci.function_table = EG(function_table); + ectx.fci.function_name = callback; + ectx.fci.no_separation = 1; + ectx.fci_cache = empty_fcall_info_cache; + ectx.args[0] = &zstart; + ectx.args[1] = &zlimit; + ectx.args[2] = &ztype; + ectx.fci.param_count = 3; + ectx.fci.params = ectx.args; + TSRMLS_SET_CTX(ectx.thread_ctx); + + u_enumCharTypes((UCharEnumTypeRange *)php_enum_char_type_range, (void *)&ectx); + + zval_ptr_dtor(&zstart); + zval_ptr_dtor(&zlimit); + zval_ptr_dtor(&ztype); + + RETURN_TRUE; +} + /* }}} */ /* diff --git a/ext/unicode/unicode.c b/ext/unicode/unicode.c index 7cbdef1d2e..26c3fa1ad8 100644 --- a/ext/unicode/unicode.c +++ b/ext/unicode/unicode.c @@ -296,6 +296,7 @@ zend_function_entry unicode_functions[] = { PHP_FE(char_get_property_value_from_name, NULL) PHP_FE(char_enum_names, NULL) + PHP_FE(char_enum_types, NULL) { NULL, NULL, NULL } };