SWIG_ZTS_SetPointerZval() now interprets bit 1 in newobject as meaning (wrap

in a PHP class wrapper), rather than taking newobject==2 as meaning this,
so we can wrap new and existing objects in this way.

Handle wrapping classes in a C++ namespace being returned by director methods.

No need to force classname to lowercase as zend_lookup_class() does that
internally.


git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12723 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Olly Betts 2011-05-30 06:47:47 +00:00
commit 29190559f8
3 changed files with 30 additions and 14 deletions

View file

@ -347,7 +347,7 @@
SWIGTYPE [],
SWIGTYPE &
%{
SWIG_SetPointerZval($input, (void *)&$1_name, $1_descriptor, $owner);
SWIG_SetPointerZval($input, (void *)&$1_name, $1_descriptor, ($owner)|2);
%}
%typemap(out, fragment="swig_php_init_member_ptr") SWIGTYPE (CLASS::*)

View file

@ -96,7 +96,6 @@ static ZEND_RSRC_DTOR_FUNC(SWIG_landfill) { (void)rsrc; }
static void
SWIG_ZTS_SetPointerZval(zval *z, void *ptr, swig_type_info *type, int newobject TSRMLS_DC) {
swig_object_wrapper *value=NULL;
/*
* First test for Null pointers. Return those as PHP native NULL
*/
@ -105,12 +104,13 @@ SWIG_ZTS_SetPointerZval(zval *z, void *ptr, swig_type_info *type, int newobject
return;
}
if (type->clientdata) {
swig_object_wrapper *value;
if (! (*(int *)(type->clientdata)))
zend_error(E_ERROR, "Type: %s failed to register with zend",type->name);
value=(swig_object_wrapper *)emalloc(sizeof(swig_object_wrapper));
value->ptr=ptr;
value->newobject=newobject;
if (newobject <= 1) {
value->newobject=(newobject & 1);
if ((newobject & 2) == 0) {
/* Just register the pointer as a resource. */
ZEND_REGISTER_RESOURCE(z, value, *(int *)(type->clientdata));
} else {
@ -119,18 +119,32 @@ SWIG_ZTS_SetPointerZval(zval *z, void *ptr, swig_type_info *type, int newobject
* via the "_cPtr" member. This is currently only used by
* directorin typemaps.
*/
value->newobject = 0;
zval *resource;
zend_class_entry **ce = NULL;
const char *type_name = type->name+3; /* +3 so: _p_Foo -> Foo */
size_t type_name_len;
int result;
const char * p;
/* Namespace__Foo -> Foo */
/* FIXME: ugly and goes wrong for classes with __ in their names. */
while ((p = strstr(type_name, "__")) != NULL) {
type_name = p + 2;
}
type_name_len = strlen(type_name);
MAKE_STD_ZVAL(resource);
ZEND_REGISTER_RESOURCE(resource, value, *(int *)(type->clientdata));
zend_class_entry **ce = NULL;
zval *classname;
MAKE_STD_ZVAL(classname);
/* _p_Foo -> Foo */
ZVAL_STRING(classname, (char*)type->name+3, 1);
/* class names are stored in lowercase */
php_strtolower(Z_STRVAL_PP(&classname), Z_STRLEN_PP(&classname));
if (zend_lookup_class(Z_STRVAL_P(classname), Z_STRLEN_P(classname), &ce TSRMLS_CC) != SUCCESS) {
if (SWIG_PREFIX_LEN > 0) {
char * classname = (char*)emalloc(SWIG_PREFIX_LEN + type_name_len + 1);
strcpy(classname, SWIG_PREFIX);
strcpy(classname + SWIG_PREFIX_LEN, type_name);
result = zend_lookup_class(classname, SWIG_PREFIX_LEN + type_name_len, &ce TSRMLS_CC);
efree(classname);
} else {
result = zend_lookup_class(type_name, type_name_len, &ce TSRMLS_CC);
}
if (result != SUCCESS) {
/* class does not exist */
object_init(z);
} else {
@ -139,7 +153,6 @@ SWIG_ZTS_SetPointerZval(zval *z, void *ptr, swig_type_info *type, int newobject
Z_SET_REFCOUNT_P(z, 1);
Z_SET_ISREF_P(z);
zend_hash_update(HASH_OF(z), (char*)"_cPtr", sizeof("_cPtr"), (void*)&resource, sizeof(zval), NULL);
FREE_ZVAL(classname);
}
return;
}

View file

@ -328,6 +328,9 @@ public:
if (!prefix)
prefix = NewStringEmpty();
Printf(f_runtime, "#define SWIG_PREFIX \"%s\"\n", prefix);
Printf(f_runtime, "#define SWIG_PREFIX_LEN %lu\n", (unsigned long)Len(prefix));
if (directorsEnabled()) {
Swig_banner(f_directors_h);
Printf(f_directors_h, "\n");