swig/Lib/php4/php4run.swg
Kevin Ruland 3ab65a48a0 Fairly major update to php code generation and type library. Brief summary:
- Revised simplified makefile generation using -make switch.
 - Proper support of in, out, argout, ret typemaps.
 - Function overloading with typecheck typemap support.
 - Fragment inclusion in typemaps.
 - Proper handling of object destructors relying on PHP's reference counting.
 - Constants using consttab and varinit typemaps.
 - Global variables using varinit typemaps.
 - Can generate C++ bindings using either objects or no objects (-noproxy).
 - Special phppointer.i typemaps for using php references for pointer passing.


git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@7392 626c5289-ae23-0410-ae9c-e8d60b6d4f22
2005-08-24 17:10:11 +00:00

243 lines
6.9 KiB
Text

/*
* php4.swg
*
* PHP4 runtime library
*
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "zend.h"
#include "zend_API.h"
#include "php.h"
/* These TSRMLS_ stuff should already be defined now, but with older php under
redhat are not... */
#ifndef TSRMLS_D
#define TSRMLS_D
#endif
#ifndef TSRMLS_DC
#define TSRMLS_DC
#endif
#ifndef TSRMLS_C
#define TSRMLS_C
#endif
#ifndef TSRMLS_CC
#define TSRMLS_CC
#endif
#ifdef __cplusplus
}
#endif
#define SWIG_fail goto fail
static char *default_error_msg = "Unknown error occurred";
static int default_error_code = E_ERROR;
#define SWIG_PHP_Arg_Error_Msg(argnum,extramsg) "Error in argument " #argnum " "#extramsg
#define SWIG_PHP_Error(code,msg) ErrorCode() = code; ErrorMsg() = msg; SWIG_fail;
#define SWIG_contract_assert(expr,msg) \
if (!(expr) ) { zend_printf("Contract Assert Failed %s\n",msg ); } else
/* Standard SWIG API */
#define SWIG_GetModule(clientdata) SWIG_Php4_GetModule()
#define SWIG_SetModule(clientdata, pointer) SWIG_Php4_SetModule(pointer)
/* used to wrap returned objects in so we know whether they are newobject
and need freeing, or not */
typedef struct _swig_object_wrapper {
void * ptr;
int newobject;
} swig_object_wrapper;
/* empty zend destructor for types without one */
static ZEND_RSRC_DTOR_FUNC(SWIG_landfill) {};
#define SWIG_SetPointerZval(a,b,c,d) SWIG_ZTS_SetPointerZval(a,b,c,d, SWIG_module_entry TSRMLS_CC)
static void
SWIG_ZTS_SetPointerZval(zval *z, void *ptr, swig_type_info *type, int newobject, zend_module_entry* module_entry TSRMLS_DC) {
swig_object_wrapper *value=NULL;
/*
* First test for Null pointers. Return those as PHP native NULL
*/
if (!ptr ) {
ZVAL_NULL(z);
return;
}
if (type->clientdata) {
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;
ZEND_REGISTER_RESOURCE(z, value, *(int *)(type->clientdata));
return;
} else { /* have to deal with old fashioned string pointer?
but this should not get this far */
zend_error(E_ERROR, "Type: %s not registered with zend",type->name);
}
}
/* This old-style routine converts an old string-pointer c into a real pointer
ptr calling making appropriate casting functions according to ty
We don't use this any more */
static int
SWIG_ConvertPtr_(char *c, void **ptr, swig_type_info *ty) {
register int d;
unsigned long p;
swig_cast_info *tc;
if(c == NULL) {
*ptr = 0;
return 0;
}
p = 0;
if (*c != '_') {
*ptr = (void *) 0;
if (strcmp(c,"NULL") == 0) {
return 0;
} else {
goto type_error;
}
}
c++;
/* Extract hex value from pointer */
while ((d = *c)) {
if ((d >= '0') && (d <= '9'))
p = (p << 4) + (d - '0');
else if ((d >= 'a') && (d <= 'f'))
p = (p << 4) + (d - ('a'-10));
else
break;
c++;
}
*ptr = (void *) p;
if(ty) {
tc = SWIG_TypeCheck(c,ty);
if(!tc) goto type_error;
*ptr = SWIG_TypeCast(tc, (void*)p);
}
return 0;
type_error:
return -1;
}
/* This is a new pointer conversion routine
Taking the native pointer p (which would have been converted from the old
string pointer) and it's php type id, and it's type name (which also would
have come from the old string pointer) it converts it to ptr calling
appropriate casting functions according to ty
Sadly PHP has no API to find a type name from a type id, only from an instance
of a resource of the type id, so we have to pass type_name as well.
The two functions which might call this are:
SWIG_ZTS_ConvertResourcePtr which gets the type name from the resource
and the registered zend destructors for which we have one per type each
with the type name hard wired in. */
static int
SWIG_ZTS_ConvertResourceData(void * p, int type, const char *type_name, void **ptr, swig_type_info *ty TSRMLS_DC) {
swig_cast_info *tc;
if (ty) {
if (! type_name) {
/* can't convert p to ptr type ty if we don't know what type p is */
return -1;
} else {
/* convert and cast p from type_name to ptr as ty
Need to sort out const-ness, can SWIG_TypeCast really not take a const? */
tc = SWIG_TypeCheck((char *)type_name,ty);
if (!tc) return -1;
*ptr = SWIG_TypeCast(tc, (void*)p);
}
} else {
/* They don't care about the target type, so just pass on the pointer! */
*ptr = (void *) p;
}
return 0;
}
/* This function fills ptr with a pointer of type ty by extracting the pointer
and type info from the resource in z. z must be a resource
It uses SWIG_ZTS_ConvertResourceData to do the real work. */
static int
SWIG_ZTS_ConvertResourcePtr(zval *z, void **ptr, swig_type_info *ty TSRMLS_DC) {
swig_object_wrapper *value;
void *p;
int type;
char *type_name;
value = (swig_object_wrapper *) zend_list_find(z->value.lval,&type);
p = value->ptr;
if (type==-1) return -1;
type_name=zend_rsrc_list_get_rsrc_type(z->value.lval TSRMLS_CC);
return SWIG_ZTS_ConvertResourceData(p,type,type_name,ptr,ty TSRMLS_CC);
}
/* But in fact SWIG_ConvertPtr is the native interface for getting typed
pointer values out of zvals. We need the TSRMLS_ macros for when we
make PHP type calls later as we handle php resources */
#define SWIG_ConvertPtr(a,b,c) SWIG_ZTS_ConvertPtr(a,b,c TSRMLS_CC)
/* We allow passing of a STRING or RESOURCE pointing to the object
or an OBJECT whose _cPtr is a string or resource pointing to the object
STRING pointers are very depracated */
static int
SWIG_ZTS_ConvertPtr(zval *z, void **ptr, swig_type_info *ty TSRMLS_DC) {
char *c;
zval *val;
if(z == NULL) {
*ptr = 0;
return 0;
}
if (z->type==IS_OBJECT) {
zval ** _cPtr;
if (zend_hash_find(HASH_OF(z),"_cPtr",sizeof("_cPtr"),(void**)&_cPtr)==SUCCESS) {
/* Don't co-erce to string if it isn't */
if ((*_cPtr)->type==IS_STRING) c = Z_STRVAL_PP(_cPtr);
else if ((*_cPtr)->type==IS_RESOURCE) {
return SWIG_ZTS_ConvertResourcePtr(*_cPtr,ptr,ty TSRMLS_CC);
} else goto type_error; /* _cPtr was not string or resource property */
} else goto type_error; /* can't find property _cPtr */
} else if (z->type==IS_RESOURCE) {
return SWIG_ZTS_ConvertResourcePtr(z,ptr,ty TSRMLS_CC);
} else if (z->type==IS_STRING) {
c = Z_STRVAL_P(z);
return SWIG_ConvertPtr_(c,ptr,ty);
} else goto type_error;
type_error:
return -1;
}
static char const_name[] = "swig_runtime_data_type_pointer";
static swig_module_info *SWIG_Php4_GetModule() {
zval *pointer;
swig_module_info *ret = 0;
MAKE_STD_ZVAL(pointer);
if (zend_get_constant(const_name, sizeof(const_name), pointer)) {
if (pointer->type == IS_LONG) {
ret = (swig_module_info *) pointer->value.lval;
}
}
return 0;
}
static void SWIG_Php4_SetModule(swig_module_info *pointer) {
REGISTER_MAIN_LONG_CONSTANT(const_name, (long) pointer, 0);
}