]> granicus.if.org Git - php/commitdiff
Change get_class() so that it returns qualified names for namespaced
authorStanislav Malyshev <stas@php.net>
Mon, 21 Apr 2003 17:01:34 +0000 (17:01 +0000)
committerStanislav Malyshev <stas@php.net>
Mon, 21 Apr 2003 17:01:34 +0000 (17:01 +0000)
classes.

*HEADS UP*: get_class_name() handler interface is changed, now it should
allocate the space it returns with emalloc, and the users free it. If
anyone has problems with it or has suggestions how to do it without this -
please tell.

Also: make function_exists() understand namespaces.

Zend/zend.c
Zend/zend_API.c
Zend/zend_API.h
Zend/zend_builtin_functions.c
Zend/zend_object_handlers.c

index 995c6f6d757bfe7c1e36ba1b4cad4cbf0db9586a..ddff001b2bff634f9a325a365435ba4493cca7a1 100644 (file)
@@ -283,10 +283,10 @@ ZEND_API void zend_print_flat_zval_r(zval *expr TSRMLS_DC)
                        if (Z_OBJ_HANDLER_P(expr, get_class_name)) {
                                Z_OBJ_HANDLER_P(expr, get_class_name)(expr, &class_name, &clen, 0 TSRMLS_CC);
                        }
-                       if (class_name == NULL) {
-                               class_name = "Unknown Class";
+                       zend_printf("%s Object (", class_name?class_name:"Unknown Class");
+                       if(class_name) {
+                               efree(class_name);
                        }
-                       zend_printf("%s Object (", class_name);
                        if (Z_OBJ_HANDLER_P(expr, get_properties)) {
                                properties = Z_OBJPROP_P(expr);
                        }
@@ -336,10 +336,10 @@ ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int
                                if (Z_OBJ_HANDLER_P(expr, get_class_name)) {
                                        Z_OBJ_HANDLER_P(expr, get_class_name)(expr, &class_name, &clen, 0 TSRMLS_CC);
                                }
-                               if (class_name == NULL) {
-                                       class_name = "Unknown Class";
+                               zend_printf("%s Object\n", class_name?class_name:"Unknown Class");
+                               if(class_name) {
+                                       efree(class_name);
                                }
-                               zend_printf("%s Object\n", class_name);
                                if (Z_OBJ_HANDLER_P(expr, get_properties)) {
                                        properties = Z_OBJPROP_P(expr);
                                }
index 6bd21b3cd984c420754a152fa100a7b1a579013a..fcfd7dff6119c81e0cf98fbe4eb669a7fe9fae42 100644 (file)
@@ -1631,6 +1631,29 @@ ZEND_API char *zend_get_module_version(char *module_name)
     return module->version;
 }
 
+ZEND_API void zend_make_full_classname(zend_class_entry *ce, char **name, zend_uint *name_len)
+{
+       int len = ce->name_length;
+       char *full_name;
+
+       if(ce->ns && ce->ns->name) {
+               len += ce->ns->name_length + 2;
+       }
+
+       *name = full_name = emalloc(len+1);
+       *name_len = len;
+       
+       if(ce->ns && ce->ns->name) {
+               memcpy(full_name, ce->ns->name, ce->ns->name_length);
+               full_name += ce->ns->name_length;
+               *(full_name++) = ':';
+               *(full_name++) = ':';
+       }
+
+       memcpy(full_name, ce->name, ce->name_length);
+       full_name[ce->name_length] = '\0';
+}
+
 /*
  * Local variables:
  * tab-width: 4
index cf3612ee18dc1e54ff82213b29179319239e6391..5fa9b446242ff8b8a4d3bba1f32695613e1cf0c4 100644 (file)
@@ -260,6 +260,8 @@ ZEND_API int zend_set_hash_symbol(zval *symbol, char *name, int name_length,
 ZEND_API ZEND_FUNCTION(display_disabled_function);
 ZEND_API ZEND_FUNCTION(display_disabled_class);
 
+ZEND_API void zend_make_full_classname(zend_class_entry *ce, char **name, zend_uint *name_len);
+
 #if ZEND_DEBUG
 #define CHECK_ZVAL_STRING(z) \
        if ((z)->value.str.val[ (z)->value.str.len ] != '\0') { zend_error(E_WARNING, "String is not zero-terminated (%s)", (z)->value.str.val); }
index 82281c60a92241c54f8df26e7c2dd0fd300d84a2..69921a1d60a260617eb99b2a88e24a1b8ad72e9b 100644 (file)
@@ -516,8 +516,8 @@ ZEND_FUNCTION(defined)
 ZEND_FUNCTION(get_class)
 {
        zval **arg;
-       char *name;
-       zend_uint name_len;
+       char *name = "";
+       zend_uint name_len = 0;
        
        if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &arg)==FAILURE) {
                ZEND_WRONG_PARAM_COUNT();
@@ -535,11 +535,15 @@ ZEND_FUNCTION(get_class)
                        RETURN_FALSE;
                }
 
-               name = ce->name;
-               name_len = ce->name_length;
-       }
+               if(ce->ns) {
+                       zend_make_full_classname(ce, &name, &name_len);
+                       RETURN_STRINGL(name, name_len, 0);
+               } else {
+                       RETURN_STRINGL(ce->name, ce->name_length, 1);
+               }
+       } 
 
-       RETURN_STRINGL(name, name_len, 1);
+       RETURN_STRINGL(name, name_len, 0);
 }
 /* }}} */
 
@@ -550,20 +554,21 @@ ZEND_FUNCTION(get_parent_class)
 {
        zval **arg;
        zend_class_entry *ce = NULL;
+       char *name;
+       zend_uint name_length;
        
        if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &arg)==FAILURE) {
                ZEND_WRONG_PARAM_COUNT();
        }
 
        if (Z_TYPE_PP(arg) == IS_OBJECT) {
-               char *name;
-               zend_uint name_length;
 
                if (Z_OBJ_HT_PP(arg)->get_class_name
                        && Z_OBJ_HT_PP(arg)->get_class_name(*arg, &name, &name_length, 1 TSRMLS_CC) == SUCCESS) {
-                       RETURN_STRINGL(name, name_length, 1);
+                       RETURN_STRINGL(name, name_length, 0);
                } else if (Z_OBJ_HT_PP(arg)->get_class_entry && (ce = zend_get_class_entry(*arg TSRMLS_CC))) {
-                       RETURN_STRINGL(ce->name, ce->name_length, 1);
+                       zend_make_full_classname(ce, &name, &name_length);
+                       RETURN_STRINGL(name, name_length, 0);
                } else {
                        RETURN_FALSE;
                }
@@ -578,7 +583,8 @@ ZEND_FUNCTION(get_parent_class)
        }
 
        if (ce && ce->parent) {
-               RETURN_STRINGL(ce->parent->name, ce->parent->name_length, 1);
+               zend_make_full_classname(ce->parent, &name, &name_length);
+               RETURN_STRINGL(name, name_length, 0);
        } else {
                RETURN_FALSE;
        }
@@ -846,7 +852,7 @@ ZEND_FUNCTION(function_exists)
 {
        zval **function_name;
        zend_function *func;
-       char *lcname;
+       char *lcname, *func_name, *func_name_end;
        zend_bool retval;
        
        if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &function_name)==FAILURE) {
@@ -856,14 +862,45 @@ ZEND_FUNCTION(function_exists)
        lcname = estrndup((*function_name)->value.str.val, (*function_name)->value.str.len);
        zend_str_tolower(lcname, (*function_name)->value.str.len);
 
-       retval = (zend_hash_find(EG(function_table), lcname, (*function_name)->value.str.len+1, (void **)&func) == SUCCESS);
+       func_name_end = lcname + (*function_name)->value.str.len;
+       if((func_name = zend_memnstr(lcname, "::", sizeof("::")-1, func_name_end)) == NULL) {
+               retval = (zend_hash_find(EG(function_table), lcname, (*function_name)->value.str.len+1, (void **)&func) == SUCCESS);
+       } else {
+               /* handle ::f case */
+               if (func_name == lcname) {
+                       retval = (zend_hash_find(EG(function_table), lcname+sizeof("::")-1, (*function_name)->value.str.len-(sizeof("::")-1)+1, (void **)&func) == SUCCESS);
+               } else {
+                       /* handle ns::f case */
+                       int ns_name_length = func_name - lcname;
+                       char *ns_name;
+                       zend_namespace **ns;
+                       
+                       func_name += sizeof("::")-1;
+
+                       if(func_name >= func_name_end) {
+                               /* ns:: case */
+                               retval = 0;
+                       } else {
+                               ns_name = estrndup(lcname, ns_name_length);
+
+                               if (zend_hash_find(&EG(global_namespace_ptr)->class_table, ns_name, ns_name_length+1, (void **)&ns) == SUCCESS &&
+                                       CLASS_IS_NAMESPACE(*ns) && 
+                                       zend_hash_find(&(*ns)->function_table, func_name, func_name_end - func_name + 1, (void **)&func) == SUCCESS) {
+                                       retval = 1;
+                               } else {
+                                       retval = 0;
+                               }
+                               efree(ns_name);
+                       }
+               }
+       }
        efree(lcname);
 
        /*
         * A bit of a hack, but not a bad one: we see if the handler of the function
         * is actually one that displays "function is disabled" message.
         */
-       if (retval &&
+       if (retval && func->type == ZEND_INTERNAL_FUNCTION &&
                func->internal_function.handler == zif_display_disabled_function) {
                retval = 0;
        }
index 44e2405048b148ebb0cf6c64663007a3731360c4..759967bec551ad957925d9c3fd3d943699583573 100644 (file)
@@ -795,18 +795,19 @@ zend_class_entry *zend_std_object_get_class(zval *object TSRMLS_DC)
 int zend_std_object_get_class_name(zval *object, char **class_name, zend_uint *class_name_len, int parent TSRMLS_DC)
 {
        zend_object *zobj;
+       zend_class_entry *ce;
        zobj = Z_OBJ_P(object);
 
        if (parent) {
                if (!zobj->ce->parent) {
                        return FAILURE;
                }
-               *class_name = zobj->ce->parent->name;
-               *class_name_len = zobj->ce->parent->name_length;
+               ce = zobj->ce->parent;
        } else {
-               *class_name = zobj->ce->name;
-               *class_name_len = zobj->ce->name_length;
+               ce = zobj->ce;
        }
+
+       zend_make_full_classname(ce, class_name, class_name_len);
        return SUCCESS;
 }