From 907fa6650719ee7a2107c53ea33b3d7a6df2877f Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 12 May 2008 07:11:55 +0000 Subject: [PATCH] Added API to use namesapces in internal extensions --- Zend/zend_API.c | 14 +++++++++++ Zend/zend_API.h | 27 +++++++++++++++++++++ Zend/zend_builtin_functions.c | 45 +++++++++++++++++++++++++++++++++++ Zend/zend_constants.h | 5 ++++ 4 files changed, 91 insertions(+) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 22ba08e55f..a3b2b1e4ae 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -2213,6 +2213,20 @@ ZEND_API zend_class_entry *zend_register_internal_interface(zend_class_entry *or } /* }}} */ +ZEND_API int zend_register_class_alias_ex(char *name, int name_len, zend_class_entry *ce TSRMLS_DC) /* {{{ */ +{ + char *lcname = zend_str_tolower_dup(name, name_len); + int ret; + + ret = zend_hash_add(CG(class_table), lcname, name_len+1, &ce, sizeof(zend_class_entry *), NULL); + efree(lcname); + if (ret == SUCCESS) { + ce->refcount++; + } + return ret; +} +/* }}} */ + ZEND_API int zend_set_hash_symbol(zval *symbol, char *name, int name_length, zend_bool is_ref, int num_symbol_tables, ...) /* {{{ */ { HashTable *symbol_table; diff --git a/Zend/zend_API.h b/Zend/zend_API.h index e52104c3bc..a71900f514 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -40,6 +40,8 @@ typedef struct _zend_function_entry { zend_uint flags; } zend_function_entry; +#define ZEND_NS_NAME(ns, name) ns"::"name + #define ZEND_FN(name) zif_##name #define ZEND_MN(name) zim_##name #define ZEND_NAMED_FUNCTION(name) void name(INTERNAL_FUNCTION_PARAMETERS) @@ -63,6 +65,17 @@ typedef struct _zend_function_entry { ZEND_FENTRY(name, ZEND_MN(classname##_##alias), arg_info, flags) #define ZEND_ME_MAPPING(name, func_name, arg_types, flags) ZEND_NAMED_ME(name, ZEND_FN(func_name), arg_types, flags) +#define ZEND_NS_FENTRY(ns, zend_name, name, arg_info, flags) ZEND_RAW_FENTRY(ZEND_NS_NAME(ns, #zend_name), name, arg_info, flags) + +#define ZEND_NS_RAW_FENTRY(ns, zend_name, name, arg_info, flags) ZEND_RAW_FENTRY(ZEND_NS_NAME(ns, zend_name), name, arg_info, flags) +#define ZEND_NS_RAW_NAMED_FE(ns, zend_name, name, arg_info) ZEND_NS_RAW_FENTRY(ns, #zend_name, name, arg_info, 0) + +#define ZEND_NS_NAMED_FE(ns, zend_name, name, arg_info) +#define ZEND_NS_FE(ns, name, arg_info) ZEND_NS_FENTRY(ns, name, ZEND_FN(name), arg_info, 0) +#define ZEND_NS_DEP_FE(ns, name, arg_info) ZEND_NS_FENTRY(ns, name, ZEND_FN(name), arg_info, ZEND_ACC_DEPRECATED) +#define ZEND_NS_FALIAS(ns, name, alias, arg_info) ZEND_NS_FENTRY(ns, name, ZEND_FN(alias), arg_info, 0) +#define ZEND_NS_DEP_FALIAS(ns, name, alias, arg_info) ZEND_NS_FENTRY(ns, name, ZEND_FN(alias), arg_info, ZEND_ACC_DEPRECATED) + #define ZEND_ARG_INFO(pass_by_ref, name) { #name, sizeof(#name)-1, NULL, 0, 0, 0, pass_by_ref, 0, 0 }, #define ZEND_ARG_PASS_INFO(pass_by_ref) { NULL, 0, NULL, 0, 0, 0, pass_by_ref, 0, 0 }, #define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) { #name, sizeof(#name)-1, #classname, sizeof(#classname)-1, 0, allow_null, pass_by_ref, 0, 0 }, @@ -166,6 +179,13 @@ typedef struct _zend_function_entry { #define INIT_OVERLOADED_CLASS_ENTRY(class_container, class_name, functions, handle_fcall, handle_propget, handle_propset) \ INIT_OVERLOADED_CLASS_ENTRY_EX(class_container, class_name, sizeof(class_name)-1, functions, handle_fcall, handle_propget, handle_propset, NULL, NULL) +#define INIT_NS_CLASS_ENTRY(class_container, ns, class_name, functions) \ + INIT_CLASS_ENTRY(class_container, ZEND_NS_NAME(ns, class_name), functions) +#define INIT_OVERLOADED_NS_CLASS_ENTRY_EX(class_container, ns, class_name, functions, handle_fcall, handle_propget, handle_propset, handle_propunset, handle_propisset) \ + INIT_OVERLOADED_CLASS_ENTRY_EX(class_container, ZEND_NS_NAME(ns, class_name), sizeof(ZEND_NS_NAME(ns, class_name))-1, functions, handle_fcall, handle_propget, handle_propset, handle_propunset, handle_propisset) +#define INIT_OVERLOADED_NS_CLASS_ENTRY(class_container, ns, class_name, functions, handle_fcall, handle_propget, handle_propset) \ + INIT_OVERLOADED_CLASS_ENTRY(class_container, ZEND_NS_NAME(ns, class_name), functions, handle_fcall, handle_propget, handle_propset) + #ifdef ZTS # define CE_STATIC_MEMBERS(ce) (((ce)->type==ZEND_USER_CLASS)?(ce)->static_members:CG(static_members)[(zend_intptr_t)(ce)->static_members]) #else @@ -218,6 +238,13 @@ ZEND_API zend_class_entry *zend_register_internal_class_ex(zend_class_entry *cla ZEND_API zend_class_entry *zend_register_internal_interface(zend_class_entry *orig_class_entry TSRMLS_DC); ZEND_API void zend_class_implements(zend_class_entry *class_entry TSRMLS_DC, int num_interfaces, ...); +ZEND_API int zend_register_class_alias_ex(char *name, int name_len, zend_class_entry *ce TSRMLS_DC); + +#define zend_register_class_alias(name, ce) \ + zend_register_class_alias_ex(name, sizeof(name)-1, ce TSRMLS_DC) +#define zend_register_ns_class_alias(ns, name, ce) \ + zend_register_class_alias_ex(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name))-1, ce TSRMLS_DC) + ZEND_API int zend_disable_function(char *function_name, uint function_name_length TSRMLS_DC); ZEND_API int zend_disable_class(char *class_name, uint class_name_length TSRMLS_DC); diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 007378784d..9006e15fde 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -50,6 +50,7 @@ static ZEND_FUNCTION(property_exists); static ZEND_FUNCTION(class_exists); static ZEND_FUNCTION(interface_exists); static ZEND_FUNCTION(function_exists); +static ZEND_FUNCTION(class_alias); #if ZEND_DEBUG static ZEND_FUNCTION(leak); #ifdef ZEND_TEST_EXCEPTIONS @@ -115,6 +116,7 @@ static const zend_function_entry builtin_functions[] = { ZEND_FE(class_exists, NULL) ZEND_FE(interface_exists, NULL) ZEND_FE(function_exists, NULL) + ZEND_FE(class_alias, NULL) #if ZEND_DEBUG ZEND_FE(leak, NULL) #ifdef ZEND_TEST_EXCEPTIONS @@ -1146,6 +1148,49 @@ ZEND_FUNCTION(function_exists) } /* }}} */ +/* {{{ proto bool class_alias(string user_class_name , string alias_name [, bool autoload]) + Creates an alias for user defined class */ +ZEND_FUNCTION(class_alias) +{ + char *class_name, *lc_name, *alias_name; + zend_class_entry **ce; + int class_name_len, alias_name_len; + int found; + zend_bool autoload = 1; + ALLOCA_FLAG(use_heap) + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|b", &class_name, &class_name_len, &alias_name, &alias_name_len, &autoload) == FAILURE) { + return; + } + + if (!autoload) { + lc_name = do_alloca(class_name_len + 1, use_heap); + zend_str_tolower_copy(lc_name, class_name, class_name_len); + + found = zend_hash_find(EG(class_table), lc_name, class_name_len+1, (void **) &ce); + free_alloca(lc_name, use_heap); + } else { + found = zend_lookup_class(class_name, class_name_len, &ce TSRMLS_CC); + } + if (found == SUCCESS) { + if ((*ce)->type == ZEND_USER_CLASS) { + if (zend_register_class_alias_ex(alias_name, alias_name_len, *ce TSRMLS_CC) == SUCCESS) { + RETURN_TRUE; + } else { + zend_error(E_WARNING, "Cannot redeclare class %s", alias_name); + RETURN_FALSE; + } + } else { + zend_error(E_WARNING, "First argument of class_alias() must be a name of user defined class"); + RETURN_FALSE; + } + } else { + zend_error(E_WARNING, "Class '%s' not found", class_name); + RETURN_FALSE; + } +} +/* }}} */ + #if ZEND_DEBUG /* {{{ proto void leak(int num_bytes=3) Cause an intentional memory leak, for testing/debugging purposes */ diff --git a/Zend/zend_constants.h b/Zend/zend_constants.h index 4c30252cd0..3ef555348a 100644 --- a/Zend/zend_constants.h +++ b/Zend/zend_constants.h @@ -43,6 +43,11 @@ typedef struct _zend_constant { #define REGISTER_STRING_CONSTANT(name, str, flags) zend_register_string_constant((name), sizeof(name), (str), (flags), module_number TSRMLS_CC) #define REGISTER_STRINGL_CONSTANT(name, str, len, flags) zend_register_stringl_constant((name), sizeof(name), (str), (len), (flags), module_number TSRMLS_CC) +#define REGISTER_NS_LONG_CONSTANT(ns, name, lval, flags) zend_register_long_constant(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name)), (lval), (flags), module_number TSRMLS_CC) +#define REGISTER_NS_DOUBLE_CONSTANT(ns, name, dval, flags) zend_register_double_constant(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name)), (dval), (flags), module_number TSRMLS_CC) +#define REGISTER_NS_STRING_CONSTANT(ns, name, str, flags) zend_register_string_constant(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name)), (str), (flags), module_number TSRMLS_CC) +#define REGISTER_NS_STRINGL_CONSTANT(ns, name, str, len, flags) zend_register_stringl_constant(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name)), (str), (len), (flags), module_number TSRMLS_CC) + #define REGISTER_MAIN_LONG_CONSTANT(name, lval, flags) zend_register_long_constant((name), sizeof(name), (lval), (flags), 0 TSRMLS_CC) #define REGISTER_MAIN_DOUBLE_CONSTANT(name, dval, flags) zend_register_double_constant((name), sizeof(name), (dval), (flags), 0 TSRMLS_CC) #define REGISTER_MAIN_STRING_CONSTANT(name, str, flags) zend_register_string_constant((name), sizeof(name), (str), (flags), 0 TSRMLS_CC) -- 2.40.0