Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * php4.swg | |
3 | * | |
4 | * PHP4 runtime library | |
5 | * | |
6 | */ | |
7 | ||
8 | #ifdef __cplusplus | |
9 | extern "C" { | |
10 | #endif | |
11 | #include "zend.h" | |
12 | #include "zend_API.h" | |
13 | #include "php.h" | |
14 | ||
15 | /* These TSRMLS_ stuff should already be defined now, but with older php under | |
16 | redhat are not... */ | |
17 | #ifndef TSRMLS_D | |
18 | #define TSRMLS_D | |
19 | #endif | |
20 | #ifndef TSRMLS_DC | |
21 | #define TSRMLS_DC | |
22 | #endif | |
23 | #ifndef TSRMLS_C | |
24 | #define TSRMLS_C | |
25 | #endif | |
26 | #ifndef TSRMLS_CC | |
27 | #define TSRMLS_CC | |
28 | #endif | |
29 | ||
30 | #ifdef __cplusplus | |
31 | } | |
32 | #endif | |
33 | ||
34 | /* But in fact SWIG_ConvertPtr is the native interface for getting typed | |
35 | pointer values out of zvals. We need the TSRMLS_ macros for when we | |
36 | make PHP type calls later as we handle php resources */ | |
37 | #define SWIG_ConvertPtr(obj,pp,type,flags) SWIG_ZTS_ConvertPtr(obj,pp,type,flags TSRMLS_CC) | |
38 | ||
39 | /* Flags for SWIG_ConvertPtr */ | |
40 | #define SWIG_POINTER_DISOWN 0x1 | |
41 | ||
42 | #define SWIG_fail goto fail | |
43 | ||
44 | static char *default_error_msg = "Unknown error occurred"; | |
45 | static int default_error_code = E_ERROR; | |
46 | ||
47 | #define SWIG_PHP_Arg_Error_Msg(argnum,extramsg) "Error in argument " #argnum " "#extramsg | |
48 | ||
49 | #define SWIG_PHP_Error(code,msg) ErrorCode() = code; ErrorMsg() = msg; SWIG_fail; | |
50 | ||
51 | #define SWIG_contract_assert(expr,msg) \ | |
52 | if (!(expr) ) { zend_printf("Contract Assert Failed %s\n",msg ); } else | |
53 | ||
54 | /* Standard SWIG API */ | |
55 | #define SWIG_GetModule(clientdata) SWIG_Php4_GetModule() | |
56 | #define SWIG_SetModule(clientdata, pointer) SWIG_Php4_SetModule(pointer) | |
57 | ||
58 | /* used to wrap returned objects in so we know whether they are newobject | |
59 | and need freeing, or not */ | |
60 | typedef struct _swig_object_wrapper { | |
61 | void * ptr; | |
62 | int newobject; | |
63 | } swig_object_wrapper; | |
64 | ||
65 | /* empty zend destructor for types without one */ | |
66 | static ZEND_RSRC_DTOR_FUNC(SWIG_landfill) {}; | |
67 | ||
68 | #define SWIG_SetPointerZval(a,b,c,d) SWIG_ZTS_SetPointerZval(a,b,c,d, SWIG_module_entry TSRMLS_CC) | |
69 | ||
70 | static void | |
71 | SWIG_ZTS_SetPointerZval(zval *z, void *ptr, swig_type_info *type, int newobject, zend_module_entry* module_entry TSRMLS_DC) { | |
72 | swig_object_wrapper *value=NULL; | |
73 | /* | |
74 | * First test for Null pointers. Return those as PHP native NULL | |
75 | */ | |
76 | if (!ptr ) { | |
77 | ZVAL_NULL(z); | |
78 | return; | |
79 | } | |
80 | if (type->clientdata) { | |
81 | if (! (*(int *)(type->clientdata))) | |
82 | zend_error(E_ERROR, "Type: %s failed to register with zend",type->name); | |
83 | value=(swig_object_wrapper *)emalloc(sizeof(swig_object_wrapper)); | |
84 | value->ptr=ptr; | |
85 | value->newobject=newobject; | |
86 | ZEND_REGISTER_RESOURCE(z, value, *(int *)(type->clientdata)); | |
87 | return; | |
88 | } else { /* have to deal with old fashioned string pointer? | |
89 | but this should not get this far */ | |
90 | zend_error(E_ERROR, "Type: %s not registered with zend",type->name); | |
91 | } | |
92 | } | |
93 | ||
94 | /* This is a new pointer conversion routine | |
95 | Taking the native pointer p (which would have been converted from the old | |
96 | string pointer) and it's php type id, and it's type name (which also would | |
97 | have come from the old string pointer) it converts it to ptr calling | |
98 | appropriate casting functions according to ty | |
99 | Sadly PHP has no API to find a type name from a type id, only from an instance | |
100 | of a resource of the type id, so we have to pass type_name as well. | |
101 | The two functions which might call this are: | |
102 | SWIG_ZTS_ConvertResourcePtr which gets the type name from the resource | |
103 | and the registered zend destructors for which we have one per type each | |
104 | with the type name hard wired in. */ | |
105 | static int | |
106 | SWIG_ZTS_ConvertResourceData(void * p, int type, const char *type_name, void **ptr, swig_type_info *ty TSRMLS_DC) { | |
107 | swig_cast_info *tc; | |
108 | ||
109 | if (ty) { | |
110 | if (! type_name) { | |
111 | /* can't convert p to ptr type ty if we don't know what type p is */ | |
112 | return -1; | |
113 | } else { | |
114 | /* convert and cast p from type_name to ptr as ty | |
115 | Need to sort out const-ness, can SWIG_TypeCast really not take a const? */ | |
116 | tc = SWIG_TypeCheck((char *)type_name,ty); | |
117 | if (!tc) return -1; | |
118 | *ptr = SWIG_TypeCast(tc, (void*)p); | |
119 | } | |
120 | } else { | |
121 | /* They don't care about the target type, so just pass on the pointer! */ | |
122 | *ptr = (void *) p; | |
123 | } | |
124 | return 0; | |
125 | } | |
126 | ||
127 | /* This function fills ptr with a pointer of type ty by extracting the pointer | |
128 | and type info from the resource in z. z must be a resource | |
129 | It uses SWIG_ZTS_ConvertResourceData to do the real work. */ | |
130 | static int | |
131 | SWIG_ZTS_ConvertResourcePtr(zval *z, void **ptr, swig_type_info *ty, int flags TSRMLS_DC) { | |
132 | swig_object_wrapper *value; | |
133 | void *p; | |
134 | int type; | |
135 | char *type_name; | |
136 | ||
137 | value = (swig_object_wrapper *) zend_list_find(z->value.lval,&type); | |
138 | if ( flags && SWIG_POINTER_DISOWN ) { | |
139 | value->newobject = 0; | |
140 | } | |
141 | p = value->ptr; | |
142 | if (type==-1) return -1; | |
143 | ||
144 | type_name=zend_rsrc_list_get_rsrc_type(z->value.lval TSRMLS_CC); | |
145 | ||
146 | return SWIG_ZTS_ConvertResourceData(p,type,type_name,ptr,ty TSRMLS_CC); | |
147 | } | |
148 | ||
149 | /* We allow passing of a STRING or RESOURCE pointing to the object | |
150 | or an OBJECT whose _cPtr is a string or resource pointing to the object | |
151 | STRING pointers are very depracated */ | |
152 | static int | |
153 | SWIG_ZTS_ConvertPtr(zval *z, void **ptr, swig_type_info *ty, int flags TSRMLS_DC) { | |
154 | char *c; | |
155 | zval *val; | |
156 | ||
157 | if(z == NULL) { | |
158 | *ptr = 0; | |
159 | return 0; | |
160 | } | |
161 | ||
162 | if (z->type==IS_OBJECT) { | |
163 | zval ** _cPtr; | |
164 | if (zend_hash_find(HASH_OF(z),"_cPtr",sizeof("_cPtr"),(void**)&_cPtr)==SUCCESS) { | |
165 | /* Don't co-erce to string if it isn't */ | |
166 | if ((*_cPtr)->type==IS_STRING) c = Z_STRVAL_PP(_cPtr); | |
167 | else if ((*_cPtr)->type==IS_RESOURCE) { | |
168 | return SWIG_ZTS_ConvertResourcePtr(*_cPtr,ptr,ty, flags TSRMLS_CC); | |
169 | } else goto type_error; /* _cPtr was not string or resource property */ | |
170 | } else goto type_error; /* can't find property _cPtr */ | |
171 | } else if (z->type==IS_RESOURCE) { | |
172 | return SWIG_ZTS_ConvertResourcePtr(z,ptr,ty, flags TSRMLS_CC); | |
173 | } if (z->type==IS_NULL ) { | |
174 | *ptr = 0; | |
175 | return 0; | |
176 | } else goto type_error; | |
177 | ||
178 | type_error: | |
179 | ||
180 | return -1; | |
181 | } | |
182 | ||
183 | static char const_name[] = "swig_runtime_data_type_pointer"; | |
184 | static swig_module_info *SWIG_Php4_GetModule() { | |
185 | zval *pointer; | |
186 | swig_module_info *ret = 0; | |
187 | ||
188 | MAKE_STD_ZVAL(pointer); | |
189 | ||
190 | if (zend_get_constant(const_name, sizeof(const_name), pointer)) { | |
191 | if (pointer->type == IS_LONG) { | |
192 | ret = (swig_module_info *) pointer->value.lval; | |
193 | } | |
194 | } | |
195 | return 0; | |
196 | } | |
197 | ||
198 | static void SWIG_Php4_SetModule(swig_module_info *pointer) { | |
199 | REGISTER_MAIN_LONG_CONSTANT(const_name, (long) pointer, 0); | |
200 | } |