Hi Andi et al., the attached patch adds the module registering an internal function to the zend_internal_function structure. This information can be (and is by this patch) used by the reflection API - currently it's quite hard to get the extension defining a function. I additionally used this information to make a more verbose error messages when redefining an internal function.
Please take a look at it and commit at will. johannes p.s. If the patch doesn't reach the list it's available at http://svn.schlueters.de/phpatches/HEAD/zend_function_module.diff, too. p.p.s. In Steph's PAT directory is my ReflectionProptery::getLinenumber() patch still waiting, too ;-) http://www.zend.com/zend/week/pat/pat26.txt
Index: Zend/zend_API.c =================================================================== RCS file: /repository/ZendEngine2/zend_API.c,v retrieving revision 1.313 diff -u -p -r1.313 zend_API.c --- Zend/zend_API.c 23 Aug 2005 12:53:19 -0000 1.313 +++ Zend/zend_API.c 27 Aug 2005 01:15:56 -0000 @@ -1914,12 +1914,15 @@ ZEND_API zend_module_entry* zend_registe } efree(lcname); module = module_ptr; + EG(current_module) = module; if (module->functions && zend_register_functions(NULL, module->functions, NULL, module->type TSRMLS_CC)==FAILURE) { + EG(current_module) = NULL; zend_error(E_CORE_WARNING,"%s: Unable to register functions, unable to load", module->name); return NULL; } + EG(current_module) = NULL; return module; } @@ -1996,7 +1999,8 @@ ZEND_API int zend_register_functions(zen target_function_table = CG(function_table); } internal_function->type = ZEND_INTERNAL_FUNCTION; - + internal_function->module = EG(current_module); + if (scope) { class_name_len = scope->name_length; lc_class_name = zend_str_tolower_dup(scope->name, class_name_len); Index: Zend/zend_compile.c =================================================================== RCS file: /repository/ZendEngine2/zend_compile.c,v retrieving revision 1.658 diff -u -p -r1.658 zend_compile.c --- Zend/zend_compile.c 24 Aug 2005 20:42:05 -0000 1.658 +++ Zend/zend_compile.c 27 Aug 2005 01:15:57 -0000 @@ -2277,6 +2277,10 @@ ZEND_API int do_bind_function(zend_op *o Z_TYPE(opline->op2.u.constant), Z_UNIVAL(opline->op2.u.constant), ((zend_op_array *) function)->filename, ((zend_op_array *) function)->opcodes[0].lineno); + } else if (((zend_internal_function *)function)->module) { + zend_error(error_level, "Cannot redeclare %R() (internal function exists in module %s)", + Z_TYPE(opline->op2.u.constant), Z_UNIVAL(opline->op2.u.constant), + ((zend_internal_function *)function)->module->name); } else { zend_error(error_level, "Cannot redeclare %R()", Z_TYPE(opline->op2.u.constant), Z_UNIVAL(opline->op2.u.constant)); } Index: Zend/zend_compile.h =================================================================== RCS file: /repository/ZendEngine2/zend_compile.h,v retrieving revision 1.321 diff -u -p -r1.321 zend_compile.h --- Zend/zend_compile.h 24 Aug 2005 20:42:06 -0000 1.321 +++ Zend/zend_compile.h 27 Aug 2005 01:15:57 -0000 @@ -238,6 +238,7 @@ typedef struct _zend_internal_function { /* END of common elements */ void (*handler)(INTERNAL_FUNCTION_PARAMETERS); + struct _zend_module_entry *module; } zend_internal_function; #define ZEND_FN_SCOPE_NAME(function) ((function) && (function)->common.scope ? (function)->common.scope->name : EMPTY_STR) Index: Zend/zend_object_handlers.c =================================================================== RCS file: /repository/ZendEngine2/zend_object_handlers.c,v retrieving revision 1.144 diff -u -p -r1.144 zend_object_handlers.c --- Zend/zend_object_handlers.c 19 Aug 2005 22:33:39 -0000 1.144 +++ Zend/zend_object_handlers.c 27 Aug 2005 01:15:57 -0000 @@ -716,6 +716,7 @@ static union _zend_function *zend_std_ge if (zobj->ce->__call) { zend_internal_function *call_user_call = emalloc(sizeof(zend_internal_function)); call_user_call->type = ZEND_INTERNAL_FUNCTION; + call_user_call->module = zobj->ce->module; call_user_call->handler = zend_std_call_user_call; call_user_call->arg_info = NULL; call_user_call->num_args = 0; Index: Zend/zend_reflection_api.c =================================================================== RCS file: /repository/ZendEngine2/zend_reflection_api.c,v retrieving revision 1.172 diff -u -p -r1.172 zend_reflection_api.c --- Zend/zend_reflection_api.c 19 Aug 2005 13:20:14 -0000 1.172 +++ Zend/zend_reflection_api.c 27 Aug 2005 01:15:58 -0000 @@ -648,7 +648,13 @@ static void _function_string(string *str } string_printf(str, fptr->common.scope ? "%sMethod [ " : "%sFunction [ ", indent); - string_printf(str, (fptr->type == ZEND_USER_FUNCTION) ? "<user> " : "<internal> "); + string_printf(str, (fptr->type == ZEND_USER_FUNCTION) ? "<user" : "<internal"); + if (fptr->type == ZEND_INTERNAL_FUNCTION && ((zend_internal_function*)fptr)->module) { + string_printf(str, ":%s", ((zend_internal_function*)fptr)->module->name); + } + string_printf(str, "> "); + + if (fptr->common.fn_flags & ZEND_ACC_CTOR) { string_printf(str, "<ctor> "); } @@ -1552,7 +1558,7 @@ ZEND_METHOD(reflection_function, getNumb } /* }}} */ -/* {{{ proto public ReflectionParameter[] Reflection_Function::getParameters() +/* {{{ proto public ReflectionParameter[] ReflectionFunction::getParameters() Returns an array of parameter objects for this function */ ZEND_METHOD(reflection_function, getParameters) { @@ -1579,6 +1585,54 @@ ZEND_METHOD(reflection_function, getPara } /* }}} */ +/* {{{ proto public ReflectionExtension|NULL ReflectionFunction::getExtension() + Returns NULL or the extension the function belongs to */ +ZEND_METHOD(reflection_function, getExtension) +{ + reflection_object *intern; + zend_function *fptr; + zend_internal_function *internal; + + METHOD_NOTSTATIC; + GET_REFLECTION_OBJECT_PTR(fptr); + + if (fptr->type != ZEND_INTERNAL_FUNCTION) { + RETURN_NULL(); + } + + internal = (zend_internal_function *)fptr; + if (internal->module) { + reflection_extension_factory(return_value, internal->module->name TSRMLS_CC); + } else { + RETURN_NULL(); + } +} +/* }}} */ + +/* {{{ proto public string|false ReflectionFunction::getExtensionName() + Returns false or the name of the extension the function belongs to */ +ZEND_METHOD(reflection_function, getExtensionName) +{ + reflection_object *intern; + zend_function *fptr; + zend_internal_function *internal; + + METHOD_NOTSTATIC; + GET_REFLECTION_OBJECT_PTR(fptr); + + if (fptr->type != ZEND_INTERNAL_FUNCTION) { + RETURN_FALSE; + } + + internal = (zend_internal_function *)fptr; + if (internal->module) { + RETURN_STRING(internal->module->name, 1); + } else { + RETURN_FALSE; + } +} +/* }}} */ + /* {{{ proto public static mixed ReflectionParameter::export(mixed function, mixed parameter [, bool return]) throws ReflectionException Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */ ZEND_METHOD(reflection_parameter, export) @@ -3849,6 +3903,8 @@ static zend_function_entry reflection_fu ZEND_ME(reflection_function, getParameters, NULL, 0) ZEND_ME(reflection_function, getNumberOfParameters, NULL, 0) ZEND_ME(reflection_function, getNumberOfRequiredParameters, NULL, 0) + ZEND_ME(reflection_function, getExtension, NULL, 0) + ZEND_ME(reflection_function, getExtensionName, NULL, 0) {NULL, NULL, NULL} };
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php