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