summaryrefslogtreecommitdiff
path: root/Zend/zend_builtin_functions.c
diff options
context:
space:
mode:
authorStanislav Malyshev <stas@php.net>2003-04-21 17:01:34 +0000
committerStanislav Malyshev <stas@php.net>2003-04-21 17:01:34 +0000
commitad01495a482dc31f56af1a4e79ff29cae2d319f2 (patch)
tree7762cf3f78f2992f5152edd6987cf925c1661765 /Zend/zend_builtin_functions.c
parentc5b1314e0561b84cd1639899bf303c993f8e66af (diff)
downloadphp-git-ad01495a482dc31f56af1a4e79ff29cae2d319f2.tar.gz
Change get_class() so that it returns qualified names for namespaced
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.
Diffstat (limited to 'Zend/zend_builtin_functions.c')
-rw-r--r--Zend/zend_builtin_functions.c65
1 files changed, 51 insertions, 14 deletions
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
index 82281c60a9..69921a1d60 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -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;
}