~ubuntu-branches/ubuntu/maverick/swig1.3/maverick

« back to all changes in this revision

Viewing changes to Source/Modules/php4.cxx

  • Committer: Bazaar Package Importer
  • Author(s): Michael Vogt
  • Date: 2006-12-20 14:43:24 UTC
  • mfrom: (1.2.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20061220144324-bps3kb06xp5oy9w1
Tags: 1.3.31-1ubuntu1
* Merge from debian unstable, remaining changes:
  - drop support for pike
  - use php5 instead of php4
  - clean Runtime/ as well
  - force a few environment variables

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* ----------------------------------------------------------------------------- 
 
1
/* -----------------------------------------------------------------------------
2
2
 * See the LICENSE file for information on copyright, usage and redistribution
3
3
 * of SWIG, and the README file for authors - http://www.swig.org/release.html.
4
4
 *
5
5
 * php4.cxx
6
6
 *
7
7
 * Php language module for SWIG.
8
 
 * ----------------------------------------------------------------------------- */
 
8
 * -----------------------------------------------------------------------------
 
9
 */
 
10
 
 
11
/* FIXME: PHP5 OO wrapping TODO list:
 
12
 *
 
13
 * Short term (ideally before 1.3.30 is released):
 
14
 *
 
15
 * Sort out auto-renaming of method and class names which are reserved
 
16
 *   words (e.g. empty, clone, exception, etc.) vs -php4/-php5 in some
 
17
 *   sane way.
 
18
 *
 
19
 * Sort out wrapping of static member variables in OO PHP5 (which first may
 
20
 *   mean we need to sort them out for PHP4!)
 
21
 *
 
22
 * Medium term:
 
23
 *
 
24
 * Handle default parameters on overloaded methods in PHP where possible.
 
25
 *   (Mostly done - just need to handle cases of overloaded methods with
 
26
 *   default parameters...)
 
27
 *   This is an optimisation - we could handle this case using a PHP
 
28
 *   default value, but currently we treat it as we would for a default
 
29
 *   value which is a compound C++ expression (i.e. as if we had a
 
30
 *   a method with two overloaded forms instead of a single method with
 
31
 *   a default parameter value).
 
32
 *
 
33
 * Create __isset method for PHP 5.1 and later (we can probably just
 
34
 *   always generate as PHP 5.0 should just ignore it).
 
35
 *
 
36
 * Long term:
 
37
 *
 
38
 * Option to generate code to work with PHP4 instead ("public $_cPtr;" ->
 
39
 *   "var $_cPtr;", "abstract" -> "", no static class functions - but making
 
40
 *   these changes gives a segfault with make check...)
 
41
 * Sort out locale-dependent behaviour of strtod() - it's harmless unless
 
42
 *   SWIG ever sets the locale and DOH/base.c calls atof, so we're probably
 
43
 *   OK currently at least.
 
44
 */
9
45
 
10
46
/*
11
 
 * TODO: Replace stderr messages with Swig_warning
 
47
 * TODO: Replace remaining stderr messages with Swig_error or Swig_warning
 
48
 * (may need to add more WARN_PHP4_xxx codes...)
12
49
 */
13
50
 
14
 
char cvsroot_php4_cxx[] = "$Header: /cvsroot/swig/SWIG/Source/Modules/php4.cxx,v 1.34 2006/03/20 00:24:39 marcelomatus Exp $";
 
51
char cvsroot_php4_cxx[] = "$Header: /cvsroot/swig/SWIG/Source/Modules/php4.cxx,v 1.68 2006/11/01 23:54:52 wsfulton Exp $";
15
52
 
16
53
#include "swigmod.h"
17
54
 
18
55
#include <ctype.h>
19
 
 
20
 
 
21
 
static const char *usage = (char*)"\
22
 
PHP4 Options (available with -php4)\n\
23
 
     -cppext         - cpp file extension (default to .cpp)\n\
24
 
     -noproxy        - Don't generate proxy classes.\n\
25
 
     -dlname <name>  - Set module prefix to <name>\n\
26
 
     -make           - Create simple makefile\n\
27
 
     -phpfull        - Create full make files\n\
28
 
     -withincs <libs>- With -phpfull writes needed incs in config.m4\n\
29
 
     -withlibs <libs>- With -phpfull writes needed libs in config.m4\n\
30
 
     -withc <libs>   - With -phpfull makes extra c files in Makefile.in\n\
31
 
     -withcxx <libs> - With -phpfull makes extra c++ files in Makefile.in\n\
 
56
#include <errno.h>
 
57
 
 
58
static const char *usage = (char *) "\
 
59
PHP Options (available with -php4 or -php5)\n\
 
60
     -cppext          - cpp file extension (default to .cpp)\n\
 
61
     -noproxy         - Don't generate proxy classes.\n\
 
62
     -prefix <prefix> - Prepend <prefix> to all class names in PHP5 wrappers\n\
 
63
     -make            - Create simple makefile\n\
 
64
     -phpfull         - Create full make files\n\
 
65
     -withincs <incs> - With -phpfull writes needed incs in config.m4\n\
 
66
     -withlibs <libs> - With -phpfull writes needed libs in config.m4\n\
 
67
     -withc <files>   - With -phpfull makes extra C files in Makefile.in\n\
 
68
     -withcxx <files> - With -phpfull makes extra C++ files in Makefile.in\n\
32
69
\n";
33
70
 
34
 
static int constructors=0;
35
 
static String *NOTCLASS=NewString("Not a class");
36
 
static Node *classnode=0;
 
71
/* The original class wrappers for PHP4 store the pointer to the C++ class in
 
72
 * the object property _cPtr.  If we use the same name for the member variable
 
73
 * which we put the pointer to the C++ class in, then the flat function
 
74
 * wrappers will automatically pull it out without any changes being required.
 
75
 * FIXME: Isn't using a leading underscore a bit suspect here?
 
76
 */
 
77
#define SWIG_PTR "_cPtr"
 
78
 
 
79
static int constructors = 0;
 
80
static String *NOTCLASS = NewString("Not a class");
 
81
static Node *classnode = 0;
37
82
static String *module = 0;
38
83
static String *cap_module = 0;
39
 
static String *dlname = 0;
 
84
static String *prefix = 0;
40
85
static String *withlibs = 0;
41
86
static String *withincs = 0;
42
87
static String *withc = 0;
43
88
static String *withcxx = 0;
44
89
 
45
 
static char *shadow_classname;
46
 
 
47
 
static int      gen_extra = 0;
48
 
static int      gen_make = 0;
49
 
 
50
 
static File       *f_runtime = 0;
51
 
static File       *f_h = 0;
52
 
static File       *f_phpcode = 0;
53
 
static String     *phpfilename =0;
54
 
 
55
 
static String     *s_header;
56
 
static String     *s_wrappers;
57
 
static String     *s_init;
58
 
static String     *r_init;       // RINIT user code
59
 
static String     *s_shutdown;   // MSHUTDOWN user code
60
 
static String     *r_shutdown;   // RSHUTDOWN user code
61
 
static String     *s_vinit;      // varinit initialization code.
62
 
static String     *s_vdecl;
63
 
static String     *s_cinit;      // consttab initialization code.
64
 
static String     *s_oinit;
65
 
static String     *s_entry;
66
 
static String     *cs_entry;
67
 
static String     *all_cs_entry;
68
 
static String     *pragma_incl;
69
 
static String     *pragma_code;
70
 
static String     *pragma_phpinfo;
 
90
static String *shadow_classname = 0;
 
91
 
 
92
static int gen_extra = 0;
 
93
static int gen_make = 0;
 
94
 
 
95
static File *f_runtime = 0;
 
96
static File *f_h = 0;
 
97
static File *f_phpcode = 0;
 
98
static String *phpfilename = 0;
 
99
 
 
100
static String *s_header;
 
101
static String *s_wrappers;
 
102
static String *s_init;
 
103
static String *r_init;          // RINIT user code
 
104
static String *s_shutdown;      // MSHUTDOWN user code
 
105
static String *r_shutdown;      // RSHUTDOWN user code
 
106
static String *s_vinit;         // varinit initialization code.
 
107
static String *s_vdecl;
 
108
static String *s_cinit;         // consttab initialization code.
 
109
static String *s_oinit;
 
110
static String *s_entry;
 
111
static String *cs_entry;
 
112
static String *all_cs_entry;
 
113
static String *pragma_incl;
 
114
static String *pragma_code;
 
115
static String *pragma_phpinfo;
 
116
static String *s_oowrappers;
 
117
static String *s_fakeoowrappers;
 
118
static String *s_phpclasses;
71
119
 
72
120
/* Variables for using PHP classes */
73
 
static String     *class_name = 0;
 
121
static Node *current_class = 0;
74
122
 
75
 
static Hash     *shadow_get_vars;
76
 
static Hash     *shadow_set_vars;
 
123
static Hash *shadow_get_vars;
 
124
static Hash *shadow_set_vars;
77
125
#define NATIVE_CONSTRUCTOR 1
78
126
#define ALTERNATIVE_CONSTRUCTOR 2
79
 
static int      native_constructor=0;
80
 
static Hash     *zend_types = 0;
81
 
 
82
 
static int        shadow        = 1;
 
127
static int native_constructor = 0;
 
128
static Hash *zend_types = 0;
 
129
 
 
130
static int shadow = 1;
 
131
 
 
132
static bool class_has_ctor = false;
 
133
static String *wrapping_member_constant = NULL;
83
134
 
84
135
// These static variables are used to pass some state from Handlers into functionWrapper
85
136
static enum {
93
144
} wrapperType = standard;
94
145
 
95
146
extern "C" {
96
 
static void (*r_prevtracefunc)(SwigType *t, String *mangled, String *clientdata) = 0;
 
147
  static void (*r_prevtracefunc) (SwigType *t, String *mangled, String *clientdata) = 0;
97
148
}
98
149
 
99
150
static const char *php_header =
100
 
"/*"
101
 
"\n  +----------------------------------------------------------------------+"
102
 
"\n  | PHP version 4.0                                                      |"
103
 
"\n  +----------------------------------------------------------------------+"
104
 
"\n  | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group             |"
105
 
"\n  +----------------------------------------------------------------------+"
106
 
"\n  | This source file is subject to version 2.02 of the PHP license,      |"
107
 
"\n  | that is bundled with this package in the file LICENSE, and is        |"
108
 
"\n  | available at through the world-wide-web at                           |"
109
 
"\n  | http://www.php.net/license/2_02.txt.                                 |"
110
 
"\n  | If you did not receive a copy of the PHP license and are unable to   |"
111
 
"\n  | obtain it through the world-wide-web, please send a note to          |"
112
 
"\n  | license@php.net so we can mail you a copy immediately.               |"
113
 
"\n  +----------------------------------------------------------------------+"
114
 
"\n  | Authors:                                                             |"
115
 
"\n  |                                                                      |"
116
 
"\n  +----------------------------------------------------------------------+"
117
 
"\n */\n";
 
151
    "/*"
 
152
    "\n  +----------------------------------------------------------------------+"
 
153
    "\n  | PHP version 4.0                                                      |"
 
154
    "\n  +----------------------------------------------------------------------+"
 
155
    "\n  | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group             |"
 
156
    "\n  +----------------------------------------------------------------------+"
 
157
    "\n  | This source file is subject to version 2.02 of the PHP license,      |"
 
158
    "\n  | that is bundled with this package in the file LICENSE, and is        |"
 
159
    "\n  | available at through the world-wide-web at                           |"
 
160
    "\n  | http://www.php.net/license/2_02.txt.                                 |"
 
161
    "\n  | If you did not receive a copy of the PHP license and are unable to   |"
 
162
    "\n  | obtain it through the world-wide-web, please send a note to          |"
 
163
    "\n  | license@php.net so we can mail you a copy immediately.               |"
 
164
    "\n  +----------------------------------------------------------------------+"
 
165
    "\n  | Authors:                                                             |"
 
166
    "\n  |                                                                      |"
 
167
    "\n  +----------------------------------------------------------------------+" "\n */\n";
118
168
 
119
 
void
120
 
SwigPHP_emit_resource_registrations() {
121
 
  DOH *key;
 
169
void SwigPHP_emit_resource_registrations() {
122
170
  Iterator ki;
123
 
  String *destructor=0;
124
 
  String *classname=0;
125
 
  String *shadow_classname=0;
126
171
 
127
 
  if (!zend_types) return;
 
172
  if (!zend_types)
 
173
    return;
128
174
 
129
175
  ki = First(zend_types);
130
 
  if (ki.key) Printf(s_oinit,"\n/* Register resource destructors for pointer types */\n");
131
 
  while (ki.key) if (1 /* is pointer type*/) {
132
 
    key = ki.key;
133
 
    Node *class_node;
134
 
    if ((class_node=Getattr(zend_types,key))) {
 
176
  if (ki.key)
 
177
    Printf(s_oinit, "\n/* Register resource destructors for pointer types */\n");
 
178
  while (ki.key)
 
179
    if (1 /* is pointer type */ ) {
 
180
      DOH *key = ki.key;
 
181
      Node *class_node = ki.item;
 
182
      String *human_name = key;
 
183
 
135
184
      // Write out destructor function header
136
 
      Printf(s_wrappers,"/* NEW Destructor style */\nstatic ZEND_RSRC_DTOR_FUNC(_wrap_destroy%s) {\n",key);
 
185
      Printf(s_wrappers, "/* NEW Destructor style */\nstatic ZEND_RSRC_DTOR_FUNC(_wrap_destroy%s) {\n", key);
137
186
 
138
187
      // write out body
139
 
      if ((class_node!=NOTCLASS)) {
140
 
        classname = Getattr(class_node,"name");
141
 
        if (! (shadow_classname = Getattr(class_node,"sym:name"))) {
142
 
          shadow_classname=classname;
143
 
        }
144
 
        // Do we have a known destructor for this type?
145
 
        if ((destructor = Getattr(class_node,"destructor"))) {
146
 
          Printf(s_wrappers,"  /* has destructor: %s */\n",destructor);
147
 
          Printf(s_wrappers,"  %s(rsrc, SWIGTYPE%s->name TSRMLS_CC);\n",destructor,key);
148
 
        } else {
149
 
          Printf(s_wrappers,"  /* bah! No destructor for this wrapped class!! */\n");
150
 
        }
 
188
      if ((class_node != NOTCLASS)) {
 
189
        String *destructor = Getattr(class_node, "destructor");
 
190
        human_name = Getattr(class_node, "sym:name");
 
191
        if (!human_name)
 
192
          human_name = Getattr(class_node, "name");
 
193
        // Do we have a known destructor for this type?
 
194
        if (destructor) {
 
195
          Printf(s_wrappers, "  %s(rsrc, SWIGTYPE%s->name TSRMLS_CC);\n", destructor, key);
 
196
        } else {
 
197
          Printf(s_wrappers, "  /* No destructor for class %s */\n", human_name);
 
198
        }
151
199
      } else {
152
 
          Printf(s_wrappers,"  /* bah! No destructor for this simple type!! */\n");
 
200
        Printf(s_wrappers, "  /* No destructor for simple type %s */\n", key);
153
201
      }
154
202
 
155
203
      // close function
156
 
      Printf(s_wrappers,"}\n");
 
204
      Printf(s_wrappers, "}\n");
157
205
 
158
206
      // declare le_swig_<mangled> to store php registration
159
 
      Printf(s_vdecl,"static int le_swig_%s=0; /* handle for %s */\n", key, shadow_classname);
 
207
      Printf(s_vdecl, "static int le_swig_%s=0; /* handle for %s */\n", key, human_name);
160
208
 
161
209
      // register with php
162
 
      Printf(s_oinit,"le_swig_%s=zend_register_list_destructors_ex"
163
 
             "(_wrap_destroy%s,NULL,(char *)(SWIGTYPE%s->name),module_number);\n",
164
 
             key,key,key);
 
210
      Printf(s_oinit, "le_swig_%s=zend_register_list_destructors_ex" "(_wrap_destroy%s,NULL,(char *)(SWIGTYPE%s->name),module_number);\n", key, key, key);
165
211
 
166
212
      // store php type in class struct
167
 
      Printf(s_oinit,"SWIG_TypeClientData(SWIGTYPE%s,&le_swig_%s);\n",
168
 
             key,key);
 
213
      Printf(s_oinit, "SWIG_TypeClientData(SWIGTYPE%s,&le_swig_%s);\n", key, key);
 
214
 
 
215
      ki = Next(ki);
169
216
    }
170
 
    ki = Next(ki);
171
 
  }
172
217
}
173
218
 
174
 
class PHP4 : public Language {
 
219
class PHP:public Language {
 
220
  int php_version;
 
221
 
175
222
public:
 
223
   PHP(int php_version_):php_version(php_version_) {
 
224
  }
176
225
 
177
226
  /* Test to see if a type corresponds to something wrapped with a shadow class. */
178
227
  
180
229
    String *r = 0;
181
230
    Node *n = classLookup(t);
182
231
    if (n) {
183
 
      r = Getattr(n,"php:proxy");   // Set by classDeclaration()
 
232
      r = Getattr(n, "php:proxy");      // Set by classDeclaration()
184
233
      if (!r) {
185
 
        r = Getattr(n,"sym:name");      // Not seen by classDeclaration yet, but this is the name
 
234
        r = Getattr(n, "sym:name");     // Not seen by classDeclaration yet, but this is the name
186
235
      }
187
236
    }
188
237
    return r;
189
238
  }
190
 
  
 
239
 
191
240
  /* ------------------------------------------------------------
192
241
   * main()
193
242
   * ------------------------------------------------------------ */
194
 
  
 
243
 
195
244
  virtual void main(int argc, char *argv[]) {
196
245
    int i;
197
246
    SWIG_library_directory("php4");
198
247
    SWIG_config_cppext("cpp");
199
 
    
200
 
    for(i = 1; i < argc; i++) {
 
248
 
 
249
    for (i = 1; i < argc; i++) {
201
250
      if (argv[i]) {
202
 
        if(strcmp(argv[i], "-phpfull") == 0) {
203
 
          gen_extra = 1;
204
 
          Swig_mark_arg(i);
205
 
        } else if(strcmp(argv[i], "-dlname") == 0) {
206
 
          if (argv[i+1]) {
207
 
            dlname = NewString(argv[i+1]);
208
 
            Swig_mark_arg(i);
209
 
            Swig_mark_arg(i+1);
210
 
            i++;
211
 
          } else {
212
 
            Swig_arg_error();
213
 
          }
214
 
        } else if(strcmp(argv[i], "-withlibs") == 0) {
215
 
          if (argv[i+1]) {
216
 
            withlibs = NewString(argv[i+1]);
217
 
            Swig_mark_arg(i);
218
 
            Swig_mark_arg(i+1);
219
 
            i++;
220
 
          } else {
221
 
            Swig_arg_error();
222
 
          }
223
 
        } else if(strcmp(argv[i], "-withincs") == 0) {
224
 
          if (argv[i+1]) {
225
 
            withincs = NewString(argv[i+1]);
226
 
            Swig_mark_arg(i);
227
 
            Swig_mark_arg(i+1);
228
 
            i++;
229
 
          } else {
230
 
            Swig_arg_error();
231
 
          }
232
 
        } else if(strcmp(argv[i], "-withc") == 0) {
233
 
          if (argv[i+1]) {
234
 
            withc = NewString(argv[i+1]);
235
 
            Swig_mark_arg(i);
236
 
            Swig_mark_arg(i+1);
237
 
            i++;
238
 
          } else {
239
 
            Swig_arg_error();
240
 
          }
241
 
        } else if(strcmp(argv[i], "-withcxx") == 0) {
242
 
          if (argv[i+1]) {
243
 
            withcxx = NewString(argv[i+1]);
244
 
            Swig_mark_arg(i);
245
 
            Swig_mark_arg(i+1);
246
 
            i++;
247
 
          } else {
248
 
            Swig_arg_error();
249
 
          }
250
 
        } else if(strcmp(argv[i], "-cppext") == 0) {
251
 
          if (argv[i+1]) {
252
 
            SWIG_config_cppext(argv[i+1]);
253
 
            Swig_mark_arg(i);
254
 
            Swig_mark_arg(i+1);
255
 
            i++;
256
 
          } else {
257
 
            Swig_arg_error();
258
 
          }
259
 
        }  else if((strcmp(argv[i], "-noshadow") == 0)
260
 
                   || (strcmp(argv[i],"-noproxy") == 0)) {
261
 
          shadow = 0;
262
 
          Swig_mark_arg(i);
263
 
        } else if(strcmp(argv[i], "-make") == 0) {
264
 
          gen_make = 1;
265
 
          Swig_mark_arg(i);
266
 
        } else if(strcmp(argv[i], "-help") == 0) {
267
 
          fputs(usage, stdout);
268
 
        }
 
251
        if (strcmp(argv[i], "-phpfull") == 0) {
 
252
          gen_extra = 1;
 
253
          Swig_mark_arg(i);
 
254
        } else if (strcmp(argv[i], "-dlname") == 0) {
 
255
          Printf(stderr, "*** -dlname is no longer supported\n*** if you want to change the module name, use -module instead.\n");
 
256
          SWIG_exit(EXIT_FAILURE);
 
257
        } else if (strcmp(argv[i], "-prefix") == 0) {
 
258
          if (argv[i + 1]) {
 
259
            prefix = NewString(argv[i + 1]);
 
260
            Swig_mark_arg(i);
 
261
            Swig_mark_arg(i + 1);
 
262
            i++;
 
263
          } else {
 
264
            Swig_arg_error();
 
265
          }
 
266
        } else if (strcmp(argv[i], "-withlibs") == 0) {
 
267
          if (argv[i + 1]) {
 
268
            withlibs = NewString(argv[i + 1]);
 
269
            Swig_mark_arg(i);
 
270
            Swig_mark_arg(i + 1);
 
271
            i++;
 
272
          } else {
 
273
            Swig_arg_error();
 
274
          }
 
275
        } else if (strcmp(argv[i], "-withincs") == 0) {
 
276
          if (argv[i + 1]) {
 
277
            withincs = NewString(argv[i + 1]);
 
278
            Swig_mark_arg(i);
 
279
            Swig_mark_arg(i + 1);
 
280
            i++;
 
281
          } else {
 
282
            Swig_arg_error();
 
283
          }
 
284
        } else if (strcmp(argv[i], "-withc") == 0) {
 
285
          if (argv[i + 1]) {
 
286
            withc = NewString(argv[i + 1]);
 
287
            Swig_mark_arg(i);
 
288
            Swig_mark_arg(i + 1);
 
289
            i++;
 
290
          } else {
 
291
            Swig_arg_error();
 
292
          }
 
293
        } else if (strcmp(argv[i], "-withcxx") == 0) {
 
294
          if (argv[i + 1]) {
 
295
            withcxx = NewString(argv[i + 1]);
 
296
            Swig_mark_arg(i);
 
297
            Swig_mark_arg(i + 1);
 
298
            i++;
 
299
          } else {
 
300
            Swig_arg_error();
 
301
          }
 
302
        } else if (strcmp(argv[i], "-cppext") == 0) {
 
303
          if (argv[i + 1]) {
 
304
            SWIG_config_cppext(argv[i + 1]);
 
305
            Swig_mark_arg(i);
 
306
            Swig_mark_arg(i + 1);
 
307
            i++;
 
308
          } else {
 
309
            Swig_arg_error();
 
310
          }
 
311
        } else if ((strcmp(argv[i], "-noshadow") == 0) || (strcmp(argv[i], "-noproxy") == 0)) {
 
312
          shadow = 0;
 
313
          Swig_mark_arg(i);
 
314
        } else if (strcmp(argv[i], "-make") == 0) {
 
315
          gen_make = 1;
 
316
          Swig_mark_arg(i);
 
317
        } else if (strcmp(argv[i], "-help") == 0) {
 
318
          fputs(usage, stdout);
 
319
        }
269
320
      }
270
321
    }
271
 
    
 
322
 
272
323
    Preprocessor_define((void *) "SWIGPHP 1", 0);
273
 
    Preprocessor_define((void *) "SWIGPHP4 1", 0);
 
324
    if (php_version == 4) {
 
325
      Preprocessor_define((void *) "SWIGPHP4 1", 0);
 
326
    } else if (php_version == 5) {
 
327
      Preprocessor_define((void *) "SWIGPHP5 1", 0);
 
328
    }
274
329
    SWIG_typemap_lang("php4");
275
330
    /* DB: Suggest using a language configuration file */
276
331
    SWIG_config_file("php4.swg");
277
332
    allow_overloading();
278
333
  }
279
 
  
 
334
 
280
335
  void create_simple_make(void) {
281
336
    File *f_make;
282
 
    
283
 
    f_make = NewFile((void *)"makefile", "w");
 
337
 
 
338
    f_make = NewFile((void *) "makefile", "w");
284
339
    Printf(f_make, "CC=gcc\n");
285
340
    Printf(f_make, "CXX=g++\n");
286
 
    Printf(f_make, "CXX_SOURCES=%s\n", withcxx );
287
 
    Printf(f_make, "C_SOURCES=%s\n", withc );
288
 
    Printf(f_make, "OBJS=%s_wrap.o $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cxx=.o)\n", module );
289
 
    Printf(f_make, "PROG=%s\n", dlname);
290
 
    Printf(f_make, "CFLAGS=-fpic\n" );
 
341
    Printf(f_make, "CXX_SOURCES=%s\n", withcxx);
 
342
    Printf(f_make, "C_SOURCES=%s\n", withc);
 
343
    Printf(f_make, "OBJS=%s_wrap.o $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cxx=.o)\n", module);
 
344
    Printf(f_make, "MODULE=%s.`php -r 'switch(PHP_SHLIB_SUFFIX){case\"PHP_SHLIB_SUFFIX\":case\"dylib\":echo\"so\";break;default:echo PHP_SHLIB_SUFFIX;}'`\n",
 
345
           module);
 
346
    Printf(f_make, "CFLAGS=-fpic\n");
291
347
    Printf(f_make, "LDFLAGS=-shared\n");
292
348
    Printf(f_make, "PHP_INC=`php-config --includes`\n");
293
349
    Printf(f_make, "EXTRA_INC=\n");
294
 
    Printf(f_make, "EXTRA_LIB=\n\n" );
295
 
    Printf(f_make, "$(PROG): $(OBJS)\n");
296
 
    if ( CPlusPlus || (withcxx != NULL) ) {
 
350
    Printf(f_make, "EXTRA_LIB=\n\n");
 
351
    Printf(f_make, "$(MODULE): $(OBJS)\n");
 
352
    if (CPlusPlus || (withcxx != NULL)) {
297
353
      Printf(f_make, "\t$(CXX) $(LDFLAGS) $(OBJS) -o $(PROG) $(EXTRA_LIB)\n\n");
298
354
    } else {
299
355
      Printf(f_make, "\t$(CC) $(LDFLAGS) $(OBJS) -o $(PROG) $(EXTRA_LIB)\n\n");
307
363
 
308
364
    Close(f_make);
309
365
  }
310
 
  
 
366
 
311
367
  void create_extra_files(String *outfile) {
312
368
    File *f_extra;
313
 
    
314
 
    static String *configm4=0;
315
 
    static String *makefilein=0;
316
 
    static String *credits=0;
317
 
    
318
 
    configm4=NewString("");
 
369
 
 
370
    static String *configm4 = 0;
 
371
    static String *makefilein = 0;
 
372
    static String *credits = 0;
 
373
 
 
374
    configm4 = NewStringEmpty();
319
375
    Printv(configm4, SWIG_output_directory(), "config.m4", NIL);
320
 
    
321
 
    makefilein=NewString("");
 
376
 
 
377
    makefilein = NewStringEmpty();
322
378
    Printv(makefilein, SWIG_output_directory(), "Makefile.in", NIL);
323
 
    
324
 
    credits=NewString("");
 
379
 
 
380
    credits = NewStringEmpty();
325
381
    Printv(credits, SWIG_output_directory(), "CREDITS", NIL);
326
 
    
 
382
 
327
383
    // are we a --with- or --enable-
328
 
    int with=(withincs || withlibs)?1:0;
329
 
    
330
 
    // Note makefile.in only copes with one source file
 
384
    int with = (withincs || withlibs) ? 1 : 0;
 
385
 
 
386
    // Note Makefile.in only copes with one source file
331
387
    // also withincs and withlibs only take one name each now
332
388
    // the code they generate should be adapted to take multiple lines
333
 
    
 
389
 
334
390
    /* Write out Makefile.in */
335
391
    f_extra = NewFile(makefilein, "w");
336
392
    if (!f_extra) {
337
393
      FileErrorDisplay(makefilein);
338
394
      SWIG_exit(EXIT_FAILURE);
339
395
    }
340
 
    
341
 
    Printf(f_extra,
342
 
           "# $Id: php4.cxx,v 1.34 2006/03/20 00:24:39 marcelomatus Exp $\n\n"
343
 
           "LTLIBRARY_NAME          = php_%s.la\n",
344
 
           module);
345
 
    
346
 
    // CPP has more and different entires to C in Makefile.in
347
 
    if (! CPlusPlus) {
348
 
      Printf(f_extra,"LTLIBRARY_SOURCES       = %s %s\n", Swig_file_filename(outfile),withc);
349
 
      Printf(f_extra,"LTLIBRARY_SOURCES_CPP   = %s\n", withcxx);
 
396
 
 
397
    Printf(f_extra, "# $Id: php4.cxx,v 1.68 2006/11/01 23:54:52 wsfulton Exp $\n\n" "LTLIBRARY_NAME          = %s.la\n", module);
 
398
 
 
399
    // C++ has more and different entries to C in Makefile.in
 
400
    if (!CPlusPlus) {
 
401
      Printf(f_extra, "LTLIBRARY_SOURCES       = %s %s\n", Swig_file_filename(outfile), withc);
 
402
      Printf(f_extra, "LTLIBRARY_SOURCES_CPP   = %s\n", withcxx);
350
403
    } else {
351
 
      Printf(f_extra,"LTLIBRARY_SOURCES       = %s\n", withc );
352
 
      Printf(f_extra,"LTLIBRARY_SOURCES_CPP   = %s %s\n", Swig_file_filename(outfile),withcxx);
353
 
      Printf(f_extra,"LTLIBRARY_OBJECTS_X = $(LTLIBRARY_SOURCES_CPP:.cpp=.lo) $(LTLIBRARY_SOURCES_CPP:.cxx=.lo)\n");
354
 
      
 
404
      Printf(f_extra, "LTLIBRARY_SOURCES       = %s\n", withc);
 
405
      Printf(f_extra, "LTLIBRARY_SOURCES_CPP   = %s %s\n", Swig_file_filename(outfile), withcxx);
 
406
      Printf(f_extra, "LTLIBRARY_OBJECTS_X = $(LTLIBRARY_SOURCES_CPP:.cpp=.lo) $(LTLIBRARY_SOURCES_CPP:.cxx=.lo)\n");
355
407
    }
356
 
    Printf(f_extra,"LTLIBRARY_SHARED_NAME   = php_%s.la\n", module);
357
 
    Printf(f_extra,"LTLIBRARY_SHARED_LIBADD = $(%(upper)s_SHARED_LIBADD)\n\n",module);
358
 
    Printf(f_extra,"include $(top_srcdir)/build/dynlib.mk\n");
359
 
    
360
 
    Printf(f_extra,"\n# patch in .cxx support to php build system to work like .cpp\n");
361
 
    Printf(f_extra,".SUFFIXES: .cxx\n\n");
362
 
    
363
 
    Printf(f_extra,".cxx.o:\n");
364
 
    Printf(f_extra,"  $(CXX_COMPILE) -c $<\n\n");
365
 
    
366
 
    Printf(f_extra,".cxx.lo:\n");
367
 
    Printf(f_extra,"  $(CXX_PHP_COMPILE)\n\n");
368
 
    Printf(f_extra,".cxx.slo:\n");
369
 
    
370
 
    Printf(f_extra,"  $(CXX_SHARED_COMPILE)\n\n");
371
 
    
372
 
    Printf(f_extra,"\n# make it easy to test module\n");
373
 
    Printf(f_extra,"testmodule:\n");
374
 
    Printf(f_extra,"  php -q -d extension_dir=modules %s\n\n",Swig_file_filename(phpfilename));
375
 
    
 
408
    Printf(f_extra, "LTLIBRARY_SHARED_NAME   = %s.la\n", module);
 
409
    Printf(f_extra, "LTLIBRARY_SHARED_LIBADD = $(%s_SHARED_LIBADD)\n\n", cap_module);
 
410
    Printf(f_extra, "include $(top_srcdir)/build/dynlib.mk\n");
 
411
 
 
412
    Printf(f_extra, "\n# patch in .cxx support to php build system to work like .cpp\n");
 
413
    Printf(f_extra, ".SUFFIXES: .cxx\n\n");
 
414
 
 
415
    Printf(f_extra, ".cxx.o:\n");
 
416
    Printf(f_extra, "\t$(CXX_COMPILE) -c $<\n\n");
 
417
 
 
418
    Printf(f_extra, ".cxx.lo:\n");
 
419
    Printf(f_extra, "\t$(CXX_PHP_COMPILE)\n\n");
 
420
    Printf(f_extra, ".cxx.slo:\n");
 
421
 
 
422
    Printf(f_extra, "\t$(CXX_SHARED_COMPILE)\n\n");
 
423
 
 
424
    Printf(f_extra, "\n# make it easy to test module\n");
 
425
    Printf(f_extra, "testmodule:\n");
 
426
    Printf(f_extra, "\tphp -q -d extension_dir=modules %s\n\n", Swig_file_filename(phpfilename));
 
427
 
376
428
    Close(f_extra);
377
 
      
 
429
 
378
430
    /* Now config.m4 */
379
431
    // Note: # comments are OK in config.m4 if you don't mind them
380
 
    // appearing in the final ./configure file 
 
432
    // appearing in the final ./configure file
381
433
    // (which can help with ./configure debugging)
382
 
    
 
434
 
383
435
    // NOTE2: phpize really ought to be able to write out a sample
384
436
    // config.m4 based on some simple data, I'll take this up with
385
437
    // the php folk!
388
440
      FileErrorDisplay(configm4);
389
441
      SWIG_exit(EXIT_FAILURE);
390
442
    }
391
 
    
392
 
    Printf(f_extra,"dnl $Id: php4.cxx,v 1.34 2006/03/20 00:24:39 marcelomatus Exp $\n");
393
 
    Printf(f_extra,"dnl ***********************************************************************\n");
394
 
    Printf(f_extra,"dnl ** THIS config.m4 is provided for PHPIZE and PHP's consumption NOT\n");
395
 
    Printf(f_extra,"dnl ** for any part of the rest of the %s build system\n",module);
396
 
    Printf(f_extra,"dnl ***********************************************************************\n\n");
397
 
    
398
 
    
399
 
    if (! with) { // must be enable then
400
 
      Printf(f_extra,"PHP_ARG_ENABLE(%s, whether to enable %s support,\n",module,module);
401
 
      Printf(f_extra,"[  --enable-%s             Enable %s support])\n\n",module,module);
 
443
 
 
444
    Printf(f_extra, "dnl $Id: php4.cxx,v 1.68 2006/11/01 23:54:52 wsfulton Exp $\n");
 
445
    Printf(f_extra, "dnl ***********************************************************************\n");
 
446
    Printf(f_extra, "dnl ** THIS config.m4 is provided for PHPIZE and PHP's consumption NOT\n");
 
447
    Printf(f_extra, "dnl ** for any part of the rest of the %s build system\n", module);
 
448
    Printf(f_extra, "dnl ***********************************************************************\n\n");
 
449
 
 
450
 
 
451
    if (!with) {                // must be enable then
 
452
      Printf(f_extra, "PHP_ARG_ENABLE(%s, whether to enable %s support,\n", module, module);
 
453
      Printf(f_extra, "[  --enable-%s             Enable %s support])\n\n", module, module);
402
454
    } else {
403
 
      Printf(f_extra,"PHP_ARG_WITH(%s, for %s support,\n",module,module);
404
 
      Printf(f_extra,"[  --with-%s[=DIR]             Include %s support.])\n\n",module,module);
 
455
      Printf(f_extra, "PHP_ARG_WITH(%s, for %s support,\n", module, module);
 
456
      Printf(f_extra, "[  --with-%s[=DIR]             Include %s support.])\n\n", module, module);
405
457
      // These tests try and file the library we need
406
 
      Printf(f_extra,"dnl THESE TESTS try and find the library and header files\n");
407
 
      Printf(f_extra,"dnl your new php module needs. YOU MAY NEED TO EDIT THEM\n");
408
 
      Printf(f_extra,"dnl as written they assume your header files are all in the same place\n\n");
409
 
      
410
 
      Printf(f_extra,"dnl ** are we looking for %s_lib.h or something else?\n",module);
 
458
      Printf(f_extra, "dnl THESE TESTS try and find the library and header files\n");
 
459
      Printf(f_extra, "dnl your new php module needs. YOU MAY NEED TO EDIT THEM\n");
 
460
      Printf(f_extra, "dnl as written they assume your header files are all in the same place\n\n");
 
461
 
 
462
      Printf(f_extra, "dnl ** are we looking for %s_lib.h or something else?\n", module);
411
463
      if (withincs)
412
 
        Printf(f_extra,"HNAMES=\"%s\"\n\n",withincs);
 
464
        Printf(f_extra, "HNAMES=\"%s\"\n\n", withincs);
413
465
      else
414
 
        Printf(f_extra,"HNAMES=\"\"; # %s_lib.h ?\n\n",module);
415
 
      
416
 
      Printf(f_extra,"dnl ** Are we looking for lib%s.a or lib%s.so or something else?\n",module,module);
417
 
      
 
466
        Printf(f_extra, "HNAMES=\"\"; # %s_lib.h ?\n\n", module);
 
467
 
 
468
      Printf(f_extra, "dnl ** Are we looking for lib%s.a or lib%s.so or something else?\n", module, module);
 
469
 
418
470
      if (withlibs)
419
 
        Printf(f_extra,"LIBNAMES=\"%s\"\n\n",withlibs);
 
471
        Printf(f_extra, "LIBNAMES=\"%s\"\n\n", withlibs);
420
472
      else
421
 
        Printf(f_extra,"LIBNAMES=\"\"; # lib_%s.so ?\n\n",withlibs);
422
 
      
423
 
      Printf(f_extra,"dnl IF YOU KNOW one of the symbols in the library and you\n");
424
 
      Printf(f_extra,"dnl specify it below then we can have a link test to see if it works\n");
425
 
      Printf(f_extra,"LIBSYMBOL=\"\"\n\n");
 
473
        Printf(f_extra, "LIBNAMES=\"\"; # lib%s.so ?\n\n", module);
 
474
 
 
475
      Printf(f_extra, "dnl IF YOU KNOW one of the symbols in the library and you\n");
 
476
      Printf(f_extra, "dnl specify it below then we can have a link test to see if it works\n");
 
477
      Printf(f_extra, "LIBSYMBOL=\"\"\n\n");
426
478
    }
427
 
    
 
479
 
428
480
    // Now write out tests to find thing.. they may need to extend tests
429
 
    Printf(f_extra,"if test \"$PHP_%(upper)s\" != \"no\"; then\n\n",module);
430
 
    
 
481
    Printf(f_extra, "if test \"$PHP_%s\" != \"no\"; then\n\n", cap_module);
 
482
 
431
483
    // Ready for when we add libraries as we find them
432
 
    Printf(f_extra,"  PHP_SUBST(%(upper)s_SHARED_LIBADD)\n\n",module);
433
 
    
434
 
    if (withlibs) { // find more than one library
435
 
      Printf(f_extra,"  for LIBNAME in $LIBNAMES ; do\n");
436
 
      Printf(f_extra,"    LIBDIR=\"\"\n");
 
484
    Printf(f_extra, "  PHP_SUBST(%s_SHARED_LIBADD)\n\n", cap_module);
 
485
 
 
486
    if (withlibs) {             // find more than one library
 
487
      Printf(f_extra, "  for LIBNAME in $LIBNAMES ; do\n");
 
488
      Printf(f_extra, "    LIBDIR=\"\"\n");
437
489
      // For each path element to try...
438
 
      Printf(f_extra,"    for i in $PHP_%(upper)s $PHP_%(upper)s/lib /usr/lib /usr/local/lib ; do\n",module,module);
439
 
      Printf(f_extra,"      if test -r $i/lib$LIBNAME.a -o -r $i/lib$LIBNAME.so ; then\n");
440
 
      Printf(f_extra,"        LIBDIR=\"$i\"\n");
441
 
      Printf(f_extra,"        break\n");
442
 
      Printf(f_extra,"      fi\n");
443
 
      Printf(f_extra,"    done\n\n");
444
 
      Printf(f_extra,"    dnl ** and $LIBDIR should be the library path\n");
445
 
      Printf(f_extra,"    if test \"$LIBNAME\" != \"\" -a -z \"$LIBDIR\" ; then\n");
446
 
      Printf(f_extra,"      AC_MSG_RESULT(Library files $LIBNAME not found)\n");
447
 
      Printf(f_extra,"      AC_MSG_ERROR(Is the %s distribution installed properly?)\n",module);
448
 
      Printf(f_extra,"    else\n");
449
 
      Printf(f_extra,"      AC_MSG_RESULT(Library files $LIBNAME found in $LIBDIR)\n");
450
 
      Printf(f_extra,"      PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $LIBDIR, %(upper)s_SHARED_LIBADD)\n",module);
451
 
      Printf(f_extra,"    fi\n");
452
 
      Printf(f_extra,"  done\n\n");
 
490
      Printf(f_extra, "    for i in $PHP_%s $PHP_%s/lib /usr/lib /usr/local/lib ; do\n", cap_module, cap_module);
 
491
      Printf(f_extra, "      if test -r $i/lib$LIBNAME.a -o -r $i/lib$LIBNAME.so ; then\n");
 
492
      Printf(f_extra, "        LIBDIR=\"$i\"\n");
 
493
      Printf(f_extra, "        break\n");
 
494
      Printf(f_extra, "      fi\n");
 
495
      Printf(f_extra, "    done\n\n");
 
496
      Printf(f_extra, "    dnl ** and $LIBDIR should be the library path\n");
 
497
      Printf(f_extra, "    if test \"$LIBNAME\" != \"\" -a -z \"$LIBDIR\" ; then\n");
 
498
      Printf(f_extra, "      AC_MSG_RESULT(Library files $LIBNAME not found)\n");
 
499
      Printf(f_extra, "      AC_MSG_ERROR(Is the %s distribution installed properly?)\n", module);
 
500
      Printf(f_extra, "    else\n");
 
501
      Printf(f_extra, "      AC_MSG_RESULT(Library files $LIBNAME found in $LIBDIR)\n");
 
502
      Printf(f_extra, "      PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $LIBDIR, %s_SHARED_LIBADD)\n", cap_module);
 
503
      Printf(f_extra, "    fi\n");
 
504
      Printf(f_extra, "  done\n\n");
453
505
    }
454
 
    
455
 
    if (withincs) {  // Find more than once include
456
 
      Printf(f_extra,"  for HNAME in $HNAMES ; do\n");
457
 
      Printf(f_extra,"    INCDIR=\"\"\n");
 
506
 
 
507
    if (withincs) {             // Find more than once include
 
508
      Printf(f_extra, "  for HNAME in $HNAMES ; do\n");
 
509
      Printf(f_extra, "    INCDIR=\"\"\n");
458
510
      // For each path element to try...
459
 
      Printf(f_extra,"    for i in $PHP_%(upper)s $PHP_%(upper)s/include $PHP_%(upper)s/includes $PHP_%(upper)s/inc $PHP_%(upper)s/incs /usr/local/include /usr/include; do\n",module,module,module,module,module);
 
511
      Printf(f_extra, "    for i in $PHP_%s $PHP_%s/include $PHP_%s/includes $PHP_%s/inc $PHP_%s/incs /usr/local/include /usr/include; do\n", cap_module,
 
512
             cap_module, cap_module, cap_module, cap_module);
460
513
      // Try and find header files
461
 
      Printf(f_extra,"      if test \"$HNAME\" != \"\" -a -r $i/$HNAME ; then\n");
462
 
      Printf(f_extra,"        INCDIR=\"$i\"\n");
463
 
      Printf(f_extra,"        break\n");
464
 
      Printf(f_extra,"      fi\n");
465
 
      Printf(f_extra,"    done\n\n");
466
 
      
467
 
      Printf(f_extra,"    dnl ** Now $INCDIR should be the include file path\n");
468
 
      Printf(f_extra,"    if test \"$HNAME\" != \"\" -a -z \"$INCDIR\" ; then\n");
469
 
      Printf(f_extra,"      AC_MSG_RESULT(Include files $HNAME not found)\n");
470
 
      Printf(f_extra,"      AC_MSG_ERROR(Is the %s distribution installed properly?)\n",module);
471
 
      Printf(f_extra,"    else\n");
472
 
      Printf(f_extra,"      AC_MSG_RESULT(Include files $HNAME found in $INCDIR)\n");
473
 
      Printf(f_extra,"      PHP_ADD_INCLUDE($INCDIR)\n");
474
 
      Printf(f_extra,"    fi\n\n");
475
 
      Printf(f_extra,"  done\n\n");
 
514
      Printf(f_extra, "      if test \"$HNAME\" != \"\" -a -r $i/$HNAME ; then\n");
 
515
      Printf(f_extra, "        INCDIR=\"$i\"\n");
 
516
      Printf(f_extra, "        break\n");
 
517
      Printf(f_extra, "      fi\n");
 
518
      Printf(f_extra, "    done\n\n");
 
519
 
 
520
      Printf(f_extra, "    dnl ** Now $INCDIR should be the include file path\n");
 
521
      Printf(f_extra, "    if test \"$HNAME\" != \"\" -a -z \"$INCDIR\" ; then\n");
 
522
      Printf(f_extra, "      AC_MSG_RESULT(Include files $HNAME not found)\n");
 
523
      Printf(f_extra, "      AC_MSG_ERROR(Is the %s distribution installed properly?)\n", module);
 
524
      Printf(f_extra, "    else\n");
 
525
      Printf(f_extra, "      AC_MSG_RESULT(Include files $HNAME found in $INCDIR)\n");
 
526
      Printf(f_extra, "      PHP_ADD_INCLUDE($INCDIR)\n");
 
527
      Printf(f_extra, "    fi\n\n");
 
528
      Printf(f_extra, "  done\n\n");
476
529
    }
477
 
    
 
530
 
478
531
    if (CPlusPlus) {
479
 
      Printf(f_extra,"  # As this is a C++ module..\n");
 
532
      Printf(f_extra, "  # As this is a C++ module..\n");
480
533
    }
481
 
    
482
 
    Printf(f_extra,"  PHP_REQUIRE_CXX\n");
483
 
    Printf(f_extra,"  AC_CHECK_LIB(stdc++, cin)\n");
484
 
    
 
534
 
 
535
    Printf(f_extra, "  PHP_REQUIRE_CXX\n");
 
536
    Printf(f_extra, "  AC_CHECK_LIB(stdc++, cin)\n");
 
537
 
485
538
    if (with) {
486
 
      Printf(f_extra,"  if test \"$LIBSYMBOL\" != \"\" ; then\n");
487
 
      Printf(f_extra,"    old_LIBS=\"$LIBS\"\n");
488
 
      Printf(f_extra,"    LIBS=\"$LIBS -L$TEST_DIR/lib -lm -ldl\"\n");
489
 
      Printf(f_extra,"    AC_CHECK_LIB($LIBNAME, $LIBSYMBOL, [AC_DEFINE(HAVE_TESTLIB,1,  [ ])],\n");
490
 
      Printf(f_extra,"    [AC_MSG_ERROR(wrong test lib version or lib not found)])\n");
491
 
      Printf(f_extra,"    LIBS=\"$old_LIBS\"\n");
492
 
      Printf(f_extra,"  fi\n\n");
 
539
      Printf(f_extra, "  if test \"$LIBSYMBOL\" != \"\" ; then\n");
 
540
      Printf(f_extra, "    old_LIBS=\"$LIBS\"\n");
 
541
      Printf(f_extra, "    LIBS=\"$LIBS -L$TEST_DIR/lib -lm -ldl\"\n");
 
542
      Printf(f_extra, "    AC_CHECK_LIB($LIBNAME, $LIBSYMBOL, [AC_DEFINE(HAVE_TESTLIB,1,  [ ])],\n");
 
543
      Printf(f_extra, "    [AC_MSG_ERROR(wrong test lib version or lib not found)])\n");
 
544
      Printf(f_extra, "    LIBS=\"$old_LIBS\"\n");
 
545
      Printf(f_extra, "  fi\n\n");
493
546
    }
494
 
    
495
 
    Printf(f_extra,"  AC_DEFINE(HAVE_%(upper)s, 1, [ ])\n",module);
496
 
    Printf(f_extra,"dnl  AC_DEFINE_UNQUOTED(PHP_%(upper)s_DIR, \"$%(upper)s_DIR\", [ ])\n",module,module);
497
 
    Printf(f_extra,"  PHP_EXTENSION(%s, $ext_shared)\n",module);
498
 
    
 
547
 
 
548
    Printf(f_extra, "  AC_DEFINE(HAVE_%s, 1, [ ])\n", cap_module);
 
549
    Printf(f_extra, "dnl  AC_DEFINE_UNQUOTED(PHP_%s_DIR, \"$%s_DIR\", [ ])\n", cap_module, cap_module);
 
550
    Printf(f_extra, "  PHP_EXTENSION(%s, $ext_shared)\n", module);
 
551
 
499
552
    // and thats all!
500
 
    Printf(f_extra,"fi\n");
501
 
    
 
553
    Printf(f_extra, "fi\n");
 
554
 
502
555
    Close(f_extra);
503
 
    
 
556
 
504
557
    /*  CREDITS */
505
558
    f_extra = NewFile(credits, "w");
506
559
    if (!f_extra) {
519
572
 
520
573
    String *filen;
521
574
    String *s_type;
522
 
    
 
575
 
523
576
    /* Initialize all of the output files */
524
 
    String *outfile = Getattr(n,"outfile");
525
 
    
 
577
    String *outfile = Getattr(n, "outfile");
 
578
 
526
579
    /* main output file */
527
 
    f_runtime = NewFile(outfile,"w");
 
580
    f_runtime = NewFile(outfile, "w");
528
581
    if (!f_runtime) {
529
582
      FileErrorDisplay(outfile);
530
583
      SWIG_exit(EXIT_FAILURE);
531
584
    }
532
 
    
 
585
 
533
586
    Swig_banner(f_runtime);
534
 
    
 
587
 
535
588
    /* sections of the output file */
536
589
    s_init = NewString("/* init section */\n");
537
590
    r_init = NewString("/* rinit section */\n");
539
592
    r_shutdown = NewString("/* rshutdown section */\n");
540
593
    s_header = NewString("/* header section */\n");
541
594
    s_wrappers = NewString("/* wrapper section */\n");
542
 
    s_type = NewString("");
 
595
    s_type = NewStringEmpty();
543
596
    /* subsections of the init section */
544
597
    s_vinit = NewString("/* vinit subsection */\n");
545
598
    s_vdecl = NewString("/* vdecl subsection */\n");
546
599
    s_cinit = NewString("/* cinit subsection */\n");
547
600
    s_oinit = NewString("/* oinit subsection */\n");
548
 
    pragma_phpinfo = NewString("");
549
 
    
 
601
    pragma_phpinfo = NewStringEmpty();
 
602
    s_phpclasses = NewString("/* PHP Proxy Classes */\n");
 
603
 
550
604
    /* Register file targets with the SWIG file handler */
551
 
    Swig_register_filebyname("runtime",f_runtime);
552
 
    Swig_register_filebyname("init",s_init);
553
 
    Swig_register_filebyname("rinit",r_init);
554
 
    Swig_register_filebyname("shutdown",s_shutdown);
555
 
    Swig_register_filebyname("rshutdown",r_shutdown);
556
 
    Swig_register_filebyname("header",s_header);
557
 
    Swig_register_filebyname("wrapper",s_wrappers);
558
 
    
 
605
    Swig_register_filebyname("runtime", f_runtime);
 
606
    Swig_register_filebyname("init", s_init);
 
607
    Swig_register_filebyname("rinit", r_init);
 
608
    Swig_register_filebyname("shutdown", s_shutdown);
 
609
    Swig_register_filebyname("rshutdown", r_shutdown);
 
610
    Swig_register_filebyname("header", s_header);
 
611
    Swig_register_filebyname("wrapper", s_wrappers);
 
612
 
559
613
    /* Set the module name */
560
 
    module = Copy(Getattr(n,"name"));
561
 
    cap_module = NewStringf("%(upper)s",module);
562
 
    
563
 
    /* Set the dlname */
564
 
    if (!dlname) {
565
 
#if defined(_WIN32) || defined(__WIN32__)
566
 
      dlname = NewStringf("php_%s.dll", module);
567
 
#else
568
 
      dlname = NewStringf("php_%s.so", module);
569
 
#endif
570
 
    }
571
 
    
 
614
    module = Copy(Getattr(n, "name"));
 
615
    cap_module = NewStringf("%(upper)s", module);
 
616
    if (!prefix)
 
617
      prefix = NewStringEmpty();
 
618
 
572
619
    /* PHP module file */
573
 
    filen = NewString("");
 
620
    filen = NewStringEmpty();
574
621
    Printv(filen, SWIG_output_directory(), module, ".php", NIL);
575
622
    phpfilename = NewString(filen);
576
 
    
 
623
 
577
624
    f_phpcode = NewFile(filen, "w");
578
625
    if (!f_phpcode) {
579
626
      FileErrorDisplay(filen);
580
627
      SWIG_exit(EXIT_FAILURE);
581
628
    }
582
 
    
 
629
 
583
630
    Printf(f_phpcode, "<?php\n\n");
584
 
    
 
631
 
585
632
    Swig_banner(f_phpcode);
586
 
    
587
 
    Printf(f_phpcode,"global $%s_LOADED__;\n", cap_module);
588
 
    Printf(f_phpcode,"if ($%s_LOADED__) return;\n", cap_module);
589
 
    Printf(f_phpcode,"$%s_LOADED__ = true;\n\n", cap_module);
590
 
    Printf(f_phpcode,"/* if our extension has not been loaded, do what we can */\n");
591
 
    Printf(f_phpcode,"if (!extension_loaded(\"php_%s\")) {\n", module);
592
 
    Printf(f_phpcode,"  if (!dl(\"%s\")) return;\n", dlname);
593
 
    Printf(f_phpcode,"}\n\n");
594
 
    
595
 
    
 
633
 
 
634
    Printf(f_phpcode, "// Try to load our extension if it's not already loaded.\n");
 
635
    Printf(f_phpcode, "if (!extension_loaded(\"%s\")) {\n", module);
 
636
    Printf(f_phpcode, "  if (strtolower(substr(PHP_OS, 0, 3)) === 'win') {\n");
 
637
    Printf(f_phpcode, "    if (!dl('php_%s.dll')) return;\n", module);
 
638
    Printf(f_phpcode, "  } else {\n");
 
639
    Printf(f_phpcode, "    // PHP_SHLIB_SUFFIX is available as of PHP 4.3.0, for older PHP assume 'so'.\n");
 
640
    Printf(f_phpcode, "    // It gives 'dylib' on MacOS X which is for libraries, modules are 'so'.\n");
 
641
    Printf(f_phpcode, "    if (PHP_SHLIB_SUFFIX === 'PHP_SHLIB_SUFFIX' || PHP_SHLIB_SUFFIX === 'dylib') {\n");
 
642
    Printf(f_phpcode, "      if (!dl('%s.so')) return;\n", module);
 
643
    Printf(f_phpcode, "    } else {\n");
 
644
    Printf(f_phpcode, "      if (!dl('%s.'.PHP_SHLIB_SUFFIX)) return;\n", module);
 
645
    Printf(f_phpcode, "    }\n");
 
646
    Printf(f_phpcode, "  }\n");
 
647
    Printf(f_phpcode, "}\n\n");
 
648
 
596
649
    /* sub-sections of the php file */
597
 
    pragma_code = NewString("");
598
 
    pragma_incl = NewString("");
599
 
    
 
650
    pragma_code = NewStringEmpty();
 
651
    pragma_incl = NewStringEmpty();
 
652
 
600
653
    /* Initialize the rest of the module */
601
654
 
602
 
    Printf(s_oinit, "ZEND_INIT_MODULE_GLOBALS(%s, %s_init_globals, %s_destroy_globals);\n",module,module,module);
603
 
    
 
655
    Printf(s_oinit, "ZEND_INIT_MODULE_GLOBALS(%s, %s_init_globals, %s_destroy_globals);\n", module, module, module);
 
656
 
604
657
    /* start the header section */
605
658
    Printf(s_header, php_header);
606
659
    Printf(s_header, "ZEND_BEGIN_MODULE_GLOBALS(%s)\n", module);
607
660
    Printf(s_header, "char *error_msg;\n");
608
661
    Printf(s_header, "int error_code;\n");
609
 
    Printf(s_header, "ZEND_END_MODULE_GLOBALS(%s)\n", module );
610
 
    Printf(s_header, "ZEND_DECLARE_MODULE_GLOBALS(%s)\n",module );
611
 
    Printf(s_header, "#ifdef ZTS\n" );
612
 
    Printf(s_header, "#define ErrorMsg() TSRMG(%s_globals_id, zend_%s_globals *, error_msg )\n",module,module);
613
 
    Printf(s_header, "#define ErrorCode() TSRMG(%s_globals_id, zend_%s_globals *, error_code )\n",module,module);
614
 
    Printf(s_header, "#else\n" );
615
 
    Printf(s_header, "#define ErrorMsg() (%s_globals.error_msg)\n",module);
616
 
    Printf(s_header, "#define ErrorCode() (%s_globals.error_code)\n",module);
617
 
    Printf(s_header, "#endif\n\n" );
618
 
    
619
 
    Printf(s_header, "static void %s_init_globals(zend_%s_globals *%s_globals ) {\n",module,module,module);
620
 
    Printf(s_header, "  %s_globals->error_msg = default_error_msg;\n", module);
621
 
    Printf(s_header, "  %s_globals->error_code = default_error_code;\n",module);
 
662
    Printf(s_header, "ZEND_END_MODULE_GLOBALS(%s)\n", module);
 
663
    Printf(s_header, "ZEND_DECLARE_MODULE_GLOBALS(%s)\n", module);
 
664
    Printf(s_header, "#ifdef ZTS\n");
 
665
    Printf(s_header, "#define SWIG_ErrorMsg() TSRMG(%s_globals_id, zend_%s_globals *, error_msg )\n", module, module);
 
666
    Printf(s_header, "#define SWIG_ErrorCode() TSRMG(%s_globals_id, zend_%s_globals *, error_code )\n", module, module);
 
667
    Printf(s_header, "#else\n");
 
668
    Printf(s_header, "#define SWIG_ErrorMsg() (%s_globals.error_msg)\n", module);
 
669
    Printf(s_header, "#define SWIG_ErrorCode() (%s_globals.error_code)\n", module);
 
670
    Printf(s_header, "#endif\n\n");
 
671
 
 
672
    Printf(s_header, "static void %s_init_globals(zend_%s_globals *globals ) {\n", module, module);
 
673
    Printf(s_header, "  globals->error_msg = default_error_msg;\n");
 
674
    Printf(s_header, "  globals->error_code = default_error_code;\n");
622
675
    Printf(s_header, "}\n");
623
 
    
624
 
    Printf(s_header, "static void %s_destroy_globals(zend_%s_globals *%s_globals) { }\n",module,module,module);
 
676
 
 
677
    Printf(s_header, "static void %s_destroy_globals(zend_%s_globals * globals) { (void)globals; }\n", module, module);
625
678
 
626
679
    Printf(s_header, "\n");
627
 
    Printf(s_header, "void SWIG_ResetError() {\n");
 
680
    Printf(s_header, "static void SWIG_ResetError() {\n");
628
681
    Printf(s_header, "  TSRMLS_FETCH();\n");
629
 
    Printf(s_header, "  ErrorMsg() = default_error_msg;\n");
630
 
    Printf(s_header, "  ErrorCode() = default_error_code;\n");
 
682
    Printf(s_header, "  SWIG_ErrorMsg() = default_error_msg;\n");
 
683
    Printf(s_header, "  SWIG_ErrorCode() = default_error_code;\n");
631
684
    Printf(s_header, "}\n");
632
685
 
633
 
    Printf(s_header,"#define SWIG_name  \"%s\"\n", module);
 
686
    Printf(s_header, "#define SWIG_name  \"%s\"\n", module);
634
687
    /*     Printf(s_header,"#ifdef HAVE_CONFIG_H\n");
635
 
           Printf(s_header,"#include \"config.h\"\n");
636
 
           Printf(s_header,"#endif\n\n");
637
 
    */
638
 
    Printf(s_header,"#ifdef __cplusplus\n");
639
 
    Printf(s_header,"extern \"C\" {\n");
640
 
    Printf(s_header,"#endif\n");
641
 
    Printf(s_header,"#include \"php.h\"\n");
642
 
    Printf(s_header,"#include \"php_ini.h\"\n");
643
 
    Printf(s_header,"#include \"ext/standard/info.h\"\n");
644
 
    Printf(s_header,"#include \"php_%s.h\"\n", module);
645
 
    Printf(s_header,"#ifdef __cplusplus\n");
646
 
    Printf(s_header,"}\n");
647
 
    Printf(s_header,"#endif\n\n");
648
 
           
 
688
       Printf(s_header,"#include \"config.h\"\n");
 
689
       Printf(s_header,"#endif\n\n");
 
690
     */
 
691
    Printf(s_header, "#ifdef __cplusplus\n");
 
692
    Printf(s_header, "extern \"C\" {\n");
 
693
    Printf(s_header, "#endif\n");
 
694
    Printf(s_header, "#include \"php.h\"\n");
 
695
    Printf(s_header, "#include \"php_ini.h\"\n");
 
696
    Printf(s_header, "#include \"ext/standard/info.h\"\n");
 
697
    Printf(s_header, "#include \"php_%s.h\"\n", module);
 
698
    Printf(s_header, "#ifdef __cplusplus\n");
 
699
    Printf(s_header, "}\n");
 
700
    Printf(s_header, "#endif\n\n");
 
701
 
649
702
    /* Create the .h file too */
650
 
    filen = NewString("");
 
703
    filen = NewStringEmpty();
651
704
    Printv(filen, SWIG_output_directory(), "php_", module, ".h", NIL);
652
705
    f_h = NewFile(filen, "w");
653
706
    if (!f_h) {
654
707
      FileErrorDisplay(filen);
655
708
      SWIG_exit(EXIT_FAILURE);
656
709
    }
657
 
    
 
710
 
658
711
    Swig_banner(f_h);
659
712
    Printf(f_h, php_header);
660
 
    
 
713
 
661
714
    Printf(f_h, "\n\n");
662
 
    Printf(f_h, "#ifndef PHP_%s_H\n", cap_module );
663
 
    Printf(f_h, "#define PHP_%s_H\n\n", cap_module );
664
 
    Printf(f_h, "extern zend_module_entry %s_module_entry;\n", module );
665
 
    Printf(f_h, "#define phpext_%s_ptr &%s_module_entry\n\n", module, module );
666
 
    Printf(f_h, "#ifdef PHP_WIN32\n" );
667
 
    Printf(f_h, "# define PHP_%s_API __declspec(dllexport)\n", cap_module );
668
 
    Printf(f_h, "#else\n" );
669
 
    Printf(f_h, "# define PHP_%s_API\n", cap_module );
670
 
    Printf(f_h, "#endif\n\n" );
671
 
    Printf(f_h, "#ifdef ZTS\n" );
672
 
    Printf(f_h, "#include \"TSRM.h\"\n" );
673
 
    Printf(f_h, "#endif\n\n" );
674
 
    Printf(f_h, "PHP_MINIT_FUNCTION(%s);\n", module );
675
 
    Printf(f_h, "PHP_MSHUTDOWN_FUNCTION(%s);\n", module );
676
 
    Printf(f_h, "PHP_RINIT_FUNCTION(%s);\n", module );
677
 
    Printf(f_h, "PHP_RSHUTDOWN_FUNCTION(%s);\n", module );
678
 
    Printf(f_h, "PHP_MINFO_FUNCTION(%s);\n\n", module );
679
 
    
 
715
    Printf(f_h, "#ifndef PHP_%s_H\n", cap_module);
 
716
    Printf(f_h, "#define PHP_%s_H\n\n", cap_module);
 
717
    Printf(f_h, "extern zend_module_entry %s_module_entry;\n", module);
 
718
    Printf(f_h, "#define phpext_%s_ptr &%s_module_entry\n\n", module, module);
 
719
    Printf(f_h, "#ifdef PHP_WIN32\n");
 
720
    Printf(f_h, "# define PHP_%s_API __declspec(dllexport)\n", cap_module);
 
721
    Printf(f_h, "#else\n");
 
722
    Printf(f_h, "# define PHP_%s_API\n", cap_module);
 
723
    Printf(f_h, "#endif\n\n");
 
724
    Printf(f_h, "#ifdef ZTS\n");
 
725
    Printf(f_h, "#include \"TSRM.h\"\n");
 
726
    Printf(f_h, "#endif\n\n");
 
727
    Printf(f_h, "PHP_MINIT_FUNCTION(%s);\n", module);
 
728
    Printf(f_h, "PHP_MSHUTDOWN_FUNCTION(%s);\n", module);
 
729
    Printf(f_h, "PHP_RINIT_FUNCTION(%s);\n", module);
 
730
    Printf(f_h, "PHP_RSHUTDOWN_FUNCTION(%s);\n", module);
 
731
    Printf(f_h, "PHP_MINFO_FUNCTION(%s);\n\n", module);
 
732
 
680
733
    /* start the function entry section */
681
734
    s_entry = NewString("/* entry subsection */\n");
682
735
 
683
736
    /* holds all the per-class function entry sections */
684
737
    all_cs_entry = NewString("/* class entry subsection */\n");
685
738
    cs_entry = NULL;
686
 
    
687
 
    Printf(s_entry,"/* Every non-class user visible function must have an entry here */\n");
688
 
    Printf(s_entry,"function_entry %s_functions[] = {\n", module);
689
 
    
 
739
 
 
740
    Printf(s_entry, "/* Every non-class user visible function must have an entry here */\n");
 
741
    Printf(s_entry, "static function_entry %s_functions[] = {\n", module);
 
742
 
690
743
    /* start the init section */
691
 
    if (gen_extra) {
692
 
      Printf(s_init,"#ifdef COMPILE_DL_%s\n", cap_module);
693
 
    }
694
 
    Printf(s_init,"#ifdef __cplusplus\n");
695
 
    Printf(s_init,"extern \"C\" {\n");
696
 
    Printf(s_init,"#endif\n");
697
 
    Printf(s_init,"ZEND_GET_MODULE(%s)\n",module);
698
 
    Printf(s_init,"#ifdef __cplusplus\n");
699
 
    Printf(s_init,"}\n");
700
 
    Printf(s_init,"#endif\n\n");
701
 
           
702
 
    if (gen_extra) {
703
 
      Printf(s_init,"#endif\n\n");
704
 
    }
705
 
    
 
744
    Printv(s_init, "zend_module_entry ", module, "_module_entry = {\n" "#if ZEND_MODULE_API_NO > 20010900\n" "    STANDARD_MODULE_HEADER,\n" "#endif\n", NIL);
 
745
    Printf(s_init, "    \"%s\",\n", module);
 
746
    Printf(s_init, "    %s_functions,\n", module);
 
747
    Printf(s_init, "    PHP_MINIT(%s),\n", module);
 
748
    Printf(s_init, "    PHP_MSHUTDOWN(%s),\n", module);
 
749
    Printf(s_init, "    PHP_RINIT(%s),\n", module);
 
750
    Printf(s_init, "    PHP_RSHUTDOWN(%s),\n", module);
 
751
    Printf(s_init, "    PHP_MINFO(%s),\n", module);
 
752
    Printf(s_init, "#if ZEND_MODULE_API_NO > 20010900\n");
 
753
    Printf(s_init, "    NO_VERSION_YET,\n");
 
754
    Printf(s_init, "#endif\n");
 
755
    Printf(s_init, "    STANDARD_MODULE_PROPERTIES\n");
 
756
    Printf(s_init, "};\n");
 
757
    Printf(s_init, "zend_module_entry* SWIG_module_entry = &%s_module_entry;\n\n", module);
 
758
 
 
759
    if (gen_extra) {
 
760
      Printf(s_init, "#ifdef COMPILE_DL_%s\n", cap_module);
 
761
    }
 
762
    Printf(s_init, "#ifdef __cplusplus\n");
 
763
    Printf(s_init, "extern \"C\" {\n");
 
764
    Printf(s_init, "#endif\n");
 
765
    // We want to write "SWIGEXPORT ZEND_GET_MODULE(%s)" but ZEND_GET_MODULE
 
766
    // in PHP5 has "extern "C" { ... }" around it so we can't do that.
 
767
    Printf(s_init, "SWIGEXPORT zend_module_entry *get_module(void) { return &%s_module_entry; }\n", module);
 
768
    Printf(s_init, "#ifdef __cplusplus\n");
 
769
    Printf(s_init, "}\n");
 
770
    Printf(s_init, "#endif\n\n");
 
771
 
 
772
    if (gen_extra) {
 
773
      Printf(s_init, "#endif\n\n");
 
774
    }
 
775
 
706
776
    /* We have to register the constants before they are (possibly) used
707
777
     * by the pointer typemaps. This all needs re-arranging really as
708
778
     * things are being called in the wrong order
709
779
     */
710
 
    
711
 
    Printf(s_init,"#define SWIG_php_minit PHP_MINIT_FUNCTION(%s)\n", module);
 
780
    Printf(s_init, "#define SWIG_php_minit PHP_MINIT_FUNCTION(%s)\n", module);
712
781
 
713
782
    /* Emit all of the code */
714
783
    Language::top(n);
715
784
 
716
 
    SwigPHP_emit_resource_registrations();    
 
785
    SwigPHP_emit_resource_registrations();
717
786
    //    Printv(s_init,s_resourcetypes,NIL);
718
787
    /* We need this after all classes written out by ::top */
719
 
    Printf(s_oinit, "CG(active_class_entry) = NULL;\n");        
 
788
    Printf(s_oinit, "CG(active_class_entry) = NULL;\n");
720
789
    Printf(s_oinit, "/* end oinit subsection */\n");
721
790
    Printf(s_init, "%s\n", s_oinit);
722
 
    
 
791
 
723
792
    /* Constants generated during top call */
724
 
    // But save them for RINIT
725
793
    Printf(s_cinit, "/* end cinit subsection */\n");
726
 
    
 
794
    Printf(s_init, "%s\n", s_cinit);
 
795
    Clear(s_cinit);
 
796
    Delete(s_cinit);
 
797
 
 
798
    Printf(s_init, "    return SUCCESS;\n");
 
799
    Printf(s_init, "}\n\n");
 
800
 
 
801
    // Now do REQUEST init which holds any user specified %rinit, and also vinit
 
802
    Printf(s_init, "PHP_RINIT_FUNCTION(%s)\n{\n", module);
 
803
    Printf(s_init, "%s\n", r_init);
 
804
 
727
805
    /* finish our init section which will have been used by class wrappers */
728
806
    Printf(s_vinit, "/* end vinit subsection */\n");
729
 
    
730
 
    Printf(s_init, "    return SUCCESS;\n");
731
 
    Printf(s_init,"}\n");
732
 
    
733
 
    // Now do REQUEST init which holds cinit and vinit
734
 
    Printf(s_init,"PHP_RINIT_FUNCTION(%s)\n{\n",module);
735
 
    Printf(s_init,"%s\n",r_init);
736
 
    Printf(s_init,"%s\n",s_cinit); 
737
 
    Clear(s_cinit);
738
 
    Delete(s_cinit);
739
 
    
740
807
    Printf(s_init, "%s\n", s_vinit);
741
808
    Clear(s_vinit);
742
809
    Delete(s_vinit);
743
 
    
744
 
    Printf(s_init,"    return SUCCESS;\n");
745
 
    Printf(s_init,"}\n");
746
 
    
747
 
    
748
 
    Printf(s_init,"PHP_MSHUTDOWN_FUNCTION(%s)\n{\n",module);
749
 
    Printf(s_init,"%s\n",s_shutdown);
750
 
    Printf(s_init,"    return SUCCESS;\n");
751
 
    Printf(s_init,"}\n");
752
 
    
753
 
    Printf(s_init,"PHP_RSHUTDOWN_FUNCTION(%s)\n{\n",module);
754
 
    Printf(s_init,"%s\n",r_shutdown);
755
 
    Printf(s_init,"    return SUCCESS;\n");
756
 
    Printf(s_init,"}\n");
757
 
           
758
 
    
759
 
    Printf(s_init,"PHP_MINFO_FUNCTION(%s)\n{\n",module);
760
 
    Printf(s_init,"%s", pragma_phpinfo);
761
 
    Printf(s_init,"}\n");
762
 
    Printf(s_init,"/* end init section */\n");
763
 
           
764
 
    Printf(f_h, "#endif /* PHP_%s_H */\n",  cap_module);
 
810
 
 
811
    Printf(s_init, "    return SUCCESS;\n");
 
812
    Printf(s_init, "}\n\n");
 
813
 
 
814
    Printf(s_init, "PHP_MSHUTDOWN_FUNCTION(%s)\n{\n", module);
 
815
    Printf(s_init, "%s\n", s_shutdown);
 
816
    Printf(s_init, "    return SUCCESS;\n");
 
817
    Printf(s_init, "}\n\n");
 
818
 
 
819
    Printf(s_init, "PHP_RSHUTDOWN_FUNCTION(%s)\n{\n", module);
 
820
    Printf(s_init, "%s\n", r_shutdown);
 
821
    Printf(s_init, "    return SUCCESS;\n");
 
822
    Printf(s_init, "}\n\n");
 
823
 
 
824
    Printf(s_init, "PHP_MINFO_FUNCTION(%s)\n{\n", module);
 
825
    Printf(s_init, "%s", pragma_phpinfo);
 
826
    Printf(s_init, "}\n");
 
827
    Printf(s_init, "/* end init section */\n");
 
828
 
 
829
    Printf(f_h, "#endif /* PHP_%s_H */\n", cap_module);
765
830
 
766
831
    Close(f_h);
767
832
 
768
 
    Printf(s_header, "%s\n\n",all_cs_entry);
769
 
    Printf(s_header, "%s {NULL, NULL, NULL}\n};\n\n",s_entry);
770
 
    Printf(s_header, "zend_module_entry %s_module_entry = {\n", module );
771
 
    Printf(s_header, "#if ZEND_MODULE_API_NO > 20010900\n" );
772
 
    Printf(s_header, "    STANDARD_MODULE_HEADER,\n");
773
 
    Printf(s_header, "#endif\n");
774
 
    Printf(s_header, "    \"%s\",\n", module);
775
 
    Printf(s_header, "    %s_functions,\n", module);
776
 
    Printf(s_header, "    PHP_MINIT(%s),\n", module);
777
 
    Printf(s_header, "    PHP_MSHUTDOWN(%s),\n", module);
778
 
    Printf(s_header, "    PHP_RINIT(%s),\n", module);
779
 
    Printf(s_header, "    PHP_RSHUTDOWN(%s),\n", module);
780
 
    Printf(s_header, "    PHP_MINFO(%s),\n",module);
781
 
    Printf(s_header, "#if ZEND_MODULE_API_NO > 20010900\n");
782
 
    Printf(s_header, "    NO_VERSION_YET,\n");
783
 
    Printf(s_header, "#endif\n");
784
 
    Printf(s_header, "    STANDARD_MODULE_PROPERTIES\n");
785
 
    Printf(s_header, "};\nzend_module_entry* SWIG_module_entry = &%s_module_entry;\n\n",module);
786
 
    
787
 
    String *type_table = NewString("");
788
 
    SwigType_emit_type_table(f_runtime,type_table);
789
 
    Printf(s_header,"%s",type_table);
 
833
    String *type_table = NewStringEmpty();
 
834
    SwigType_emit_type_table(f_runtime, type_table);
 
835
    Printf(s_header, "%s", type_table);
790
836
    Delete(type_table);
791
 
    
 
837
 
792
838
    /* Oh dear, more things being called in the wrong order. This whole
793
839
     * function really needs totally redoing.
794
840
     */
795
 
    
 
841
 
796
842
    Printf(s_header, "/* end header section */\n");
797
843
    Printf(s_wrappers, "/* end wrapper section */\n");
798
844
    Printf(s_vdecl, "/* end vdecl subsection */\n");
799
 
    
800
 
    Printv(f_runtime, s_header, s_vdecl, s_wrappers, s_init, NIL);
 
845
 
 
846
    Printv(f_runtime, s_header, s_vdecl, s_wrappers, NIL);
 
847
    Printv(f_runtime, all_cs_entry, "\n\n", s_entry, "{NULL, NULL, NULL}\n};\n\n", NIL);
 
848
    Printv(f_runtime, s_init, NIL);
801
849
    Delete(s_header);
802
850
    Delete(s_wrappers);
803
851
    Delete(s_init);
804
852
    Delete(s_vdecl);
 
853
    Delete(all_cs_entry);
 
854
    Delete(s_entry);
805
855
    Close(f_runtime);
806
 
    Printf(f_phpcode, "%s\n%s\n?>\n", pragma_incl, pragma_code);
807
 
    Close(f_phpcode); 
808
 
    
809
 
    if ( gen_extra ) {
 
856
 
 
857
    Printf(f_phpcode, "%s\n%s\n", pragma_incl, pragma_code);
 
858
    if (s_fakeoowrappers) {
 
859
      Printf(f_phpcode, "abstract class %s {", Len(prefix) ? prefix : module);
 
860
      Printf(f_phpcode, "%s", s_fakeoowrappers);
 
861
      Printf(f_phpcode, "}\n\n");
 
862
      Delete(s_fakeoowrappers);
 
863
      s_fakeoowrappers = NULL;
 
864
    }
 
865
    Printf(f_phpcode, "%s\n?>\n", s_phpclasses);
 
866
    Close(f_phpcode);
 
867
 
 
868
    if (gen_extra) {
810
869
      create_extra_files(outfile);
811
 
    }
812
 
    else if( gen_make ) {
 
870
    } else if (gen_make) {
813
871
      create_simple_make();
814
872
    }
815
 
    
 
873
 
816
874
    return SWIG_OK;
817
875
  }
818
 
  
819
 
/* Just need to append function names to function table to register with
820
 
   PHP
821
 
*/
822
876
 
 
877
  /* Just need to append function names to function table to register with PHP. */
823
878
  void create_command(String *cname, String *iname) {
824
 
    
 
879
    // This is for the single main function_entry record
 
880
    if (shadow && php_version == 4) {
 
881
      if (wrapperType != standard)
 
882
        return;
 
883
    }
825
884
    Printf(f_h, "ZEND_NAMED_FUNCTION(%s);\n", iname);
826
 
    
827
 
    // This is for the single main function_entry record
828
885
    if (cs_entry) {
829
 
      Printf(cs_entry," ZEND_NAMED_FE(%(lower)s,%s, NULL)\n", cname,iname );
 
886
      Printf(cs_entry, " ZEND_NAMED_FE(%(lower)s,%s,NULL)\n", cname, iname);
830
887
    } else {
831
 
      Printf(s_entry,"  ZEND_NAMED_FE(%(lower)s,%s, NULL)\n", cname,iname );
 
888
      Printf(s_entry, " ZEND_NAMED_FE(%(lower)s,%s,NULL)\n", cname, iname);
832
889
    }
833
890
  }
 
891
 
834
892
  /* ------------------------------------------------------------
835
893
   * dispatchFunction()
836
894
   * ------------------------------------------------------------ */
838
896
    /* Last node in overloaded chain */
839
897
 
840
898
    int maxargs;
841
 
    String *tmp = NewString("");
842
 
    String *dispatch = Swig_overload_dispatch(n,"return %s(INTERNAL_FUNCTION_PARAM_PASSTHRU);",&maxargs);
843
 
 
844
 
    int has_this_ptr = (wrapperType==memberfn)?shadow:0;
845
 
        
 
899
    String *tmp = NewStringEmpty();
 
900
    String *dispatch = Swig_overload_dispatch(n, "return %s(INTERNAL_FUNCTION_PARAM_PASSTHRU);", &maxargs);
 
901
 
 
902
    int has_this_ptr = (wrapperType == memberfn && shadow && php_version == 4);
 
903
 
846
904
    /* Generate a dispatch wrapper for all overloaded functions */
847
 
    
848
 
    Wrapper *f       = NewWrapper();
849
 
    String  *symname = Getattr(n,"sym:name");
850
 
    String  *wname   = Swig_name_wrapper(symname);
851
 
    
852
 
    create_command( symname, wname );
853
 
    Printv(f->def, "ZEND_NAMED_FUNCTION(", wname, ") {\n", NIL );
854
 
    
855
 
    Wrapper_add_local(f,"argc","int argc");
856
 
 
857
 
    Printf(tmp,"zval **argv[%d]", maxargs);
858
 
    Wrapper_add_local(f,"argv",tmp);
859
 
 
860
 
    Wrapper_add_local(f,"ii","int ii");
861
 
 
862
 
    Printf(f->code,"argc = ZEND_NUM_ARGS();\n");
863
 
 
864
 
    if ( has_this_ptr ) {
865
 
      Printf(f->code,"argv[0] = &this_ptr;\n");
866
 
      Printf(f->code,"zend_get_parameters_array_ex(argc,argv+1);\n");
867
 
      Printf(f->code,"argc++;\n");
868
 
    }
869
 
    else {
870
 
      Printf(f->code,"zend_get_parameters_array_ex(argc,argv);\n");
871
 
    }
872
 
    
873
 
    Replaceall(dispatch,"$args","self,args");
874
 
 
875
 
    Printv(f->code,dispatch,"\n",NIL);
876
 
 
877
 
    Printf(f->code,"ErrorCode() = E_ERROR;\n");
878
 
    Printf(f->code,"ErrorMsg() = \"No matching function for overloaded '%s'\";\n", symname);
879
 
    Printv(f->code,"zend_error(ErrorCode(),ErrorMsg());",NIL);
880
 
    Printf(f->code,"\n");
881
 
 
882
 
    Printv(f->code,"}\n",NIL);
883
 
    Wrapper_print(f,s_wrappers);
 
905
 
 
906
    Wrapper *f = NewWrapper();
 
907
    String *symname = Getattr(n, "sym:name");
 
908
    String *wname = Swig_name_wrapper(symname);
 
909
 
 
910
    create_command(symname, wname);
 
911
    Printv(f->def, "ZEND_NAMED_FUNCTION(", wname, ") {\n", NIL);
 
912
 
 
913
    Wrapper_add_local(f, "argc", "int argc");
 
914
 
 
915
    Printf(tmp, "zval **argv[%d]", maxargs);
 
916
    Wrapper_add_local(f, "argv", tmp);
 
917
 
 
918
    Printf(f->code, "argc = ZEND_NUM_ARGS();\n");
 
919
 
 
920
    if (has_this_ptr) {
 
921
      Printf(f->code, "argv[0] = &this_ptr;\n");
 
922
      Printf(f->code, "zend_get_parameters_array_ex(argc,argv+1);\n");
 
923
      Printf(f->code, "argc++;\n");
 
924
    } else {
 
925
      Printf(f->code, "zend_get_parameters_array_ex(argc,argv);\n");
 
926
    }
 
927
 
 
928
    Replaceall(dispatch, "$args", "self,args");
 
929
 
 
930
    Printv(f->code, dispatch, "\n", NIL);
 
931
 
 
932
    Printf(f->code, "SWIG_ErrorCode() = E_ERROR;\n");
 
933
    Printf(f->code, "SWIG_ErrorMsg() = \"No matching function for overloaded '%s'\";\n", symname);
 
934
    Printv(f->code, "zend_error(SWIG_ErrorCode(),SWIG_ErrorMsg());\n", NIL);
 
935
 
 
936
    Printv(f->code, "}\n", NIL);
 
937
    Wrapper_print(f, s_wrappers);
884
938
 
885
939
    DelWrapper(f);
886
940
    Delete(dispatch);
892
946
   * functionWrapper()
893
947
   * ------------------------------------------------------------ */
894
948
 
 
949
  /* Helper method for PHP::functionWrapper */
 
950
  bool is_class(SwigType *t) {
 
951
    Node *n = classLookup(t);
 
952
    if (n) {
 
953
      String *r = Getattr(n, "php:proxy");      // Set by classDeclaration()
 
954
      if (!r)
 
955
        r = Getattr(n, "sym:name");     // Not seen by classDeclaration yet, but this is the name
 
956
      if (r)
 
957
        return true;
 
958
    }
 
959
    return false;
 
960
  }
 
961
 
895
962
  virtual int functionWrapper(Node *n) {
896
 
    String   *name  = GetChar(n,"name");
897
 
    String   *iname = GetChar(n,"sym:name");
898
 
    SwigType *d     = Getattr(n,"type");
899
 
    ParmList *l     = Getattr(n,"parms");
 
963
    String *name = GetChar(n, "name");
 
964
    String *iname = GetChar(n, "sym:name");
 
965
    SwigType *d = Getattr(n, "type");
 
966
    ParmList *l = Getattr(n, "parms");
900
967
    String *nodeType = Getattr(n, "nodeType");
901
 
    int newobject   = GetFlag(n,"feature:new");
 
968
    int newobject = GetFlag(n, "feature:new");
902
969
 
903
970
    Parm *p;
904
 
    char source[256];
905
 
    char argnum[32];
906
 
    char args[32];
907
 
    int i,numopt;
 
971
    int i, numopt;
908
972
    String *tm;
909
973
    Wrapper *f;
910
 
    bool mvr=(shadow && wrapperType == membervar);
911
 
    bool mvrset=(mvr && (Strcmp(iname, Swig_name_set(Swig_name_member(shadow_classname, name)))==0) );
 
974
    bool mvr = (shadow && php_version == 4 && wrapperType == membervar);
 
975
    bool mvrset = (mvr && (Strcmp(iname, Swig_name_set(Swig_name_member(shadow_classname, name))) == 0));
912
976
 
913
 
    char wname[256];
 
977
    String *wname;
914
978
    int overloaded = 0;
915
979
    String *overname = 0;
916
980
 
917
 
    int destructor = ( Cmp(nodeType, "destructor") == 0 );
918
 
    if ( destructor ) {
919
 
      // We only generate the Zend List Destructor.  Have
920
 
      // Zend manage the reference counting.
 
981
    if (Cmp(nodeType, "destructor") == 0) {
 
982
      // We just generate the Zend List Destructor and let Zend manage the
 
983
      // reference counting.  There's no explicit destructor, but the user can
 
984
      // just do `$obj = null;' to remove a reference to an object.
921
985
      return CreateZendListDestructor(n);
922
 
 
923
 
#if 0
924
 
      //If a script accessible destructor is desired/required, this code needs to be
925
 
      //put back into play.
926
 
      // Then we modify the wrap_action so it nulls out the self variable.
927
 
      String *del = Getattr(n,"wrap:action");
928
 
      Printf(del,"\nRETVAL_NULL();\n");
929
 
      Setattr(n,"wrap:action",del);
930
 
#endif
931
986
    }
932
 
 
933
987
    // Test for overloading;
934
 
    if (Getattr(n,"sym:overloaded")) {
 
988
    if (Getattr(n, "sym:overloaded")) {
935
989
      overloaded = 1;
936
 
      overname = Getattr(n,"sym:overname");
 
990
      overname = Getattr(n, "sym:overname");
937
991
    } else {
938
 
      if (!addSymbol(iname,n))
939
 
        return SWIG_ERROR;
 
992
      if (!addSymbol(iname, n))
 
993
        return SWIG_ERROR;
940
994
    }
941
995
 
942
 
    strcpy(wname,Char(Swig_name_wrapper(iname)));
 
996
    wname = Swig_name_wrapper(iname);
943
997
    if (overname) {
944
 
      strcat(wname,Char(overname));
 
998
      Printf(wname, "%s", overname);
945
999
    }
946
 
 
947
 
    // if shadow and variable wrapper we want to snag the main contents
948
 
    // of this function to stick in to the property handler....    
 
1000
    // if PHP4, shadow and variable wrapper we want to snag the main contents
 
1001
    // of this function to stick in to the property handler...
949
1002
    if (mvr) {
950
1003
      String *php_function_name = NewString(iname);
951
 
      if( Strcmp( iname, Swig_name_set(Swig_name_member(shadow_classname, name)))== 0) {
952
 
        Setattr(shadow_set_vars, php_function_name, name);
 
1004
      if (Strcmp(iname, Swig_name_set(Swig_name_member(shadow_classname, name))) == 0) {
 
1005
        Setattr(shadow_set_vars, php_function_name, name);
953
1006
      }
954
 
      if( Strcmp(iname, Swig_name_get(Swig_name_member(shadow_classname, name))) == 0) {
955
 
        Setattr(shadow_get_vars, php_function_name, name);
 
1007
      if (Strcmp(iname, Swig_name_get(Swig_name_member(shadow_classname, name))) == 0) {
 
1008
        Setattr(shadow_get_vars, php_function_name, name);
956
1009
      }
957
1010
 
958
1011
      Delete(php_function_name);
959
1012
    }
960
1013
 
961
 
    f   = NewWrapper();
 
1014
    f = NewWrapper();
962
1015
    numopt = 0;
963
 
    
964
 
    String *outarg = NewString("");
965
 
    String *cleanup = NewString("");
966
 
    
967
 
    if (mvr) { // do prop[gs]et header
 
1016
 
 
1017
    String *outarg = NewStringEmpty();
 
1018
    String *cleanup = NewStringEmpty();
 
1019
 
 
1020
    if (mvr) {                  // do prop[gs]et header
968
1021
      if (mvrset) {
969
 
        Printf(f->def, "static int _wrap_%s(zend_property_reference *property_reference, pval *value) {\n",iname);
970
 
      }
971
 
      else {
972
 
        Printf(f->def, "static pval _wrap_%s(zend_property_reference *property_reference) {\n",iname);
 
1022
        Printf(f->def, "static int _wrap_%s(zend_property_reference *property_reference, pval *value) {\n", iname);
 
1023
      } else {
 
1024
        Printf(f->def, "static pval _wrap_%s(zend_property_reference *property_reference) {\n", iname);
973
1025
      }
974
1026
    } else {
975
1027
      // regular header
976
 
      // We don't issue these for overloaded functions.
977
 
      // destructors when using shadows.
978
 
      // And for static member variables
979
 
      if (!overloaded &&
980
 
          !(destructor && shadow) &&
981
 
          wrapperType != staticmembervar ) {
982
 
        create_command( iname, wname );
 
1028
      // Not issued for overloaded functions or static member variables.
 
1029
      if (!overloaded && wrapperType != staticmembervar) {
 
1030
        create_command(iname, wname);
983
1031
      }
984
 
      Printv(f->def, "ZEND_NAMED_FUNCTION(" , wname, ") {\n", NIL);
 
1032
      Printv(f->def, "ZEND_NAMED_FUNCTION(", wname, ") {\n", NIL);
985
1033
    }
986
1034
 
987
1035
    emit_args(d, l, f);
988
1036
    /* Attach standard typemaps */
989
1037
 
990
 
    emit_attach_parmmaps(l,f);
 
1038
    emit_attach_parmmaps(l, f);
991
1039
 
992
1040
    // wrap:parms is used by overload resolution.
993
 
    Setattr(n,"wrap:parms",l);
 
1041
    Setattr(n, "wrap:parms", l);
994
1042
 
995
1043
    int num_arguments = emit_num_arguments(l);
996
 
    int num_required  = emit_num_required(l);
 
1044
    int num_required = emit_num_required(l);
997
1045
    numopt = num_arguments - num_required;
998
1046
 
999
 
    int has_this_ptr = (wrapperType==memberfn)?shadow:0;
1000
 
 
1001
 
    sprintf(args, "%s[%d]", "zval **args", num_arguments-has_this_ptr); 
1002
 
 
1003
 
    Wrapper_add_local(f, "args",args);
1004
 
 
1005
 
    // This generated code may be called 
 
1047
    int has_this_ptr = (wrapperType == memberfn && shadow && php_version == 4);
 
1048
 
 
1049
    if (num_arguments - has_this_ptr > 0) {
 
1050
      String *args = NewStringf("zval **args[%d]", num_arguments - has_this_ptr);
 
1051
      Wrapper_add_local(f, "args", args);
 
1052
      Delete(args);
 
1053
      args = NULL;
 
1054
    }
 
1055
    // This generated code may be called:
1006
1056
    // 1) as an object method, or
1007
1057
    // 2) as a class-method/function (without a "this_ptr")
1008
1058
    // Option (1) has "this_ptr" for "this", option (2) needs it as
1016
1066
      Printf(f->code, "/* This function uses a this_ptr*/\n");
1017
1067
 
1018
1068
    if (native_constructor) {
1019
 
      if (native_constructor==NATIVE_CONSTRUCTOR) {
1020
 
        Printf(f->code, "/* NATIVE Constructor */\n");
1021
 
      }
1022
 
      else {
1023
 
        Printf(f->code, "/* ALTERNATIVE Constructor */\n");
 
1069
      if (native_constructor == NATIVE_CONSTRUCTOR) {
 
1070
        Printf(f->code, "/* NATIVE Constructor */\n");
 
1071
      } else {
 
1072
        Printf(f->code, "/* ALTERNATIVE Constructor */\n");
1024
1073
      }
1025
1074
    }
1026
1075
 
1027
 
    if (mvr && ! mvrset) {
 
1076
    if (mvr && !mvrset) {
1028
1077
      Wrapper_add_local(f, "_return_value", "zval _return_value");
1029
1078
      Wrapper_add_local(f, "return_value", "zval *return_value=&_return_value");
1030
 
    };
 
1079
    }
1031
1080
 
1032
 
    if(numopt > 0) { // membervariable wrappers do not have optional args
 
1081
    if (numopt > 0) {           // membervariable wrappers do not have optional args
1033
1082
      Wrapper_add_local(f, "arg_count", "int arg_count");
1034
 
      Printf(f->code,"arg_count = ZEND_NUM_ARGS();\n");
1035
 
      Printf(f->code,"if(arg_count<%d || arg_count>%d)\n",num_required, num_arguments);
1036
 
      Printf(f->code,"\tWRONG_PARAM_COUNT;\n\n");
1037
 
             
1038
 
      
1039
 
      /* Verified args, retrieve them... */
1040
 
      Printf(f->code,"if(zend_get_parameters_array_ex(arg_count,args)!=SUCCESS)\n");
1041
 
      Printf(f->code,"\t\tWRONG_PARAM_COUNT;\n\n");
1042
 
      
 
1083
      Printf(f->code, "arg_count = ZEND_NUM_ARGS();\n");
 
1084
      Printf(f->code, "if(arg_count<%d || arg_count>%d ||\n", num_required, num_arguments);
 
1085
      Printf(f->code, "   zend_get_parameters_array_ex(arg_count,args)!=SUCCESS)\n");
 
1086
      Printf(f->code, "\tWRONG_PARAM_COUNT;\n\n");
1043
1087
    } else if (!mvr) {
1044
 
      Printf(f->code, "if(((ZEND_NUM_ARGS() )!= %d) || (zend_get_parameters_array_ex(%d, args)",
1045
 
             num_arguments-has_this_ptr, num_arguments-has_this_ptr);
1046
 
      Printf(f->code, "!= SUCCESS)) {\n");
1047
 
      Printf(f->code, "WRONG_PARAM_COUNT;\n}\n\n");     
 
1088
      int num = num_arguments - has_this_ptr;
 
1089
      if (num == 0) {
 
1090
        Printf(f->code, "if(ZEND_NUM_ARGS() != 0) {\n");
 
1091
      } else {
 
1092
        Printf(f->code, "if(ZEND_NUM_ARGS() != %d || zend_get_parameters_array_ex(%d, args) != SUCCESS) {\n", num, num);
 
1093
      }
 
1094
      Printf(f->code, "WRONG_PARAM_COUNT;\n}\n\n");
1048
1095
    }
1049
 
    
 
1096
 
1050
1097
    /* Now convert from php to C variables */
1051
 
    // At this point, argcount if used is the number of deliberatly passed args
 
1098
    // At this point, argcount if used is the number of deliberately passed args
1052
1099
    // not including this_ptr even if it is used.
1053
1100
    // It means error messages may be out by argbase with error
1054
 
    // reports.  We can either take argbase into account when raising 
1055
 
    // errors, or find a better way of dealing with _thisptr
 
1101
    // reports.  We can either take argbase into account when raising
 
1102
    // errors, or find a better way of dealing with _thisptr.
1056
1103
    // I would like, if objects are wrapped, to assume _thisptr is always
1057
 
    // _this and the and not the first argument
1058
 
    // This may mean looking at Lang::memberfunctionhandler
 
1104
    // _this and not the first argument.
 
1105
    // This may mean looking at Language::memberfunctionHandler
1059
1106
 
1060
1107
    for (i = 0, p = l; i < num_arguments; i++) {
 
1108
      String *source;
 
1109
 
1061
1110
      /* Skip ignored arguments */
1062
1111
      //while (Getattr(p,"tmap:ignore")) { p = Getattr(p,"tmap:ignore:next");}
1063
 
      while (checkAttribute(p,"tmap:in:numinputs","0")) {
1064
 
        p = Getattr(p,"tmap:in:next");
1065
 
      }
1066
 
 
1067
 
      SwigType *pt = Getattr(p,"type");
1068
 
      
1069
 
      if (mvr) { // do we assert that numargs=2, that i<2
1070
 
        if (i==0) {
1071
 
          sprintf(source,"&(property_reference->object)");
1072
 
        }
1073
 
        else {
1074
 
          sprintf(source,"&value");
1075
 
        }
1076
 
      } else {
1077
 
        if (i==0 && has_this_ptr ) {
1078
 
          sprintf(source,"&this_ptr");
1079
 
        } else {
1080
 
          sprintf(source, "args[%d]", i-has_this_ptr);
1081
 
        }
1082
 
      }
1083
 
      
1084
 
      String *ln = Getattr(p,"lname");
1085
 
      sprintf(argnum, "%d", i+1);
1086
 
      
1087
 
       /* Check if optional */
1088
 
      
1089
 
      if(i>= (num_required)) {
1090
 
        Printf(f->code,"\tif(arg_count > %d) {\n", i);
1091
 
      }
1092
 
      
1093
 
      if ((tm = Getattr(p,"tmap:in"))) {
1094
 
        Replaceall(tm,"$source",source);
1095
 
        Replaceall(tm,"$target",ln);
1096
 
        Replaceall(tm,"$input", source);
1097
 
        Setattr(p,"emit:input", source);
1098
 
        Printf(f->code,"%s\n",tm);
1099
 
        p = Getattr(p,"tmap:in:next");
1100
 
        if (i >= num_required) {
1101
 
          Printf(f->code,"}\n");
1102
 
        }
1103
 
        continue;
1104
 
      } else {
1105
 
        Printf(stderr,"%s : Line %d, Unable to use type %s as a function argument.\n",
1106
 
               input_file, line_number, SwigType_str(pt,0));
1107
 
      }
1108
 
      if (i>= num_required) {
1109
 
        Printf(f->code,"\t}\n");
1110
 
      }
 
1112
      while (checkAttribute(p, "tmap:in:numinputs", "0")) {
 
1113
        p = Getattr(p, "tmap:in:next");
 
1114
      }
 
1115
 
 
1116
      SwigType *pt = Getattr(p, "type");
 
1117
 
 
1118
      if (mvr) {                // do we assert that numargs=2, that i<2
 
1119
        if (i == 0) {
 
1120
          source = NewString("&(property_reference->object)");
 
1121
        } else {
 
1122
          source = NewString("&value");
 
1123
        }
 
1124
      } else {
 
1125
        if (i == 0 && has_this_ptr) {
 
1126
          source = NewString("&this_ptr");
 
1127
        } else {
 
1128
          source = NewStringf("args[%d]", i - has_this_ptr);
 
1129
        }
 
1130
      }
 
1131
 
 
1132
      String *ln = Getattr(p, "lname");
 
1133
 
 
1134
      /* Check if optional */
 
1135
      if (i >= num_required) {
 
1136
        Printf(f->code, "\tif(arg_count > %d) {\n", i);
 
1137
      }
 
1138
 
 
1139
      if ((tm = Getattr(p, "tmap:in"))) {
 
1140
        Replaceall(tm, "$source", source);
 
1141
        Replaceall(tm, "$target", ln);
 
1142
        Replaceall(tm, "$input", source);
 
1143
        Setattr(p, "emit:input", source);
 
1144
        Printf(f->code, "%s\n", tm);
 
1145
        if (i == 0 && HashGetAttr(p, k_self)) {
 
1146
          Printf(f->code, "\tif(!arg1) SWIG_PHP_Error(E_ERROR, \"this pointer is NULL\");\n");
 
1147
        }
 
1148
        p = Getattr(p, "tmap:in:next");
 
1149
        if (i >= num_required) {
 
1150
          Printf(f->code, "}\n");
 
1151
        }
 
1152
        continue;
 
1153
      } else {
 
1154
        Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
 
1155
      }
 
1156
      if (i >= num_required) {
 
1157
        Printf(f->code, "\t}\n");
 
1158
      }
 
1159
      Delete(source);
1111
1160
    }
1112
 
    
 
1161
 
1113
1162
    /* Insert constraint checking code */
1114
1163
    for (p = l; p;) {
1115
 
      if ((tm = Getattr(p,"tmap:check"))) {
1116
 
        Replaceall(tm,"$target",Getattr(p,"lname"));
1117
 
        Printv(f->code,tm,"\n",NIL);
1118
 
        p = Getattr(p,"tmap:check:next");
 
1164
      if ((tm = Getattr(p, "tmap:check"))) {
 
1165
        Replaceall(tm, "$target", Getattr(p, "lname"));
 
1166
        Printv(f->code, tm, "\n", NIL);
 
1167
        p = Getattr(p, "tmap:check:next");
1119
1168
      } else {
1120
 
        p = nextSibling(p);
 
1169
        p = nextSibling(p);
1121
1170
      }
1122
1171
    }
1123
1172
 
1124
1173
    /* Insert cleanup code */
1125
1174
    for (i = 0, p = l; p; i++) {
1126
 
      if ((tm = Getattr(p,"tmap:freearg"))) {
1127
 
        Replaceall(tm,"$source",Getattr(p,"lname"));
1128
 
        Printv(cleanup,tm,"\n",NIL);
1129
 
        p = Getattr(p,"tmap:freearg:next");
 
1175
      if ((tm = Getattr(p, "tmap:freearg"))) {
 
1176
        Replaceall(tm, "$source", Getattr(p, "lname"));
 
1177
        Printv(cleanup, tm, "\n", NIL);
 
1178
        p = Getattr(p, "tmap:freearg:next");
1130
1179
      } else {
1131
 
        p = nextSibling(p);
 
1180
        p = nextSibling(p);
1132
1181
      }
1133
1182
    }
1134
 
    
 
1183
 
1135
1184
    /* Insert argument output code */
1136
 
    for (i=0,p = l; p;i++) {
1137
 
      if ((tm = Getattr(p,"tmap:argout"))) {
1138
 
        Replaceall(tm,"$source",Getattr(p,"lname"));
1139
 
        //      Replaceall(tm,"$input",Getattr(p,"lname"));
1140
 
        Replaceall(tm,"$target","return_value");
1141
 
        Replaceall(tm,"$result","return_value");
1142
 
        Replaceall(tm,"$arg", Getattr(p,"emit:input"));
1143
 
        Replaceall(tm,"$input", Getattr(p,"emit:input"));
1144
 
        Printv(outarg,tm,"\n",NIL);
1145
 
        p = Getattr(p,"tmap:argout:next");
 
1185
    for (i = 0, p = l; p; i++) {
 
1186
      if ((tm = Getattr(p, "tmap:argout"))) {
 
1187
        Replaceall(tm, "$source", Getattr(p, "lname"));
 
1188
        //      Replaceall(tm,"$input",Getattr(p,"lname"));
 
1189
        Replaceall(tm, "$target", "return_value");
 
1190
        Replaceall(tm, "$result", "return_value");
 
1191
        Replaceall(tm, "$arg", Getattr(p, "emit:input"));
 
1192
        Replaceall(tm, "$input", Getattr(p, "emit:input"));
 
1193
        Printv(outarg, tm, "\n", NIL);
 
1194
        p = Getattr(p, "tmap:argout:next");
1146
1195
      } else {
1147
 
        p = nextSibling(p);
 
1196
        p = nextSibling(p);
1148
1197
      }
1149
1198
    }
1150
 
    
1151
 
    /* emit function call*/
1152
 
    emit_action(n,f);
1153
 
    
1154
 
    if((tm = Swig_typemap_lookup_new("out",n,"result",0))) {
 
1199
 
 
1200
    /* emit function call */
 
1201
    emit_action(n, f);
 
1202
 
 
1203
    if ((tm = Swig_typemap_lookup_new("out", n, "result", 0))) {
1155
1204
      Replaceall(tm, "$input", "result");
1156
1205
      Replaceall(tm, "$source", "result");
1157
1206
      Replaceall(tm, "$target", "return_value");
1158
1207
      Replaceall(tm, "$result", "return_value");
1159
 
      Replaceall(tm,"$owner", newobject ? "1" : "0");
 
1208
      Replaceall(tm, "$owner", newobject ? "1" : "0");
1160
1209
      Printf(f->code, "%s\n", tm);
1161
1210
      // are we returning a wrapable object?
1162
 
      // I don't know if this test is comlete, I nicked it
1163
 
      if(is_shadow(d) && (SwigType_type(d) != T_ARRAY)) {
1164
 
        Printf(f->code,"/* Wrap this return value */\n");
1165
 
        if (native_constructor==NATIVE_CONSTRUCTOR) {
1166
 
          Printf(f->code, "if (this_ptr) {\n");
1167
 
          Printf(f->code, "/* NATIVE Constructor, use this_ptr */\n");
1168
 
          Printf(f->code, "zval *_cPtr; MAKE_STD_ZVAL(_cPtr);\n");
1169
 
          Printf(f->code, "*_cPtr = *return_value;\n");
1170
 
          Printf(f->code, "INIT_ZVAL(*return_value);\n");
1171
 
          Printf(f->code, "add_property_zval(this_ptr,\"_cPtr\",_cPtr);\n");
1172
 
          Printf(f->code, "} else if (! this_ptr) ");
1173
 
        }
1174
 
        { // THIS CODE only really needs writing out if the object to be returned
1175
 
          // Is being shadow-wrap-thingied
1176
 
          Printf(f->code, "{\n/* ALTERNATIVE Constructor, make an object wrapper */\n");
1177
 
          // Make object 
1178
 
          String *shadowrettype = NewString("");
1179
 
          SwigToPhpType(d, iname, shadowrettype, shadow);
1180
 
          
1181
 
          Printf(f->code,"zval *obj, *_cPtr;\n");
1182
 
          Printf(f->code,"MAKE_STD_ZVAL(obj);\n");
1183
 
          Printf(f->code,"MAKE_STD_ZVAL(_cPtr);\n");
1184
 
          Printf(f->code,"*_cPtr = *return_value;\n");
1185
 
          Printf(f->code,"INIT_ZVAL(*return_value);\n");
1186
 
          
1187
 
          if (! shadow) {
1188
 
            Printf(f->code,"*return_value=*_cPtr;\n");
1189
 
          } else {
1190
 
            Printf(f->code,"object_init_ex(obj,ptr_ce_swig_%s);\n",shadowrettype);
1191
 
            Printf(f->code,"add_property_zval(obj,\"_cPtr\",_cPtr);\n");
1192
 
            Printf(f->code,"*return_value=*obj;\n");
1193
 
                   
1194
 
          }
1195
 
          Printf(f->code, "}\n");
1196
 
        }
1197
 
      } // end of if-shadow lark
 
1211
      // I don't know if this test is complete, I nicked it
 
1212
      if (is_shadow(d) && (SwigType_type(d) != T_ARRAY)) {
 
1213
        Printf(f->code, "/* Wrap this return value */\n");
 
1214
        if (native_constructor == NATIVE_CONSTRUCTOR) {
 
1215
          Printf(f->code, "if (this_ptr) {\n");
 
1216
          Printf(f->code, "/* NATIVE Constructor, use this_ptr */\n");
 
1217
          Printf(f->code, "zval *_cPtr; MAKE_STD_ZVAL(_cPtr);\n");
 
1218
          Printf(f->code, "*_cPtr = *return_value;\n");
 
1219
          Printf(f->code, "INIT_ZVAL(*return_value);\n");
 
1220
          Printf(f->code, "add_property_zval(this_ptr,\"" SWIG_PTR "\",_cPtr);\n");
 
1221
          Printf(f->code, "} else if (! this_ptr) ");
 
1222
        }
 
1223
        {                       // THIS CODE only really needs writing out if the object to be returned
 
1224
          // Is being shadow-wrap-thingied
 
1225
          Printf(f->code, "{\n/* ALTERNATIVE Constructor, make an object wrapper */\n");
 
1226
          // Make object
 
1227
          String *shadowrettype = NewStringEmpty();
 
1228
          SwigToPhpType(d, iname, shadowrettype, (shadow && php_version == 4));
 
1229
 
 
1230
          Printf(f->code, "zval *obj, *_cPtr;\n");
 
1231
          Printf(f->code, "MAKE_STD_ZVAL(obj);\n");
 
1232
          Printf(f->code, "MAKE_STD_ZVAL(_cPtr);\n");
 
1233
          Printf(f->code, "*_cPtr = *return_value;\n");
 
1234
          Printf(f->code, "INIT_ZVAL(*return_value);\n");
 
1235
 
 
1236
          if (shadow && php_version == 4) {
 
1237
            Printf(f->code, "object_init_ex(obj,ptr_ce_swig_%s);\n", shadowrettype);
 
1238
            Printf(f->code, "add_property_zval(obj,\"" SWIG_PTR "\",_cPtr);\n");
 
1239
            Printf(f->code, "*return_value=*obj;\n");
 
1240
          } else {
 
1241
            Printf(f->code, "*return_value=*_cPtr;\n");
 
1242
          }
 
1243
          Printf(f->code, "}\n");
 
1244
        }
 
1245
      }                         // end of if-shadow lark
1198
1246
    } else {
1199
 
      Printf(stderr,"%s: Line %d, Unable to use return type %s in function %s.\n",
1200
 
             input_file, line_number, SwigType_str(d,0), name);
1201
 
    }
1202
 
    
1203
 
    if(outarg) {
1204
 
      Printv(f->code,outarg,NIL);
1205
 
    }
1206
 
    
1207
 
    if(cleanup) {
1208
 
      Printv(f->code,cleanup,NIL);
1209
 
    }
1210
 
    
1211
 
    // Whats this bit for?
1212
 
    if((tm = Swig_typemap_lookup_new("ret",n,"result",0))) {
1213
 
      Printf(f->code,"%s\n", tm);
 
1247
      Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), name);
 
1248
    }
 
1249
 
 
1250
    if (outarg) {
 
1251
      Printv(f->code, outarg, NIL);
 
1252
    }
 
1253
 
 
1254
    if (cleanup) {
 
1255
      Printv(f->code, cleanup, NIL);
 
1256
    }
 
1257
    // What's this bit for?
 
1258
    if ((tm = Swig_typemap_lookup_new("ret", n, "result", 0))) {
 
1259
      Printf(f->code, "%s\n", tm);
1214
1260
    }
1215
1261
 
1216
1262
    if (mvr) {
1217
 
      if (! mvrset) {
1218
 
        Printf(f->code,"return _return_value;\n");    
1219
 
      }
1220
 
      else{
1221
 
        Printf(f->code,"return SUCCESS;\n");
1222
 
      }
1223
 
    }
1224
 
    else {
1225
 
      Printf(f->code,"return;\n");
 
1263
      if (!mvrset) {
 
1264
        Printf(f->code, "return _return_value;\n");
 
1265
      } else {
 
1266
        Printf(f->code, "return SUCCESS;\n");
 
1267
      }
 
1268
    } else {
 
1269
      Printf(f->code, "return;\n");
1226
1270
    }
1227
1271
 
1228
1272
    /* Error handling code */
1229
 
    Printf(f->code,"fail:\n");
1230
 
    Printv(f->code,cleanup,NIL);
1231
 
    Printv(f->code,"zend_error(ErrorCode(),ErrorMsg());",NIL);
1232
 
 
1233
 
    Printf(f->code, "}\n");    
1234
 
 
1235
 
    // These were cribbed from python.cxx
1236
 
    Replaceall(f->code,"$cleanup",cleanup);
1237
 
    Replaceall(f->code,"$symname",iname);
1238
 
 
1239
 
    Wrapper_print(f,s_wrappers);
 
1273
    Printf(f->code, "fail:\n");
 
1274
    Printv(f->code, cleanup, NIL);
 
1275
    Printv(f->code, "zend_error(SWIG_ErrorCode(),SWIG_ErrorMsg());", NIL);
 
1276
 
 
1277
    Printf(f->code, "}\n");
 
1278
 
 
1279
    Replaceall(f->code, "$cleanup", cleanup);
 
1280
    Replaceall(f->code, "$symname", iname);
 
1281
 
 
1282
    Wrapper_print(f, s_wrappers);
1240
1283
 
1241
1284
    // wrap:name is used by overload resolution
1242
 
    Setattr(n,"wrap:name",wname);
1243
 
    if (overloaded && !Getattr(n,"sym:nextSibling")) {
 
1285
    Setattr(n, "wrap:name", wname);
 
1286
    if (overloaded && !Getattr(n, "sym:nextSibling")) {
1244
1287
      dispatchFunction(n);
1245
1288
    }
1246
1289
 
 
1290
    Delete(wname);
 
1291
    wname = NULL;
 
1292
 
 
1293
    if (!(shadow && php_version == 5))
 
1294
      return SWIG_OK;
 
1295
 
 
1296
    // Handle getters and setters.
 
1297
    if (wrapperType == membervar) {
 
1298
      const char *p = Char(iname);
 
1299
      if (strlen(p) > 4) {
 
1300
        p += strlen(p) - 4;
 
1301
        String *varname = Getattr(n, "membervariableHandler:sym:name");
 
1302
        if (strcmp(p, "_get") == 0) {
 
1303
          Setattr(shadow_get_vars, varname, iname);
 
1304
        } else if (strcmp(p, "_set") == 0) {
 
1305
          Setattr(shadow_set_vars, varname, iname);
 
1306
        }
 
1307
      }
 
1308
    }
 
1309
    // Only look at non-overloaded methods and the last entry in each overload
 
1310
    // chain (we check the last so that wrap:parms and wrap:name have been set
 
1311
    // for them all).
 
1312
    if (overloaded && Getattr(n, "sym:nextSibling") != 0)
 
1313
      return SWIG_OK;
 
1314
 
 
1315
    if (!s_oowrappers)
 
1316
      s_oowrappers = NewStringEmpty();
 
1317
    if (newobject || wrapperType == memberfn || wrapperType == staticmemberfn || wrapperType == standard) {
 
1318
      bool handle_as_overload = false;
 
1319
      String **arg_names;
 
1320
      String **arg_values;
 
1321
      bool *arg_case = NULL;
 
1322
      // Method or static method or plain function.
 
1323
      const char *methodname = 0;
 
1324
      String *output = s_oowrappers;
 
1325
      if (newobject) {
 
1326
        class_has_ctor = true;
 
1327
        methodname = "__construct";
 
1328
      } else if (wrapperType == memberfn) {
 
1329
        methodname = Char(Getattr(n, "memberfunctionHandler:sym:name"));
 
1330
      } else if (wrapperType == staticmemberfn) {
 
1331
        methodname = Char(Getattr(n, "staticmemberfunctionHandler:sym:name"));
 
1332
      } else {                  // wrapperType == standard
 
1333
        methodname = Char(iname);
 
1334
        if (!s_fakeoowrappers)
 
1335
          s_fakeoowrappers = NewStringEmpty();
 
1336
        output = s_fakeoowrappers;
 
1337
      }
 
1338
 
 
1339
      bool really_overloaded = overloaded ? true : false;
 
1340
      int min_num_of_arguments = emit_num_required(l);
 
1341
      int max_num_of_arguments = emit_num_arguments(l);
 
1342
      // For a function with default arguments, we end up with the fullest
 
1343
      // parmlist in full_parmlist.
 
1344
      ParmList *full_parmlist = l;
 
1345
      Hash *ret_types = NewHash();
 
1346
      Setattr(ret_types, d, d);
 
1347
 
 
1348
      if (overloaded) {
 
1349
        // Look at all the overloaded versions of this method in turn to
 
1350
        // decide if it's really an overloaded method, or just one where some
 
1351
        // parameters have default values.
 
1352
        Node *o = Getattr(n, "sym:overloaded");
 
1353
        while (o) {
 
1354
          if (o == n) {
 
1355
            o = Getattr(o, "sym:nextSibling");
 
1356
            continue;
 
1357
          }
 
1358
 
 
1359
          SwigType *d2 = Getattr(o, "type");
 
1360
          if (!d2) {
 
1361
            assert(constructor);
 
1362
          } else if (!Getattr(ret_types, d2)) {
 
1363
            Setattr(ret_types, d2, d2);
 
1364
          }
 
1365
 
 
1366
          ParmList *l2 = Getattr(o, "wrap:parms");
 
1367
          int num_arguments = emit_num_arguments(l2);
 
1368
          int num_required = emit_num_required(l2);
 
1369
          if (num_required < min_num_of_arguments)
 
1370
            min_num_of_arguments = num_required;
 
1371
 
 
1372
          if (num_arguments > max_num_of_arguments) {
 
1373
            max_num_of_arguments = num_arguments;
 
1374
            full_parmlist = l2;
 
1375
          }
 
1376
          o = Getattr(o, "sym:nextSibling");
 
1377
        }
 
1378
 
 
1379
        o = Getattr(n, "sym:overloaded");
 
1380
        while (o) {
 
1381
          if (o == n) {
 
1382
            o = Getattr(o, "sym:nextSibling");
 
1383
            continue;
 
1384
          }
 
1385
 
 
1386
          ParmList *l2 = Getattr(o, "wrap:parms");
 
1387
          Parm *p = l, *p2 = l2;
 
1388
          if (wrapperType == memberfn) {
 
1389
            p = nextSibling(p);
 
1390
            p2 = nextSibling(p2);
 
1391
          }
 
1392
          while (p && p2) {
 
1393
            if (Cmp(Getattr(p, "type"), Getattr(p2, "type")) != 0)
 
1394
              break;
 
1395
            if (Cmp(Getattr(p, "name"), Getattr(p2, "name")) != 0)
 
1396
              break;
 
1397
            String *value = Getattr(p, "value");
 
1398
            String *value2 = Getattr(p2, "value");
 
1399
            if (value && !value2)
 
1400
              break;
 
1401
            if (!value && value2)
 
1402
              break;
 
1403
            if (value) {
 
1404
              if (Cmp(value, value2) != 0)
 
1405
                break;
 
1406
            }
 
1407
            p = nextSibling(p);
 
1408
            p2 = nextSibling(p2);
 
1409
          }
 
1410
          if (p && p2)
 
1411
            break;
 
1412
          // One parameter list is a prefix of the other, so check that all
 
1413
          // remaining parameters of the longer list are optional.
 
1414
          if (p2)
 
1415
            p = p2;
 
1416
          while (p && Getattr(p, "value"))
 
1417
            p = nextSibling(p);
 
1418
          if (p)
 
1419
            break;
 
1420
          o = Getattr(o, "sym:nextSibling");
 
1421
        }
 
1422
        if (!o) {
 
1423
          // This "overloaded method" is really just one with default args.
 
1424
          really_overloaded = false;
 
1425
          if (l != full_parmlist) {
 
1426
            l = full_parmlist;
 
1427
            if (wrapperType == memberfn)
 
1428
              l = nextSibling(l);
 
1429
          }
 
1430
        }
 
1431
 
 
1432
        arg_case = (bool *) malloc(max_num_of_arguments * sizeof(bool));
 
1433
        if (!arg_case) {
 
1434
          /* FIXME: How should this be handled?  The rest of SWIG just seems
 
1435
           * to not bother checking for malloc failing! */
 
1436
          fprintf(stderr, "Malloc failed!\n");
 
1437
          exit(1);
 
1438
        }
 
1439
        for (int i = 0; i < max_num_of_arguments; ++i) {
 
1440
          arg_case[i] = false;
 
1441
        }
 
1442
 
 
1443
        o = Getattr(n, "sym:overloaded");
 
1444
        while (o) {
 
1445
          ParmList *l2 = Getattr(o, "wrap:parms");
 
1446
          int num_arguments = emit_num_arguments(l2);
 
1447
          int num_required = emit_num_required(l2);
 
1448
          if (wrapperType == memberfn) {
 
1449
            --num_arguments;
 
1450
            --num_required;
 
1451
          }
 
1452
          for (int i = num_required; i <= num_arguments; ++i) {
 
1453
            arg_case[i] = true;
 
1454
          }
 
1455
          o = Getattr(o, "sym:nextSibling");
 
1456
        }
 
1457
      }
 
1458
 
 
1459
      if (wrapperType == memberfn) {
 
1460
        // Allow for the "this" pointer.
 
1461
        --min_num_of_arguments;
 
1462
        --max_num_of_arguments;
 
1463
      }
 
1464
 
 
1465
      arg_names = (String **) malloc(max_num_of_arguments * sizeof(String *));
 
1466
      if (!arg_names) {
 
1467
        /* FIXME: How should this be handled?  The rest of SWIG just seems
 
1468
         * to not bother checking for malloc failing! */
 
1469
        fprintf(stderr, "Malloc failed!\n");
 
1470
        exit(1);
 
1471
      }
 
1472
      for (int i = 0; i < max_num_of_arguments; ++i) {
 
1473
        arg_names[i] = NULL;
 
1474
      }
 
1475
 
 
1476
      arg_values = (String **) malloc(max_num_of_arguments * sizeof(String *));
 
1477
      if (!arg_values) {
 
1478
        /* FIXME: How should this be handled?  The rest of SWIG just seems
 
1479
         * to not bother checking for malloc failing! */
 
1480
        fprintf(stderr, "Malloc failed!\n");
 
1481
        exit(1);
 
1482
      }
 
1483
      for (int i = 0; i < max_num_of_arguments; ++i) {
 
1484
        arg_values[i] = NULL;
 
1485
      }
 
1486
 
 
1487
      Node *o;
 
1488
      if (overloaded) {
 
1489
        o = Getattr(n, "sym:overloaded");
 
1490
      } else {
 
1491
        o = n;
 
1492
      }
 
1493
      while (o) {
 
1494
        int argno = 0;
 
1495
        Parm *p = Getattr(o, "wrap:parms");
 
1496
        if (wrapperType == memberfn)
 
1497
          p = nextSibling(p);
 
1498
        while (p) {
 
1499
          assert(0 <= argno && argno < max_num_of_arguments);
 
1500
          String *&pname = arg_names[argno];
 
1501
          const char *pname_cstr = GetChar(p, "name");
 
1502
          if (!pname_cstr) {
 
1503
            // Unnamed parameter, e.g. int foo(int);
 
1504
          } else if (pname == NULL) {
 
1505
            pname = NewString(pname_cstr);
 
1506
          } else {
 
1507
            size_t len = strlen(pname_cstr);
 
1508
            size_t spc = 0;
 
1509
            size_t len_pname = strlen(Char(pname));
 
1510
            while (spc + len <= len_pname) {
 
1511
              if (strncmp(pname_cstr, Char(pname) + spc, len) == 0) {
 
1512
                char ch = ((char *) Char(pname))[spc + len];
 
1513
                if (ch == '\0' || ch == ' ') {
 
1514
                  // Already have this pname_cstr.
 
1515
                  pname_cstr = NULL;
 
1516
                  break;
 
1517
                }
 
1518
              }
 
1519
              char *p = strchr(Char(pname) + spc, ' ');
 
1520
              if (!p)
 
1521
                break;
 
1522
              spc = (p + 4) - Char(pname);
 
1523
            }
 
1524
            if (pname_cstr) {
 
1525
              Printf(pname, " or_%s", pname_cstr);
 
1526
            }
 
1527
          }
 
1528
          const char *value = GetChar(p, "value");
 
1529
          if (value) {
 
1530
            /* Check that value is a valid constant in PHP (and adjust it if
 
1531
             * necessary, or replace it with "?" if it's just not valid). */
 
1532
            SwigType *type = Getattr(p, "type");
 
1533
            switch (SwigType_type(type)) {
 
1534
            case T_BOOL:{
 
1535
                if (strcmp(value, "true") == 0 || strcmp(value, "false") == 0)
 
1536
                  break;
 
1537
                char *p;
 
1538
                errno = 0;
 
1539
                int n = strtol(Char(value), &p, 0);
 
1540
                if (errno || *p)
 
1541
                  value = "?";
 
1542
                else if (n)
 
1543
                  value = "true";
 
1544
                else
 
1545
                  value = "false";
 
1546
                break;
 
1547
              }
 
1548
            case T_CHAR:
 
1549
            case T_SCHAR:
 
1550
            case T_SHORT:
 
1551
            case T_INT:
 
1552
            case T_LONG:{
 
1553
                char *p;
 
1554
                errno = 0;
 
1555
                (void) strtol(Char(value), &p, 0);
 
1556
                if (errno || *p)
 
1557
                  value = "?";
 
1558
                break;
 
1559
              }
 
1560
            case T_UCHAR:
 
1561
            case T_USHORT:
 
1562
            case T_UINT:
 
1563
            case T_ULONG:{
 
1564
                char *p;
 
1565
                errno = 0;
 
1566
                (void) strtoul(Char(value), &p, 0);
 
1567
                if (errno || *p)
 
1568
                  value = "?";
 
1569
                break;
 
1570
              }
 
1571
            case T_FLOAT:
 
1572
            case T_DOUBLE:{
 
1573
                char *p;
 
1574
                errno = 0;
 
1575
                /* FIXME: strtod is locale dependent... */
 
1576
                (void) strtod(Char(value), &p);
 
1577
                if (errno || *p)
 
1578
                  value = "?";
 
1579
                break;
 
1580
              }
 
1581
            case T_REFERENCE:
 
1582
            case T_USER:
 
1583
            case T_ARRAY:
 
1584
              value = "?";
 
1585
              break;
 
1586
            case T_STRING:
 
1587
              if (Len(value) < 2) {
 
1588
                // How can a string (including "" be less than 2 characters?)
 
1589
                value = "?";
 
1590
              } else {
 
1591
                const char *v = Char(value);
 
1592
                if (v[0] != '"' || v[Len(value) - 1] != '"')
 
1593
                  value = "?";
 
1594
                // Strings containing "$" require special handling, but we do that later.
 
1595
              }
 
1596
              break;
 
1597
            case T_VOID:
 
1598
              assert(false);
 
1599
              break;
 
1600
            case T_POINTER:{
 
1601
                const char *v = value;
 
1602
                if (v[0] == '(') {
 
1603
                  // Handle "(void*)0", "(TYPE*)0", "(char*)NULL", etc.
 
1604
                  v += strcspn(v + 1, "*()") + 1;
 
1605
                  if (*v == '*') {
 
1606
                    do {
 
1607
                      v++;
 
1608
                      v += strspn(v, " \t");
 
1609
                    } while (*v == '*');
 
1610
                    if (*v++ == ')') {
 
1611
                      v += strspn(v, " \t");
 
1612
                      value = v;
 
1613
                    }
 
1614
                  }
 
1615
                }
 
1616
                if (strcmp(value, "NULL") == 0 || strcmp(value, "0") == 0 || strcmp(value, "0L") == 0) {
 
1617
                  value = "null";
 
1618
                } else {
 
1619
                  value = "?";
 
1620
                }
 
1621
                break;
 
1622
              }
 
1623
            }
 
1624
 
 
1625
            if (!arg_values[argno]) {
 
1626
              arg_values[argno] = NewString(value);
 
1627
            } else if (Cmp(arg_values[argno], value) != 0) {
 
1628
              // If a parameter has two different default values in
 
1629
              // different overloaded forms of the function, we can't
 
1630
              // set its default in PHP.  Flag this by setting its
 
1631
              // default to `?'.
 
1632
              Delete(arg_values[argno]);
 
1633
              arg_values[argno] = NewString("?");
 
1634
            }
 
1635
          }
 
1636
          p = nextSibling(p);
 
1637
          ++argno;
 
1638
        }
 
1639
        if (!really_overloaded)
 
1640
          break;
 
1641
        o = Getattr(o, "sym:nextSibling");
 
1642
      }
 
1643
 
 
1644
      /* Clean up any parameters which haven't yet got names, or whose
 
1645
       * names clash. */
 
1646
      Hash *seen = NewHash();
 
1647
      /* We need $this to refer to the current class, so can't allow it
 
1648
       * to be used as a parameter. */
 
1649
      Setattr(seen, "this", seen);
 
1650
      /* We use $r to store the return value, so disallow that as a parameter
 
1651
       * name in case the user uses the "call-time pass-by-reference" feature
 
1652
       * (it's deprecated and off by default in PHP5 and even later PHP4
 
1653
       * versions apparently, but we want to be maximally portable).
 
1654
       */
 
1655
      Setattr(seen, "r", seen);
 
1656
 
 
1657
      for (int argno = 0; argno < max_num_of_arguments; ++argno) {
 
1658
        String *&pname = arg_names[argno];
 
1659
        if (pname) {
 
1660
          Replaceall(pname, " ", "_");
 
1661
        } else {
 
1662
          /* We get here if the SWIG .i file has "int foo(int);" */
 
1663
          pname = NewStringEmpty();
 
1664
          Printf(pname, "arg%d", argno + 1);
 
1665
        }
 
1666
        // Check if we've already used this parameter name.
 
1667
        while (Getattr(seen, pname)) {
 
1668
          // Append "_" to clashing names until they stop clashing...
 
1669
          Printf(pname, "_");
 
1670
        }
 
1671
        Setattr(seen, Char(pname), seen);
 
1672
 
 
1673
        if (arg_values[argno] && Cmp(arg_values[argno], "?") == 0) {
 
1674
          handle_as_overload = true;
 
1675
        }
 
1676
      }
 
1677
      Delete(seen);
 
1678
      seen = NULL;
 
1679
 
 
1680
      String *invoke = NewStringEmpty();
 
1681
      String *prepare = NewStringEmpty();
 
1682
      String *args = NewStringEmpty();
 
1683
 
 
1684
      if (!handle_as_overload && !(really_overloaded && max_num_of_arguments > min_num_of_arguments)) {
 
1685
        Printf(invoke, "%s(", iname);
 
1686
        if (wrapperType == memberfn) {
 
1687
          Printf(invoke, "$this->%s", SWIG_PTR);
 
1688
        }
 
1689
        for (int i = 0; i < max_num_of_arguments; ++i) {
 
1690
          if (i)
 
1691
            Printf(args, ",");
 
1692
          if (i || wrapperType == memberfn)
 
1693
            Printf(invoke, ",");
 
1694
          String *value = arg_values[i];
 
1695
          if (value) {
 
1696
            const char *v = Char(value);
 
1697
            if (v[0] == '"') {
 
1698
              /* In a PHP double quoted string, $ needs to be escaped as \$. */
 
1699
              Replaceall(value, "$", "\\$");
 
1700
            }
 
1701
            Printf(args, "$%s=%s", arg_names[i], value);
 
1702
          } else {
 
1703
            Printf(args, "$%s", arg_names[i]);
 
1704
          }
 
1705
          Printf(invoke, "$%s", arg_names[i]);
 
1706
        }
 
1707
        Printf(invoke, ")");
 
1708
      } else {
 
1709
        int i;
 
1710
        for (i = 0; i < min_num_of_arguments; ++i) {
 
1711
          if (i)
 
1712
            Printf(args, ",");
 
1713
          Printf(args, "$%s", arg_names[i]);
 
1714
        }
 
1715
        String *invoke_args = NewStringEmpty();
 
1716
        if (wrapperType == memberfn) {
 
1717
          Printf(invoke_args, "$this->%s", SWIG_PTR);
 
1718
          if (min_num_of_arguments > 0)
 
1719
            Printf(invoke_args, ",");
 
1720
        }
 
1721
        Printf(invoke_args, "%s", args);
 
1722
        bool had_a_case = false;
 
1723
        int last_handled_i = i - 1;
 
1724
        for (; i < max_num_of_arguments; ++i) {
 
1725
          if (i)
 
1726
            Printf(args, ",");
 
1727
          const char *value = Char(arg_values[i]);
 
1728
          bool non_php_default = (!value || strcmp(value, "?") == 0);
 
1729
          if (non_php_default)
 
1730
            value = "null";
 
1731
          Printf(args, "$%s=%s", arg_names[i], value);
 
1732
          if (non_php_default) {
 
1733
            if (!had_a_case) {
 
1734
              Printf(prepare, "\t\tswitch (func_num_args()) {\n");
 
1735
              had_a_case = true;
 
1736
            }
 
1737
            Printf(prepare, "\t\t");
 
1738
            while (last_handled_i < i) {
 
1739
              Printf(prepare, "case %d: ", ++last_handled_i);
 
1740
            }
 
1741
            if (Cmp(d, "void") != 0)
 
1742
              Printf(prepare, "$r=");
 
1743
            Printf(prepare, "%s(%s); break;\n", iname, invoke_args);
 
1744
          }
 
1745
          if (i || wrapperType == memberfn)
 
1746
            Printf(invoke_args, ",");
 
1747
          Printf(invoke_args, "$%s", arg_names[i]);
 
1748
        }
 
1749
        Printf(prepare, "\t\t");
 
1750
        if (had_a_case)
 
1751
          Printf(prepare, "default: ");
 
1752
        if (Cmp(d, "void") != 0)
 
1753
          Printf(prepare, "$r=");
 
1754
        Printf(prepare, "%s(%s);\n", iname, invoke_args);
 
1755
        if (had_a_case)
 
1756
          Printf(prepare, "\t\t}\n");
 
1757
        Delete(invoke_args);
 
1758
        Printf(invoke, "$r");
 
1759
      }
 
1760
 
 
1761
      Printf(output, "\n");
 
1762
      if (wrapperType == memberfn || newobject) {
 
1763
        Printf(output, "\tfunction %s(%s) {\n", methodname, args);
 
1764
        // We don't need this code if the wrapped class has a copy ctor
 
1765
        // since the flat function new_CLASSNAME will handle it for us.
 
1766
        if (newobject && !Getattr(current_class, "allocate:copy_constructor")) {
 
1767
          SwigType *t = Getattr(current_class, "classtype");
 
1768
          String *mangled_type = SwigType_manglestr(SwigType_ltype(t));
 
1769
          Printf(s_oowrappers, "\t\tif (is_resource($%s) && get_resource_type($%s) == \"_p%s\") {\n", arg_names[0], arg_names[0], mangled_type);
 
1770
          Printf(s_oowrappers, "\t\t\t$this->%s=$%s;\n", SWIG_PTR, arg_names[0]);
 
1771
          Printf(s_oowrappers, "\t\t\treturn;\n");
 
1772
          Printf(s_oowrappers, "\t\t}\n");
 
1773
        }
 
1774
      } else {
 
1775
        Printf(output, "\tstatic function %s(%s) {\n", methodname, args);
 
1776
      }
 
1777
      Delete(args);
 
1778
      args = NULL;
 
1779
 
 
1780
      for (int i = 0; i < max_num_of_arguments; ++i) {
 
1781
        Delete(arg_names[i]);
 
1782
      }
 
1783
      free(arg_names);
 
1784
      arg_names = NULL;
 
1785
 
 
1786
      Printf(output, "%s", prepare);
 
1787
      if (newobject) {
 
1788
        Printf(output, "\t\t$this->%s=%s;\n", SWIG_PTR, invoke);
 
1789
      } else if (Cmp(d, "void") == 0) {
 
1790
        if (Cmp(invoke, "$r") != 0)
 
1791
          Printf(output, "\t\t%s;\n", invoke);
 
1792
      } else if (is_class(d)) {
 
1793
        if (Cmp(invoke, "$r") != 0)
 
1794
          Printf(output, "\t\t$r=%s;\n", invoke);
 
1795
        if (Len(ret_types) == 1) {
 
1796
          Printf(output, "\t\treturn is_resource($r) ? new %s%s($r) : $r;\n", prefix, Getattr(classLookup(d), "sym:name"));
 
1797
        } else {
 
1798
          Printf(output, "\t\tif (!is_resource($r)) return $r;\n");
 
1799
          Printf(output, "\t\tswitch (get_resource_type($r)) {\n");
 
1800
          Iterator i = First(ret_types);
 
1801
          while (i.item) {
 
1802
            SwigType *ret_type = i.item;
 
1803
            i = Next(i);
 
1804
            Printf(output, "\t\t");
 
1805
            String *mangled = NewString("_p");
 
1806
            Printf(mangled, "%s", SwigType_manglestr(ret_type));
 
1807
            Node *class_node = Getattr(zend_types, mangled);
 
1808
            if (i.item) {
 
1809
              Printf(output, "case \"%s\": ", mangled);
 
1810
            } else {
 
1811
              Printf(output, "default: ", mangled);
 
1812
            }
 
1813
            const char *classname = GetChar(class_node, "sym:name");
 
1814
            if (!classname)
 
1815
              classname = GetChar(class_node, "name");
 
1816
            Printf(output, "return new %s%s($r);\n", prefix, classname);
 
1817
            Delete(mangled);
 
1818
          }
 
1819
          Printf(output, "\t\t}\n");
 
1820
        }
 
1821
      } else {
 
1822
        Printf(output, "\t\treturn %s;\n", invoke);
 
1823
      }
 
1824
      Printf(output, "\t}\n");
 
1825
      Delete(prepare);
 
1826
      Delete(invoke);
 
1827
    }
 
1828
 
1247
1829
    return SWIG_OK;
1248
1830
  }
1249
 
  
 
1831
 
1250
1832
  /* ------------------------------------------------------------
1251
1833
   * globalvariableHandler()
1252
1834
   * ------------------------------------------------------------ */
1253
1835
 
1254
1836
  virtual int globalvariableHandler(Node *n) {
1255
 
    char *name = GetChar(n,"name");
1256
 
    char *iname = GetChar(n,"sym:name");
1257
 
    SwigType *t = Getattr(n,"type");
 
1837
    char *name = GetChar(n, "name");
 
1838
    char *iname = GetChar(n, "sym:name");
 
1839
    SwigType *t = Getattr(n, "type");
1258
1840
    String *tm;
1259
1841
 
1260
1842
    /* First do the wrappers such as name_set(), name_get()
1261
1843
     * as provided by the baseclass's implementation of variableWrapper
1262
1844
     */
1263
 
    if (Language::globalvariableHandler(n) == SWIG_NOWRAP ) {
 
1845
    if (Language::globalvariableHandler(n) == SWIG_NOWRAP) {
1264
1846
      return SWIG_NOWRAP;
1265
1847
    }
1266
1848
 
1267
 
    if (!addSymbol(iname,n))
 
1849
    if (!addSymbol(iname, n))
1268
1850
      return SWIG_ERROR;
1269
1851
 
1270
1852
    SwigType_remember(t);
1272
1854
    /* First link C variables to PHP */
1273
1855
 
1274
1856
    tm = Swig_typemap_lookup_new("varinit", n, name, 0);
1275
 
    if(tm) {
 
1857
    if (tm) {
1276
1858
      Replaceall(tm, "$target", name);
1277
1859
      Printf(s_vinit, "%s\n", tm);
1278
1860
    } else {
1279
 
      Printf(stderr,"%s: Line %d, Unable to link with type %s\n", 
1280
 
             input_file, line_number, SwigType_str(t,0), name);
 
1861
      Printf(stderr, "%s: Line %d, Unable to link with type %s\n", input_file, line_number, SwigType_str(t, 0), name);
1281
1862
    }
1282
1863
 
1283
1864
    /* Now generate PHP -> C sync blocks */
1284
1865
    /*
1285
 
    tm = Swig_typemap_lookup_new("varin", n, name, 0);
1286
 
      if(tm) {
1287
 
      Replaceall(tm, "$symname", iname);
1288
 
      Printf(f_c->code, "%s\n", tm);
1289
 
      } else {
1290
 
      Printf(stderr,"%s: Line %d, Unable to link with type %s\n", 
1291
 
      input_file, line_number, SwigType_str(t, 0), name);
1292
 
      }
1293
 
    */
 
1866
       tm = Swig_typemap_lookup_new("varin", n, name, 0);
 
1867
       if(tm) {
 
1868
       Replaceall(tm, "$symname", iname);
 
1869
       Printf(f_c->code, "%s\n", tm);
 
1870
       } else {
 
1871
       Printf(stderr,"%s: Line %d, Unable to link with type %s\n", 
 
1872
       input_file, line_number, SwigType_str(t, 0), name);
 
1873
       }
 
1874
     */
1294
1875
    /* Now generate C -> PHP sync blocks */
1295
1876
    /*
1296
 
      if(!GetFlag(n,"feature:immutable")) {
1297
 
      
1298
 
      tm = Swig_typemap_lookup_new("varout", n, name, 0);
1299
 
      if(tm) {
1300
 
      Replaceall(tm, "$symname", iname);
1301
 
      Printf(f_php->code, "%s\n", tm);
1302
 
      } else {
1303
 
      Printf(stderr,"%s: Line %d, Unable to link with type %s\n", 
1304
 
      input_file, line_number, SwigType_str(t, 0), name);
1305
 
      }
1306
 
      }
1307
 
    */
 
1877
       if(!GetFlag(n,"feature:immutable")) {
 
1878
 
 
1879
       tm = Swig_typemap_lookup_new("varout", n, name, 0);
 
1880
       if(tm) {
 
1881
       Replaceall(tm, "$symname", iname);
 
1882
       Printf(f_php->code, "%s\n", tm);
 
1883
       } else {
 
1884
       Printf(stderr,"%s: Line %d, Unable to link with type %s\n", 
 
1885
       input_file, line_number, SwigType_str(t, 0), name);
 
1886
       }
 
1887
       }
 
1888
     */
1308
1889
    return SWIG_OK;
1309
1890
  }
1310
1891
 
1311
1892
  /* ------------------------------------------------------------
1312
1893
   * constantWrapper()
1313
1894
   * ------------------------------------------------------------ */
1314
 
  
 
1895
 
1315
1896
  virtual int constantWrapper(Node *n) {
1316
 
    String *name = GetChar(n,"name");
1317
 
    String *iname = GetChar(n,"sym:name");
1318
 
    SwigType *type = Getattr(n,"type");
1319
 
    String   *rawval = Getattr(n,"rawval");
1320
 
    String   *value = rawval ? rawval : Getattr(n,"value");
1321
 
    String  *tm;
 
1897
    String *name = GetChar(n, "name");
 
1898
    String *iname = GetChar(n, "sym:name");
 
1899
    SwigType *type = Getattr(n, "type");
 
1900
    String *rawval = Getattr(n, "rawval");
 
1901
    String *value = rawval ? rawval : Getattr(n, "value");
 
1902
    String *tm;
1322
1903
 
1323
 
    if (!addSymbol(iname,n)) return SWIG_ERROR;
 
1904
    if (!addSymbol(iname, n))
 
1905
      return SWIG_ERROR;
1324
1906
 
1325
1907
    SwigType_remember(type);
1326
1908
 
1327
 
    if((tm = Swig_typemap_lookup_new("consttab", n, name, 0))) {
 
1909
    if ((tm = Swig_typemap_lookup_new("consttab", n, name, 0))) {
1328
1910
      Replaceall(tm, "$source", value);
1329
1911
      Replaceall(tm, "$target", name);
1330
1912
      Replaceall(tm, "$value", value);
1331
1913
      Printf(s_cinit, "%s\n", tm);
1332
1914
    }
 
1915
 
 
1916
    if (shadow && php_version == 5) {
 
1917
      if (wrapping_member_constant) {
 
1918
        if (!s_oowrappers)
 
1919
          s_oowrappers = NewStringEmpty();
 
1920
        Printf(s_oowrappers, "\n\tconst %s = %s;\n", wrapping_member_constant, iname);
 
1921
      } else {
 
1922
        if (!s_fakeoowrappers)
 
1923
          s_fakeoowrappers = NewStringEmpty();
 
1924
        Printf(s_fakeoowrappers, "\n\tconst %s = %s;\n", name, iname);
 
1925
      }
 
1926
    }
 
1927
 
1333
1928
    return SWIG_OK;
1334
1929
  }
1335
1930
 
1336
1931
  /*
1337
 
   * PHP4::pragma()
 
1932
   * PHP::pragma()
1338
1933
   *
1339
1934
   * Pragma directive.
1340
1935
   *
1341
1936
   * %pragma(php4) code="String"         # Includes a string in the .php file
1342
1937
   * %pragma(php4) include="file.pl"     # Includes a file in the .php file
1343
1938
   */
1344
 
  
 
1939
 
1345
1940
  virtual int pragmaDirective(Node *n) {
1346
1941
    if (!ImportMode) {
1347
 
      String *lang = Getattr(n,"lang");
1348
 
      String *type = Getattr(n,"name");
1349
 
      String *value = Getattr(n,"value");
 
1942
      String *lang = Getattr(n, "lang");
 
1943
      String *type = Getattr(n, "name");
 
1944
      String *value = Getattr(n, "value");
1350
1945
 
1351
 
      if (Strcmp(lang,"php4") == 0) {
1352
 
        
1353
 
        if (Strcmp(type, "code") == 0) {
1354
 
          if (value) {
1355
 
            Printf(pragma_code, "%s\n", value);
1356
 
          }
1357
 
        } else if (Strcmp(type, "include") == 0) {
1358
 
          if (value) {
1359
 
            Printf(pragma_incl, "include \"%s\";\n", value);
1360
 
          }
1361
 
        } else if (Strcmp(type, "phpinfo") == 0) {
1362
 
          if (value) {
1363
 
            Printf(pragma_phpinfo, "%s\n", value);
1364
 
          }
1365
 
        } else {
1366
 
          Printf(stderr, "%s : Line %d. Unrecognized pragma.\n",
1367
 
                 input_file, line_number);
1368
 
        }
 
1946
      if (Strcmp(lang, "php4") == 0) {
 
1947
        if (Strcmp(type, "code") == 0) {
 
1948
          if (value) {
 
1949
            Printf(pragma_code, "%s\n", value);
 
1950
          }
 
1951
        } else if (Strcmp(type, "include") == 0) {
 
1952
          if (value) {
 
1953
            Printf(pragma_incl, "include \"%s\";\n", value);
 
1954
          }
 
1955
        } else if (Strcmp(type, "phpinfo") == 0) {
 
1956
          if (value) {
 
1957
            Printf(pragma_phpinfo, "%s\n", value);
 
1958
          }
 
1959
        } else {
 
1960
          Swig_warning(WARN_PHP4_UNKNOWN_PRAGMA, input_file, line_number, "Unrecognized pragma <%s>.\n", type);
 
1961
        }
1369
1962
      }
1370
1963
    }
1371
1964
    return Language::pragmaDirective(n);
1376
1969
   * ------------------------------------------------------------ */
1377
1970
 
1378
1971
  virtual int classDeclaration(Node *n) {
1379
 
    if (!Getattr(n,"feature:onlychildren")) {
1380
 
      String *symname = Getattr(n,"sym:name");
1381
 
      Setattr(n,"php:proxy",symname);
 
1972
    if (!Getattr(n, "feature:onlychildren")) {
 
1973
      String *symname = Getattr(n, "sym:name");
 
1974
      Setattr(n, "php:proxy", symname);
1382
1975
    }
1383
 
    
 
1976
 
1384
1977
    return Language::classDeclaration(n);
1385
1978
  }
1386
 
  
 
1979
 
1387
1980
  /* ------------------------------------------------------------
1388
1981
   * classHandler()
1389
1982
   * ------------------------------------------------------------ */
1390
1983
 
1391
1984
  virtual int classHandler(Node *n) {
1392
 
    constructors=0;
 
1985
    constructors = 0;
1393
1986
    //SwigType *t = Getattr(n, "classtype");
1394
 
    class_name = Getattr(n, "sym:name");
 
1987
    current_class = n;
1395
1988
    // String *use_class_name=SwigType_manglestr(SwigType_ltype(t));
1396
1989
 
1397
 
    if(shadow) {
 
1990
    if (shadow && php_version == 4) {
1398
1991
      char *rename = GetChar(n, "sym:name");
1399
1992
 
1400
 
      if (!addSymbol(rename,n)) return SWIG_ERROR;
1401
 
      shadow_classname = Swig_copy_string(rename);
1402
 
      cs_entry = NewString("");
1403
 
      Printf(cs_entry,"/* Function entries for %s */\n",shadow_classname);
1404
 
      Printf(cs_entry,"static zend_function_entry %s_functions[] = {\n", shadow_classname);
 
1993
      if (!addSymbol(rename, n))
 
1994
        return SWIG_ERROR;
 
1995
      shadow_classname = NewString(rename);
 
1996
      cs_entry = NewStringEmpty();
 
1997
      Printf(cs_entry, "/* Function entries for %s */\n", shadow_classname);
 
1998
      Printf(cs_entry, "static zend_function_entry %s_functions[] = {\n", shadow_classname);
1405
1999
 
1406
 
      if(Strcmp(shadow_classname, module) == 0) {
1407
 
        Printf(stderr, "class name cannot be equal to module name: %s\n", shadow_classname);
1408
 
        SWIG_exit(1);
 
2000
      if (Strcmp(shadow_classname, module) == 0) {
 
2001
        Printf(stderr, "class name cannot be equal to module name: %s\n", module);
 
2002
        SWIG_exit(1);
1409
2003
      }
1410
2004
 
1411
2005
      shadow_get_vars = NewHash();
1412
2006
      shadow_set_vars = NewHash();
1413
2007
 
1414
2008
      /* Deal with inheritance */
1415
 
      List *baselist = Getattr(n,"bases");
 
2009
      List *baselist = Getattr(n, "bases");
1416
2010
      if (baselist) {
1417
2011
        Iterator base = First(baselist);
1418
 
        while(base.item && GetFlag(base.item,"feature:ignore")) {
 
2012
        while (base.item && GetFlag(base.item, "feature:ignore")) {
1419
2013
          base = Next(base);
1420
2014
        }
1421
2015
        base = Next(base);
1422
2016
        if (base.item) {
1423
2017
          /* Warn about multiple inheritance for additional base class(es) */
1424
2018
          while (base.item) {
1425
 
            if (GetFlag(base.item,"feature:ignore")) {
 
2019
            if (GetFlag(base.item, "feature:ignore")) {
1426
2020
              base = Next(base);
1427
2021
              continue;
1428
2022
            }
1429
 
            String *proxyclassname = SwigType_str(Getattr(n,"classtypeobj"),0);
1430
 
            String *baseclassname = SwigType_str(Getattr(base.item,"name"),0);
1431
 
            Swig_warning(WARN_PHP4_MULTIPLE_INHERITANCE, input_file, line_number, 
1432
 
                "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Php4.\n", proxyclassname, baseclassname);
 
2023
            String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0);
 
2024
            String *baseclassname = SwigType_str(Getattr(base.item, "name"), 0);
 
2025
            Swig_warning(WARN_PHP4_MULTIPLE_INHERITANCE, input_file, line_number,
 
2026
                         "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Php4.\n", proxyclassname, baseclassname);
1433
2027
            base = Next(base);
1434
2028
          }
1435
2029
        }
1436
2030
      }
1437
2031
 
1438
2032
      /* Write out class init code */
1439
 
      Printf(s_vdecl,"static zend_class_entry ce_swig_%s;\n",shadow_classname);
1440
 
      Printf(s_vdecl,"static zend_class_entry* ptr_ce_swig_%s=NULL;\n",shadow_classname);
 
2033
      Printf(s_vdecl, "static zend_class_entry ce_swig_%s;\n", shadow_classname);
 
2034
      Printf(s_vdecl, "static zend_class_entry* ptr_ce_swig_%s=NULL;\n", shadow_classname);
 
2035
    } else if (shadow && php_version == 5) {
 
2036
      char *rename = GetChar(n, "sym:name");
 
2037
 
 
2038
      if (!addSymbol(rename, n))
 
2039
        return SWIG_ERROR;
 
2040
      shadow_classname = NewString(rename);
 
2041
 
 
2042
      shadow_get_vars = NewHash();
 
2043
      shadow_set_vars = NewHash();
 
2044
 
 
2045
      /* Deal with inheritance */
 
2046
      List *baselist = Getattr(n, "bases");
 
2047
      if (baselist) {
 
2048
        Iterator base = First(baselist);
 
2049
        while (base.item && GetFlag(base.item, "feature:ignore")) {
 
2050
          base = Next(base);
 
2051
        }
 
2052
        base = Next(base);
 
2053
        if (base.item) {
 
2054
          /* Warn about multiple inheritance for additional base class(es) */
 
2055
          while (base.item) {
 
2056
            if (GetFlag(base.item, "feature:ignore")) {
 
2057
              base = Next(base);
 
2058
              continue;
 
2059
            }
 
2060
            String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0);
 
2061
            String *baseclassname = SwigType_str(Getattr(base.item, "name"), 0);
 
2062
            Swig_warning(WARN_PHP4_MULTIPLE_INHERITANCE, input_file, line_number,
 
2063
                         "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Php4.\n", proxyclassname, baseclassname);
 
2064
            base = Next(base);
 
2065
          }
 
2066
        }
 
2067
      }
1441
2068
    }
1442
2069
 
1443
 
    classnode=n;
 
2070
    classnode = n;
1444
2071
    Language::classHandler(n);
1445
 
    classnode=0;
 
2072
    classnode = 0;
1446
2073
 
1447
 
    if(shadow) {
 
2074
    if (shadow && php_version == 4) {
1448
2075
      DOH *key;
1449
 
      int gcount, scount;
1450
 
      String      *s_propget=NewString("");
1451
 
      String      *s_propset=NewString("");
 
2076
      String *s_propget = NewStringEmpty();
 
2077
      String *s_propset = NewStringEmpty();
1452
2078
      List *baselist = Getattr(n, "bases");
1453
2079
      Iterator ki, base;
1454
2080
 
1455
 
 
1456
2081
      // If no constructor was generated (abstract class) we had better
1457
2082
      // generate a constructor that raises an error about instantiating
1458
2083
      // abstract classes
1459
 
      if (Getattr(n,"abstract") && constructors==0 ) {
1460
 
        // have to write out fake constructor which raises an error when called
1461
 
        abstractConstructorHandler(n);
 
2084
      if (Getattr(n, "abstract") && constructors == 0) {
 
2085
        // have to write out fake constructor which raises an error when called
 
2086
        abstractConstructorHandler(n);
1462
2087
      }
1463
2088
 
1464
 
      Printf(s_oinit,"/* Define class %s */\n",shadow_classname);
1465
 
      Printf(s_oinit,"INIT_OVERLOADED_CLASS_ENTRY(ce_swig_%s,\"%(lower)s\",%s_functions,",
1466
 
             shadow_classname,shadow_classname, shadow_classname);
1467
 
      Printf(s_oinit,"NULL,_wrap_propget_%s,_wrap_propset_%s);\n",shadow_classname,shadow_classname);
 
2089
      Printf(s_oinit, "/* Define class %s */\n", shadow_classname);
 
2090
      Printf(s_oinit, "INIT_OVERLOADED_CLASS_ENTRY(ce_swig_%s,\"%(lower)s\",%s_functions,", shadow_classname, shadow_classname, shadow_classname);
 
2091
      Printf(s_oinit, "NULL,_wrap_propget_%s,_wrap_propset_%s);\n", shadow_classname, shadow_classname);
1468
2092
 
1469
2093
      // ******** Write property SET handlers
1470
 
      Printf(s_header,"static int _wrap_propset_%s(zend_property_reference *property_reference, pval *value);\n",
1471
 
             shadow_classname);
1472
 
      Printf(s_header,"static int _propset_%s(zend_property_reference *property_reference, pval *value);\n",
1473
 
             shadow_classname);
 
2094
      Printf(s_header, "static int _wrap_propset_%s(zend_property_reference *property_reference, pval *value);\n", shadow_classname);
 
2095
      Printf(s_header, "static int _propset_%s(zend_property_reference *property_reference, pval *value);\n", shadow_classname);
1474
2096
 
1475
 
      Printf(s_propset,"static int _wrap_propset_%s(zend_property_reference *property_reference, pval *value) { \n",
1476
 
             shadow_classname);
1477
 
      Printf(s_propset,"  zval * _value;\n");
1478
 
      Printf(s_propset,"  zend_llist_element *element = property_reference->elements_list->head;\n");
1479
 
      Printf(s_propset,"  zend_overloaded_element *property=(zend_overloaded_element *)element->data;\n");
1480
 
      Printf(s_propset,"  if (_propset_%s(property_reference, value)==SUCCESS) return SUCCESS;\n", shadow_classname);
1481
 
      Printf(s_propset,"  /* set it ourselves as it is %s */\n",shadow_classname);
1482
 
      Printf(s_propset,"  MAKE_STD_ZVAL(_value);\n");
1483
 
      Printf(s_propset,"  *_value=*value;\n");
1484
 
      Printf(s_propset,"  INIT_PZVAL(_value);\n");
1485
 
      Printf(s_propset,"  zval_copy_ctor(_value);\n");
1486
 
      Printf(s_propset,"  return add_property_zval_ex(property_reference->object,Z_STRVAL_P(&(property->element)),1+Z_STRLEN_P(&(property->element)),_value);\n");
1487
 
      Printf(s_propset,"}\n");
1488
 
      Printf(s_propset,"static int _propset_%s(zend_property_reference *property_reference, pval *value) {\n",
1489
 
             shadow_classname);
 
2097
      Printf(s_propset, "static int _wrap_propset_%s(zend_property_reference *property_reference, pval *value) { \n", shadow_classname);
 
2098
      Printf(s_propset, "  zval * _value;\n");
 
2099
      Printf(s_propset, "  zend_llist_element *element = property_reference->elements_list->head;\n");
 
2100
      Printf(s_propset, "  zend_overloaded_element *property=(zend_overloaded_element *)element->data;\n");
 
2101
      Printf(s_propset, "  if (_propset_%s(property_reference, value)==SUCCESS) return SUCCESS;\n", shadow_classname);
 
2102
      Printf(s_propset, "  /* set it ourselves as it is %s */\n", shadow_classname);
 
2103
      Printf(s_propset, "  MAKE_STD_ZVAL(_value);\n");
 
2104
      Printf(s_propset, "  *_value=*value;\n");
 
2105
      Printf(s_propset, "  INIT_PZVAL(_value);\n");
 
2106
      Printf(s_propset, "  zval_copy_ctor(_value);\n");
 
2107
      Printf(s_propset,
 
2108
             "  return add_property_zval_ex(property_reference->object,Z_STRVAL_P(&(property->element)),1+Z_STRLEN_P(&(property->element)),_value);\n");
 
2109
      Printf(s_propset, "}\n");
 
2110
      Printf(s_propset, "static int _propset_%s(zend_property_reference *property_reference, pval *value) {\n", shadow_classname);
1490
2111
 
1491
2112
 
1492
2113
      if (baselist) {
1493
 
        base=First(baselist);
1494
 
      }
1495
 
      else {
1496
 
        base.item = NULL;
 
2114
        base = First(baselist);
 
2115
      } else {
 
2116
        base.item = NULL;
1497
2117
      }
1498
2118
 
1499
 
      while(base.item && GetFlag(base.item,"feature:ignore")) {
1500
 
        base = Next(base);
 
2119
      while (base.item && GetFlag(base.item, "feature:ignore")) {
 
2120
        base = Next(base);
1501
2121
      }
1502
2122
 
1503
2123
      ki = First(shadow_set_vars);
1505
2125
 
1506
2126
      // Print function header; we only need to find property name if there
1507
2127
      // are properties for this class to look up...
1508
 
      if (key || ! base.item) { // or if we are base class and set it ourselves
1509
 
        Printf(s_propset,"  /* get the property name */\n");
1510
 
        Printf(s_propset,"  zend_llist_element *element = property_reference->elements_list->head;\n");
1511
 
        Printf(s_propset,"  zend_overloaded_element *property=(zend_overloaded_element *)element->data;\n");
1512
 
        Printf(s_propset,"  char *propname=Z_STRVAL_P(&(property->element));\n");
 
2128
      if (key || !base.item) {  // or if we are base class and set it ourselves
 
2129
        Printf(s_propset, "  /* get the property name */\n");
 
2130
        Printf(s_propset, "  zend_llist_element *element = property_reference->elements_list->head;\n");
 
2131
        Printf(s_propset, "  zend_overloaded_element *property=(zend_overloaded_element *)element->data;\n");
 
2132
        Printf(s_propset, "  char *propname=Z_STRVAL_P(&(property->element));\n");
1513
2133
      } else {
1514
 
        if (base.item) {
1515
 
          Printf(s_propset,"  /* No extra properties for subclass %s */\n",shadow_classname);
1516
 
        } else {
1517
 
          Printf(s_propset,"  /* No properties for base class %s */\n",shadow_classname);
1518
 
        }
 
2134
        if (base.item) {
 
2135
          Printf(s_propset, "  /* No extra properties for subclass %s */\n", shadow_classname);
 
2136
        } else {
 
2137
          Printf(s_propset, "  /* No properties for base class %s */\n", shadow_classname);
 
2138
        }
1519
2139
      }
1520
2140
 
1521
 
      scount=0;
1522
2141
      while (ki.key) {
1523
 
        key = ki.key;
1524
 
        if (scount++) {
1525
 
          Printf(s_propset," else");
1526
 
        }
1527
 
        Printf(s_propset,"  if (strcmp(propname,\"%s\")==0) {\n",Getattr(shadow_set_vars,key) );
1528
 
        Printf(s_propset,"    return _wrap_%s(property_reference, value);\n",key);
1529
 
        Printf(s_propset,"  }");
1530
 
 
1531
 
        ki=Next(ki);
1532
 
      }
1533
 
 
1534
 
      if (scount) {
1535
 
        Printf(s_propset," else");
1536
 
      }
1537
 
 
1538
 
      // If there is a base class then chain it's handler else set directly
1539
 
      // try each base class handler, else set directly...
 
2142
        key = ki.key;
 
2143
        Printf(s_propset, "  if (strcmp(propname,\"%s\")==0) return _wrap_%s(property_reference, value);\n", ki.item, key);
 
2144
 
 
2145
        ki = Next(ki);
 
2146
      }
 
2147
 
 
2148
      // If the property wasn't in this class, try the handlers of each base
 
2149
      // class (if any) in turn until we succeed in setting the property or
 
2150
      // have tried all base classes.
1540
2151
      if (base.item) {
1541
 
        Printf(s_propset,  "  {\n    /* chain to base class */\n");
1542
 
        while(base.item) {
1543
 
          Printf(s_propset,"    if (_propset_%s(property_reference, value)==SUCCESS) return SUCCESS;\n",
1544
 
                 GetChar(base.item, "sym:name"));
1545
 
          
1546
 
          base=Next(base);
1547
 
          while (base.item && GetFlag(base.item,"feature:ignore")) {
1548
 
            base=Next(base);
1549
 
          }
1550
 
        }
1551
 
        Printf(s_propset,"  }\n");
 
2152
        Printf(s_propset, "  /* Try base class(es) */\n");
 
2153
        while (base.item) {
 
2154
          Printf(s_propset, "  if (_propset_%s(property_reference, value)==SUCCESS) return SUCCESS;\n", GetChar(base.item, "sym:name"));
 
2155
 
 
2156
          base = Next(base);
 
2157
          while (base.item && GetFlag(base.item, "feature:ignore")) {
 
2158
            base = Next(base);
 
2159
          }
 
2160
        }
1552
2161
      }
1553
 
      Printf(s_propset,"  return FAILURE;\n}\n\n");
 
2162
      Printf(s_propset, "  return FAILURE;\n}\n\n");
1554
2163
 
1555
2164
      // ******** Write property GET handlers
1556
 
      Printf(s_header,"static pval _wrap_propget_%s(zend_property_reference *property_reference);\n",
1557
 
             shadow_classname);
1558
 
      Printf(s_header,"static int _propget_%s(zend_property_reference *property_reference, pval *value);\n",
1559
 
             shadow_classname);
 
2165
      Printf(s_header, "static pval _wrap_propget_%s(zend_property_reference *property_reference);\n", shadow_classname);
 
2166
      Printf(s_header, "static int _propget_%s(zend_property_reference *property_reference, pval *value);\n", shadow_classname);
1560
2167
 
1561
 
      Printf(s_propget,"static pval _wrap_propget_%s(zend_property_reference *property_reference) {\n",
1562
 
             shadow_classname);
1563
 
      Printf(s_propget,"  pval result;\n");
1564
 
      Printf(s_propget,"  pval **_result;\n");
1565
 
      Printf(s_propget,"  zend_llist_element *element = property_reference->elements_list->head;\n");
1566
 
      Printf(s_propget,"  zend_overloaded_element *property=(zend_overloaded_element *)element->data;\n");
1567
 
      Printf(s_propget,"  result.type = IS_NULL;\n");
1568
 
      Printf(s_propget,"  if (_propget_%s(property_reference, &result)==SUCCESS) return result;\n", shadow_classname);
1569
 
      Printf(s_propget,"  /* return it ourselves */\n");
1570
 
      Printf(s_propget,"  if (zend_hash_find(Z_OBJPROP_P(property_reference->object),Z_STRVAL_P(&(property->element)),1+Z_STRLEN_P(&(property->element)),(void**)&_result)==SUCCESS) {\n");
1571
 
      Printf(s_propget,"  zval *_value;\n");
1572
 
      Printf(s_propget,"  MAKE_STD_ZVAL(_value);");
1573
 
      Printf(s_propget,"  *_value=**_result;\n");
1574
 
      Printf(s_propget,"  INIT_PZVAL(_value);\n");
1575
 
      Printf(s_propget,"  zval_copy_ctor(_value);\n");
1576
 
      Printf(s_propget,"  return *_value;\n");
1577
 
      Printf(s_propget,"  }\n");
1578
 
      Printf(s_propget,"  result.type = IS_NULL;\n");
1579
 
      Printf(s_propget,"  return result;\n");
1580
 
      Printf(s_propget,"}\n");
1581
 
      Printf(s_propget,"static int _propget_%s(zend_property_reference *property_reference, pval *value) {\n",
1582
 
             shadow_classname);
 
2168
      Printf(s_propget, "static pval _wrap_propget_%s(zend_property_reference *property_reference) {\n", shadow_classname);
 
2169
      Printf(s_propget, "  pval result;\n");
 
2170
      Printf(s_propget, "  pval **_result;\n");
 
2171
      Printf(s_propget, "  zend_llist_element *element = property_reference->elements_list->head;\n");
 
2172
      Printf(s_propget, "  zend_overloaded_element *property=(zend_overloaded_element *)element->data;\n");
 
2173
      Printf(s_propget, "  result.type = IS_NULL;\n");
 
2174
      Printf(s_propget, "  if (_propget_%s(property_reference, &result)==SUCCESS) return result;\n", shadow_classname);
 
2175
      Printf(s_propget, "  /* return it ourselves */\n");
 
2176
      Printf(s_propget,
 
2177
             "  if (zend_hash_find(Z_OBJPROP_P(property_reference->object),Z_STRVAL_P(&(property->element)),1+Z_STRLEN_P(&(property->element)),(void**)&_result)==SUCCESS) {\n");
 
2178
      Printf(s_propget, "  zval *_value;\n");
 
2179
      Printf(s_propget, "  MAKE_STD_ZVAL(_value);");
 
2180
      Printf(s_propget, "  *_value=**_result;\n");
 
2181
      Printf(s_propget, "  INIT_PZVAL(_value);\n");
 
2182
      Printf(s_propget, "  zval_copy_ctor(_value);\n");
 
2183
      Printf(s_propget, "  return *_value;\n");
 
2184
      Printf(s_propget, "  }\n");
 
2185
      Printf(s_propget, "  result.type = IS_NULL;\n");
 
2186
      Printf(s_propget, "  return result;\n");
 
2187
      Printf(s_propget, "}\n");
 
2188
      Printf(s_propget, "static int _propget_%s(zend_property_reference *property_reference, pval *value) {\n", shadow_classname);
1583
2189
 
1584
2190
      if (baselist) {
1585
 
        base=First(baselist); 
 
2191
        base = First(baselist);
1586
2192
      } else {
1587
 
        base.item=NULL;
 
2193
        base.item = NULL;
1588
2194
      }
1589
 
      while(base.item && GetFlag(base.item,"feature:ignore")) {
1590
 
        base = Next(base);
 
2195
      while (base.item && GetFlag(base.item, "feature:ignore")) {
 
2196
        base = Next(base);
1591
2197
      }
1592
2198
      ki = First(shadow_get_vars);
1593
2199
 
1595
2201
 
1596
2202
      // Print function header; we only need to find property name if there
1597
2203
      // are properties for this class to look up...
1598
 
      if (key || !base.item ) { // or if we are base class...
1599
 
        Printf(s_propget,"  /* get the property name */\n");
1600
 
        Printf(s_propget,"  zend_llist_element *element = property_reference->elements_list->head;\n");
1601
 
        Printf(s_propget,"  zend_overloaded_element *property=(zend_overloaded_element *)element->data;\n");
1602
 
        Printf(s_propget,"  char *propname=Z_STRVAL_P(&(property->element));\n");
 
2204
      if (key || !base.item) {  // or if we are base class...
 
2205
        Printf(s_propget, "  /* get the property name */\n");
 
2206
        Printf(s_propget, "  zend_llist_element *element = property_reference->elements_list->head;\n");
 
2207
        Printf(s_propget, "  zend_overloaded_element *property=(zend_overloaded_element *)element->data;\n");
 
2208
        Printf(s_propget, "  char *propname=Z_STRVAL_P(&(property->element));\n");
1603
2209
      } else {
1604
 
        if (base.item) {
1605
 
          Printf(s_propget,"  /* No extra properties for subclass %s */\n",shadow_classname);
1606
 
        } else {
1607
 
          Printf(s_propget,"  /* No properties for base class %s */\n",shadow_classname);
1608
 
        }
 
2210
        if (base.item) {
 
2211
          Printf(s_propget, "  /* No extra properties for subclass %s */\n", shadow_classname);
 
2212
        } else {
 
2213
          Printf(s_propget, "  /* No properties for base class %s */\n", shadow_classname);
 
2214
        }
1609
2215
      }
1610
2216
 
1611
 
      gcount=0;
1612
2217
      while (ki.key) {
1613
 
        key = ki.key;
1614
 
        if (gcount++) {
1615
 
          Printf(s_propget," else");
1616
 
        }
1617
 
        Printf(s_propget,"  if (strcmp(propname,\"%s\")==0) {\n",Getattr(shadow_get_vars,key));
1618
 
        Printf(s_propget,"    *value=_wrap_%s(property_reference);\n",key);
1619
 
        Printf(s_propget,"    return SUCCESS;\n");
1620
 
        Printf(s_propget,"  }");
1621
 
 
1622
 
        ki=Next(ki);
1623
 
      }
1624
 
 
1625
 
      if (gcount) {
1626
 
        Printf(s_propget," else");
1627
 
      }
1628
 
 
1629
 
      // If there is a base class then chain it's handler else return null
 
2218
        key = ki.key;
 
2219
        Printf(s_propget, "  if (strcmp(propname,\"%s\")==0) {\n", ki.item);
 
2220
        Printf(s_propget, "    *value=_wrap_%s(property_reference);\n", key);
 
2221
        Printf(s_propget, "    return SUCCESS;\n");
 
2222
        Printf(s_propget, "  }\n");
 
2223
 
 
2224
        ki = Next(ki);
 
2225
      }
 
2226
 
 
2227
      // If the property wasn't in this class, try the handlers of each base
 
2228
      // class (if any) in turn until we succeed in setting the property or
 
2229
      // have tried all base classes.
1630
2230
      if (base.item) {
1631
 
        Printf(s_propget,  "  {\n    /* chain to base class */\n");
1632
 
        while(base.item) {
1633
 
          Printf(s_propget,"    if (_propget_%s(property_reference,  value)==SUCCESS) return SUCCESS;\n",
1634
 
               GetChar(base.item, "sym:name"));
 
2231
        Printf(s_propget, "  /* Try base class(es). */\n");
 
2232
        while (base.item) {
 
2233
          Printf(s_propget, "  if (_propget_%s(property_reference, value)==SUCCESS) return SUCCESS;\n", GetChar(base.item, "sym:name"));
1635
2234
 
1636
 
          base=Next(base);
1637
 
          while (base.item && GetFlag(base.item,"feature:ignore")) {
1638
 
            base=Next(base);
1639
 
          }
1640
 
        }
1641
 
        Printf(s_propget,"  }\n");
 
2235
          base = Next(base);
 
2236
          while (base.item && GetFlag(base.item, "feature:ignore")) {
 
2237
            base = Next(base);
 
2238
          }
 
2239
        }
1642
2240
      }
1643
 
      Printf(s_propget,"  return FAILURE;\n}\n\n");
 
2241
      Printf(s_propget, "  return FAILURE;\n}\n\n");
1644
2242
 
1645
2243
      // wrappers generated now...
1646
2244
 
1647
2245
      // add wrappers to output code
1648
 
      Printf(s_wrappers,"/* property handler for class %s */\n",shadow_classname);
1649
 
      Printv(s_wrappers,s_propget,s_propset,NIL);
 
2246
      Printf(s_wrappers, "/* property handler for class %s */\n", shadow_classname);
 
2247
      Printv(s_wrappers, s_propget, s_propset, NIL);
1650
2248
 
1651
2249
      // Save class in class table
1652
2250
      if (baselist) {
1653
 
        base=First(baselist);
1654
 
      }
1655
 
      else {
1656
 
        base.item=NULL;
1657
 
      }
1658
 
      while(base.item && GetFlag(base.item,"feature:ignore")) {
1659
 
        base = Next(base);
 
2251
        base = First(baselist);
 
2252
      } else {
 
2253
        base.item = NULL;
 
2254
      }
 
2255
      while (base.item && GetFlag(base.item, "feature:ignore")) {
 
2256
        base = Next(base);
1660
2257
      }
1661
2258
 
1662
2259
      if (base.item) {
1663
 
        Printf(s_oinit,"if (! (ptr_ce_swig_%s=zend_register_internal_class_ex(&ce_swig_%s,&ce_swig_%s,NULL))) zend_error(E_ERROR,\"Error registering wrapper for class %s\");\n",
1664
 
               shadow_classname,shadow_classname,GetChar(base.item, "sym:name"), shadow_classname);
 
2260
        Printf(s_oinit,
 
2261
               "if (! (ptr_ce_swig_%s=zend_register_internal_class_ex(&ce_swig_%s,&ce_swig_%s,NULL))) zend_error(E_ERROR,\"Error registering wrapper for class %s\");\n",
 
2262
               shadow_classname, shadow_classname, GetChar(base.item, "sym:name"), shadow_classname);
1665
2263
      } else {
1666
 
        Printf(s_oinit,"if (! (ptr_ce_swig_%s=zend_register_internal_class_ex(&ce_swig_%s,NULL,NULL))) zend_error(E_ERROR,\"Error registering wrapper for class %s\");\n",
1667
 
               shadow_classname,shadow_classname, shadow_classname);
 
2264
        Printf(s_oinit,
 
2265
               "if (! (ptr_ce_swig_%s=zend_register_internal_class_ex(&ce_swig_%s,NULL,NULL))) zend_error(E_ERROR,\"Error registering wrapper for class %s\");\n",
 
2266
               shadow_classname, shadow_classname, shadow_classname);
1668
2267
      }
1669
 
      Printf(s_oinit,"\n");
 
2268
      Printf(s_oinit, "\n");
1670
2269
 
1671
2270
      // Write the enum initialisation code in a static block
1672
 
      // These are all the enums defined withing the c++ class.
1673
 
      
1674
 
 
1675
 
      free(shadow_classname);
1676
 
      shadow_classname = NULL;
1677
 
      
1678
 
      Delete(shadow_set_vars); shadow_set_vars = NULL;
1679
 
      Delete(shadow_get_vars); shadow_get_vars = NULL;
1680
 
      
1681
 
      Printf(all_cs_entry,"%s   { NULL, NULL, NULL}\n};\n",cs_entry);
1682
 
      //??delete cs_entry;
1683
 
      cs_entry=NULL;
 
2271
      // These are all the enums defined within the C++ class.
 
2272
 
 
2273
      Delete(shadow_classname);
 
2274
      shadow_classname = NULL;
 
2275
 
 
2276
      Delete(shadow_set_vars);
 
2277
      shadow_set_vars = NULL;
 
2278
      Delete(shadow_get_vars);
 
2279
      shadow_get_vars = NULL;
 
2280
 
 
2281
      Printv(all_cs_entry, cs_entry, " { NULL, NULL, NULL}\n};\n", NIL);
 
2282
      Delete(cs_entry);
 
2283
      cs_entry = NULL;
 
2284
    } else if (shadow && php_version == 5) {
 
2285
      DOH *key;
 
2286
      List *baselist = Getattr(n, "bases");
 
2287
      Iterator ki, base;
 
2288
 
 
2289
      if (baselist) {
 
2290
        base = First(baselist);
 
2291
        while (base.item && GetFlag(base.item, "feature:ignore")) {
 
2292
          base = Next(base);
 
2293
        }
 
2294
      } else {
 
2295
        base.item = NULL;
 
2296
      }
 
2297
 
 
2298
      if (Getattr(n, "abstract")) {
 
2299
        Printf(s_phpclasses, "abstract ");
 
2300
      }
 
2301
 
 
2302
      Printf(s_phpclasses, "class %s%s ", prefix, shadow_classname);
 
2303
      if (base.item) {
 
2304
        String *baseclass = Getattr(base.item, "sym:name");
 
2305
        if (!baseclass)
 
2306
          baseclass = Getattr(base.item, "name");
 
2307
        Printf(s_phpclasses, "extends %s%s ", prefix, baseclass);
 
2308
      }
 
2309
      Printf(s_phpclasses, "{\n\tpublic $%s=null;\n", SWIG_PTR);
 
2310
 
 
2311
      // Write property SET handlers
 
2312
      ki = First(shadow_set_vars);
 
2313
 
 
2314
      if (ki.key) {
 
2315
        // This class has setters.
 
2316
        // FIXME: just ignore setting an unknown property name for now.
 
2317
        Printf(s_phpclasses, "\n\tfunction __set($var,$value) {\n");
 
2318
        // FIXME: tune this threshold...
 
2319
        if (Len(shadow_set_vars) <= 2) {
 
2320
          // Not many setters, so avoid call_user_func.
 
2321
          while (ki.key) {
 
2322
            key = ki.key;
 
2323
            Printf(s_phpclasses, "\t\tif ($var == '%s') return %s($this->%s,$value);\n", key, ki.item, SWIG_PTR);
 
2324
            ki = Next(ki);
 
2325
          }
 
2326
        } else {
 
2327
          Printf(s_phpclasses, "\t\t$func = '%s_'.$var.'_set';\n", shadow_classname);
 
2328
          Printf(s_phpclasses, "\t\tif (function_exists($func) call_user_func($func,$this->%s,$value);\n", SWIG_PTR);
 
2329
        }
 
2330
        Printf(s_phpclasses, "\t}\n");
 
2331
        /* FIXME: also create __isset for PHP 5.1 and later? */
 
2332
      }
 
2333
      // Write property GET handlers
 
2334
      ki = First(shadow_get_vars);
 
2335
 
 
2336
      if (ki.key) {
 
2337
        // This class has getters.
 
2338
        Printf(s_phpclasses, "\n\tfunction __get($var) {\n");
 
2339
        // FIXME: tune this threshold...
 
2340
        if (Len(shadow_get_vars) <= 2) {
 
2341
          // Not many getters, so avoid call_user_func.
 
2342
          while (ki.key) {
 
2343
            key = ki.key;
 
2344
            Printf(s_phpclasses, "\t\tif ($var == '%s') return %s($this->%s);\n", key, ki.item, SWIG_PTR);
 
2345
            ki = Next(ki);
 
2346
          }
 
2347
        } else {
 
2348
          Printf(s_phpclasses, "\t\t$func = '%s_'.$var.'_get';\n", shadow_classname);
 
2349
          Printf(s_phpclasses, "\t\tif (function_exists($func) return call_user_func($func,$this->%s);\n", SWIG_PTR);
 
2350
        }
 
2351
        // Reading an unknown property name gives null in PHP.
 
2352
        Printf(s_phpclasses, "\t\treturn null;\n");
 
2353
        Printf(s_phpclasses, "\t}\n");
 
2354
      }
 
2355
 
 
2356
      if (!class_has_ctor) {
 
2357
        Printf(s_phpclasses, "\tfunction __construct($h) {\n");
 
2358
        Printf(s_phpclasses, "\t\t$this->%s=$h;\n", SWIG_PTR);
 
2359
        Printf(s_phpclasses, "\t}\n");
 
2360
      }
 
2361
 
 
2362
      if (s_oowrappers) {
 
2363
        Printf(s_phpclasses, "%s", s_oowrappers);
 
2364
        Delete(s_oowrappers);
 
2365
        s_oowrappers = NULL;
 
2366
      }
 
2367
      class_has_ctor = false;
 
2368
 
 
2369
      Printf(s_phpclasses, "}\n\n");
 
2370
 
 
2371
      Delete(shadow_classname);
 
2372
      shadow_classname = NULL;
 
2373
 
 
2374
      Delete(shadow_set_vars);
 
2375
      shadow_set_vars = NULL;
 
2376
      Delete(shadow_get_vars);
 
2377
      shadow_get_vars = NULL;
1684
2378
    }
1685
2379
    return SWIG_OK;
1686
2380
  }
1692
2386
  virtual int memberfunctionHandler(Node *n) {
1693
2387
    char *name = GetChar(n, "name");
1694
2388
    char *iname = GetChar(n, "sym:name");
1695
 
    
 
2389
 
1696
2390
    wrapperType = memberfn;
1697
2391
    this->Language::memberfunctionHandler(n);
1698
2392
    wrapperType = standard;
1699
 
    
 
2393
 
1700
2394
    // Only declare the member function if
1701
2395
    // we are doing shadow classes, and the function
1702
2396
    // is not overloaded, or if it is overloaded, it is the dispatch function.
1703
 
    if(shadow && (!Getattr(n,"sym:overloaded") || !Getattr(n,"sym:nextSibling"))) {
 
2397
    if (shadow && php_version == 4 && (!Getattr(n, "sym:overloaded") || !Getattr(n, "sym:nextSibling"))) {
1704
2398
      char *realname = iname ? iname : name;
1705
2399
      String *php_function_name = Swig_name_member(shadow_classname, realname);
1706
 
      create_command(realname,Swig_name_wrapper(php_function_name));
 
2400
      create_command(realname, Swig_name_wrapper(php_function_name));
1707
2401
    }
1708
2402
    return SWIG_OK;
1709
2403
  }
1713
2407
   * ------------------------------------------------------------ */
1714
2408
 
1715
2409
  virtual int membervariableHandler(Node *n) {
1716
 
    
 
2410
 
1717
2411
    wrapperType = membervar;
1718
2412
    Language::membervariableHandler(n);
1719
2413
    wrapperType = standard;
1720
 
    
 
2414
 
1721
2415
    return SWIG_OK;
1722
2416
  }
1723
2417
 
1731
2425
    Language::staticmembervariableHandler(n);
1732
2426
    wrapperType = standard;
1733
2427
 
1734
 
    SwigType* type = Getattr(n, "type" );
1735
 
    String *name  = Getattr(n, "name" );
1736
 
    String *iname = Getattr(n, "sym:name" );
 
2428
    SwigType *type = Getattr(n, "type");
 
2429
    String *name = Getattr(n, "name");
 
2430
    String *iname = Getattr(n, "sym:name");
1737
2431
 
1738
2432
    /* A temporary(!) hack for static member variables.
1739
2433
     * Php currently supports class functions, but not class variables.
1749
2443
     */
1750
2444
 
1751
2445
    // If the variable is const, then it's wrapped as a constant with set/get functions.
1752
 
    if ( SwigType_isconst(type) )
 
2446
    if (SwigType_isconst(type))
1753
2447
      return SWIG_OK;
1754
2448
 
1755
2449
    // This duplicates the logic from Language::variableWrapper() to test if the set wrapper
1756
2450
    // is made.
1757
2451
    int assignable = is_assignable(n);
1758
2452
    if (assignable) {
1759
 
      String *tm = Swig_typemap_lookup_new("globalin",n,name,0);
 
2453
      String *tm = Swig_typemap_lookup_new("globalin", n, name, 0);
1760
2454
      if (!tm && SwigType_isarray(type)) {
1761
 
        assignable = 0;
 
2455
        assignable = 0;
1762
2456
      }
1763
2457
    }
1764
2458
 
1765
 
    String *class_iname = Swig_name_member(class_name,iname);
1766
 
    create_command( iname, Swig_name_wrapper(class_iname) );
 
2459
    String *class_iname = Swig_name_member(Getattr(current_class, "sym:name"), iname);
 
2460
    create_command(iname, Swig_name_wrapper(class_iname));
1767
2461
 
1768
2462
    Wrapper *f = NewWrapper();
1769
2463
 
1770
 
    Printv(f->def, "ZEND_NAMED_FUNCTION(",Swig_name_wrapper(class_iname), ") {\n", NIL );
 
2464
    Printv(f->def, "ZEND_NAMED_FUNCTION(", Swig_name_wrapper(class_iname), ") {\n", NIL);
1771
2465
    String *mget = Swig_name_wrapper(Swig_name_get(class_iname));
1772
2466
    String *mset = Swig_name_wrapper(Swig_name_set(class_iname));
1773
2467
 
1774
 
    if ( assignable ) {
1775
 
      Printf(f->code, "if (ZEND_NUM_ARGS() > 0 ) {\n" );
1776
 
      Printf(f->code, "  %s( INTERNAL_FUNCTION_PARAM_PASSTHRU );\n", mset );
1777
 
      Printf(f->code, "  // need some error checking here?\n" );
 
2468
    if (assignable) {
 
2469
      Printf(f->code, "if (ZEND_NUM_ARGS() > 0 ) {\n");
 
2470
      Printf(f->code, "  %s( INTERNAL_FUNCTION_PARAM_PASSTHRU );\n", mset);
 
2471
      Printf(f->code, "  // need some error checking here?\n");
1778
2472
      Printf(f->code, "  // Set the argument count to 0 for the get call\n");
1779
2473
      Printf(f->code, "  ht = 0;\n");
1780
 
      Printf(f->code, "}\n" );
 
2474
      Printf(f->code, "}\n");
1781
2475
    }
1782
2476
 
1783
 
    Printf(f->code, "%s( INTERNAL_FUNCTION_PARAM_PASSTHRU );\n",mget );
 
2477
    Printf(f->code, "%s( INTERNAL_FUNCTION_PARAM_PASSTHRU );\n", mget);
1784
2478
    Printf(f->code, "}\n");
1785
2479
 
1786
2480
    Wrapper_print(f, s_wrappers);
1799
2493
  virtual int staticmemberfunctionHandler(Node *n) {
1800
2494
    char *name = GetChar(n, "name");
1801
2495
    char *iname = GetChar(n, "sym:name");
1802
 
    
 
2496
 
 
2497
    wrapperType = staticmemberfn;
1803
2498
    Language::staticmemberfunctionHandler(n);
1804
 
    
1805
 
    if(shadow) {
 
2499
    wrapperType = standard;
 
2500
 
 
2501
    if (shadow && php_version == 4) {
1806
2502
      String *symname = Getattr(n, "sym:name");
1807
2503
      char *realname = iname ? iname : name;
1808
2504
      String *php_function_name = Swig_name_member(shadow_classname, realname);
1809
 
      create_command(symname, Swig_name_wrapper(php_function_name) );
 
2505
      create_command(symname, Swig_name_wrapper(php_function_name));
1810
2506
    }
1811
 
    
 
2507
 
1812
2508
    return SWIG_OK;
1813
2509
  }
1814
2510
 
1815
 
  
1816
 
  void SwigToPhpType(SwigType *t, String_or_char *pname, String* php_type, int shadow_flag) {
1817
 
    char *ptype = 0;
1818
 
    
1819
 
    if(shadow_flag) {
1820
 
      ptype = PhpTypeFromTypemap((char*)"pstype", t, pname,(char*)"");
1821
 
    }
1822
 
    if(!ptype) {
1823
 
      ptype = PhpTypeFromTypemap((char*)"ptype",t,pname,(char*)"");
1824
 
    }
1825
 
    
1826
 
    
1827
 
    if(ptype) {
1828
 
      Printf(php_type, ptype);
1829
 
      free(ptype);
1830
 
    }
1831
 
    else {
 
2511
 
 
2512
  void SwigToPhpType(SwigType *t, String_or_char *pname, String *php_type, int shadow_flag) {
 
2513
    String *ptype = 0;
 
2514
 
 
2515
    if (shadow_flag) {
 
2516
      ptype = PhpTypeFromTypemap((char *) "pstype", t, pname, (char *) "");
 
2517
    }
 
2518
    if (!ptype) {
 
2519
      ptype = PhpTypeFromTypemap((char *) "ptype", t, pname, (char *) "");
 
2520
    }
 
2521
 
 
2522
    if (ptype) {
 
2523
      Printf(php_type, "%s", ptype);
 
2524
      Delete(ptype);
 
2525
    } else {
1832
2526
      /* Map type here */
1833
 
      switch(SwigType_type(t)) {
 
2527
      switch (SwigType_type(t)) {
1834
2528
      case T_CHAR:
1835
2529
      case T_SCHAR:
1836
2530
      case T_UCHAR:
1845
2539
      case T_BOOL:
1846
2540
      case T_STRING:
1847
2541
      case T_VOID:
1848
 
        Printf(php_type, "");
1849
 
        break;
 
2542
        Printf(php_type, "");
 
2543
        break;
1850
2544
      case T_POINTER:
1851
2545
      case T_REFERENCE:
1852
2546
      case T_USER:
1853
 
        if(shadow_flag && is_shadow(t)) {
1854
 
          Printf(php_type, Char(is_shadow(t)));
1855
 
        }
1856
 
        else {
1857
 
          Printf(php_type, "");
1858
 
        }
1859
 
        break;
 
2547
        if (shadow_flag && is_shadow(t)) {
 
2548
          Printf(php_type, Char(is_shadow(t)));
 
2549
        } else {
 
2550
          Printf(php_type, "");
 
2551
        }
 
2552
        break;
1860
2553
      case T_ARRAY:
1861
 
        /* TODO */
1862
 
        break;
 
2554
        /* TODO */
 
2555
        break;
1863
2556
      default:
1864
 
        Printf(stderr, "SwigToPhpType: unhandled data type: %s\n", SwigType_str(t,0));
1865
 
        break;
 
2557
        Printf(stderr, "SwigToPhpType: unhandled data type: %s\n", SwigType_str(t, 0));
 
2558
        break;
1866
2559
      }
1867
2560
    }
1868
2561
  }
1869
 
  
1870
 
  
1871
 
  char *PhpTypeFromTypemap(char *op, SwigType *t, String_or_char *pname, String_or_char *lname) {
 
2562
 
 
2563
 
 
2564
  String *PhpTypeFromTypemap(char *op, SwigType *t, String_or_char *pname, String_or_char *lname) {
1872
2565
    String *tms;
1873
 
    char bigbuf[1024];
1874
 
    char *tm;
1875
 
    char *c = bigbuf;
1876
 
    if(!(tms = Swig_typemap_lookup(op, t, pname, lname, (char*)"", (char*)"", NULL))) {
 
2566
    tms = Swig_typemap_lookup(op, t, pname, lname, (char *) "", (char *) "", NULL);
 
2567
    if (!tms) {
1877
2568
      return NULL;
1878
2569
    }
1879
 
    
1880
 
    tm = Char(tms);
1881
 
    while(*tm && (isspace(*tm) || *tm == '{')) {
1882
 
      tm++;
1883
 
    }
1884
 
    while(*tm && *tm != '}') {
1885
 
      *c++ = *tm++;
1886
 
    }
1887
 
    *c='\0';
1888
 
    return Swig_copy_string(bigbuf);
 
2570
 
 
2571
    char *start = Char(tms);
 
2572
    while (isspace(*start) || *start == '{') {
 
2573
      start++;
 
2574
    }
 
2575
    char *end = start;
 
2576
    while (*end && *end != '}') {
 
2577
      end++;
 
2578
    }
 
2579
    return NewStringWithSize(start, end - start);
1889
2580
  }
1890
 
  
 
2581
 
1891
2582
  int abstractConstructorHandler(Node *n) {
1892
2583
    String *iname = GetChar(n, "sym:name");
1893
 
    if (shadow) {
1894
 
      Wrapper *f;
1895
 
      f   = NewWrapper();
1896
 
 
1897
 
      String *wname = NewStringf( "_wrap_new_%s", iname );
1898
 
      create_command( iname, wname );
1899
 
 
1900
 
      Printf(f->def, "ZEND_NAMED_FUNCTION(_wrap_new_%s) {\n", iname );
1901
 
      Printf(f->def, "zend_error(E_ERROR,\"Cannot create swig object type: %s as the underlying object is abstract\");\n",
1902
 
             iname);
 
2584
    if (shadow && php_version == 4) {
 
2585
      Wrapper *f = NewWrapper();
 
2586
 
 
2587
      String *wname = NewStringf("_wrap_new_%s", iname);
 
2588
      create_command(iname, wname);
 
2589
 
 
2590
      Printf(f->def, "ZEND_NAMED_FUNCTION(_wrap_new_%s) {\n", iname);
 
2591
      Printf(f->def, "  zend_error(E_ERROR,\"Cannot create swig object type: %s as the underlying class is abstract\");\n", iname);
1903
2592
      Printf(f->def, "}\n\n");
1904
 
      Wrapper_print(f,s_wrappers);
 
2593
      Wrapper_print(f, s_wrappers);
1905
2594
      DelWrapper(f);
1906
2595
      Delete(wname);
1907
2596
    }
1910
2599
  /* ------------------------------------------------------------
1911
2600
   * constructorHandler()
1912
2601
   * ------------------------------------------------------------ */
1913
 
  
 
2602
 
1914
2603
  virtual int constructorHandler(Node *n) {
1915
2604
    char *name = GetChar(n, "name");
1916
2605
    char *iname = GetChar(n, "sym:name");
1917
2606
 
1918
 
    if (shadow) {
1919
 
      native_constructor = (strcmp(iname, shadow_classname) == 0)?\
1920
 
        NATIVE_CONSTRUCTOR:ALTERNATIVE_CONSTRUCTOR;
1921
 
    }
1922
 
    else {
1923
 
      native_constructor=0;
 
2607
    if (shadow && php_version == 4) {
 
2608
      if (strcmp(iname, Char(shadow_classname)) == 0) {
 
2609
        native_constructor = NATIVE_CONSTRUCTOR;
 
2610
      } else {
 
2611
        native_constructor = ALTERNATIVE_CONSTRUCTOR;
 
2612
      }
 
2613
    } else {
 
2614
      native_constructor = 0;
1924
2615
    }
1925
2616
    constructors++;
 
2617
    wrapperType = constructor;
1926
2618
    Language::constructorHandler(n);
1927
 
    
1928
 
    if(shadow) {
1929
 
      String *wname = NewStringf( "_wrap_new_%s", iname );
1930
 
      if(!Getattr(n,"sym:overloaded") || !Getattr(n,"sym:nextSibling")) {
1931
 
        char *realname = iname ? iname : name;
1932
 
        String *php_function_name = Swig_name_construct(realname);
1933
 
        create_command(realname,Swig_name_wrapper(php_function_name));
 
2619
    wrapperType = standard;
 
2620
 
 
2621
    if (shadow && php_version == 4) {
 
2622
      if (!Getattr(n, "sym:overloaded") || !Getattr(n, "sym:nextSibling")) {
 
2623
        char *realname = iname ? iname : name;
 
2624
        String *php_function_name = Swig_name_construct(realname);
 
2625
        create_command(realname, Swig_name_wrapper(php_function_name));
1934
2626
      }
1935
 
      Delete(wname);
1936
2627
    }
1937
 
    
 
2628
 
1938
2629
    native_constructor = 0;
1939
2630
    return SWIG_OK;
1940
2631
  }
1945
2636
  //virtual int destructorHandler(Node *n) {
1946
2637
  //}
1947
2638
  int CreateZendListDestructor(Node *n) {
1948
 
    String *name    = GetChar(Swig_methodclass(n),"name");
1949
 
    String *iname   = GetChar(n,"sym:name");
1950
 
    SwigType *d     = Getattr(n,"type");
1951
 
    ParmList *l     = Getattr(n,"parms");
1952
 
    
1953
 
    String *destructorname=NewString("");
1954
 
    Printf(destructorname,"_%s",Swig_name_wrapper(iname));
1955
 
    Setattr(classnode,"destructor",destructorname);
 
2639
    String *name = GetChar(Swig_methodclass(n), "name");
 
2640
    String *iname = GetChar(n, "sym:name");
 
2641
    SwigType *d = Getattr(n, "type");
 
2642
    ParmList *l = Getattr(n, "parms");
 
2643
 
 
2644
    String *destructorname = NewStringEmpty();
 
2645
    Printf(destructorname, "_%s", Swig_name_wrapper(iname));
 
2646
    Setattr(classnode, "destructor", destructorname);
1956
2647
 
1957
2648
    Wrapper *df = NewWrapper();
1958
 
    Printf(df->def,"/* This function is designed to be called by the zend list destructors */\n");
1959
 
    Printf(df->def,"/* to typecast and do the actual destruction */\n");
1960
 
    Printf(df->def,"void %s(zend_rsrc_list_entry *rsrc, const char *type_name TSRMLS_DC) {\n",destructorname);
 
2649
    Printf(df->def, "/* This function is designed to be called by the zend list destructors */\n");
 
2650
    Printf(df->def, "/* to typecast and do the actual destruction */\n");
 
2651
    Printf(df->def, "static void %s(zend_rsrc_list_entry *rsrc, const char *type_name TSRMLS_DC) {\n", destructorname);
1961
2652
 
1962
2653
    Wrapper_add_localv(df, "value", "swig_object_wrapper *value=(swig_object_wrapper *) rsrc->ptr", NIL);
1963
2654
    Wrapper_add_localv(df, "ptr", "void *ptr=value->ptr", NIL);
1964
2655
    Wrapper_add_localv(df, "newobject", "int newobject=value->newobject", NIL);
1965
2656
 
1966
2657
    emit_args(d, l, df);
1967
 
    emit_attach_parmmaps(l,df);
 
2658
    emit_attach_parmmaps(l, df);
1968
2659
 
1969
2660
    // Get type of first arg, thing to be destructed
1970
2661
    // Skip ignored arguments
1971
 
    Parm *p=l;
 
2662
    Parm *p = l;
1972
2663
    //while (Getattr(p,"tmap:ignore")) {p = Getattr(p,"tmap:ignore:next");}
1973
 
    while (checkAttribute(p,"tmap:in:numinputs","0")) {
1974
 
      p = Getattr(p,"tmap:in:next");
 
2664
    while (checkAttribute(p, "tmap:in:numinputs", "0")) {
 
2665
      p = Getattr(p, "tmap:in:next");
1975
2666
    }
1976
 
    SwigType *pt = Getattr(p,"type");
1977
 
 
1978
 
    Printf(df->code,"  efree(value);\n");
1979
 
    Printf(df->code,"  if (! newobject) return; /* can't delete it! */\n");
1980
 
    Printf(df->code,"  SWIG_ZTS_ConvertResourceData(ptr,rsrc->type,type_name,(void **) &arg1,SWIGTYPE%s TSRMLS_CC);\n",
1981
 
           SwigType_manglestr(pt));
1982
 
    Printf(df->code,"  if (! arg1) zend_error(E_ERROR, \"%s resource already free'd\");\n", Char(name));
1983
 
 
1984
 
    emit_action(n,df);
1985
 
    
1986
 
    Printf(df->code,"}\n");
1987
 
 
1988
 
    Wrapper_print(df,s_wrappers);
 
2667
    SwigType *pt = Getattr(p, "type");
 
2668
 
 
2669
    Printf(df->code, "  efree(value);\n");
 
2670
    Printf(df->code, "  if (! newobject) return; /* can't delete it! */\n");
 
2671
    Printf(df->code, "  arg1 = (%s)SWIG_ZTS_ConvertResourceData(ptr,type_name,SWIGTYPE%s TSRMLS_CC);\n", SwigType_lstr(pt, 0), SwigType_manglestr(pt));
 
2672
    Printf(df->code, "  if (! arg1) zend_error(E_ERROR, \"%s resource already free'd\");\n", Char(name));
 
2673
 
 
2674
    emit_action(n, df);
 
2675
 
 
2676
    Printf(df->code, "}\n");
 
2677
 
 
2678
    Wrapper_print(df, s_wrappers);
1989
2679
 
1990
2680
    return SWIG_OK;
1991
2681
 
1992
2682
  }
1993
 
  
 
2683
 
1994
2684
  /* ------------------------------------------------------------
1995
2685
   * memberconstantHandler()
1996
2686
   * ------------------------------------------------------------ */
1997
2687
 
1998
2688
  virtual int memberconstantHandler(Node *n) {
 
2689
    wrapping_member_constant = Getattr(n, "name");
1999
2690
    Language::memberconstantHandler(n);
 
2691
    wrapping_member_constant = NULL;
2000
2692
    return SWIG_OK;
2001
2693
  }
2002
2694
 
2003
 
};  /* class PHP4 */
 
2695
};                              /* class PHP */
2004
2696
 
2005
2697
/* -----------------------------------------------------------------------------
2006
2698
 * swig_php()    - Instantiate module
2007
2699
 * ----------------------------------------------------------------------------- */
2008
2700
 
2009
 
static PHP4 *maininstance=0;
 
2701
static PHP *maininstance = 0;
2010
2702
 
2011
2703
// We use this function to be able to write out zend_register_list_destructor_ex
2012
2704
// lines for most things in the type table
2013
 
// NOTE: it's a function NOT A PHP4::METHOD
2014
 
extern "C"
2015
 
void typetrace(SwigType *ty, String *mangled, String *clientdata) {
 
2705
// NOTE: it's a function NOT A PHP::METHOD
 
2706
extern "C" void typetrace(SwigType *ty, String *mangled, String *clientdata) {
2016
2707
  Node *class_node;
2017
2708
  if (!zend_types) {
2018
 
    zend_types=NewHash();
 
2709
    zend_types = NewHash();
2019
2710
  }
2020
2711
  // we want to know if the type which reduced to this has a constructor
2021
 
  if ((class_node=maininstance->classLookup(ty))) {
2022
 
    if (! Getattr(zend_types,mangled)) {
 
2712
  if ((class_node = maininstance->classLookup(ty))) {
 
2713
    if (!Getattr(zend_types, mangled)) {
2023
2714
      // OK it may have been set before by a different SwigType but it would
2024
2715
      // have had the same underlying class node I think
2025
2716
      // - it is certainly required not to have different originating class
2026
2717
      // nodes for the same SwigType
2027
 
      Setattr(zend_types,mangled,class_node);
 
2718
      Setattr(zend_types, mangled, class_node);
2028
2719
    }
2029
 
  } else { // a non-class pointer
2030
 
    Setattr(zend_types,mangled,NOTCLASS);
 
2720
  } else {                      // a non-class pointer
 
2721
    Setattr(zend_types, mangled, NOTCLASS);
2031
2722
  }
2032
 
  if (r_prevtracefunc) (*r_prevtracefunc)(ty, mangled, (String *) clientdata);
 
2723
  if (r_prevtracefunc)
 
2724
    (*r_prevtracefunc) (ty, mangled, (String *) clientdata);
2033
2725
}
2034
2726
 
2035
 
static Language * new_swig_php() {
2036
 
  maininstance=new PHP4();
2037
 
  if (! r_prevtracefunc) {
2038
 
    r_prevtracefunc=SwigType_remember_trace(typetrace);
 
2727
static Language *new_swig_php(int php_version) {
 
2728
  maininstance = new PHP(php_version);
 
2729
  if (!r_prevtracefunc) {
 
2730
    r_prevtracefunc = SwigType_remember_trace(typetrace);
2039
2731
  } else {
2040
 
    Printf(stderr,"php4 Typetrace vector already saved!\n");
 
2732
    Printf(stderr, "php Typetrace vector already saved!\n");
2041
2733
    assert(0);
2042
2734
  }
2043
2735
  return maininstance;
2044
2736
}
2045
 
extern "C" Language * swig_php(void) {
2046
 
  return new_swig_php();
2047
 
}
2048
 
 
2049
 
 
 
2737
extern "C" Language *swig_php4(void) {
 
2738
  return new_swig_php(4);
 
2739
}
 
2740
extern "C" Language *swig_php5(void) {
 
2741
  return new_swig_php(5);
 
2742
}