1 /* ----------------------------------------------------------------------------- 2 * phprun.swg 3 * 4 * PHP runtime library 5 * ----------------------------------------------------------------------------- */ 6 7 #ifdef __cplusplus 8 extern "C" { 9 #endif 10 #include "zend.h" 11 #include "zend_API.h" 12 #include "zend_exceptions.h" 13 #include "php.h" 14 #include "ext/standard/php_string.h" 15 #include <stdlib.h> /* for abort(), used in generated code. */ 16 17 #ifdef ZEND_RAW_FENTRY 18 /* ZEND_RAW_FENTRY was added somewhere between 5.2.0 and 5.2.3 */ 19 # define SWIG_ZEND_NAMED_FE(ZN, N, A) ZEND_RAW_FENTRY((char*)#ZN, N, A, 0) 20 #else 21 /* This causes warnings from GCC >= 4.2 (assigning a string literal to char*). 22 * But this seems to be unavoidable without directly assuming knowledge of 23 * the structure, which changed between PHP4 and PHP5. */ 24 # define SWIG_ZEND_NAMED_FE(ZN, N, A) ZEND_NAMED_FE(ZN, N, A) 25 #endif 26 27 #ifndef Z_SET_ISREF_P 28 /* For PHP < 5.3 */ 29 # define Z_SET_ISREF_P(z) (z)->is_ref = 1 30 #endif 31 #ifndef Z_SET_REFCOUNT_P 32 /* For PHP < 5.3 */ 33 # define Z_SET_REFCOUNT_P(z, rc) (z)->refcount = (rc) 34 #endif 35 36 #define SWIG_LONG_CONSTANT(N, V) zend_register_long_constant((char*)#N, sizeof(#N), V, CONST_CS | CONST_PERSISTENT, module_number TSRMLS_CC) 37 #define SWIG_DOUBLE_CONSTANT(N, V) zend_register_double_constant((char*)#N, sizeof(#N), V, CONST_CS | CONST_PERSISTENT, module_number TSRMLS_CC) 38 #define SWIG_STRING_CONSTANT(N, V) zend_register_stringl_constant((char*)#N, sizeof(#N), (char*)(V), strlen(V), CONST_CS | CONST_PERSISTENT, module_number TSRMLS_CC) 39 #define SWIG_CHAR_CONSTANT(N, V) do {\ 40 static char swig_char = (V);\ 41 zend_register_stringl_constant((char*)#N, sizeof(#N), &swig_char, 1, CONST_CS | CONST_PERSISTENT, module_number TSRMLS_CC);\ 42 } while (0) 43 44 /* These TSRMLS_ stuff should already be defined now, but with older php under 45 redhat are not... */ 46 #ifndef TSRMLS_D 47 #define TSRMLS_D 48 #endif 49 #ifndef TSRMLS_DC 50 #define TSRMLS_DC 51 #endif 52 #ifndef TSRMLS_C 53 #define TSRMLS_C 54 #endif 55 #ifndef TSRMLS_CC 56 #define TSRMLS_CC 57 #endif 58 59 #ifdef __cplusplus 60 } 61 #endif 62 63 /* But in fact SWIG_ConvertPtr is the native interface for getting typed 64 pointer values out of zvals. We need the TSRMLS_ macros for when we 65 make PHP type calls later as we handle php resources */ 66 #define SWIG_ConvertPtr(obj,pp,type,flags) SWIG_ZTS_ConvertPtr(obj,pp,type,flags TSRMLS_CC) 67 68 69 #define SWIG_fail goto fail 70 71 static const char *default_error_msg = "Unknown error occurred"; 72 static int default_error_code = E_ERROR; 73 74 #define SWIG_PHP_Arg_Error_Msg(argnum,extramsg) "Error in argument " #argnum " "#extramsg 75 76 #define SWIG_PHP_Error(code,msg) do { SWIG_ErrorCode() = code; SWIG_ErrorMsg() = msg; SWIG_fail; } while (0) 77 78 #define SWIG_contract_assert(expr,msg) \ 79 if (!(expr) ) { zend_printf("Contract Assert Failed %s\n",msg ); } else 80 81 /* Standard SWIG API */ 82 #define SWIG_GetModule(clientdata) SWIG_Php_GetModule(clientdata) 83 #define SWIG_SetModule(clientdata, pointer) SWIG_Php_SetModule(pointer) 84 85 /* used to wrap returned objects in so we know whether they are newobject 86 and need freeing, or not */ 87 typedef struct { 88 void * ptr; 89 int newobject; 90 } swig_object_wrapper; 91 92 /* empty zend destructor for types without one */ 93 static ZEND_RSRC_DTOR_FUNC(SWIG_landfill) { (void)rsrc; } 94 95 #define SWIG_SetPointerZval(a,b,c,d) SWIG_ZTS_SetPointerZval(a,b,c,d TSRMLS_CC) 96 #define SWIG_as_voidptr(a) const_cast< void * >(static_cast< const void * >(a)) 97 98 static void 99 SWIG_ZTS_SetPointerZval(zval *z, void *ptr, swig_type_info *type, int newobject TSRMLS_DC) { 100 /* 101 * First test for Null pointers. Return those as PHP native NULL 102 */ 103 if (!ptr ) { 104 ZVAL_NULL(z); 105 return; 106 } 107 if (type->clientdata) { 108 swig_object_wrapper *value; 109 if (! (*(int *)(type->clientdata))) 110 zend_error(E_ERROR, "Type: %s failed to register with zend",type->name); 111 value=(swig_object_wrapper *)emalloc(sizeof(swig_object_wrapper)); 112 value->ptr=ptr; 113 value->newobject=(newobject & 1); 114 if ((newobject & 2) == 0) { 115 /* Just register the pointer as a resource. */ 116 ZEND_REGISTER_RESOURCE(z, value, *(int *)(type->clientdata)); 117 } else { 118 /* 119 * Wrap the resource in an object, the resource will be accessible 120 * via the "_cPtr" member. This is currently only used by 121 * directorin typemaps. 122 */ 123 zval *resource; 124 zend_class_entry **ce = NULL; 125 const char *type_name = type->name+3; /* +3 so: _p_Foo -> Foo */ 126 size_t type_name_len; 127 int result; 128 const char * p; 129 130 /* Namespace__Foo -> Foo */ 131 /* FIXME: ugly and goes wrong for classes with __ in their names. */ 132 while ((p = strstr(type_name, "__")) != NULL) { 133 type_name = p + 2; 134 } 135 type_name_len = strlen(type_name); 136 137 MAKE_STD_ZVAL(resource); 138 ZEND_REGISTER_RESOURCE(resource, value, *(int *)(type->clientdata)); 139 if (SWIG_PREFIX_LEN > 0) { 140 char * classname = (char*)emalloc(SWIG_PREFIX_LEN + type_name_len + 1); 141 strcpy(classname, SWIG_PREFIX); 142 strcpy(classname + SWIG_PREFIX_LEN, type_name); 143 result = zend_lookup_class(classname, SWIG_PREFIX_LEN + type_name_len, &ce TSRMLS_CC); 144 efree(classname); 145 } else { 146 result = zend_lookup_class((char *)type_name, type_name_len, &ce TSRMLS_CC); 147 } 148 if (result != SUCCESS) { 149 /* class does not exist */ 150 object_init(z); 151 } else { 152 object_init_ex(z, *ce); 153 } 154 Z_SET_REFCOUNT_P(z, 1); 155 Z_SET_ISREF_P(z); 156 zend_hash_update(HASH_OF(z), (char*)"_cPtr", sizeof("_cPtr"), (void*)&resource, sizeof(zval), NULL); 157 } 158 return; 159 } 160 zend_error(E_ERROR, "Type: %s not registered with zend",type->name); 161 } 162 163 /* This pointer conversion routine takes the native pointer p (along with 164 its type name) and converts it by calling appropriate casting functions 165 according to ty. The resultant pointer is returned, or NULL is returned 166 if the pointer can't be cast. 167 168 Sadly PHP has no API to find a type name from a type id, only from an 169 instance of a resource of the type id, so we have to pass type_name as well. 170 171 The two functions which might call this are: 172 SWIG_ZTS_ConvertResourcePtr which gets the type name from the resource 173 and the registered zend destructors for which we have one per type each 174 with the type name hard wired in. */ 175 static void * 176 SWIG_ZTS_ConvertResourceData(void * p, const char *type_name, swig_type_info *ty TSRMLS_DC) { 177 swig_cast_info *tc; 178 void *result = 0; 179 180 if (!ty) { 181 /* They don't care about the target type, so just pass on the pointer! */ 182 return p; 183 } 184 185 if (! type_name) { 186 /* can't convert p to ptr type ty if we don't know what type p is */ 187 return NULL; 188 } 189 190 /* convert and cast p from type_name to ptr as ty. */ 191 tc = SWIG_TypeCheck(type_name, ty); 192 if (tc) { 193 int newmemory = 0; 194 result = SWIG_TypeCast(tc, p, &newmemory); 195 assert(!newmemory); /* newmemory handling not yet implemented */ 196 } 197 return result; 198 } 199 200 /* This function returns a pointer of type ty by extracting the pointer 201 and type info from the resource in z. z must be a resource. 202 If it fails, NULL is returned. 203 It uses SWIG_ZTS_ConvertResourceData to do the real work. */ 204 static void * 205 SWIG_ZTS_ConvertResourcePtr(zval *z, swig_type_info *ty, int flags TSRMLS_DC) { 206 swig_object_wrapper *value; 207 void *p; 208 int type; 209 const char *type_name; 210 211 value = (swig_object_wrapper *) zend_list_find(z->value.lval, &type); 212 if (type==-1) return NULL; 213 if (flags & SWIG_POINTER_DISOWN) { 214 value->newobject = 0; 215 } 216 p = value->ptr; 217 218 type_name=zend_rsrc_list_get_rsrc_type(z->value.lval TSRMLS_CC); 219 220 return SWIG_ZTS_ConvertResourceData(p, type_name, ty TSRMLS_CC); 221 } 222 223 /* We allow passing of a RESOURCE pointing to the object or an OBJECT whose 224 _cPtr is a resource pointing to the object */ 225 static int 226 SWIG_ZTS_ConvertPtr(zval *z, void **ptr, swig_type_info *ty, int flags TSRMLS_DC) { 227 if (z == NULL) { 228 *ptr = 0; 229 return 0; 230 } 231 232 switch (z->type) { 233 case IS_OBJECT: { 234 zval ** _cPtr; 235 if (zend_hash_find(HASH_OF(z),(char*)"_cPtr",sizeof("_cPtr"),(void**)&_cPtr)==SUCCESS) { 236 if ((*_cPtr)->type==IS_RESOURCE) { 237 *ptr = SWIG_ZTS_ConvertResourcePtr(*_cPtr, ty, flags TSRMLS_CC); 238 return (*ptr == NULL ? -1 : 0); 239 } 240 } 241 break; 242 } 243 case IS_RESOURCE: 244 *ptr = SWIG_ZTS_ConvertResourcePtr(z, ty, flags TSRMLS_CC); 245 return (*ptr == NULL ? -1 : 0); 246 case IS_NULL: 247 *ptr = 0; 248 return 0; 249 } 250 251 return -1; 252 } 253 254 static char const_name[] = "swig_runtime_data_type_pointer"; 255 static swig_module_info *SWIG_Php_GetModule(void *SWIGUNUSEDPARM(clientdata)) { 256 zval *pointer; 257 swig_module_info *ret = 0; 258 259 MAKE_STD_ZVAL(pointer); 260 261 TSRMLS_FETCH(); 262 263 if (zend_get_constant(const_name, sizeof(const_name) - 1, pointer TSRMLS_CC)) { 264 if (pointer->type == IS_LONG) { 265 ret = (swig_module_info *) pointer->value.lval; 266 } 267 } 268 FREE_ZVAL(pointer); 269 return ret; 270 } 271 272 static void SWIG_Php_SetModule(swig_module_info *pointer) { 273 TSRMLS_FETCH(); 274 REGISTER_MAIN_LONG_CONSTANT(const_name, (long) pointer, 0); 275 } 276