1 /* -----------------------------------------------------------------------------
2 * See the LICENSE file for information on copyright, usage and redistribution
3 * of SWIG, and the README file for authors - http://www.swig.org/release.html.
7 * PHP language module for SWIG.
8 * -----------------------------------------------------------------------------
11 /* FIXME: PHP5 OO wrapping TODO list:
15 * Handle default parameters on overloaded methods in PHP where possible.
16 * (Mostly done - just need to handle cases of overloaded methods with
17 * default parameters...)
18 * This is an optimisation - we could handle this case using a PHP
19 * default value, but currently we treat it as we would for a default
20 * value which is a compound C++ expression (i.e. as if we had a
21 * method with two overloaded forms instead of a single method with
22 * a default parameter value).
26 * Sort out locale-dependent behaviour of strtod() - it's harmless unless
27 * SWIG ever sets the locale and DOH/base.c calls atof, so we're probably
28 * OK currently at least.
32 * TODO: Replace remaining stderr messages with Swig_error or Swig_warning
33 * (may need to add more WARN_PHP_xxx codes...)
36 char cvsroot_php_cxx[] = "$Id: php.cxx 11637 2009-08-18 16:23:23Z vmiklos $";
43 static const char *usage = (char *) "\
44 PHP Options (available with -php)\n\
45 -cppext - cpp file extension (default to .cpp)\n\
46 -noproxy - Don't generate proxy classes.\n\
47 -prefix <prefix> - Prepend <prefix> to all class names in PHP wrappers\n\
50 /* The original class wrappers for PHP stored the pointer to the C++ class in
51 * the object property _cPtr. If we use the same name for the member variable
52 * which we put the pointer to the C++ class in, then the flat function
53 * wrappers will automatically pull it out without any changes being required.
54 * FIXME: Isn't using a leading underscore a bit suspect here?
56 #define SWIG_PTR "_cPtr"
58 /* This is the name of the hash where the variables existing only in PHP
61 #define SWIG_DATA "_pData"
63 static int constructors = 0;
64 static String *NOTCLASS = NewString("Not a class");
65 static Node *classnode = 0;
66 static String *module = 0;
67 static String *cap_module = 0;
68 static String *prefix = 0;
70 static String *shadow_classname = 0;
72 static File *f_begin = 0;
73 static File *f_runtime = 0;
74 static File *f_runtime_h = 0;
76 static File *f_phpcode = 0;
77 static File *f_directors = 0;
78 static File *f_directors_h = 0;
79 static String *phpfilename = 0;
81 static String *s_header;
82 static String *s_wrappers;
83 static String *s_init;
84 static String *r_init; // RINIT user code
85 static String *s_shutdown; // MSHUTDOWN user code
86 static String *r_shutdown; // RSHUTDOWN user code
87 static String *s_vinit; // varinit initialization code.
88 static String *s_vdecl;
89 static String *s_cinit; // consttab initialization code.
90 static String *s_oinit;
91 static String *s_entry;
92 static String *cs_entry;
93 static String *all_cs_entry;
94 static String *pragma_incl;
95 static String *pragma_code;
96 static String *pragma_phpinfo;
97 static String *s_oowrappers;
98 static String *s_fakeoowrappers;
99 static String *s_phpclasses;
101 /* Variables for using PHP classes */
102 static Node *current_class = 0;
104 static Hash *shadow_get_vars;
105 static Hash *shadow_set_vars;
106 static Hash *zend_types = 0;
108 static int shadow = 1;
110 static bool class_has_ctor = false;
111 static String *wrapping_member_constant = NULL;
113 // These static variables are used to pass some state from Handlers into functionWrapper
122 } wrapperType = standard;
125 static void (*r_prevtracefunc) (SwigType *t, String *mangled, String *clientdata) = 0;
128 static void SwigPHP_emit_resource_registrations() {
134 ki = First(zend_types);
136 Printf(s_oinit, "\n/* Register resource destructors for pointer types */\n");
139 Node *class_node = ki.item;
140 String *human_name = key;
142 // Write out destructor function header
143 Printf(s_wrappers, "static ZEND_RSRC_DTOR_FUNC(_wrap_destroy%s) {\n", key);
146 if (class_node != NOTCLASS) {
147 String *destructor = Getattr(class_node, "destructor");
148 human_name = Getattr(class_node, "sym:name");
150 human_name = Getattr(class_node, "name");
151 // Do we have a known destructor for this type?
153 Printf(s_wrappers, " %s(rsrc, SWIGTYPE%s->name TSRMLS_CC);\n", destructor, key);
155 Printf(s_wrappers, " /* No destructor for class %s */\n", human_name);
156 Printf(s_wrappers, " efree(rsrc->ptr);\n");
159 Printf(s_wrappers, " /* No destructor for simple type %s */\n", key);
160 Printf(s_wrappers, " efree(rsrc->ptr);\n");
164 Printf(s_wrappers, "}\n");
166 // declare le_swig_<mangled> to store php registration
167 Printf(s_vdecl, "static int le_swig_%s=0; /* handle for %s */\n", key, human_name);
170 Printf(s_oinit, "le_swig_%s=zend_register_list_destructors_ex"
171 "(_wrap_destroy%s,NULL,(char *)(SWIGTYPE%s->name),module_number);\n", key, key, key);
173 // store php type in class struct
174 Printf(s_oinit, "SWIG_TypeClientData(SWIGTYPE%s,&le_swig_%s);\n", key, key);
180 class PHP : public Language {
183 director_language = 1;
186 /* ------------------------------------------------------------
188 * ------------------------------------------------------------ */
190 virtual void main(int argc, char *argv[]) {
191 SWIG_library_directory("php");
192 SWIG_config_cppext("cpp");
194 for (int i = 1; i < argc; i++) {
195 if (strcmp(argv[i], "-prefix") == 0) {
197 prefix = NewString(argv[i + 1]);
199 Swig_mark_arg(i + 1);
204 } else if (strcmp(argv[i], "-cppext") == 0) {
206 SWIG_config_cppext(argv[i + 1]);
208 Swig_mark_arg(i + 1);
213 } else if ((strcmp(argv[i], "-noshadow") == 0) || (strcmp(argv[i], "-noproxy") == 0)) {
216 } else if (strcmp(argv[i], "-help") == 0) {
217 fputs(usage, stdout);
218 } else if (strcmp(argv[i], "-make") == 0 ||
219 strcmp(argv[i], "-withc") == 0 ||
220 strcmp(argv[i], "-withcxx") == 0) {
221 Printf(stderr, "*** %s is no longer supported.\n", argv[i]);
222 SWIG_exit(EXIT_FAILURE);
223 } else if (strcmp(argv[i], "-phpfull") == 0 ||
224 strcmp(argv[i], "-withlibs") == 0 ||
225 strcmp(argv[i], "-withincs") == 0) {
226 Printf(stderr, "*** %s is no longer supported.\n*** We recommend building as a dynamically loadable module.\n", argv[i]);
227 SWIG_exit(EXIT_FAILURE);
228 } else if (strcmp(argv[i], "-dlname") == 0) {
229 Printf(stderr, "*** -dlname is no longer supported.\n*** If you want to change the module name, use -module instead.\n");
230 SWIG_exit(EXIT_FAILURE);
234 Preprocessor_define("SWIGPHP 1", 0);
235 // SWIGPHP5 is deprecated, and no longer documented.
236 Preprocessor_define("SWIGPHP5 1", 0);
237 SWIG_typemap_lang("php");
238 SWIG_config_file("php.swg");
242 /* ------------------------------------------------------------
244 * ------------------------------------------------------------ */
246 virtual int top(Node *n) {
251 /* Check if directors are enabled for this module. */
252 Node *mod = Getattr(n, "module");
254 Node *options = Getattr(mod, "options");
255 if (options && Getattr(options, "directors")) {
260 /* Set comparison with null for ConstructorToFunction */
261 setSubclassInstanceCheck(NewString("$arg->type != IS_NULL"));
263 /* Initialize all of the output files */
264 String *outfile = Getattr(n, "outfile");
265 String *outfile_h = Getattr(n, "outfile_h");
267 /* main output file */
268 f_begin = NewFile(outfile, "w", SWIG_output_files());
270 FileErrorDisplay(outfile);
271 SWIG_exit(EXIT_FAILURE);
273 f_runtime = NewStringEmpty();
275 /* sections of the output file */
276 s_init = NewString("/* init section */\n");
277 r_init = NewString("/* rinit section */\n");
278 s_shutdown = NewString("/* shutdown section */\n");
279 r_shutdown = NewString("/* rshutdown section */\n");
280 s_header = NewString("/* header section */\n");
281 s_wrappers = NewString("/* wrapper section */\n");
282 s_type = NewStringEmpty();
283 /* subsections of the init section */
284 s_vinit = NewString("/* vinit subsection */\n");
285 s_vdecl = NewString("/* vdecl subsection */\n");
286 s_cinit = NewString("/* cinit subsection */\n");
287 s_oinit = NewString("/* oinit subsection */\n");
288 pragma_phpinfo = NewStringEmpty();
289 s_phpclasses = NewString("/* PHP Proxy Classes */\n");
290 f_directors_h = NewStringEmpty();
291 f_directors = NewStringEmpty();
293 if (directorsEnabled()) {
294 f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
296 FileErrorDisplay(outfile_h);
297 SWIG_exit(EXIT_FAILURE);
301 /* Register file targets with the SWIG file handler */
302 Swig_register_filebyname("begin", f_begin);
303 Swig_register_filebyname("runtime", f_runtime);
304 Swig_register_filebyname("init", s_init);
305 Swig_register_filebyname("rinit", r_init);
306 Swig_register_filebyname("shutdown", s_shutdown);
307 Swig_register_filebyname("rshutdown", r_shutdown);
308 Swig_register_filebyname("header", s_header);
309 Swig_register_filebyname("wrapper", s_wrappers);
310 Swig_register_filebyname("director", f_directors);
311 Swig_register_filebyname("director_h", f_directors_h);
313 Swig_banner(f_begin);
315 Printf(f_runtime, "\n");
316 Printf(f_runtime, "#define SWIGPHP\n");
317 Printf(f_runtime, "\n");
319 if (directorsEnabled()) {
320 Printf(f_runtime, "#define SWIG_DIRECTORS\n");
323 /* Set the module name */
324 module = Copy(Getattr(n, "name"));
325 cap_module = NewStringf("%(upper)s", module);
327 prefix = NewStringEmpty();
329 if (directorsEnabled()) {
330 Swig_banner(f_directors_h);
331 Printf(f_directors_h, "\n");
332 Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", cap_module);
333 Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", cap_module);
335 Printf(f_directors, "\n#include \"%s\"\n\n", Swig_file_filename(outfile_h));
338 /* PHP module file */
339 filen = NewStringEmpty();
340 Printv(filen, SWIG_output_directory(), module, ".php", NIL);
341 phpfilename = NewString(filen);
343 f_phpcode = NewFile(filen, "w", SWIG_output_files());
345 FileErrorDisplay(filen);
346 SWIG_exit(EXIT_FAILURE);
349 Printf(f_phpcode, "<?php\n\n");
351 Swig_banner(f_phpcode);
353 Printf(f_phpcode, "\n");
354 Printf(f_phpcode, "// Try to load our extension if it's not already loaded.\n");
355 Printf(f_phpcode, "if (!extension_loaded('%s')) {\n", module);
356 Printf(f_phpcode, " if (strtolower(substr(PHP_OS, 0, 3)) === 'win') {\n");
357 Printf(f_phpcode, " if (!dl('php_%s.dll')) return;\n", module);
358 Printf(f_phpcode, " } else {\n");
359 Printf(f_phpcode, " // PHP_SHLIB_SUFFIX gives 'dylib' on MacOS X but modules are 'so'.\n");
360 Printf(f_phpcode, " if (PHP_SHLIB_SUFFIX === 'dylib') {\n");
361 Printf(f_phpcode, " if (!dl('%s.so')) return;\n", module);
362 Printf(f_phpcode, " } else {\n");
363 Printf(f_phpcode, " if (!dl('%s.'.PHP_SHLIB_SUFFIX)) return;\n", module);
364 Printf(f_phpcode, " }\n");
365 Printf(f_phpcode, " }\n");
366 Printf(f_phpcode, "}\n\n");
368 /* sub-sections of the php file */
369 pragma_code = NewStringEmpty();
370 pragma_incl = NewStringEmpty();
372 /* Initialize the rest of the module */
374 Printf(s_oinit, "ZEND_INIT_MODULE_GLOBALS(%s, %s_init_globals, %s_destroy_globals);\n", module, module, module);
376 /* start the header section */
377 Printf(s_header, "ZEND_BEGIN_MODULE_GLOBALS(%s)\n", module);
378 Printf(s_header, "const char *error_msg;\n");
379 Printf(s_header, "int error_code;\n");
380 Printf(s_header, "ZEND_END_MODULE_GLOBALS(%s)\n", module);
381 Printf(s_header, "ZEND_DECLARE_MODULE_GLOBALS(%s)\n", module);
382 Printf(s_header, "#ifdef ZTS\n");
383 Printf(s_header, "#define SWIG_ErrorMsg() TSRMG(%s_globals_id, zend_%s_globals *, error_msg )\n", module, module);
384 Printf(s_header, "#define SWIG_ErrorCode() TSRMG(%s_globals_id, zend_%s_globals *, error_code )\n", module, module);
385 Printf(s_header, "#else\n");
386 Printf(s_header, "#define SWIG_ErrorMsg() (%s_globals.error_msg)\n", module);
387 Printf(s_header, "#define SWIG_ErrorCode() (%s_globals.error_code)\n", module);
388 Printf(s_header, "#endif\n\n");
390 Printf(s_header, "static void %s_init_globals(zend_%s_globals *globals ) {\n", module, module);
391 Printf(s_header, " globals->error_msg = default_error_msg;\n");
392 Printf(s_header, " globals->error_code = default_error_code;\n");
393 Printf(s_header, "}\n");
395 Printf(s_header, "static void %s_destroy_globals(zend_%s_globals * globals) { (void)globals; }\n", module, module);
397 Printf(s_header, "\n");
398 Printf(s_header, "static void SWIG_ResetError() {\n");
399 Printf(s_header, " TSRMLS_FETCH();\n");
400 Printf(s_header, " SWIG_ErrorMsg() = default_error_msg;\n");
401 Printf(s_header, " SWIG_ErrorCode() = default_error_code;\n");
402 Printf(s_header, "}\n");
404 Append(s_header, "\n");
405 Printf(s_header, "ZEND_NAMED_FUNCTION(_wrap_swig_%s_alter_newobject) {\n", module);
406 Append(s_header, " zval **args[2];\n");
407 Append(s_header, " swig_object_wrapper *value;\n");
408 Append(s_header, " int type;\n");
409 Append(s_header, " int thisown;\n");
410 Append(s_header, "\n");
411 Append(s_header, " SWIG_ResetError();\n");
412 Append(s_header, " if(ZEND_NUM_ARGS() != 2 || zend_get_parameters_array_ex(2, args) != SUCCESS) {\n");
413 Append(s_header, " WRONG_PARAM_COUNT;\n");
414 Append(s_header, " }\n");
415 Append(s_header, "\n");
416 Append(s_header, " value = (swig_object_wrapper *) zend_list_find((*args[0])->value.lval, &type);\n");
417 Append(s_header, " value->newobject = zval_is_true(*args[1]);\n");
418 Append(s_header, "\n");
419 Append(s_header, " return;\n");
420 Append(s_header, "}\n");
421 Printf(s_header, "ZEND_NAMED_FUNCTION(_wrap_swig_%s_get_newobject) {\n", module);
422 Append(s_header, " zval **args[1];\n");
423 Append(s_header, " swig_object_wrapper *value;\n");
424 Append(s_header, " int type;\n");
425 Append(s_header, "\n");
426 Append(s_header, " SWIG_ResetError();\n");
427 Append(s_header, " if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_array_ex(1, args) != SUCCESS) {\n");
428 Append(s_header, " WRONG_PARAM_COUNT;\n");
429 Append(s_header, " }\n");
430 Append(s_header, "\n");
431 Append(s_header, " value = (swig_object_wrapper *) zend_list_find((*args[0])->value.lval, &type);\n");
432 Append(s_header, " RETVAL_LONG(value->newobject);\n");
433 Append(s_header, "\n");
434 Append(s_header, " return;\n");
435 Append(s_header, "}\n");
437 Printf(s_header, "#define SWIG_name \"%s\"\n", module);
438 /* Printf(s_header,"#ifdef HAVE_CONFIG_H\n");
439 Printf(s_header,"#include \"config.h\"\n");
440 Printf(s_header,"#endif\n\n");
442 Printf(s_header, "#ifdef __cplusplus\n");
443 Printf(s_header, "extern \"C\" {\n");
444 Printf(s_header, "#endif\n");
445 Printf(s_header, "#include \"php.h\"\n");
446 Printf(s_header, "#include \"php_ini.h\"\n");
447 Printf(s_header, "#include \"ext/standard/info.h\"\n");
448 Printf(s_header, "#include \"php_%s.h\"\n", module);
449 Printf(s_header, "#ifdef __cplusplus\n");
450 Printf(s_header, "}\n");
451 Printf(s_header, "#endif\n\n");
453 if (directorsEnabled()) {
454 // Insert director runtime
455 Swig_insert_file("director.swg", s_header);
458 /* Create the .h file too */
459 filen = NewStringEmpty();
460 Printv(filen, SWIG_output_directory(), "php_", module, ".h", NIL);
461 f_h = NewFile(filen, "w", SWIG_output_files());
463 FileErrorDisplay(filen);
464 SWIG_exit(EXIT_FAILURE);
470 Printf(f_h, "#ifndef PHP_%s_H\n", cap_module);
471 Printf(f_h, "#define PHP_%s_H\n\n", cap_module);
472 Printf(f_h, "extern zend_module_entry %s_module_entry;\n", module);
473 Printf(f_h, "#define phpext_%s_ptr &%s_module_entry\n\n", module, module);
474 Printf(f_h, "#ifdef PHP_WIN32\n");
475 Printf(f_h, "# define PHP_%s_API __declspec(dllexport)\n", cap_module);
476 Printf(f_h, "#else\n");
477 Printf(f_h, "# define PHP_%s_API\n", cap_module);
478 Printf(f_h, "#endif\n\n");
479 Printf(f_h, "#ifdef ZTS\n");
480 Printf(f_h, "#include \"TSRM.h\"\n");
481 Printf(f_h, "#endif\n\n");
482 Printf(f_h, "PHP_MINIT_FUNCTION(%s);\n", module);
483 Printf(f_h, "PHP_MSHUTDOWN_FUNCTION(%s);\n", module);
484 Printf(f_h, "PHP_RINIT_FUNCTION(%s);\n", module);
485 Printf(f_h, "PHP_RSHUTDOWN_FUNCTION(%s);\n", module);
486 Printf(f_h, "PHP_MINFO_FUNCTION(%s);\n\n", module);
488 /* start the function entry section */
489 s_entry = NewString("/* entry subsection */\n");
491 /* holds all the per-class function entry sections */
492 all_cs_entry = NewString("/* class entry subsection */\n");
495 Printf(s_entry, "/* Every non-class user visible function must have an entry here */\n");
496 Printf(s_entry, "static zend_function_entry %s_functions[] = {\n", module);
498 /* start the init section */
499 Append(s_init, "#if ZEND_MODULE_API_NO <= 20090626\n");
500 Append(s_init, "#undef ZEND_MODULE_BUILD_ID\n");
501 Append(s_init, "#define ZEND_MODULE_BUILD_ID (char*)\"API\" ZEND_TOSTR(ZEND_MODULE_API_NO) ZEND_BUILD_TS ZEND_BUILD_DEBUG ZEND_BUILD_SYSTEM ZEND_BUILD_EXTRA\n");
502 Append(s_init, "#endif\n");
503 Printv(s_init, "zend_module_entry ", module, "_module_entry = {\n" "#if ZEND_MODULE_API_NO > 20010900\n" " STANDARD_MODULE_HEADER,\n" "#endif\n", NIL);
504 Printf(s_init, " (char*)\"%s\",\n", module);
505 Printf(s_init, " %s_functions,\n", module);
506 Printf(s_init, " PHP_MINIT(%s),\n", module);
507 Printf(s_init, " PHP_MSHUTDOWN(%s),\n", module);
508 Printf(s_init, " PHP_RINIT(%s),\n", module);
509 Printf(s_init, " PHP_RSHUTDOWN(%s),\n", module);
510 Printf(s_init, " PHP_MINFO(%s),\n", module);
511 Printf(s_init, "#if ZEND_MODULE_API_NO > 20010900\n");
512 Printf(s_init, " NO_VERSION_YET,\n");
513 Printf(s_init, "#endif\n");
514 Printf(s_init, " STANDARD_MODULE_PROPERTIES\n");
515 Printf(s_init, "};\n");
516 Printf(s_init, "zend_module_entry* SWIG_module_entry = &%s_module_entry;\n\n", module);
518 Printf(s_init, "#ifdef __cplusplus\n");
519 Printf(s_init, "extern \"C\" {\n");
520 Printf(s_init, "#endif\n");
521 // We want to write "SWIGEXPORT ZEND_GET_MODULE(%s)" but ZEND_GET_MODULE
522 // in PHP5 has "extern "C" { ... }" around it so we can't do that.
523 Printf(s_init, "SWIGEXPORT zend_module_entry *get_module(void) { return &%s_module_entry; }\n", module);
524 Printf(s_init, "#ifdef __cplusplus\n");
525 Printf(s_init, "}\n");
526 Printf(s_init, "#endif\n\n");
528 /* We have to register the constants before they are (possibly) used
529 * by the pointer typemaps. This all needs re-arranging really as
530 * things are being called in the wrong order
532 Printf(s_init, "#define SWIG_php_minit PHP_MINIT_FUNCTION(%s)\n", module);
534 /* Emit all of the code */
537 SwigPHP_emit_resource_registrations();
538 // Printv(s_init,s_resourcetypes,NIL);
539 /* We need this after all classes written out by ::top */
540 Printf(s_oinit, "CG(active_class_entry) = NULL;\n");
541 Printf(s_oinit, "/* end oinit subsection */\n");
542 Printf(s_init, "%s\n", s_oinit);
544 /* Constants generated during top call */
545 Printf(s_cinit, "/* end cinit subsection */\n");
546 Printf(s_init, "%s\n", s_cinit);
550 Printf(s_init, " return SUCCESS;\n");
551 Printf(s_init, "}\n\n");
553 // Now do REQUEST init which holds any user specified %rinit, and also vinit
554 Printf(s_init, "PHP_RINIT_FUNCTION(%s)\n{\n", module);
555 Printf(s_init, "%s\n", r_init);
557 /* finish our init section which will have been used by class wrappers */
558 Printf(s_vinit, "/* end vinit subsection */\n");
559 Printf(s_init, "%s\n", s_vinit);
563 Printf(s_init, " return SUCCESS;\n");
564 Printf(s_init, "}\n\n");
566 Printv(s_init, "PHP_MSHUTDOWN_FUNCTION(", module, ")\n"
570 " ts_free_id(", module, "_globals_id);\n"
575 Printf(s_init, "PHP_RSHUTDOWN_FUNCTION(%s)\n{\n", module);
576 Printf(s_init, "%s\n", r_shutdown);
577 Printf(s_init, " return SUCCESS;\n");
578 Printf(s_init, "}\n\n");
580 Printf(s_init, "PHP_MINFO_FUNCTION(%s)\n{\n", module);
581 Printf(s_init, "%s", pragma_phpinfo);
582 Printf(s_init, "}\n");
583 Printf(s_init, "/* end init section */\n");
585 Printf(f_h, "#endif /* PHP_%s_H */\n", cap_module);
589 String *type_table = NewStringEmpty();
590 SwigType_emit_type_table(f_runtime, type_table);
591 Printf(s_header, "%s", type_table);
594 /* Oh dear, more things being called in the wrong order. This whole
595 * function really needs totally redoing.
598 if (directorsEnabled()) {
599 Dump(f_directors_h, f_runtime_h);
600 Printf(f_runtime_h, "\n");
601 Printf(f_runtime_h, "#endif\n");
605 Printf(s_header, "/* end header section */\n");
606 Printf(s_wrappers, "/* end wrapper section */\n");
607 Printf(s_vdecl, "/* end vdecl subsection */\n");
609 Dump(f_runtime, f_begin);
610 Printv(f_begin, s_header, NIL);
611 if (directorsEnabled()) {
612 Dump(f_directors, f_begin);
614 Printv(f_begin, s_vdecl, s_wrappers, NIL);
615 Printv(f_begin, all_cs_entry, "\n\n", s_entry,
616 " SWIG_ZEND_NAMED_FE(swig_", module, "_alter_newobject,_wrap_swig_", module, "_alter_newobject,NULL)\n"
617 " SWIG_ZEND_NAMED_FE(swig_", module, "_get_newobject,_wrap_swig_", module, "_get_newobject,NULL)\n"
618 "{NULL, NULL, NULL}\n};\n\n", NIL);
619 Printv(f_begin, s_init, NIL);
624 Delete(all_cs_entry);
630 Printf(f_phpcode, "%s\n%s\n", pragma_incl, pragma_code);
631 if (s_fakeoowrappers) {
632 Printf(f_phpcode, "abstract class %s {", Len(prefix) ? prefix : module);
633 Printf(f_phpcode, "%s", s_fakeoowrappers);
634 Printf(f_phpcode, "}\n\n");
635 Delete(s_fakeoowrappers);
636 s_fakeoowrappers = NULL;
638 Printf(f_phpcode, "%s\n?>\n", s_phpclasses);
644 /* Just need to append function names to function table to register with PHP. */
645 void create_command(String *cname, String *iname) {
646 // This is for the single main zend_function_entry record
647 Printf(f_h, "ZEND_NAMED_FUNCTION(%s);\n", iname);
648 String * s = cs_entry;
650 Printf(s, " SWIG_ZEND_NAMED_FE(%(lower)s,%s,NULL)\n", cname, iname);
653 /* ------------------------------------------------------------
655 * ------------------------------------------------------------ */
656 void dispatchFunction(Node *n) {
657 /* Last node in overloaded chain */
660 String *tmp = NewStringEmpty();
661 if (Swig_directorclass(n) && wrapperType == directorconstructor) {
662 /* We have an extra 'this' parameter. */
663 SetFlag(n, "wrap:this");
665 String *dispatch = Swig_overload_dispatch(n, "return %s(INTERNAL_FUNCTION_PARAM_PASSTHRU);", &maxargs);
667 /* Generate a dispatch wrapper for all overloaded functions */
669 Wrapper *f = NewWrapper();
670 String *symname = Getattr(n, "sym:name");
671 String *wname = Swig_name_wrapper(symname);
673 create_command(symname, wname);
674 Printv(f->def, "ZEND_NAMED_FUNCTION(", wname, ") {\n", NIL);
676 Wrapper_add_local(f, "argc", "int argc");
678 Printf(tmp, "zval **argv[%d]", maxargs);
679 Wrapper_add_local(f, "argv", tmp);
681 Printf(f->code, "argc = ZEND_NUM_ARGS();\n");
683 Printf(f->code, "zend_get_parameters_array_ex(argc,argv);\n");
685 Replaceall(dispatch, "$args", "self,args");
687 Printv(f->code, dispatch, "\n", NIL);
689 Printf(f->code, "SWIG_ErrorCode() = E_ERROR;\n");
690 Printf(f->code, "SWIG_ErrorMsg() = \"No matching function for overloaded '%s'\";\n", symname);
691 Printv(f->code, "zend_error(SWIG_ErrorCode(),\"%s\",SWIG_ErrorMsg());\n", NIL);
693 Printv(f->code, "}\n", NIL);
694 Wrapper_print(f, s_wrappers);
702 /* ------------------------------------------------------------
704 * ------------------------------------------------------------ */
706 /* Helper method for PHP::functionWrapper */
707 bool is_class(SwigType *t) {
708 Node *n = classLookup(t);
710 String *r = Getattr(n, "php:proxy"); // Set by classDeclaration()
712 r = Getattr(n, "sym:name"); // Not seen by classDeclaration yet, but this is the name
719 virtual int functionWrapper(Node *n) {
720 String *name = GetChar(n, "name");
721 String *iname = GetChar(n, "sym:name");
722 SwigType *d = Getattr(n, "type");
723 ParmList *l = Getattr(n, "parms");
724 String *nodeType = Getattr(n, "nodeType");
725 int newobject = GetFlag(n, "feature:new");
726 int constructor = (Cmp(nodeType, "constructor") == 0);
736 String *overname = 0;
738 if (Cmp(nodeType, "destructor") == 0) {
739 // We just generate the Zend List Destructor and let Zend manage the
740 // reference counting. There's no explicit destructor, but the user can
741 // just do `$obj = null;' to remove a reference to an object.
742 return CreateZendListDestructor(n);
744 // Test for overloading;
745 if (Getattr(n, "sym:overloaded")) {
747 overname = Getattr(n, "sym:overname");
749 if (!addSymbol(iname, n))
753 wname = Swig_name_wrapper(iname);
755 Printf(wname, "%s", overname);
761 String *outarg = NewStringEmpty();
762 String *cleanup = NewStringEmpty();
764 // Not issued for overloaded functions.
766 create_command(iname, wname);
768 Printv(f->def, "ZEND_NAMED_FUNCTION(", wname, ") {\n", NIL);
770 emit_parameter_variables(l, f);
771 /* Attach standard typemaps */
773 emit_attach_parmmaps(l, f);
775 // wrap:parms is used by overload resolution.
776 Setattr(n, "wrap:parms", l);
778 int num_arguments = emit_num_arguments(l);
779 int num_required = emit_num_required(l);
780 numopt = num_arguments - num_required;
782 if (wrapperType == directorconstructor)
785 if (num_arguments > 0) {
786 String *args = NewStringEmpty();
787 if (wrapperType == directorconstructor)
788 Wrapper_add_local(f, "arg0", "zval *arg0");
789 Printf(args, "zval **args[%d]", num_arguments);
790 Wrapper_add_local(f, "args", args);
794 if (is_member_director(n)) {
795 Wrapper_add_local(f, "director", "Swig::Director *director = 0");
796 Printf(f->code, "director = dynamic_cast<Swig::Director*>(arg1);\n");
797 Wrapper_add_local(f, "upcall", "bool upcall = false");
798 Printf(f->code, "upcall = !director->is_overriden_method((char *)\"%s\", (char *)\"%s\");\n",
799 Swig_class_name(Swig_methodclass(n)), name);
802 // This generated code may be called:
803 // 1) as an object method, or
804 // 2) as a class-method/function (without a "this_ptr")
805 // Option (1) has "this_ptr" for "this", option (2) needs it as
808 // NOTE: possible we ignore this_ptr as a param for native constructor
810 Printf(f->code, "SWIG_ResetError();\n");
812 if (numopt > 0) { // membervariable wrappers do not have optional args
813 Wrapper_add_local(f, "arg_count", "int arg_count");
814 Printf(f->code, "arg_count = ZEND_NUM_ARGS();\n");
815 Printf(f->code, "if(arg_count<%d || arg_count>%d ||\n", num_required, num_arguments);
816 Printf(f->code, " zend_get_parameters_array_ex(arg_count,args)!=SUCCESS)\n");
817 Printf(f->code, "\tWRONG_PARAM_COUNT;\n\n");
819 if (num_arguments == 0) {
820 Printf(f->code, "if(ZEND_NUM_ARGS() != 0) {\n");
822 Printf(f->code, "if(ZEND_NUM_ARGS() != %d || zend_get_parameters_array_ex(%d, args) != SUCCESS) {\n", num_arguments, num_arguments);
824 Printf(f->code, "WRONG_PARAM_COUNT;\n}\n\n");
826 if (wrapperType == directorconstructor)
827 Printf(f->code, "arg0 = *args[0];\n \n");
829 /* Now convert from PHP to C variables */
830 // At this point, argcount if used is the number of deliberately passed args
831 // not including this_ptr even if it is used.
832 // It means error messages may be out by argbase with error
833 // reports. We can either take argbase into account when raising
834 // errors, or find a better way of dealing with _thisptr.
835 // I would like, if objects are wrapped, to assume _thisptr is always
836 // _this and not the first argument.
837 // This may mean looking at Language::memberfunctionHandler
839 int limit = num_arguments;
840 if (wrapperType == directorconstructor)
842 for (i = 0, p = l; i < limit; i++) {
845 /* Skip ignored arguments */
846 //while (Getattr(p,"tmap:ignore")) { p = Getattr(p,"tmap:ignore:next");}
847 while (checkAttribute(p, "tmap:in:numinputs", "0")) {
848 p = Getattr(p, "tmap:in:next");
851 SwigType *pt = Getattr(p, "type");
853 if (wrapperType == directorconstructor) {
854 source = NewStringf("args[%d]", i+1);
856 source = NewStringf("args[%d]", i);
859 String *ln = Getattr(p, "lname");
861 /* Check if optional */
862 if (i >= num_required) {
863 Printf(f->code, "\tif(arg_count > %d) {\n", i);
866 if ((tm = Getattr(p, "tmap:in"))) {
867 Replaceall(tm, "$source", source);
868 Replaceall(tm, "$target", ln);
869 Replaceall(tm, "$input", source);
870 Setattr(p, "emit:input", source);
871 Printf(f->code, "%s\n", tm);
872 if (i == 0 && Getattr(p, "self")) {
873 Printf(f->code, "\tif(!arg1) SWIG_PHP_Error(E_ERROR, \"this pointer is NULL\");\n");
875 p = Getattr(p, "tmap:in:next");
876 if (i >= num_required) {
877 Printf(f->code, "}\n");
881 Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
883 if (i >= num_required) {
884 Printf(f->code, "\t}\n");
889 Swig_director_emit_dynamic_cast(n, f);
891 /* Insert constraint checking code */
893 if ((tm = Getattr(p, "tmap:check"))) {
894 Replaceall(tm, "$target", Getattr(p, "lname"));
895 Printv(f->code, tm, "\n", NIL);
896 p = Getattr(p, "tmap:check:next");
902 /* Insert cleanup code */
903 for (i = 0, p = l; p; i++) {
904 if ((tm = Getattr(p, "tmap:freearg"))) {
905 Replaceall(tm, "$source", Getattr(p, "lname"));
906 Printv(cleanup, tm, "\n", NIL);
907 p = Getattr(p, "tmap:freearg:next");
913 /* Insert argument output code */
914 for (i = 0, p = l; p; i++) {
915 if ((tm = Getattr(p, "tmap:argout"))) {
916 Replaceall(tm, "$source", Getattr(p, "lname"));
917 // Replaceall(tm,"$input",Getattr(p,"lname"));
918 Replaceall(tm, "$target", "return_value");
919 Replaceall(tm, "$result", "return_value");
920 Replaceall(tm, "$arg", Getattr(p, "emit:input"));
921 Replaceall(tm, "$input", Getattr(p, "emit:input"));
922 Printv(outarg, tm, "\n", NIL);
923 p = Getattr(p, "tmap:argout:next");
929 Setattr(n, "wrap:name", wname);
931 /* emit function call */
932 String *actioncode = emit_action(n);
934 if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
935 Replaceall(tm, "$input", "result");
936 Replaceall(tm, "$source", "result");
937 Replaceall(tm, "$target", "return_value");
938 Replaceall(tm, "$result", "return_value");
939 Replaceall(tm, "$owner", newobject ? "1" : "0");
940 Printf(f->code, "%s\n", tm);
942 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);
944 emit_return_variable(n, d, f);
947 Printv(f->code, outarg, NIL);
951 Printv(f->code, cleanup, NIL);
954 /* Look to see if there is any newfree cleanup code */
955 if (GetFlag(n, "feature:new")) {
956 if ((tm = Swig_typemap_lookup("newfree", n, "result", 0))) {
957 Printf(f->code, "%s\n", tm);
962 /* See if there is any return cleanup code */
963 if ((tm = Swig_typemap_lookup("ret", n, "result", 0))) {
964 Printf(f->code, "%s\n", tm);
968 Printf(f->code, "return;\n");
970 /* Error handling code */
971 Printf(f->code, "fail:\n");
972 Printv(f->code, cleanup, NIL);
973 Printv(f->code, "zend_error_noreturn(SWIG_ErrorCode(),\"%s\",SWIG_ErrorMsg());", NIL);
975 Printf(f->code, "}\n");
977 Replaceall(f->code, "$cleanup", cleanup);
978 Replaceall(f->code, "$symname", iname);
980 Wrapper_print(f, s_wrappers);
984 if (overloaded && !Getattr(n, "sym:nextSibling")) {
995 // Handle getters and setters.
996 if (wrapperType == membervar) {
997 const char *p = Char(iname);
1000 String *varname = Getattr(n, "membervariableHandler:sym:name");
1001 if (strcmp(p, "_get") == 0) {
1002 Setattr(shadow_get_vars, varname, iname);
1003 } else if (strcmp(p, "_set") == 0) {
1004 Setattr(shadow_set_vars, varname, iname);
1010 // Only look at non-overloaded methods and the last entry in each overload
1011 // chain (we check the last so that wrap:parms and wrap:name have been set
1013 if (overloaded && Getattr(n, "sym:nextSibling") != 0)
1017 s_oowrappers = NewStringEmpty();
1019 if (newobject || wrapperType == memberfn || wrapperType == staticmemberfn || wrapperType == standard || wrapperType == staticmembervar) {
1020 bool handle_as_overload = false;
1022 String **arg_values;
1023 // Method or static method or plain function.
1024 const char *methodname = 0;
1025 String *output = s_oowrappers;
1027 class_has_ctor = true;
1028 // Skip the Foo:: prefix.
1029 char *ptr = strrchr(GetChar(Swig_methodclass(n), "sym:name"), ':');
1033 ptr = GetChar(Swig_methodclass(n), "sym:name");
1035 if (strcmp(ptr, GetChar(n, "constructorHandler:sym:name")) == 0) {
1036 methodname = "__construct";
1038 // The class has multiple constructors and this one is
1039 // renamed, so this will be a static factory function
1040 methodname = GetChar(n, "constructorHandler:sym:name");
1042 } else if (wrapperType == memberfn) {
1043 methodname = Char(Getattr(n, "memberfunctionHandler:sym:name"));
1044 } else if (wrapperType == staticmemberfn) {
1045 methodname = Char(Getattr(n, "staticmemberfunctionHandler:sym:name"));
1046 } else if (wrapperType == staticmembervar) {
1047 // Static member variable, wrapped as a function due to PHP limitations.
1048 methodname = Char(Getattr(n, "staticmembervariableHandler:sym:name"));
1049 } else { // wrapperType == standard
1050 methodname = Char(iname);
1051 if (!s_fakeoowrappers)
1052 s_fakeoowrappers = NewStringEmpty();
1053 output = s_fakeoowrappers;
1056 bool really_overloaded = overloaded ? true : false;
1057 int min_num_of_arguments = emit_num_required(l);
1058 int max_num_of_arguments = emit_num_arguments(l);
1060 // For a function with default arguments, we end up with the fullest
1061 // parmlist in full_parmlist.
1062 ParmList *full_parmlist = l;
1063 Hash *ret_types = NewHash();
1064 Setattr(ret_types, d, d);
1067 // Look at all the overloaded versions of this method in turn to
1068 // decide if it's really an overloaded method, or just one where some
1069 // parameters have default values.
1070 Node *o = Getattr(n, "sym:overloaded");
1073 o = Getattr(o, "sym:nextSibling");
1077 SwigType *d2 = Getattr(o, "type");
1079 assert(constructor);
1080 } else if (!Getattr(ret_types, d2)) {
1081 Setattr(ret_types, d2, d2);
1084 ParmList *l2 = Getattr(o, "wrap:parms");
1085 int num_arguments = emit_num_arguments(l2);
1086 int num_required = emit_num_required(l2);
1087 if (num_required < min_num_of_arguments)
1088 min_num_of_arguments = num_required;
1090 if (num_arguments > max_num_of_arguments) {
1091 max_num_of_arguments = num_arguments;
1094 o = Getattr(o, "sym:nextSibling");
1097 o = Getattr(n, "sym:overloaded");
1100 o = Getattr(o, "sym:nextSibling");
1104 ParmList *l2 = Getattr(o, "wrap:parms");
1105 Parm *p = l, *p2 = l2;
1106 if (wrapperType == memberfn) {
1108 p2 = nextSibling(p2);
1111 if (Cmp(Getattr(p, "type"), Getattr(p2, "type")) != 0)
1113 if (Cmp(Getattr(p, "name"), Getattr(p2, "name")) != 0)
1115 String *value = Getattr(p, "value");
1116 String *value2 = Getattr(p2, "value");
1117 if (value && !value2)
1119 if (!value && value2)
1122 if (Cmp(value, value2) != 0)
1126 p2 = nextSibling(p2);
1130 // One parameter list is a prefix of the other, so check that all
1131 // remaining parameters of the longer list are optional.
1134 while (p && Getattr(p, "value"))
1138 o = Getattr(o, "sym:nextSibling");
1141 // This "overloaded method" is really just one with default args.
1142 really_overloaded = false;
1143 if (l != full_parmlist) {
1145 if (wrapperType == memberfn)
1151 if (wrapperType == memberfn) {
1152 // Allow for the "this" pointer.
1153 --min_num_of_arguments;
1154 --max_num_of_arguments;
1157 arg_names = (String **) malloc(max_num_of_arguments * sizeof(String *));
1159 /* FIXME: How should this be handled? The rest of SWIG just seems
1160 * to not bother checking for malloc failing! */
1161 fprintf(stderr, "Malloc failed!\n");
1164 for (i = 0; i < max_num_of_arguments; ++i) {
1165 arg_names[i] = NULL;
1168 arg_values = (String **) malloc(max_num_of_arguments * sizeof(String *));
1170 /* FIXME: How should this be handled? The rest of SWIG just seems
1171 * to not bother checking for malloc failing! */
1172 fprintf(stderr, "Malloc failed!\n");
1175 for (i = 0; i < max_num_of_arguments; ++i) {
1176 arg_values[i] = NULL;
1181 o = Getattr(n, "sym:overloaded");
1187 Parm *p = Getattr(o, "wrap:parms");
1188 if (wrapperType == memberfn)
1191 if (GetInt(p, "tmap:in:numinputs") == 0) {
1195 assert(0 <= argno && argno < max_num_of_arguments);
1196 String *&pname = arg_names[argno];
1197 const char *pname_cstr = GetChar(p, "name");
1198 // Just get rid of the C++ namespace part for now.
1199 const char *ptr = NULL;
1200 if (pname_cstr && (ptr = strrchr(pname_cstr, ':'))) {
1201 pname_cstr = ptr + 1;
1204 // Unnamed parameter, e.g. int foo(int);
1205 } else if (pname == NULL) {
1206 pname = NewString(pname_cstr);
1208 size_t len = strlen(pname_cstr);
1210 size_t len_pname = strlen(Char(pname));
1211 while (spc + len <= len_pname) {
1212 if (strncmp(pname_cstr, Char(pname) + spc, len) == 0) {
1213 char ch = ((char *) Char(pname))[spc + len];
1214 if (ch == '\0' || ch == ' ') {
1215 // Already have this pname_cstr.
1220 char *p = strchr(Char(pname) + spc, ' ');
1223 spc = (p + 4) - Char(pname);
1226 Printf(pname, " or_%s", pname_cstr);
1229 String *value = NewString(Getattr(p, "value"));
1231 /* Check that value is a valid constant in PHP (and adjust it if
1232 * necessary, or replace it with "?" if it's just not valid). */
1233 SwigType *type = Getattr(p, "type");
1234 switch (SwigType_type(type)) {
1236 if (Strcmp(value, "true") == 0 || Strcmp(value, "false") == 0)
1240 int n = strtol(Char(value), &p, 0);
1245 Append(value, "true");
1247 Append(value, "false");
1258 unsigned int n = strtol(Char(value), &p, 0);
1272 unsigned int n = strtoul(Char(value), &p, 0);
1284 /* FIXME: strtod is locale dependent... */
1285 double val = strtod(Char(value), &p);
1289 } else if (strchr(Char(value), '.') == NULL) {
1290 // Ensure value is a double constant, not an integer one.
1291 Append(value, ".0");
1292 double val2 = strtod(Char(value), &p);
1293 if (errno || *p || val != val2) {
1307 if (Len(value) < 2) {
1308 // How can a string (including "" be less than 2 characters?)
1312 const char *v = Char(value);
1313 if (v[0] != '"' || v[Len(value) - 1] != '"') {
1317 // Strings containing "$" require special handling, but we do
1325 const char *v = Char(value);
1327 // Handle "(void*)0", "(TYPE*)0", "(char*)NULL", etc.
1328 v += strcspn(v + 1, "*()") + 1;
1332 v += strspn(v, " \t");
1333 } while (*v == '*');
1335 v += strspn(v, " \t");
1336 String * old = value;
1337 value = NewString(v);
1342 if (Strcmp(value, "NULL") == 0 ||
1343 Strcmp(value, "0") == 0 ||
1344 Strcmp(value, "0L") == 0) {
1346 Append(value, "null");
1355 if (!arg_values[argno]) {
1356 arg_values[argno] = value;
1358 } else if (Cmp(arg_values[argno], value) != 0) {
1359 // If a parameter has two different default values in
1360 // different overloaded forms of the function, we can't
1361 // set its default in PHP. Flag this by setting its
1363 Delete(arg_values[argno]);
1364 arg_values[argno] = NewString("?");
1366 } else if (arg_values[argno]) {
1367 // This argument already has a default value in another overloaded
1368 // form, but doesn't in this form. So don't try to do anything
1369 // clever, just let the C wrappers resolve the overload and set the
1372 // This handling is safe, but I'm wondering if it may be overly
1373 // conservative (FIXME) in some cases. It seems it's only bad when
1374 // there's an overloaded form with the appropriate number of
1375 // parameters which doesn't want the default value, but I need to
1376 // think about this more.
1377 Delete(arg_values[argno]);
1378 arg_values[argno] = NewString("?");
1384 if (!really_overloaded)
1386 o = Getattr(o, "sym:nextSibling");
1389 /* Clean up any parameters which haven't yet got names, or whose
1391 Hash *seen = NewHash();
1392 /* We need $this to refer to the current class, so can't allow it
1393 * to be used as a parameter. */
1394 Setattr(seen, "this", seen);
1395 /* We use $r to store the return value, so disallow that as a parameter
1396 * name in case the user uses the "call-time pass-by-reference" feature
1397 * (it's deprecated and off by default in PHP5, but we want to be
1398 * maximally portable). Similarly we use $c for the classname or new
1401 Setattr(seen, "r", seen);
1402 Setattr(seen, "c", seen);
1404 for (int argno = 0; argno < max_num_of_arguments; ++argno) {
1405 String *&pname = arg_names[argno];
1407 Replaceall(pname, " ", "_");
1409 /* We get here if the SWIG .i file has "int foo(int);" */
1410 pname = NewStringEmpty();
1411 Printf(pname, "arg%d", argno + 1);
1413 // Check if we've already used this parameter name.
1414 while (Getattr(seen, pname)) {
1415 // Append "_" to clashing names until they stop clashing...
1418 Setattr(seen, Char(pname), seen);
1420 if (arg_values[argno] && Cmp(arg_values[argno], "?") == 0) {
1421 handle_as_overload = true;
1427 String *invoke = NewStringEmpty();
1428 String *prepare = NewStringEmpty();
1429 String *args = NewStringEmpty();
1431 if (!handle_as_overload && !(really_overloaded && max_num_of_arguments > min_num_of_arguments)) {
1432 Printf(invoke, "%s(", iname);
1433 if (wrapperType == memberfn) {
1434 Printf(invoke, "$this->%s", SWIG_PTR);
1436 for (int i = 0; i < max_num_of_arguments; ++i) {
1439 if (i || wrapperType == memberfn)
1440 Printf(invoke, ",");
1441 String *value = arg_values[i];
1443 const char *v = Char(value);
1445 /* In a PHP double quoted string, $ needs to be escaped as \$. */
1446 Replaceall(value, "$", "\\$");
1448 Printf(args, "$%s=%s", arg_names[i], value);
1450 Printf(args, "$%s", arg_names[i]);
1452 Printf(invoke, "$%s", arg_names[i]);
1454 Printf(invoke, ")");
1457 for (i = 0; i < min_num_of_arguments; ++i) {
1460 Printf(args, "$%s", arg_names[i]);
1462 String *invoke_args = NewStringEmpty();
1463 if (wrapperType == memberfn) {
1464 Printf(invoke_args, "$this->%s", SWIG_PTR);
1465 if (min_num_of_arguments > 0)
1466 Printf(invoke_args, ",");
1468 Printf(invoke_args, "%s", args);
1469 bool had_a_case = false;
1470 int last_handled_i = i - 1;
1471 for (; i < max_num_of_arguments; ++i) {
1474 const char *value = Char(arg_values[i]);
1475 // FIXME: (really_overloaded && handle_as_overload) is perhaps a
1476 // little conservative, but it doesn't hit any cases that it
1477 // shouldn't for Xapian at least (and we need it to handle
1478 // "Enquire::get_mset()" correctly).
1479 bool non_php_default = ((really_overloaded && handle_as_overload) ||
1480 !value || strcmp(value, "?") == 0);
1481 if (non_php_default)
1483 Printf(args, "$%s=%s", arg_names[i], value);
1484 if (non_php_default) {
1486 Printf(prepare, "\t\tswitch (func_num_args()) {\n");
1489 Printf(prepare, "\t\t");
1490 while (last_handled_i < i) {
1491 Printf(prepare, "case %d: ", ++last_handled_i);
1493 if (Cmp(d, "void") != 0) {
1494 if ((!directorsEnabled() || !Swig_directorclass(n)) && !newobject) {
1495 Append(prepare, "$r=");
1497 Printf(prepare, "$this->%s=", SWIG_PTR);
1500 if (!directorsEnabled() || !Swig_directorclass(n) || !newobject) {
1501 Printf(prepare, "%s(%s); break;\n", iname, invoke_args);
1503 Printf(prepare, "%s($_this%s); break;\n", iname, invoke_args);
1505 Printf(prepare, "%s($_this, %s); break;\n", iname, invoke_args);
1508 if (i || wrapperType == memberfn)
1509 Printf(invoke_args, ",");
1510 Printf(invoke_args, "$%s", arg_names[i]);
1512 Printf(prepare, "\t\t");
1514 Printf(prepare, "default: ");
1515 if (Cmp(d, "void") != 0) {
1516 if ((!directorsEnabled() || !Swig_directorclass(n)) && !newobject) {
1517 Append(prepare, "$r=");
1519 Printf(prepare, "$this->%s=", SWIG_PTR);
1523 if (!directorsEnabled() || !Swig_directorclass(n) || !newobject) {
1524 Printf(prepare, "%s(%s);\n", iname, invoke_args);
1526 Printf(prepare, "%s($_this, %s);\n", iname, invoke_args);
1529 Printf(prepare, "\t\t}\n");
1530 Delete(invoke_args);
1531 Printf(invoke, "$r");
1534 Printf(output, "\n");
1535 // If it's a member function or a class constructor...
1536 if (wrapperType == memberfn || (constructor && current_class)) {
1537 String *acc = NewString(Getattr(n, "access"));
1538 // If a base has the same method with public access, then PHP
1539 // requires to have it here as public as well
1540 Node *bases = Getattr(Swig_methodclass(n), "bases");
1541 if (bases && Strcmp(acc, "public") != 0) {
1542 String *warnmsg = 0;
1543 int haspublicbase = 0;
1544 Iterator i = First(bases);
1546 Node *j = firstChild(i.item);
1548 if (Strcmp(Getattr(j, "name"), Getattr(n, "name")) != 0) {
1552 if (Strcmp(nodeType(j), "cdecl") == 0) {
1553 if (!Getattr(j, "access") || checkAttribute(j, "access", "public")) {
1556 } else if (Strcmp(nodeType(j), "using") == 0 && firstChild(j) && Strcmp(nodeType(firstChild(j)), "cdecl") == 0) {
1557 if (!Getattr(firstChild(j), "access") || checkAttribute(firstChild(j), "access", "public")) {
1561 if (haspublicbase) {
1562 warnmsg = NewStringf("Modifying the access of '%s::%s' to public, as the base '%s' has it as public as well.\n", Getattr(current_class, "classtype"), Getattr(n, "name"), Getattr(i.item, "classtype"));
1568 if (haspublicbase) {
1572 if (Getattr(n, "access") && haspublicbase) {
1574 acc = NewString("public");
1575 Swig_warning(WARN_PHP_PUBLIC_BASE, input_file, line_number, Char(warnmsg));
1579 if (Cmp(acc, "") != 0) {
1584 if (max_num_of_arguments > 0) {
1585 arg0 = Char(arg_names[0]);
1589 args = NewString("$res=null");
1591 SwigType *t = Getattr(current_class, "classtype");
1592 String *mangled_type = SwigType_manglestr(SwigType_ltype(t));
1593 Printf(output, "\t%sfunction %s(%s) {\n", acc, methodname, args);
1594 Printf(output, "\t\tif (is_resource($%s) && get_resource_type($%s) === '_p%s') {\n", arg0, arg0, mangled_type);
1595 Printf(output, "\t\t\t$this->%s=$%s;\n", SWIG_PTR, arg0);
1596 Printf(output, "\t\t\treturn;\n");
1597 Printf(output, "\t\t}\n");
1599 Printf(output, "\t%sfunction %s(%s) {\n", acc, methodname, args);
1602 } else if (wrapperType == staticmembervar) {
1603 // We're called twice for a writable static member variable - first
1604 // with "foo_set" and then with "foo_get" - so generate half the
1605 // wrapper function each time.
1607 // For a const static member, we only get called once.
1608 static bool started = false;
1610 Printf(output, "\tstatic function %s() {\n", methodname);
1611 if (max_num_of_arguments) {
1613 Printf(output, "\t\tif (func_num_args()) {\n");
1614 Printf(output, "\t\t\t%s(func_get_arg(0));\n", iname);
1615 Printf(output, "\t\t\treturn;\n");
1616 Printf(output, "\t\t}\n");
1623 Printf(output, "\tstatic function %s(%s) {\n", methodname, args);
1627 Printf(output, "%s", prepare);
1629 if (!directorsEnabled() || !Swig_directorclass(n)) {
1630 if (strcmp(methodname, "__construct") == 0) {
1631 Printf(output, "\t\t$this->%s=%s;\n", SWIG_PTR, invoke);
1633 String *classname = Swig_class_name(current_class);
1634 Printf(output, "\t\treturn new %s(%s);\n", classname, invoke);
1637 Node *parent = Swig_methodclass(n);
1638 String *classname = Swig_class_name(parent);
1639 Printf(output, "\t\tif (get_class($this) === '%s%s') {\n", prefix, classname);
1640 Printf(output, "\t\t\t$_this = null;\n");
1641 Printf(output, "\t\t} else {\n");
1642 Printf(output, "\t\t\t$_this = $this;\n");
1643 Printf(output, "\t\t}\n");
1644 if (!Len(prepare)) {
1645 if (num_arguments > 1) {
1646 Printf(output, "\t\t$this->%s=%s($_this, %s);\n", SWIG_PTR, iname, args);
1648 Printf(output, "\t\t$this->%s=%s($_this);\n", SWIG_PTR, iname);
1652 Printf(output, "%s", prepare);
1653 } else if (Cmp(d, "void") == 0) {
1654 if (Cmp(invoke, "$r") != 0)
1655 Printf(output, "\t\t%s;\n", invoke);
1656 } else if (is_class(d)) {
1657 if (Cmp(invoke, "$r") != 0)
1658 Printf(output, "\t\t$r=%s;\n", invoke);
1659 if (Len(ret_types) == 1) {
1660 /* If it has an abstract base, then we can't create a new
1662 int hasabstractbase = 0;
1663 Node *bases = Getattr(Swig_methodclass(n), "bases");
1665 Iterator i = First(bases);
1667 if (Getattr(i.item, "abstract")) {
1668 hasabstractbase = 1;
1674 if (newobject || !hasabstractbase) {
1676 * _p_Foo -> Foo, _p_ns__Bar -> Bar
1677 * TODO: do this in a more elegant way
1679 Printf(output, "\t\tif (is_resource($r)) {\n");
1680 if (Getattr(classLookup(Getattr(n, "type")), "module")) {
1681 if (Len(prefix) == 0) {
1682 Printf(output, "\t\t\t$c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3));\n");
1684 Printf(output, "\t\t\t$c='%s'.substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3));\n", prefix);
1686 Printf(output, "\t\t\tif (!class_exists($c)) {\n");
1687 Printf(output, "\t\t\t\treturn new %s($r);\n", Getattr(classLookup(d), "sym:name"));
1688 Printf(output, "\t\t\t}\n");
1689 Printf(output, "\t\t\treturn new $c($r);\n");
1691 Printf(output, "\t\t\t$c = new stdClass();\n");
1692 Printf(output, "\t\t\t$c->_cPtr = $r;\n");
1693 Printf(output, "\t\t\treturn $c;\n");
1695 Printf(output, "\t\t}\n\t\treturn $r;\n");
1697 Printf(output, "\t\t$this->%s = $r;\n", SWIG_PTR);
1698 Printf(output, "\t\treturn $this;\n");
1701 Printf(output, "\t\tif (!is_resource($r)) return $r;\n");
1702 Printf(output, "\t\tswitch (get_resource_type($r)) {\n");
1703 Iterator i = First(ret_types);
1705 SwigType *ret_type = i.item;
1707 Printf(output, "\t\t");
1708 String *mangled = NewString("_p");
1709 Printf(mangled, "%s", SwigType_manglestr(ret_type));
1710 Node *class_node = Getattr(zend_types, mangled);
1712 /* This is needed when we're returning a pointer to a type
1713 * rather than returning the type by value or reference. */
1714 class_node = current_class;
1716 mangled = NewString(SwigType_manglestr(ret_type));
1717 class_node = Getattr(zend_types, mangled);
1720 Printf(output, "case '%s': ", mangled);
1722 Printf(output, "default: ");
1724 const char *classname = GetChar(class_node, "sym:name");
1726 classname = GetChar(class_node, "name");
1728 Printf(output, "return new %s%s($r);\n", prefix, classname);
1730 Printf(output, "return $r;\n");
1733 Printf(output, "\t\t}\n");
1736 Printf(output, "\t\treturn %s;\n", invoke);
1738 Printf(output, "\t}\n");
1748 for (int i = 0; i < max_num_of_arguments; ++i) {
1749 Delete(arg_names[i]);
1758 /* ------------------------------------------------------------
1759 * globalvariableHandler()
1760 * ------------------------------------------------------------ */
1762 virtual int globalvariableHandler(Node *n) {
1763 char *name = GetChar(n, "name");
1764 char *iname = GetChar(n, "sym:name");
1765 SwigType *t = Getattr(n, "type");
1768 /* First do the wrappers such as name_set(), name_get()
1769 * as provided by the baseclass's implementation of variableWrapper
1771 if (Language::globalvariableHandler(n) == SWIG_NOWRAP) {
1775 if (!addSymbol(iname, n))
1778 SwigType_remember(t);
1780 /* First link C variables to PHP */
1782 tm = Swig_typemap_lookup("varinit", n, name, 0);
1784 Replaceall(tm, "$target", name);
1785 Printf(s_vinit, "%s\n", tm);
1787 Printf(stderr, "%s: Line %d, Unable to link with type %s\n", input_file, line_number, SwigType_str(t, 0));
1790 /* Now generate PHP -> C sync blocks */
1792 tm = Swig_typemap_lookup("varin", n, name, 0);
1794 Replaceall(tm, "$symname", iname);
1795 Printf(f_c->code, "%s\n", tm);
1797 Printf(stderr,"%s: Line %d, Unable to link with type %s\n", input_file, line_number, SwigType_str(t, 0));
1800 /* Now generate C -> PHP sync blocks */
1802 if(!GetFlag(n,"feature:immutable")) {
1804 tm = Swig_typemap_lookup("varout", n, name, 0);
1806 Replaceall(tm, "$symname", iname);
1807 Printf(f_php->code, "%s\n", tm);
1809 Printf(stderr,"%s: Line %d, Unable to link with type %s\n", input_file, line_number, SwigType_str(t, 0));
1816 /* ------------------------------------------------------------
1818 * ------------------------------------------------------------ */
1820 virtual int constantWrapper(Node *n) {
1821 String *name = GetChar(n, "name");
1822 String *iname = GetChar(n, "sym:name");
1823 SwigType *type = Getattr(n, "type");
1824 String *rawval = Getattr(n, "rawval");
1825 String *value = rawval ? rawval : Getattr(n, "value");
1828 if (!addSymbol(iname, n))
1831 SwigType_remember(type);
1833 if ((tm = Swig_typemap_lookup("consttab", n, name, 0))) {
1834 Replaceall(tm, "$source", value);
1835 Replaceall(tm, "$target", name);
1836 Replaceall(tm, "$value", value);
1837 Printf(s_cinit, "%s\n", tm);
1841 String *enumvalue = GetChar(n, "enumvalue");
1842 String *set_to = iname;
1845 enumvalue = GetChar(n, "enumvalueex");
1849 // Check for a simple constant expression which is valid in PHP.
1850 // If we find one, initialise the const member with it; otherwise
1851 // we initialise it using the C/C++ wrapped constant.
1853 for (p = Char(enumvalue); *p; ++p) {
1854 if (!isdigit((unsigned char)*p) && !strchr(" +-", *p)) {
1855 // FIXME: enhance to handle `<previous_enum> + 1' which is what
1856 // we get for enums that don't have an explicit value set.
1860 if (!*p) set_to = enumvalue;
1863 if (wrapping_member_constant) {
1865 s_oowrappers = NewStringEmpty();
1866 Printf(s_oowrappers, "\n\tconst %s = %s;\n", wrapping_member_constant, set_to);
1868 if (!s_fakeoowrappers)
1869 s_fakeoowrappers = NewStringEmpty();
1870 Printf(s_fakeoowrappers, "\n\tconst %s = %s;\n", iname, set_to);
1882 * %pragma(php) code="String" # Includes a string in the .php file
1883 * %pragma(php) include="file.php" # Includes a file in the .php file
1886 virtual int pragmaDirective(Node *n) {
1888 String *lang = Getattr(n, "lang");
1889 String *type = Getattr(n, "name");
1890 String *value = Getattr(n, "value");
1892 if (Strcmp(lang, "php") == 0 || Strcmp(lang, "php4") == 0) {
1893 if (Strcmp(type, "code") == 0) {
1895 Printf(pragma_code, "%s\n", value);
1897 } else if (Strcmp(type, "include") == 0) {
1899 Printf(pragma_incl, "include '%s';\n", value);
1901 } else if (Strcmp(type, "phpinfo") == 0) {
1903 Printf(pragma_phpinfo, "%s\n", value);
1906 Swig_warning(WARN_PHP_UNKNOWN_PRAGMA, input_file, line_number, "Unrecognized pragma <%s>.\n", type);
1910 return Language::pragmaDirective(n);
1913 /* ------------------------------------------------------------
1914 * classDeclaration()
1915 * ------------------------------------------------------------ */
1917 virtual int classDeclaration(Node *n) {
1918 if (!Getattr(n, "feature:onlychildren")) {
1919 String *symname = Getattr(n, "sym:name");
1920 Setattr(n, "php:proxy", symname);
1923 return Language::classDeclaration(n);
1926 /* ------------------------------------------------------------
1928 * ------------------------------------------------------------ */
1930 virtual int classHandler(Node *n) {
1932 //SwigType *t = Getattr(n, "classtype");
1934 // String *use_class_name=SwigType_manglestr(SwigType_ltype(t));
1937 char *rename = GetChar(n, "sym:name");
1939 if (!addSymbol(rename, n))
1941 shadow_classname = NewString(rename);
1943 shadow_get_vars = NewHash();
1944 shadow_set_vars = NewHash();
1946 /* Deal with inheritance */
1947 List *baselist = Getattr(n, "bases");
1949 Iterator base = First(baselist);
1950 while (base.item && GetFlag(base.item, "feature:ignore")) {
1955 /* Warn about multiple inheritance for additional base class(es) */
1957 if (GetFlag(base.item, "feature:ignore")) {
1961 String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0);
1962 String *baseclassname = SwigType_str(Getattr(base.item, "name"), 0);
1963 Swig_warning(WARN_PHP_MULTIPLE_INHERITANCE, input_file, line_number,
1964 "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in PHP.\n", proxyclassname, baseclassname);
1972 Language::classHandler(n);
1977 List *baselist = Getattr(n, "bases");
1981 base = First(baselist);
1982 while (base.item && GetFlag(base.item, "feature:ignore")) {
1989 if (Getattr(n, "abstract") && !GetFlag(n, "feature:notabstract")) {
1990 Printf(s_phpclasses, "abstract ");
1993 Printf(s_phpclasses, "class %s%s ", prefix, shadow_classname);
1994 String *baseclass = NULL;
1995 if (base.item && Getattr(base.item, "module")) {
1996 baseclass = Getattr(base.item, "sym:name");
1998 baseclass = Getattr(base.item, "name");
1999 Printf(s_phpclasses, "extends %s%s ", prefix, baseclass);
2000 } else if (GetFlag(n, "feature:exceptionclass")) {
2001 Append(s_phpclasses, "extends Exception ");
2003 Printf(s_phpclasses, "{\n\tpublic $%s=null;\n", SWIG_PTR);
2005 // Only store this in the base class (NB !baseclass means we *are*
2007 Printf(s_phpclasses, "\tprotected $%s=array();\n", SWIG_DATA);
2010 // Write property SET handlers
2011 ki = First(shadow_set_vars);
2014 // This class has setters.
2015 Printf(s_phpclasses, "\n\tfunction __set($var,$value) {\n");
2016 // FIXME: tune this threshold...
2017 if (Len(shadow_set_vars) <= 2) {
2018 // Not many setters, so avoid call_user_func.
2021 Printf(s_phpclasses, "\t\tif ($var === '%s') return %s($this->%s,$value);\n", key, ki.item, SWIG_PTR);
2025 Printf(s_phpclasses, "\t\t$func = '%s_'.$var.'_set';\n", shadow_classname);
2026 Printf(s_phpclasses, "\t\tif (function_exists($func)) return call_user_func($func,$this->%s,$value);\n", SWIG_PTR);
2028 Printf(s_phpclasses, "\t\tif ($var === 'thisown') return swig_%s_alter_newobject($this->%s,$value);\n", module, SWIG_PTR);
2030 Printf(s_phpclasses, "\t\t%s%s::__set($var,$value);\n", prefix, baseclass);
2032 Printf(s_phpclasses, "\t\t$this->%s[$var] = $value;\n", SWIG_DATA);
2034 Printf(s_phpclasses, "\t}\n");
2036 /* Create __isset for PHP 5.1 and later; PHP 5.0 will just ignore it. */
2037 Printf(s_phpclasses, "\n\tfunction __isset($var) {\n");
2038 Printf(s_phpclasses, "\t\tif (function_exists('%s_'.$var.'_set')) return true;\n", shadow_classname);
2039 Printf(s_phpclasses, "\t\tif ($var === 'thisown') return true;\n");
2041 Printf(s_phpclasses, "\t\treturn %s%s::__isset($var);\n", prefix, baseclass);
2043 Printf(s_phpclasses, "\t\treturn array_key_exists($var, $this->%s);\n", SWIG_DATA);
2045 Printf(s_phpclasses, "\t}\n");
2047 Printf(s_phpclasses, "\n\tfunction __set($var,$value) {\n");
2048 Printf(s_phpclasses, "\t\tif ($var === 'thisown') return swig_%s_alter_newobject($this->%s,$value);\n", module, SWIG_PTR);
2050 Printf(s_phpclasses, "\t\t%s%s::__set($var,$value);\n", prefix, baseclass);
2052 Printf(s_phpclasses, "\t\t$this->%s[$var] = $value;\n", SWIG_DATA);
2054 Printf(s_phpclasses, "\t}\n");
2055 Printf(s_phpclasses, "\n\tfunction __isset($var) {\n");
2056 Printf(s_phpclasses, "\t\tif ($var === 'thisown') return true;\n");
2058 Printf(s_phpclasses, "\t\treturn %s%s::__isset($var);\n", prefix, baseclass);
2060 Printf(s_phpclasses, "\t\treturn array_key_exists($var, $this->%s);\n", SWIG_DATA);
2062 Printf(s_phpclasses, "\t}\n");
2064 // Write property GET handlers
2065 ki = First(shadow_get_vars);
2068 // This class has getters.
2069 Printf(s_phpclasses, "\n\tfunction __get($var) {\n");
2070 // FIXME: Currently we always use call_user_func for __get, so we can
2071 // check and wrap the result. This is needless if all the properties
2072 // are primitive types. Also this doesn't handle all the cases which
2073 // a method returning an object does.
2074 Printf(s_phpclasses, "\t\t$func = '%s_'.$var.'_get';\n", shadow_classname);
2075 Printf(s_phpclasses, "\t\tif (function_exists($func)) {\n");
2076 Printf(s_phpclasses, "\t\t\t$r = call_user_func($func,$this->%s);\n", SWIG_PTR);
2077 Printf(s_phpclasses, "\t\t\tif (!is_resource($r)) return $r;\n");
2078 if (Len(prefix) == 0) {
2079 Printf(s_phpclasses, "\t\t\t$c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3));\n");
2081 Printf(s_phpclasses, "\t\t\t$c='%s'.substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3));\n", prefix);
2083 Printf(s_phpclasses, "\t\t\treturn new $c($r);\n");
2084 Printf(s_phpclasses, "\t\t}\n");
2085 Printf(s_phpclasses, "\t\tif ($var === 'thisown') return swig_%s_get_newobject($this->%s);\n", module, SWIG_PTR);
2087 Printf(s_phpclasses, "\t\treturn %s%s::__get($var);\n", prefix, baseclass);
2089 // Reading an unknown property name gives null in PHP.
2090 Printf(s_phpclasses, "\t\treturn $this->%s[$var];\n", SWIG_DATA);
2092 Printf(s_phpclasses, "\t}\n");
2094 Printf(s_phpclasses, "\n\tfunction __get($var) {\n");
2095 Printf(s_phpclasses, "\t\tif ($var === 'thisown') return swig_%s_get_newobject($this->%s);\n", module, SWIG_PTR);
2097 Printf(s_phpclasses, "\t\treturn %s%s::__get($var);\n", prefix, baseclass);
2099 Printf(s_phpclasses, "\t\treturn $this->%s[$var];\n", SWIG_DATA);
2101 Printf(s_phpclasses, "\t}\n");
2104 if (!class_has_ctor) {
2105 Printf(s_phpclasses, "\tfunction __construct($h) {\n");
2106 Printf(s_phpclasses, "\t\t$this->%s=$h;\n", SWIG_PTR);
2107 Printf(s_phpclasses, "\t}\n");
2111 Printf(s_phpclasses, "%s", s_oowrappers);
2112 Delete(s_oowrappers);
2113 s_oowrappers = NULL;
2115 class_has_ctor = false;
2117 Printf(s_phpclasses, "}\n\n");
2119 Delete(shadow_classname);
2120 shadow_classname = NULL;
2122 Delete(shadow_set_vars);
2123 shadow_set_vars = NULL;
2124 Delete(shadow_get_vars);
2125 shadow_get_vars = NULL;
2130 /* ------------------------------------------------------------
2131 * memberfunctionHandler()
2132 * ------------------------------------------------------------ */
2134 virtual int memberfunctionHandler(Node *n) {
2135 wrapperType = memberfn;
2136 Language::memberfunctionHandler(n);
2137 wrapperType = standard;
2142 /* ------------------------------------------------------------
2143 * membervariableHandler()
2144 * ------------------------------------------------------------ */
2146 virtual int membervariableHandler(Node *n) {
2147 wrapperType = membervar;
2148 Language::membervariableHandler(n);
2149 wrapperType = standard;
2154 /* ------------------------------------------------------------
2155 * staticmembervariableHandler()
2156 * ------------------------------------------------------------ */
2158 virtual int staticmembervariableHandler(Node *n) {
2159 wrapperType = staticmembervar;
2160 Language::staticmembervariableHandler(n);
2161 wrapperType = standard;
2166 /* ------------------------------------------------------------
2167 * staticmemberfunctionHandler()
2168 * ------------------------------------------------------------ */
2170 virtual int staticmemberfunctionHandler(Node *n) {
2171 wrapperType = staticmemberfn;
2172 Language::staticmemberfunctionHandler(n);
2173 wrapperType = standard;
2178 int abstractConstructorHandler(Node *) {
2182 /* ------------------------------------------------------------
2183 * constructorHandler()
2184 * ------------------------------------------------------------ */
2186 virtual int constructorHandler(Node *n) {
2188 if (Swig_directorclass(n)) {
2189 String *name = GetChar(Swig_methodclass(n), "name");
2190 String *ctype = GetChar(Swig_methodclass(n), "classtype");
2191 String *sname = GetChar(Swig_methodclass(n), "sym:name");
2192 String *args = NewStringEmpty();
2193 ParmList *p = Getattr(n, "parms");
2196 for (i = 0; p; p = nextSibling(p), i++) {
2200 if (Strcmp(GetChar(p, "type"), SwigType_str(GetChar(p, "type"), 0))) {
2201 SwigType *t = Getattr(p, "type");
2202 Printf(args, "%s", SwigType_rcaststr(t, 0));
2203 if (SwigType_isreference(t)) {
2207 Printf(args, "arg%d", i+1);
2210 /* director ctor code is specific for each class */
2211 Delete(director_ctor_code);
2212 director_ctor_code = NewStringEmpty();
2213 director_prot_ctor_code = NewStringEmpty();
2214 Printf(director_ctor_code, "if ( arg0->type == IS_NULL ) { /* not subclassed */\n");
2215 Printf(director_prot_ctor_code, "if ( arg0->type == IS_NULL ) { /* not subclassed */\n");
2216 Printf(director_ctor_code, " result = (%s *)new %s(%s);\n", ctype, ctype, args);
2217 Printf(director_prot_ctor_code, " SWIG_PHP_Error(E_ERROR, \"accessing abstract class or protected constructor\");\n", name, name, args);
2219 Insert(args, 0, ", ");
2221 Printf(director_ctor_code, "} else {\n result = (%s *)new SwigDirector_%s(arg0%s);\n}\n", ctype, sname, args);
2222 Printf(director_prot_ctor_code, "} else {\n result = (%s *)new SwigDirector_%s(arg0%s);\n}\n", ctype, sname, args);
2225 wrapperType = directorconstructor;
2227 wrapperType = constructor;
2229 Language::constructorHandler(n);
2230 wrapperType = standard;
2235 /* ------------------------------------------------------------
2236 * CreateZendListDestructor()
2237 * ------------------------------------------------------------ */
2238 //virtual int destructorHandler(Node *n) {
2240 int CreateZendListDestructor(Node *n) {
2241 String *name = GetChar(Swig_methodclass(n), "name");
2242 String *iname = GetChar(n, "sym:name");
2243 ParmList *l = Getattr(n, "parms");
2245 String *destructorname = NewStringEmpty();
2246 Printf(destructorname, "_%s", Swig_name_wrapper(iname));
2247 Setattr(classnode, "destructor", destructorname);
2249 Wrapper *f = NewWrapper();
2250 Printf(f->def, "/* This function is designed to be called by the zend list destructors */\n");
2251 Printf(f->def, "/* to typecast and do the actual destruction */\n");
2252 Printf(f->def, "static void %s(zend_rsrc_list_entry *rsrc, const char *type_name TSRMLS_DC) {\n", destructorname);
2254 Wrapper_add_localv(f, "value", "swig_object_wrapper *value=(swig_object_wrapper *) rsrc->ptr", NIL);
2255 Wrapper_add_localv(f, "ptr", "void *ptr=value->ptr", NIL);
2256 Wrapper_add_localv(f, "newobject", "int newobject=value->newobject", NIL);
2258 emit_parameter_variables(l, f);
2259 emit_attach_parmmaps(l, f);
2261 // Get type of first arg, thing to be destructed
2262 // Skip ignored arguments
2264 //while (Getattr(p,"tmap:ignore")) {p = Getattr(p,"tmap:ignore:next");}
2265 while (checkAttribute(p, "tmap:in:numinputs", "0")) {
2266 p = Getattr(p, "tmap:in:next");
2268 SwigType *pt = Getattr(p, "type");
2270 Printf(f->code, " efree(value);\n");
2271 Printf(f->code, " if (! newobject) return; /* can't delete it! */\n");
2272 Printf(f->code, " arg1 = (%s)SWIG_ZTS_ConvertResourceData(ptr,type_name,SWIGTYPE%s TSRMLS_CC);\n", SwigType_lstr(pt, 0), SwigType_manglestr(pt));
2273 Printf(f->code, " if (! arg1) zend_error(E_ERROR, \"%s resource already free'd\");\n", Char(name));
2275 Setattr(n, "wrap:name", destructorname);
2277 String *actioncode = emit_action(n);
2278 Append(f->code, actioncode);
2281 Append(f->code, "return;\n");
2282 Append(f->code, "fail:\n");
2283 Append(f->code, "zend_error_noreturn(SWIG_ErrorCode(),\"%s\",SWIG_ErrorMsg());\n");
2284 Printf(f->code, "}\n");
2286 Wrapper_print(f, s_wrappers);
2291 /* ------------------------------------------------------------
2292 * memberconstantHandler()
2293 * ------------------------------------------------------------ */
2295 virtual int memberconstantHandler(Node *n) {
2296 wrapping_member_constant = Getattr(n, "sym:name");
2297 Language::memberconstantHandler(n);
2298 wrapping_member_constant = NULL;
2302 int classDirectorInit(Node *n) {
2303 String *declaration = Swig_director_declaration(n);
2304 Printf(f_directors_h, "%s\n", declaration);
2305 Printf(f_directors_h, "public:\n");
2306 Delete(declaration);
2307 return Language::classDirectorInit(n);
2310 int classDirectorEnd(Node *n) {
2311 Printf(f_directors_h, "};\n");
2312 return Language::classDirectorEnd(n);
2315 int classDirectorConstructor(Node *n) {
2316 Node *parent = Getattr(n, "parentNode");
2317 String *decl = Getattr(n, "decl");
2318 String *supername = Swig_class_name(parent);
2319 String *classname = NewStringEmpty();
2320 Printf(classname, "SwigDirector_%s", supername);
2322 /* insert self parameter */
2324 ParmList *superparms = Getattr(n, "parms");
2325 ParmList *parms = CopyParmList(superparms);
2326 String *type = NewString("zval");
2327 SwigType_add_pointer(type);
2328 p = NewParm(type, NewString("self"));
2329 set_nextSibling(p, parms);
2332 if (!Getattr(n, "defaultargs")) {
2335 Wrapper *w = NewWrapper();
2337 String *basetype = Getattr(parent, "classtype");
2338 String *target = Swig_method_decl(0, decl, classname, parms, 0, 0);
2339 call = Swig_csuperclass_call(0, basetype, superparms);
2340 Printf(w->def, "%s::%s: %s, Swig::Director(self) {", classname, target, call);
2341 Append(w->def, "}");
2343 Wrapper_print(w, f_directors);
2348 /* constructor header */
2350 String *target = Swig_method_decl(0, decl, classname, parms, 0, 1);
2351 Printf(f_directors_h, " %s;\n", target);
2355 return Language::classDirectorConstructor(n);
2358 int classDirectorMethod(Node *n, Node *parent, String *super) {
2365 String *c_classname = Getattr(parent, "name");
2366 String *declaration;
2370 String *wrap_args = NewStringEmpty();
2371 String *return_type;
2372 String *value = Getattr(n, "value");
2373 String *storage = Getattr(n, "storage");
2374 bool pure_virtual = false;
2375 int status = SWIG_OK;
2377 bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
2379 if (Cmp(storage, "virtual") == 0) {
2380 if (Cmp(value, "0") == 0) {
2381 pure_virtual = true;
2385 classname = Getattr(parent, "sym:name");
2386 type = Getattr(n, "type");
2387 name = Getattr(n, "name");
2390 declaration = NewStringEmpty();
2392 /* determine if the method returns a pointer */
2393 decl = Getattr(n, "decl");
2394 is_pointer = SwigType_ispointer_return(decl);
2395 is_void = (Cmp(type, "void") == 0 && !is_pointer);
2397 /* form complete return type */
2398 return_type = Copy(type);
2400 SwigType *t = Copy(decl);
2401 SwigType *f = SwigType_pop_function(t);
2402 SwigType_push(return_type, t);
2407 /* virtual method definition */
2408 l = Getattr(n, "parms");
2410 String *pclassname = NewStringf("SwigDirector_%s", classname);
2411 String *qualified_name = NewStringf("%s::%s", pclassname, name);
2412 SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : type;
2413 target = Swig_method_decl(rtype, decl, qualified_name, l, 0, 0);
2414 Printf(w->def, "%s", target);
2415 Delete(qualified_name);
2417 /* header declaration */
2418 target = Swig_method_decl(rtype, decl, name, l, 0, 1);
2419 Printf(declaration, " virtual %s", target);
2422 // Get any exception classes in the throws typemap
2423 ParmList *throw_parm_list = 0;
2425 if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
2429 Append(w->def, " throw(");
2430 Append(declaration, " throw(");
2432 if (throw_parm_list)
2433 Swig_typemap_attach_parms("throws", throw_parm_list, 0);
2434 for (p = throw_parm_list; p; p = nextSibling(p)) {
2435 if ((tm = Getattr(p, "tmap:throws"))) {
2437 Append(w->def, ", ");
2438 Append(declaration, ", ");
2440 String *str = SwigType_str(Getattr(p, "type"), 0);
2441 Append(w->def, str);
2442 Append(declaration, str);
2447 Append(w->def, ")");
2448 Append(declaration, ")");
2451 Append(w->def, " {");
2452 Append(declaration, ";\n");
2454 /* declare method return value
2455 * if the return value is a reference or const reference, a specialized typemap must
2456 * handle it, including declaration of c_result ($result).
2459 if (!(ignored_method && !pure_virtual)) {
2460 String *cres = SwigType_lstr(return_type, "c_result");
2461 Printf(w->code, "%s;\n", cres);
2466 if (ignored_method) {
2467 if (!pure_virtual) {
2469 Printf(w->code, "return ");
2470 String *super_call = Swig_method_call(super, l);
2471 Printf(w->code, "%s;\n", super_call);
2474 Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname),
2475 SwigType_namestr(name));
2478 /* attach typemaps to arguments (C/C++ -> PHP) */
2479 String *parse_args = NewStringEmpty();
2481 /* remove the wrapper 'w' since it was producing spurious temps */
2482 Swig_typemap_attach_parms("in", l, 0);
2483 Swig_typemap_attach_parms("directorin", l, 0);
2484 Swig_typemap_attach_parms("directorargout", l, w);
2493 /* build argument list and type conversion string */
2498 if (checkAttribute(p, "tmap:in:numinputs", "0")) {
2499 p = Getattr(p, "tmap:in:next");
2503 if (Getattr(p, "tmap:directorargout") != 0)
2506 String *pname = Getattr(p, "name");
2507 String *ptype = Getattr(p, "type");
2509 if ((tm = Getattr(p, "tmap:directorin")) != 0) {
2510 String *parse = Getattr(p, "tmap:directorin:parse");
2512 sprintf(source, "obj%d", idx++);
2513 String *input = NewStringf("&%s", source);
2514 Replaceall(tm, "$input", input);
2516 Replaceall(tm, "$owner", "0");
2517 Printv(wrap_args, "zval ", source, ";\n", NIL);
2518 Printf(wrap_args, "args[%d] = &%s;\n", idx - 1, source);
2520 Printv(wrap_args, tm, "\n", NIL);
2521 Putc('O', parse_args);
2524 Append(parse_args, parse);
2525 Replaceall(tm, "$input", pname);
2526 Replaceall(tm, "$owner", "0");
2530 p = Getattr(p, "tmap:directorin:next");
2532 } else if (Cmp(ptype, "void")) {
2533 Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
2534 "Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0),
2535 SwigType_namestr(c_classname), SwigType_namestr(name));
2536 status = SWIG_NOWRAP;
2541 Append(w->code, "int error;\n");
2543 Printf(w->code, "zval **args = NULL;\n", idx);
2545 Printf(w->code, "zval *args[%d];\n", idx);
2547 Append(w->code, "zval *result, funcname;\n");
2548 Append(w->code, "MAKE_STD_ZVAL(result);\n");
2549 Printf(w->code, "ZVAL_STRING(&funcname, (char *)\"%s\", 0);\n", name);
2550 Append(w->code, "if (!swig_self) {\n");
2551 Append(w->code, " SWIG_PHP_Error(E_ERROR, \"this pointer is NULL\");");
2552 Append(w->code, "}\n\n");
2554 /* wrap complex arguments to zvals */
2555 Printv(w->code, wrap_args, NIL);
2557 Append(w->code, "call_user_function(EG(function_table), (zval**)&swig_self, &funcname,\n");
2558 Printf(w->code, " result, %d, args TSRMLS_CC);\n", idx);
2560 /* exception handling */
2561 tm = Swig_typemap_lookup("director:except", n, "result", 0);
2563 tm = Getattr(n, "feature:director:except");
2567 if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) {
2568 Replaceall(tm, "$error", "error");
2569 Printv(w->code, Str(tm), "\n", NIL);
2573 /* marshal return value from PHP to C/C++ type */
2575 String *cleanup = NewStringEmpty();
2576 String *outarg = NewStringEmpty();
2580 /* marshal return value */
2582 /* this seems really silly. the node's type excludes
2583 * qualifier/pointer/reference markers, which have to be retrieved
2584 * from the decl field to construct return_type. but the typemap
2585 * lookup routine uses the node's type, so we have to swap in and
2586 * out the correct type. it's not just me, similar silliness also
2587 * occurs in Language::cDeclaration().
2589 Setattr(n, "type", return_type);
2590 tm = Swig_typemap_lookup("directorout", n, "result", w);
2591 Setattr(n, "type", type);
2593 Replaceall(tm, "$input", "&result");
2595 sprintf(temp, "%d", idx);
2596 Replaceall(tm, "$argnum", temp);
2598 /* TODO check this */
2599 if (Getattr(n, "wrap:disown")) {
2600 Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
2602 Replaceall(tm, "$disown", "0");
2604 Replaceall(tm, "$result", "c_result");
2605 Printv(w->code, tm, "\n", NIL);
2608 Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
2609 "Unable to use return type %s in director method %s::%s (skipping method).\n", SwigType_str(return_type, 0), SwigType_namestr(c_classname),
2610 SwigType_namestr(name));
2611 status = SWIG_ERROR;
2615 /* marshal outputs */
2617 if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
2618 Replaceall(tm, "$input", "result");
2619 Replaceall(tm, "$result", Getattr(p, "name"));
2620 Printv(w->code, tm, "\n", NIL);
2621 p = Getattr(p, "tmap:directorargout:next");
2627 Append(w->code, "FREE_ZVAL(result);\n");
2635 if (!(ignored_method && !pure_virtual)) {
2636 String *rettype = SwigType_str(return_type, 0);
2637 if (!SwigType_isreference(return_type)) {
2638 Printf(w->code, "return (%s) c_result;\n", rettype);
2640 Printf(w->code, "return (%s) *c_result;\n", rettype);
2645 Append(w->code, "return;\n");
2648 Append(w->code, "fail:\n");
2649 Append(w->code, "zend_error_noreturn(SWIG_ErrorCode(),\"%s\",SWIG_ErrorMsg());\n");
2650 Append(w->code, "}\n");
2652 // We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method
2653 String *inline_extra_method = NewStringEmpty();
2654 if (dirprot_mode() && !is_public(n) && !pure_virtual) {
2655 Printv(inline_extra_method, declaration, NIL);
2656 String *extra_method_name = NewStringf("%sSwigPublic", name);
2657 Replaceall(inline_extra_method, name, extra_method_name);
2658 Replaceall(inline_extra_method, ";\n", " {\n ");
2660 Printf(inline_extra_method, "return ");
2661 String *methodcall = Swig_method_call(super, l);
2662 Printv(inline_extra_method, methodcall, ";\n }\n", NIL);
2664 Delete(extra_method_name);
2667 /* emit the director method */
2668 if (status == SWIG_OK) {
2669 if (!Getattr(n, "defaultargs")) {
2670 Wrapper_print(w, f_directors);
2671 Printv(f_directors_h, declaration, NIL);
2672 Printv(f_directors_h, inline_extra_method, NIL);
2678 Delete(return_type);
2684 int classDirectorDisown(Node *) {
2689 static PHP *maininstance = 0;
2691 // We use this function to be able to write out zend_register_list_destructor_ex
2692 // lines for most things in the type table
2693 // NOTE: it's a function NOT A PHP::METHOD
2694 extern "C" void typetrace(SwigType *ty, String *mangled, String *clientdata) {
2697 zend_types = NewHash();
2699 // we want to know if the type which reduced to this has a constructor
2700 if ((class_node = maininstance->classLookup(ty))) {
2701 if (!Getattr(zend_types, mangled)) {
2702 // OK it may have been set before by a different SwigType but it would
2703 // have had the same underlying class node I think
2704 // - it is certainly required not to have different originating class
2705 // nodes for the same SwigType
2706 Setattr(zend_types, mangled, class_node);
2708 } else { // a non-class pointer
2709 Setattr(zend_types, mangled, NOTCLASS);
2711 if (r_prevtracefunc)
2712 (*r_prevtracefunc) (ty, mangled, (String *) clientdata);
2715 /* -----------------------------------------------------------------------------
2716 * new_swig_php() - Instantiate module
2717 * ----------------------------------------------------------------------------- */
2719 static Language *new_swig_php() {
2720 maininstance = new PHP;
2721 if (!r_prevtracefunc) {
2722 r_prevtracefunc = SwigType_remember_trace(typetrace);
2724 Printf(stderr, "php Typetrace vector already saved!\n");
2727 return maininstance;
2730 extern "C" Language *swig_php4(void) {
2731 Printf(stderr, "*** -php4 is no longer supported.\n"
2732 "*** Either upgrade to PHP5 or use SWIG 1.3.36 or earlier.\n");
2733 SWIG_exit(EXIT_FAILURE);
2734 return NULL; // To avoid compiler warnings.
2737 extern "C" Language *swig_php(void) {
2738 return new_swig_php();