]> granicus.if.org Git - php/commitdiff
Added API to use namesapces in internal extensions
authorDmitry Stogov <dmitry@php.net>
Mon, 12 May 2008 07:11:55 +0000 (07:11 +0000)
committerDmitry Stogov <dmitry@php.net>
Mon, 12 May 2008 07:11:55 +0000 (07:11 +0000)
Zend/zend_API.c
Zend/zend_API.h
Zend/zend_builtin_functions.c
Zend/zend_constants.h

index 22ba08e55f24d0a89368e8d8de99df4c0bbdf22f..a3b2b1e4aee405ee6d55e3d140c574227ebe8012 100644 (file)
@@ -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;
index e52104c3bc5e57e19cdbdf7c5722c47118f97aa9..a71900f51468c08aa799ba25263bee49745d4841 100644 (file)
@@ -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);
 
index 007378784d72ed844862a7a015a72bb80febc73f..9006e15fde2482925c0993e776f00c2cf851107b 100644 (file)
@@ -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 */
index 4c30252cd0b7a545e8cfa97a984d78a3e1312127..3ef555348a0e5ceae57760487504815c38ff5269 100644 (file)
@@ -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)