/tags/rel-1-3-30rc1-afterbeautify/SWIG/Source/Modules/php4.cxx
C++ | 1928 lines | 1496 code | 213 blank | 219 comment | 365 complexity | 6b3b90c176f9ba188b5c284382d30ee9 MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
Large files files are truncated, but you can click here to view the full file
- /* -----------------------------------------------------------------------------
- * See the LICENSE file for information on copyright, usage and redistribution
- * of SWIG, and the README file for authors - http://www.swig.org/release.html.
- *
- * php4.cxx
- *
- * Php language module for SWIG.
- * -----------------------------------------------------------------------------
- */
- /* FIXME: PHP5 OO wrapping TODO list:
- *
- * Short term (ideally before 1.3.30 is released):
- *
- * Sort out auto-renaming of method and class names which are reserved
- * words (e.g. empty, clone, exception, etc.) vs -php4/-php5 in some
- * sane way.
- *
- * Sort out wrapping of static member variables in OO PHP5 (which first may
- * mean we need to sort them out for PHP4!)
- *
- * Medium term:
- *
- * Handle default parameters on overloaded methods in PHP where possible.
- * (Mostly done - just need to handle cases of overloaded methods with
- * default parameters...)
- * This is an optimisation - we could handle this case using a PHP
- * default value, but currently we treat it as we would for a default
- * value which is a compound C++ expression (i.e. as if we had a
- * a method with two overloaded forms instead of a single method with
- * a default parameter value).
- *
- * Create __isset method for PHP 5.1 and later (we can probably just
- * always generate as PHP 5.0 should just ignore it).
- *
- * Long term:
- *
- * Option to generate code to work with PHP4 instead ("public $_cPtr;" ->
- * "var $_cPtr;", "abstract" -> "", no static class functions - but making
- * these changes gives a segfault with make check...)
- * Sort out locale-dependent behaviour of strtod() - it's harmless unless
- * SWIG ever sets the locale and DOH/base.c calls atof, so we're probably
- * OK currently at least.
- */
- /*
- * TODO: Replace remaining stderr messages with Swig_error or Swig_warning
- * (may need to add more WARN_PHP4_xxx codes...)
- */
- char cvsroot_php4_cxx[] = "$Header$";
- #include "swigmod.h"
- #include <ctype.h>
- #include <errno.h>
- static const char *usage = (char *) "\
- PHP Options (available with -php4 or -php5)\n\
- -cppext - cpp file extension (default to .cpp)\n\
- -noproxy - Don't generate proxy classes.\n\
- -prefix <prefix> - Prepend <prefix> to all class names in PHP5 wrappers\n\
- -make - Create simple makefile\n\
- -phpfull - Create full make files\n\
- -withincs <incs> - With -phpfull writes needed incs in config.m4\n\
- -withlibs <libs> - With -phpfull writes needed libs in config.m4\n\
- -withc <files> - With -phpfull makes extra C files in Makefile.in\n\
- -withcxx <files> - With -phpfull makes extra C++ files in Makefile.in\n\
- \n";
- /* The original class wrappers for PHP4 store the pointer to the C++ class in
- * the object property _cPtr. If we use the same name for the member variable
- * which we put the pointer to the C++ class in, then the flat function
- * wrappers will automatically pull it out without any changes being required.
- * FIXME: Isn't using a leading underscore a bit suspect here?
- */
- #define SWIG_PTR "_cPtr"
- static int constructors = 0;
- static String *NOTCLASS = NewString("Not a class");
- static Node *classnode = 0;
- static String *module = 0;
- static String *cap_module = 0;
- static String *prefix = 0;
- static String *withlibs = 0;
- static String *withincs = 0;
- static String *withc = 0;
- static String *withcxx = 0;
- static String *shadow_classname = 0;
- static int gen_extra = 0;
- static int gen_make = 0;
- static File *f_runtime = 0;
- static File *f_h = 0;
- static File *f_phpcode = 0;
- static String *phpfilename = 0;
- static String *s_header;
- static String *s_wrappers;
- static String *s_init;
- static String *r_init; // RINIT user code
- static String *s_shutdown; // MSHUTDOWN user code
- static String *r_shutdown; // RSHUTDOWN user code
- static String *s_vinit; // varinit initialization code.
- static String *s_vdecl;
- static String *s_cinit; // consttab initialization code.
- static String *s_oinit;
- static String *s_entry;
- static String *cs_entry;
- static String *all_cs_entry;
- static String *pragma_incl;
- static String *pragma_code;
- static String *pragma_phpinfo;
- static String *s_oowrappers;
- static String *s_fakeoowrappers;
- static String *s_phpclasses;
- /* Variables for using PHP classes */
- static Node *current_class = 0;
- static Hash *shadow_get_vars;
- static Hash *shadow_set_vars;
- #define NATIVE_CONSTRUCTOR 1
- #define ALTERNATIVE_CONSTRUCTOR 2
- static int native_constructor = 0;
- static Hash *zend_types = 0;
- static int shadow = 1;
- static bool class_has_ctor = false;
- static String *wrapping_member_constant = NULL;
- // These static variables are used to pass some state from Handlers into functionWrapper
- static enum {
- standard = 0,
- memberfn,
- staticmemberfn,
- membervar,
- staticmembervar,
- constructor,
- destructor
- } wrapperType = standard;
- extern "C" {
- static void (*r_prevtracefunc) (SwigType *t, String *mangled, String *clientdata) = 0;
- }
- static const char *php_header =
- "/*"
- "\n +----------------------------------------------------------------------+"
- "\n | PHP version 4.0 |"
- "\n +----------------------------------------------------------------------+"
- "\n | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |"
- "\n +----------------------------------------------------------------------+"
- "\n | This source file is subject to version 2.02 of the PHP license, |"
- "\n | that is bundled with this package in the file LICENSE, and is |"
- "\n | available at through the world-wide-web at |"
- "\n | http://www.php.net/license/2_02.txt. |"
- "\n | If you did not receive a copy of the PHP license and are unable to |"
- "\n | obtain it through the world-wide-web, please send a note to |"
- "\n | license@php.net so we can mail you a copy immediately. |"
- "\n +----------------------------------------------------------------------+"
- "\n | Authors: |"
- "\n | |"
- "\n +----------------------------------------------------------------------+" "\n */\n";
- void SwigPHP_emit_resource_registrations() {
- Iterator ki;
- if (!zend_types)
- return;
- ki = First(zend_types);
- if (ki.key)
- Printf(s_oinit, "\n/* Register resource destructors for pointer types */\n");
- while (ki.key)
- if (1 /* is pointer type */ ) {
- DOH *key = ki.key;
- Node *class_node = ki.item;
- String *human_name = key;
- // Write out destructor function header
- Printf(s_wrappers, "/* NEW Destructor style */\nstatic ZEND_RSRC_DTOR_FUNC(_wrap_destroy%s) {\n", key);
- // write out body
- if ((class_node != NOTCLASS)) {
- String *destructor = Getattr(class_node, "destructor");
- human_name = Getattr(class_node, "sym:name");
- if (!human_name)
- human_name = Getattr(class_node, "name");
- // Do we have a known destructor for this type?
- if (destructor) {
- Printf(s_wrappers, " %s(rsrc, SWIGTYPE%s->name TSRMLS_CC);\n", destructor, key);
- } else {
- Printf(s_wrappers, " /* No destructor for class %s */\n", human_name);
- }
- } else {
- Printf(s_wrappers, " /* No destructor for simple type %s */\n", key);
- }
- // close function
- Printf(s_wrappers, "}\n");
- // declare le_swig_<mangled> to store php registration
- Printf(s_vdecl, "static int le_swig_%s=0; /* handle for %s */\n", key, human_name);
- // register with php
- 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);
- // store php type in class struct
- Printf(s_oinit, "SWIG_TypeClientData(SWIGTYPE%s,&le_swig_%s);\n", key, key);
- ki = Next(ki);
- }
- }
- class PHP:public Language {
- int php_version;
- public:
- PHP(int php_version_):php_version(php_version_) {
- }
- /* Test to see if a type corresponds to something wrapped with a shadow class. */
-
- String *is_shadow(SwigType *t) {
- String *r = 0;
- Node *n = classLookup(t);
- if (n) {
- r = Getattr(n, "php:proxy"); // Set by classDeclaration()
- if (!r) {
- r = Getattr(n, "sym:name"); // Not seen by classDeclaration yet, but this is the name
- }
- }
- return r;
- }
- /* ------------------------------------------------------------
- * main()
- * ------------------------------------------------------------ */
- virtual void main(int argc, char *argv[]) {
- int i;
- SWIG_library_directory("php4");
- SWIG_config_cppext("cpp");
- for (i = 1; i < argc; i++) {
- if (argv[i]) {
- if (strcmp(argv[i], "-phpfull") == 0) {
- gen_extra = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-dlname") == 0) {
- Printf(stderr, "*** -dlname is no longer supported\n*** if you want to change the module name, use -module instead.\n");
- SWIG_exit(EXIT_FAILURE);
- } else if (strcmp(argv[i], "-prefix") == 0) {
- if (argv[i + 1]) {
- prefix = NewString(argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-withlibs") == 0) {
- if (argv[i + 1]) {
- withlibs = NewString(argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-withincs") == 0) {
- if (argv[i + 1]) {
- withincs = NewString(argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-withc") == 0) {
- if (argv[i + 1]) {
- withc = NewString(argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-withcxx") == 0) {
- if (argv[i + 1]) {
- withcxx = NewString(argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if (strcmp(argv[i], "-cppext") == 0) {
- if (argv[i + 1]) {
- SWIG_config_cppext(argv[i + 1]);
- Swig_mark_arg(i);
- Swig_mark_arg(i + 1);
- i++;
- } else {
- Swig_arg_error();
- }
- } else if ((strcmp(argv[i], "-noshadow") == 0) || (strcmp(argv[i], "-noproxy") == 0)) {
- shadow = 0;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-make") == 0) {
- gen_make = 1;
- Swig_mark_arg(i);
- } else if (strcmp(argv[i], "-help") == 0) {
- fputs(usage, stdout);
- }
- }
- }
- Preprocessor_define((void *) "SWIGPHP 1", 0);
- if (php_version == 4) {
- Preprocessor_define((void *) "SWIGPHP4 1", 0);
- } else if (php_version == 5) {
- Preprocessor_define((void *) "SWIGPHP5 1", 0);
- }
- SWIG_typemap_lang("php4");
- /* DB: Suggest using a language configuration file */
- SWIG_config_file("php4.swg");
- allow_overloading();
- }
- void create_simple_make(void) {
- File *f_make;
- f_make = NewFile((void *) "makefile", "w");
- Printf(f_make, "CC=gcc\n");
- Printf(f_make, "CXX=g++\n");
- Printf(f_make, "CXX_SOURCES=%s\n", withcxx);
- Printf(f_make, "C_SOURCES=%s\n", withc);
- Printf(f_make, "OBJS=%s_wrap.o $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cxx=.o)\n", module);
- 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",
- module);
- Printf(f_make, "CFLAGS=-fpic\n");
- Printf(f_make, "LDFLAGS=-shared\n");
- Printf(f_make, "PHP_INC=`php-config --includes`\n");
- Printf(f_make, "EXTRA_INC=\n");
- Printf(f_make, "EXTRA_LIB=\n\n");
- Printf(f_make, "$(MODULE): $(OBJS)\n");
- if (CPlusPlus || (withcxx != NULL)) {
- Printf(f_make, "\t$(CXX) $(LDFLAGS) $(OBJS) -o $(PROG) $(EXTRA_LIB)\n\n");
- } else {
- Printf(f_make, "\t$(CC) $(LDFLAGS) $(OBJS) -o $(PROG) $(EXTRA_LIB)\n\n");
- }
- Printf(f_make, "%%.o: %%.cpp\n");
- Printf(f_make, "\t$(CXX) $(EXTRA_INC) $(PHP_INC) $(CFLAGS) -c $<\n");
- Printf(f_make, "%%.o: %%.cxx\n");
- Printf(f_make, "\t$(CXX) $(EXTRA_INC) $(PHP_INC) $(CFLAGS) -c $<\n");
- Printf(f_make, "%%.o: %%.c\n");
- Printf(f_make, "\t$(CC) $(EXTRA_INC) $(PHP_INC) $(CFLAGS) -c $<\n");
- Close(f_make);
- }
- void create_extra_files(String *outfile) {
- File *f_extra;
- static String *configm4 = 0;
- static String *makefilein = 0;
- static String *credits = 0;
- configm4 = NewStringEmpty();
- Printv(configm4, SWIG_output_directory(), "config.m4", NIL);
- makefilein = NewStringEmpty();
- Printv(makefilein, SWIG_output_directory(), "Makefile.in", NIL);
- credits = NewStringEmpty();
- Printv(credits, SWIG_output_directory(), "CREDITS", NIL);
- // are we a --with- or --enable-
- int with = (withincs || withlibs) ? 1 : 0;
- // Note Makefile.in only copes with one source file
- // also withincs and withlibs only take one name each now
- // the code they generate should be adapted to take multiple lines
- /* Write out Makefile.in */
- f_extra = NewFile(makefilein, "w");
- if (!f_extra) {
- FileErrorDisplay(makefilein);
- SWIG_exit(EXIT_FAILURE);
- }
- Printf(f_extra, "# $Id: php4.cxx 9505 2006-11-01 23:54:54Z wsfulton $\n\n" "LTLIBRARY_NAME = %s.la\n", module);
- // C++ has more and different entries to C in Makefile.in
- if (!CPlusPlus) {
- Printf(f_extra, "LTLIBRARY_SOURCES = %s %s\n", Swig_file_filename(outfile), withc);
- Printf(f_extra, "LTLIBRARY_SOURCES_CPP = %s\n", withcxx);
- } else {
- Printf(f_extra, "LTLIBRARY_SOURCES = %s\n", withc);
- Printf(f_extra, "LTLIBRARY_SOURCES_CPP = %s %s\n", Swig_file_filename(outfile), withcxx);
- Printf(f_extra, "LTLIBRARY_OBJECTS_X = $(LTLIBRARY_SOURCES_CPP:.cpp=.lo) $(LTLIBRARY_SOURCES_CPP:.cxx=.lo)\n");
- }
- Printf(f_extra, "LTLIBRARY_SHARED_NAME = %s.la\n", module);
- Printf(f_extra, "LTLIBRARY_SHARED_LIBADD = $(%s_SHARED_LIBADD)\n\n", cap_module);
- Printf(f_extra, "include $(top_srcdir)/build/dynlib.mk\n");
- Printf(f_extra, "\n# patch in .cxx support to php build system to work like .cpp\n");
- Printf(f_extra, ".SUFFIXES: .cxx\n\n");
- Printf(f_extra, ".cxx.o:\n");
- Printf(f_extra, "\t$(CXX_COMPILE) -c $<\n\n");
- Printf(f_extra, ".cxx.lo:\n");
- Printf(f_extra, "\t$(CXX_PHP_COMPILE)\n\n");
- Printf(f_extra, ".cxx.slo:\n");
- Printf(f_extra, "\t$(CXX_SHARED_COMPILE)\n\n");
- Printf(f_extra, "\n# make it easy to test module\n");
- Printf(f_extra, "testmodule:\n");
- Printf(f_extra, "\tphp -q -d extension_dir=modules %s\n\n", Swig_file_filename(phpfilename));
- Close(f_extra);
- /* Now config.m4 */
- // Note: # comments are OK in config.m4 if you don't mind them
- // appearing in the final ./configure file
- // (which can help with ./configure debugging)
- // NOTE2: phpize really ought to be able to write out a sample
- // config.m4 based on some simple data, I'll take this up with
- // the php folk!
- f_extra = NewFile(configm4, "w");
- if (!f_extra) {
- FileErrorDisplay(configm4);
- SWIG_exit(EXIT_FAILURE);
- }
- Printf(f_extra, "dnl $Id: php4.cxx 9505 2006-11-01 23:54:54Z wsfulton $\n");
- Printf(f_extra, "dnl ***********************************************************************\n");
- Printf(f_extra, "dnl ** THIS config.m4 is provided for PHPIZE and PHP's consumption NOT\n");
- Printf(f_extra, "dnl ** for any part of the rest of the %s build system\n", module);
- Printf(f_extra, "dnl ***********************************************************************\n\n");
- if (!with) { // must be enable then
- Printf(f_extra, "PHP_ARG_ENABLE(%s, whether to enable %s support,\n", module, module);
- Printf(f_extra, "[ --enable-%s Enable %s support])\n\n", module, module);
- } else {
- Printf(f_extra, "PHP_ARG_WITH(%s, for %s support,\n", module, module);
- Printf(f_extra, "[ --with-%s[=DIR] Include %s support.])\n\n", module, module);
- // These tests try and file the library we need
- Printf(f_extra, "dnl THESE TESTS try and find the library and header files\n");
- Printf(f_extra, "dnl your new php module needs. YOU MAY NEED TO EDIT THEM\n");
- Printf(f_extra, "dnl as written they assume your header files are all in the same place\n\n");
- Printf(f_extra, "dnl ** are we looking for %s_lib.h or something else?\n", module);
- if (withincs)
- Printf(f_extra, "HNAMES=\"%s\"\n\n", withincs);
- else
- Printf(f_extra, "HNAMES=\"\"; # %s_lib.h ?\n\n", module);
- Printf(f_extra, "dnl ** Are we looking for lib%s.a or lib%s.so or something else?\n", module, module);
- if (withlibs)
- Printf(f_extra, "LIBNAMES=\"%s\"\n\n", withlibs);
- else
- Printf(f_extra, "LIBNAMES=\"\"; # lib%s.so ?\n\n", module);
- Printf(f_extra, "dnl IF YOU KNOW one of the symbols in the library and you\n");
- Printf(f_extra, "dnl specify it below then we can have a link test to see if it works\n");
- Printf(f_extra, "LIBSYMBOL=\"\"\n\n");
- }
- // Now write out tests to find thing.. they may need to extend tests
- Printf(f_extra, "if test \"$PHP_%s\" != \"no\"; then\n\n", cap_module);
- // Ready for when we add libraries as we find them
- Printf(f_extra, " PHP_SUBST(%s_SHARED_LIBADD)\n\n", cap_module);
- if (withlibs) { // find more than one library
- Printf(f_extra, " for LIBNAME in $LIBNAMES ; do\n");
- Printf(f_extra, " LIBDIR=\"\"\n");
- // For each path element to try...
- Printf(f_extra, " for i in $PHP_%s $PHP_%s/lib /usr/lib /usr/local/lib ; do\n", cap_module, cap_module);
- Printf(f_extra, " if test -r $i/lib$LIBNAME.a -o -r $i/lib$LIBNAME.so ; then\n");
- Printf(f_extra, " LIBDIR=\"$i\"\n");
- Printf(f_extra, " break\n");
- Printf(f_extra, " fi\n");
- Printf(f_extra, " done\n\n");
- Printf(f_extra, " dnl ** and $LIBDIR should be the library path\n");
- Printf(f_extra, " if test \"$LIBNAME\" != \"\" -a -z \"$LIBDIR\" ; then\n");
- Printf(f_extra, " AC_MSG_RESULT(Library files $LIBNAME not found)\n");
- Printf(f_extra, " AC_MSG_ERROR(Is the %s distribution installed properly?)\n", module);
- Printf(f_extra, " else\n");
- Printf(f_extra, " AC_MSG_RESULT(Library files $LIBNAME found in $LIBDIR)\n");
- Printf(f_extra, " PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $LIBDIR, %s_SHARED_LIBADD)\n", cap_module);
- Printf(f_extra, " fi\n");
- Printf(f_extra, " done\n\n");
- }
- if (withincs) { // Find more than once include
- Printf(f_extra, " for HNAME in $HNAMES ; do\n");
- Printf(f_extra, " INCDIR=\"\"\n");
- // For each path element to try...
- 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,
- cap_module, cap_module, cap_module, cap_module);
- // Try and find header files
- Printf(f_extra, " if test \"$HNAME\" != \"\" -a -r $i/$HNAME ; then\n");
- Printf(f_extra, " INCDIR=\"$i\"\n");
- Printf(f_extra, " break\n");
- Printf(f_extra, " fi\n");
- Printf(f_extra, " done\n\n");
- Printf(f_extra, " dnl ** Now $INCDIR should be the include file path\n");
- Printf(f_extra, " if test \"$HNAME\" != \"\" -a -z \"$INCDIR\" ; then\n");
- Printf(f_extra, " AC_MSG_RESULT(Include files $HNAME not found)\n");
- Printf(f_extra, " AC_MSG_ERROR(Is the %s distribution installed properly?)\n", module);
- Printf(f_extra, " else\n");
- Printf(f_extra, " AC_MSG_RESULT(Include files $HNAME found in $INCDIR)\n");
- Printf(f_extra, " PHP_ADD_INCLUDE($INCDIR)\n");
- Printf(f_extra, " fi\n\n");
- Printf(f_extra, " done\n\n");
- }
- if (CPlusPlus) {
- Printf(f_extra, " # As this is a C++ module..\n");
- }
- Printf(f_extra, " PHP_REQUIRE_CXX\n");
- Printf(f_extra, " AC_CHECK_LIB(stdc++, cin)\n");
- if (with) {
- Printf(f_extra, " if test \"$LIBSYMBOL\" != \"\" ; then\n");
- Printf(f_extra, " old_LIBS=\"$LIBS\"\n");
- Printf(f_extra, " LIBS=\"$LIBS -L$TEST_DIR/lib -lm -ldl\"\n");
- Printf(f_extra, " AC_CHECK_LIB($LIBNAME, $LIBSYMBOL, [AC_DEFINE(HAVE_TESTLIB,1, [ ])],\n");
- Printf(f_extra, " [AC_MSG_ERROR(wrong test lib version or lib not found)])\n");
- Printf(f_extra, " LIBS=\"$old_LIBS\"\n");
- Printf(f_extra, " fi\n\n");
- }
- Printf(f_extra, " AC_DEFINE(HAVE_%s, 1, [ ])\n", cap_module);
- Printf(f_extra, "dnl AC_DEFINE_UNQUOTED(PHP_%s_DIR, \"$%s_DIR\", [ ])\n", cap_module, cap_module);
- Printf(f_extra, " PHP_EXTENSION(%s, $ext_shared)\n", module);
- // and thats all!
- Printf(f_extra, "fi\n");
- Close(f_extra);
- /* CREDITS */
- f_extra = NewFile(credits, "w");
- if (!f_extra) {
- FileErrorDisplay(credits);
- SWIG_exit(EXIT_FAILURE);
- }
- Printf(f_extra, "%s\n", module);
- Close(f_extra);
- }
- /* ------------------------------------------------------------
- * top()
- * ------------------------------------------------------------ */
- virtual int top(Node *n) {
- String *filen;
- String *s_type;
- /* Initialize all of the output files */
- String *outfile = Getattr(n, "outfile");
- /* main output file */
- f_runtime = NewFile(outfile, "w");
- if (!f_runtime) {
- FileErrorDisplay(outfile);
- SWIG_exit(EXIT_FAILURE);
- }
- Swig_banner(f_runtime);
- /* sections of the output file */
- s_init = NewString("/* init section */\n");
- r_init = NewString("/* rinit section */\n");
- s_shutdown = NewString("/* shutdown section */\n");
- r_shutdown = NewString("/* rshutdown section */\n");
- s_header = NewString("/* header section */\n");
- s_wrappers = NewString("/* wrapper section */\n");
- s_type = NewStringEmpty();
- /* subsections of the init section */
- s_vinit = NewString("/* vinit subsection */\n");
- s_vdecl = NewString("/* vdecl subsection */\n");
- s_cinit = NewString("/* cinit subsection */\n");
- s_oinit = NewString("/* oinit subsection */\n");
- pragma_phpinfo = NewStringEmpty();
- s_phpclasses = NewString("/* PHP Proxy Classes */\n");
- /* Register file targets with the SWIG file handler */
- Swig_register_filebyname("runtime", f_runtime);
- Swig_register_filebyname("init", s_init);
- Swig_register_filebyname("rinit", r_init);
- Swig_register_filebyname("shutdown", s_shutdown);
- Swig_register_filebyname("rshutdown", r_shutdown);
- Swig_register_filebyname("header", s_header);
- Swig_register_filebyname("wrapper", s_wrappers);
- /* Set the module name */
- module = Copy(Getattr(n, "name"));
- cap_module = NewStringf("%(upper)s", module);
- if (!prefix)
- prefix = NewStringEmpty();
- /* PHP module file */
- filen = NewStringEmpty();
- Printv(filen, SWIG_output_directory(), module, ".php", NIL);
- phpfilename = NewString(filen);
- f_phpcode = NewFile(filen, "w");
- if (!f_phpcode) {
- FileErrorDisplay(filen);
- SWIG_exit(EXIT_FAILURE);
- }
- Printf(f_phpcode, "<?php\n\n");
- Swig_banner(f_phpcode);
- Printf(f_phpcode, "// Try to load our extension if it's not already loaded.\n");
- Printf(f_phpcode, "if (!extension_loaded(\"%s\")) {\n", module);
- Printf(f_phpcode, " if (strtolower(substr(PHP_OS, 0, 3)) === 'win') {\n");
- Printf(f_phpcode, " if (!dl('php_%s.dll')) return;\n", module);
- Printf(f_phpcode, " } else {\n");
- Printf(f_phpcode, " // PHP_SHLIB_SUFFIX is available as of PHP 4.3.0, for older PHP assume 'so'.\n");
- Printf(f_phpcode, " // It gives 'dylib' on MacOS X which is for libraries, modules are 'so'.\n");
- Printf(f_phpcode, " if (PHP_SHLIB_SUFFIX === 'PHP_SHLIB_SUFFIX' || PHP_SHLIB_SUFFIX === 'dylib') {\n");
- Printf(f_phpcode, " if (!dl('%s.so')) return;\n", module);
- Printf(f_phpcode, " } else {\n");
- Printf(f_phpcode, " if (!dl('%s.'.PHP_SHLIB_SUFFIX)) return;\n", module);
- Printf(f_phpcode, " }\n");
- Printf(f_phpcode, " }\n");
- Printf(f_phpcode, "}\n\n");
- /* sub-sections of the php file */
- pragma_code = NewStringEmpty();
- pragma_incl = NewStringEmpty();
- /* Initialize the rest of the module */
- Printf(s_oinit, "ZEND_INIT_MODULE_GLOBALS(%s, %s_init_globals, %s_destroy_globals);\n", module, module, module);
- /* start the header section */
- Printf(s_header, php_header);
- Printf(s_header, "ZEND_BEGIN_MODULE_GLOBALS(%s)\n", module);
- Printf(s_header, "char *error_msg;\n");
- Printf(s_header, "int error_code;\n");
- Printf(s_header, "ZEND_END_MODULE_GLOBALS(%s)\n", module);
- Printf(s_header, "ZEND_DECLARE_MODULE_GLOBALS(%s)\n", module);
- Printf(s_header, "#ifdef ZTS\n");
- Printf(s_header, "#define SWIG_ErrorMsg() TSRMG(%s_globals_id, zend_%s_globals *, error_msg )\n", module, module);
- Printf(s_header, "#define SWIG_ErrorCode() TSRMG(%s_globals_id, zend_%s_globals *, error_code )\n", module, module);
- Printf(s_header, "#else\n");
- Printf(s_header, "#define SWIG_ErrorMsg() (%s_globals.error_msg)\n", module);
- Printf(s_header, "#define SWIG_ErrorCode() (%s_globals.error_code)\n", module);
- Printf(s_header, "#endif\n\n");
- Printf(s_header, "static void %s_init_globals(zend_%s_globals *globals ) {\n", module, module);
- Printf(s_header, " globals->error_msg = default_error_msg;\n");
- Printf(s_header, " globals->error_code = default_error_code;\n");
- Printf(s_header, "}\n");
- Printf(s_header, "static void %s_destroy_globals(zend_%s_globals * globals) { (void)globals; }\n", module, module);
- Printf(s_header, "\n");
- Printf(s_header, "static void SWIG_ResetError() {\n");
- Printf(s_header, " TSRMLS_FETCH();\n");
- Printf(s_header, " SWIG_ErrorMsg() = default_error_msg;\n");
- Printf(s_header, " SWIG_ErrorCode() = default_error_code;\n");
- Printf(s_header, "}\n");
- Printf(s_header, "#define SWIG_name \"%s\"\n", module);
- /* Printf(s_header,"#ifdef HAVE_CONFIG_H\n");
- Printf(s_header,"#include \"config.h\"\n");
- Printf(s_header,"#endif\n\n");
- */
- Printf(s_header, "#ifdef __cplusplus\n");
- Printf(s_header, "extern \"C\" {\n");
- Printf(s_header, "#endif\n");
- Printf(s_header, "#include \"php.h\"\n");
- Printf(s_header, "#include \"php_ini.h\"\n");
- Printf(s_header, "#include \"ext/standard/info.h\"\n");
- Printf(s_header, "#include \"php_%s.h\"\n", module);
- Printf(s_header, "#ifdef __cplusplus\n");
- Printf(s_header, "}\n");
- Printf(s_header, "#endif\n\n");
- /* Create the .h file too */
- filen = NewStringEmpty();
- Printv(filen, SWIG_output_directory(), "php_", module, ".h", NIL);
- f_h = NewFile(filen, "w");
- if (!f_h) {
- FileErrorDisplay(filen);
- SWIG_exit(EXIT_FAILURE);
- }
- Swig_banner(f_h);
- Printf(f_h, php_header);
- Printf(f_h, "\n\n");
- Printf(f_h, "#ifndef PHP_%s_H\n", cap_module);
- Printf(f_h, "#define PHP_%s_H\n\n", cap_module);
- Printf(f_h, "extern zend_module_entry %s_module_entry;\n", module);
- Printf(f_h, "#define phpext_%s_ptr &%s_module_entry\n\n", module, module);
- Printf(f_h, "#ifdef PHP_WIN32\n");
- Printf(f_h, "# define PHP_%s_API __declspec(dllexport)\n", cap_module);
- Printf(f_h, "#else\n");
- Printf(f_h, "# define PHP_%s_API\n", cap_module);
- Printf(f_h, "#endif\n\n");
- Printf(f_h, "#ifdef ZTS\n");
- Printf(f_h, "#include \"TSRM.h\"\n");
- Printf(f_h, "#endif\n\n");
- Printf(f_h, "PHP_MINIT_FUNCTION(%s);\n", module);
- Printf(f_h, "PHP_MSHUTDOWN_FUNCTION(%s);\n", module);
- Printf(f_h, "PHP_RINIT_FUNCTION(%s);\n", module);
- Printf(f_h, "PHP_RSHUTDOWN_FUNCTION(%s);\n", module);
- Printf(f_h, "PHP_MINFO_FUNCTION(%s);\n\n", module);
- /* start the function entry section */
- s_entry = NewString("/* entry subsection */\n");
- /* holds all the per-class function entry sections */
- all_cs_entry = NewString("/* class entry subsection */\n");
- cs_entry = NULL;
- Printf(s_entry, "/* Every non-class user visible function must have an entry here */\n");
- Printf(s_entry, "static function_entry %s_functions[] = {\n", module);
- /* start the init section */
- Printv(s_init, "zend_module_entry ", module, "_module_entry = {\n" "#if ZEND_MODULE_API_NO > 20010900\n" " STANDARD_MODULE_HEADER,\n" "#endif\n", NIL);
- Printf(s_init, " \"%s\",\n", module);
- Printf(s_init, " %s_functions,\n", module);
- Printf(s_init, " PHP_MINIT(%s),\n", module);
- Printf(s_init, " PHP_MSHUTDOWN(%s),\n", module);
- Printf(s_init, " PHP_RINIT(%s),\n", module);
- Printf(s_init, " PHP_RSHUTDOWN(%s),\n", module);
- Printf(s_init, " PHP_MINFO(%s),\n", module);
- Printf(s_init, "#if ZEND_MODULE_API_NO > 20010900\n");
- Printf(s_init, " NO_VERSION_YET,\n");
- Printf(s_init, "#endif\n");
- Printf(s_init, " STANDARD_MODULE_PROPERTIES\n");
- Printf(s_init, "};\n");
- Printf(s_init, "zend_module_entry* SWIG_module_entry = &%s_module_entry;\n\n", module);
- if (gen_extra) {
- Printf(s_init, "#ifdef COMPILE_DL_%s\n", cap_module);
- }
- Printf(s_init, "#ifdef __cplusplus\n");
- Printf(s_init, "extern \"C\" {\n");
- Printf(s_init, "#endif\n");
- // We want to write "SWIGEXPORT ZEND_GET_MODULE(%s)" but ZEND_GET_MODULE
- // in PHP5 has "extern "C" { ... }" around it so we can't do that.
- Printf(s_init, "SWIGEXPORT zend_module_entry *get_module(void) { return &%s_module_entry; }\n", module);
- Printf(s_init, "#ifdef __cplusplus\n");
- Printf(s_init, "}\n");
- Printf(s_init, "#endif\n\n");
- if (gen_extra) {
- Printf(s_init, "#endif\n\n");
- }
- /* We have to register the constants before they are (possibly) used
- * by the pointer typemaps. This all needs re-arranging really as
- * things are being called in the wrong order
- */
- Printf(s_init, "#define SWIG_php_minit PHP_MINIT_FUNCTION(%s)\n", module);
- /* Emit all of the code */
- Language::top(n);
- SwigPHP_emit_resource_registrations();
- // Printv(s_init,s_resourcetypes,NIL);
- /* We need this after all classes written out by ::top */
- Printf(s_oinit, "CG(active_class_entry) = NULL;\n");
- Printf(s_oinit, "/* end oinit subsection */\n");
- Printf(s_init, "%s\n", s_oinit);
- /* Constants generated during top call */
- Printf(s_cinit, "/* end cinit subsection */\n");
- Printf(s_init, "%s\n", s_cinit);
- Clear(s_cinit);
- Delete(s_cinit);
- Printf(s_init, " return SUCCESS;\n");
- Printf(s_init, "}\n\n");
- // Now do REQUEST init which holds any user specified %rinit, and also vinit
- Printf(s_init, "PHP_RINIT_FUNCTION(%s)\n{\n", module);
- Printf(s_init, "%s\n", r_init);
- /* finish our init section which will have been used by class wrappers */
- Printf(s_vinit, "/* end vinit subsection */\n");
- Printf(s_init, "%s\n", s_vinit);
- Clear(s_vinit);
- Delete(s_vinit);
- Printf(s_init, " return SUCCESS;\n");
- Printf(s_init, "}\n\n");
- Printf(s_init, "PHP_MSHUTDOWN_FUNCTION(%s)\n{\n", module);
- Printf(s_init, "%s\n", s_shutdown);
- Printf(s_init, " return SUCCESS;\n");
- Printf(s_init, "}\n\n");
- Printf(s_init, "PHP_RSHUTDOWN_FUNCTION(%s)\n{\n", module);
- Printf(s_init, "%s\n", r_shutdown);
- Printf(s_init, " return SUCCESS;\n");
- Printf(s_init, "}\n\n");
- Printf(s_init, "PHP_MINFO_FUNCTION(%s)\n{\n", module);
- Printf(s_init, "%s", pragma_phpinfo);
- Printf(s_init, "}\n");
- Printf(s_init, "/* end init section */\n");
- Printf(f_h, "#endif /* PHP_%s_H */\n", cap_module);
- Close(f_h);
- String *type_table = NewStringEmpty();
- SwigType_emit_type_table(f_runtime, type_table);
- Printf(s_header, "%s", type_table);
- Delete(type_table);
- /* Oh dear, more things being called in the wrong order. This whole
- * function really needs totally redoing.
- */
- Printf(s_header, "/* end header section */\n");
- Printf(s_wrappers, "/* end wrapper section */\n");
- Printf(s_vdecl, "/* end vdecl subsection */\n");
- Printv(f_runtime, s_header, s_vdecl, s_wrappers, NIL);
- Printv(f_runtime, all_cs_entry, "\n\n", s_entry, "{NULL, NULL, NULL}\n};\n\n", NIL);
- Printv(f_runtime, s_init, NIL);
- Delete(s_header);
- Delete(s_wrappers);
- Delete(s_init);
- Delete(s_vdecl);
- Delete(all_cs_entry);
- Delete(s_entry);
- Close(f_runtime);
- Printf(f_phpcode, "%s\n%s\n", pragma_incl, pragma_code);
- if (s_fakeoowrappers) {
- Printf(f_phpcode, "abstract class %s {", Len(prefix) ? prefix : module);
- Printf(f_phpcode, "%s", s_fakeoowrappers);
- Printf(f_phpcode, "}\n\n");
- Delete(s_fakeoowrappers);
- s_fakeoowrappers = NULL;
- }
- Printf(f_phpcode, "%s\n?>\n", s_phpclasses);
- Close(f_phpcode);
- if (gen_extra) {
- create_extra_files(outfile);
- } else if (gen_make) {
- create_simple_make();
- }
- return SWIG_OK;
- }
- /* Just need to append function names to function table to register with PHP. */
- void create_command(String *cname, String *iname) {
- // This is for the single main function_entry record
- if (shadow && php_version == 4) {
- if (wrapperType != standard)
- return;
- }
- Printf(f_h, "ZEND_NAMED_FUNCTION(%s);\n", iname);
- if (cs_entry) {
- Printf(cs_entry, " ZEND_NAMED_FE(%(lower)s,%s,NULL)\n", cname, iname);
- } else {
- Printf(s_entry, " ZEND_NAMED_FE(%(lower)s,%s,NULL)\n", cname, iname);
- }
- }
- /* ------------------------------------------------------------
- * dispatchFunction()
- * ------------------------------------------------------------ */
- void dispatchFunction(Node *n) {
- /* Last node in overloaded chain */
- int maxargs;
- String *tmp = NewStringEmpty();
- String *dispatch = Swig_overload_dispatch(n, "return %s(INTERNAL_FUNCTION_PARAM_PASSTHRU);", &maxargs);
- int has_this_ptr = (wrapperType == memberfn && shadow && php_version == 4);
- /* Generate a dispatch wrapper for all overloaded functions */
- Wrapper *f = NewWrapper();
- String *symname = Getattr(n, "sym:name");
- String *wname = Swig_name_wrapper(symname);
- create_command(symname, wname);
- Printv(f->def, "ZEND_NAMED_FUNCTION(", wname, ") {\n", NIL);
- Wrapper_add_local(f, "argc", "int argc");
- Printf(tmp, "zval **argv[%d]", maxargs);
- Wrapper_add_local(f, "argv", tmp);
- Printf(f->code, "argc = ZEND_NUM_ARGS();\n");
- if (has_this_ptr) {
- Printf(f->code, "argv[0] = &this_ptr;\n");
- Printf(f->code, "zend_get_parameters_array_ex(argc,argv+1);\n");
- Printf(f->code, "argc++;\n");
- } else {
- Printf(f->code, "zend_get_parameters_array_ex(argc,argv);\n");
- }
- Replaceall(dispatch, "$args", "self,args");
- Printv(f->code, dispatch, "\n", NIL);
- Printf(f->code, "SWIG_ErrorCode() = E_ERROR;\n");
- Printf(f->code, "SWIG_ErrorMsg() = \"No matching function for overloaded '%s'\";\n", symname);
- Printv(f->code, "zend_error(SWIG_ErrorCode(),SWIG_ErrorMsg());\n", NIL);
- Printv(f->code, "}\n", NIL);
- Wrapper_print(f, s_wrappers);
- DelWrapper(f);
- Delete(dispatch);
- Delete(tmp);
- Delete(wname);
- }
- /* ------------------------------------------------------------
- * functionWrapper()
- * ------------------------------------------------------------ */
- /* Helper method for PHP::functionWrapper */
- bool is_class(SwigType *t) {
- Node *n = classLookup(t);
- if (n) {
- String *r = Getattr(n, "php:proxy"); // Set by classDeclaration()
- if (!r)
- r = Getattr(n, "sym:name"); // Not seen by classDeclaration yet, but this is the name
- if (r)
- return true;
- }
- return false;
- }
- virtual int functionWrapper(Node *n) {
- String *name = GetChar(n, "name");
- String *iname = GetChar(n, "sym:name");
- SwigType *d = Getattr(n, "type");
- ParmList *l = Getattr(n, "parms");
- String *nodeType = Getattr(n, "nodeType");
- int newobject = GetFlag(n, "feature:new");
- Parm *p;
- int i, numopt;
- String *tm;
- Wrapper *f;
- bool mvr = (shadow && php_version == 4 && wrapperType == membervar);
- bool mvrset = (mvr && (Strcmp(iname, Swig_name_set(Swig_name_member(shadow_classname, name))) == 0));
- String *wname;
- int overloaded = 0;
- String *overname = 0;
- if (Cmp(nodeType, "destructor") == 0) {
- // We just generate the Zend List Destructor and let Zend manage the
- // reference counting. There's no explicit destructor, but the user can
- // just do `$obj = null;' to remove a reference to an object.
- return CreateZendListDestructor(n);
- }
- // Test for overloading;
- if (Getattr(n, "sym:overloaded")) {
- overloaded = 1;
- overname = Getattr(n, "sym:overname");
- } else {
- if (!addSymbol(iname, n))
- return SWIG_ERROR;
- }
- wname = Swig_name_wrapper(iname);
- if (overname) {
- Printf(wname, "%s", overname);
- }
- // if PHP4, shadow and variable wrapper we want to snag the main contents
- // of this function to stick in to the property handler...
- if (mvr) {
- String *php_function_name = NewString(iname);
- if (Strcmp(iname, Swig_name_set(Swig_name_member(shadow_classname, name))) == 0) {
- Setattr(shadow_set_vars, php_function_name, name);
- }
- if (Strcmp(iname, Swig_name_get(Swig_name_member(shadow_classname, name))) == 0) {
- Setattr(shadow_get_vars, php_function_name, name);
- }
- Delete(php_function_name);
- }
- f = NewWrapper();
- numopt = 0;
- String *outarg = NewStringEmpty();
- String *cleanup = NewStringEmpty();
- if (mvr) { // do prop[gs]et header
- if (mvrset) {
- Printf(f->def, "static int _wrap_%s(zend_property_reference *property_reference, pval *value) {\n", iname);
- } else {
- Printf(f->def, "static pval _wrap_%s(zend_property_reference *property_reference) {\n", iname);
- }
- } else {
- // regular header
- // Not issued for overloaded functions or static member variables.
- if (!overloaded && wrapperType != staticmembervar) {
- create_command(iname, wname);
- }
- Printv(f->def, "ZEND_NAMED_FUNCTION(", wname, ") {\n", NIL);
- }
- emit_args(d, l, f);
- /* Attach standard typemaps */
- emit_attach_parmmaps(l, f);
- // wrap:parms is used by overload resolution.
- Setattr(n, "wrap:parms", l);
- int num_arguments = emit_num_arguments(l);
- int num_required = emit_num_required(l);
- numopt = num_arguments - num_required;
- int has_this_ptr = (wrapperType == memberfn && shadow && php_version == 4);
- if (num_arguments - has_this_ptr > 0) {
- String *args = NewStringf("zval **args[%d]", num_arguments - has_this_ptr);
- Wrapper_add_local(f, "args", args);
- Delete(args);
- args = NULL;
- }
- // This generated code may be called:
- // 1) as an object method, or
- // 2) as a class-method/function (without a "this_ptr")
- // Option (1) has "this_ptr" for "this", option (2) needs it as
- // first parameter
- // NOTE: possible we ignore this_ptr as a param for native constructor
- Printf(f->code, "SWIG_ResetError();\n");
- if (has_this_ptr)
- Printf(f->code, "/* This function uses a this_ptr*/\n");
- if (native_constructor) {
- if (native_constructor == NATIVE_CONSTRUCTOR) {
- Printf(f->code, "/* NATIVE Constructor */\n");
- } else {
- Printf(f->code, "/* ALTERNATIVE Constructor */\n");
- }
- }
- if (mvr && !mvrset) {
- Wrapper_add_local(f, "_return_value", "zval _return_value");
- Wrapper_add_local(f, "return_value", "zval *return_value=&_return_value");
- }
- if (numopt > 0) { // membervariable wrappers do not have optional args
- Wrapper_add_local(f, "arg_count", "int arg_count");
- Printf(f->code, "arg_count = ZEND_NUM_ARGS();\n");
- Printf(f->code, "if(arg_count<%d || arg_count>%d ||\n", num_required, num_arguments);
- Printf(f->code, " zend_get_parameters_array_ex(arg_count,args)!=SUCCESS)\n");
- Printf(f->code, "\tWRONG_PARAM_COUNT;\n\n");
- } else if (!mvr) {
- int num = num_arguments - has_this_ptr;
- if (num == 0) {
- Printf(f->code, "if(ZEND_NUM_ARGS() != 0) {\n");
- } else {
- Printf(f->code, "if(ZEND_NUM_ARGS() != %d || zend_get_parameters_array_ex(%d, args) != SUCCESS) {\n", num, num);
- }
- Printf(f->code, "WRONG_PARAM_COUNT;\n}\n\n");
- }
- /* Now convert from php to C variables */
- // At this point, argcount if used is the number of deliberately passed args
- // not including this_ptr even if it is used.
- // It means error messages may be out by argbase with error
- // reports. We can either take argbase into account when raising
- // errors, or find a better way of dealing with _thisptr.
- // I would like, if objects are wrapped, to assume _thisptr is always
- // _this and not the first argument.
- // This may mean looking at Language::memberfunctionHandler
- for (i = 0, p = l; i < num_arguments; i++) {
- String *source;
- /* Skip ignored arguments */
- //while (Getattr(p,"tmap:ignore")) { p = Getattr(p,"tmap:ignore:next");}
- while (checkAttribute(p, "tmap:in:numinputs", "0")) {
- p = Getattr(p, "tmap:in:next");
- }
- SwigType *pt = Getattr(p, "type");
- if (mvr) { // do we assert that numargs=2, that i<2
- if (i == 0) {
- source = NewString("&(property_reference->object)");
- } else {
- source = NewString("&value");
- }
- } else {
- if (i == 0 && has_this_ptr) {
- source = NewString("&this_ptr");
- } else {
- source = NewStringf("args[%d]", i - has_this_ptr);
- }
- }
- String *ln = Getattr(p, "lname");
- /* Check if optional */
- if (i >= num_required) {
- Printf(f->code, "\tif(arg_count > %d) {\n", i);
- }
- if ((tm = Getattr(p, "tmap:in"))) {
- Replaceall(tm, "$source", source);
- Replaceall(tm, "$target", ln);
- Replaceall(tm, "$input", source);
- Setattr(p, "emit:input", source);
- Printf(f->code, "%s\n", tm);
- if (i == 0 && HashGetAttr(p, k_self)) {
- Printf(f->code, "\tif(!arg1) SWIG_PHP_Error(E_ERROR, \"this pointer is NULL\");\n");
- }
- p = Getattr(p, "tmap:in:next");
- if (i >= num_required) {
- Printf(f->code, "}\n");
- }
- continue;
- } else {
- Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
- }
- if (i >= num_required) {
- Printf(f->code, "\t}\n");
- }
- Delete(source);
- }
- /* Insert constraint checking code */
- for (p = l; p;) {
- if ((tm = Getattr(p, "tmap:check"))) {
- Replaceall(tm, "$target", Getattr(p, "lname"));
- Printv(f->code, tm, "\n", NIL);
- p = Getattr(p, "tmap:check:next");
- } else {
- p = nextSibling(p);
- }
- }
- /* Insert cleanup code */
- for (i = 0, p = l; p; i++) {
- if ((tm = Getattr(p, "tmap:freearg"))) {
- Replaceall(tm, "$source", Getattr(p, "lname"));
- Printv(cleanup, tm, "\n", NIL);
- p = Getattr(p, "tmap:freearg:next");
- } else {
- p = nextSibling(p);
- }
- }
- /* Insert argument output code */
- for (i = 0, p = l; p; i++) {
- if ((tm = Getattr(p, "tmap:argout"))) {
- Replaceall(tm, "$source", Getattr(p, "lname"));
- // Replaceall(tm,"$input",Getattr(p,"lname"));
- Replaceall(tm, "$target", "return_value");
- Replaceall(tm, "$result", "return_value");
- Replaceall(tm, "$arg", Getattr(p, "emit:input"));
- Replaceall(tm, "$input", Getattr(p, "emit:input"));
- Printv(outarg, tm, "\n", NIL);
- p = Getattr(p, "tmap:argout:next");
- } else {
- p = nextSibling(p);
- }
- }
- /* emit function call */
- emit_action(n, f);
- if ((tm = Swig_typemap_lookup_new("out", n, "result", 0))) {
- Replaceall(tm, "$input", "result");
- Replaceall(tm, "$source", "result");
- Replaceall(tm, "$target", "return_value");
- Replaceall(tm, "$result", "return_value");
- Replaceall(tm, "$owner", newobject ? "1" : "0");
- Printf(f->code, "%s\n", tm);
- // are we returning a wrapable object?
- // I don't know if this test is complete, I nicked it
- if (is_shadow(d) && (SwigType_type(d) != T_ARRAY)) {
- Printf(f->code, "/* Wrap this return value */\n");
- if (native_constructor == NATIVE_CONSTRUCTOR) {
- Printf(f->code, "if (this_ptr) {\n");
- Printf(f->code, "/* NATIVE Constructor, use this_ptr */\n");
- Printf(f->code, "zval *_cPtr; MAKE_STD_ZVAL(_cPtr);\n");
- Printf(f->code, "*_cPtr = *return_value;\n");
- Printf(f->code, "INIT_ZVAL(*return_value);\n");
- Printf(f->code, "add_property_zval(this_ptr,\"" SWIG_PTR "\",_cPtr);\n");
- Printf(f->code, "} else if (! this_ptr) ");
- }
- { // THIS CODE only really needs writing out if the object to be returned
- // Is being shadow-wrap-thingied
- Printf(f->code, "{\n/* ALTERNATIVE Constructor, make an object wrapper */\n");
- // Make object
- String *shadowrettype = NewStringEmpty();
- SwigToPhpType(d, iname, shadowrettype, (shadow && php_version == 4));
- Printf(f->code, "zval *obj, *_cPtr;\n");
- Printf(f->code, "MAKE_STD_ZVAL(obj);\n");
- Printf(f->code, "MAKE_STD_ZVAL(_cPtr);\n");
- Printf(f->code, "*_cPtr = *return_value;\n");
- Printf(f->code, "INIT_ZVAL(*return_value);\n");
- if (shadow && php_version == 4) {
- Printf(f->code, "object_init_ex(obj,ptr_ce_swig_%s);\n", shadowrettype);
- Printf(f->code, "add_property_zval(obj,\"" SWIG_PTR "\",_cPtr);\n");
- Printf(f->code, "*return_value=*obj;\n");
- } else {
- Printf(f->code, "*return_value=*_cPtr;\n");
- }
- Printf(f->code, "}\n");
- }
- } // end of if-shadow lark
- } else {
- 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);
- }
- if (outarg) {
- Printv(f->code, outarg, NIL);
- }
- if (cleanup) {
- Printv(f->code, cleanup, NIL);
- }
- // What's this bit for?
- if ((tm = Swig_typemap_lookup_new("ret", n, "result", 0))) {
- Printf(f->code, "%s\n", tm);
- }
- if (mvr) {
- if (!mvrset) {
- Printf(f->code, "return _return_value;\n");
- } else {
- Printf(f->code, "return SUCCESS;\n");
- }
- } else {
- Printf(f->code, "return;\n");
- }
- /* Error handling code */
- Printf(f->code, "fail:\n");
- Printv(f->code, cleanup, NIL);
- Printv(f->code, "zend_error(SWIG_ErrorCode(),SWIG_ErrorMsg());", NIL);
- Printf(f->code, "}\n");
- Replaceall(f->code, "$cleanup", cleanup);
- Replaceall(f->code, "$symname", iname);
- Wrapper_print(f, s_wrappers);
- // wrap:name is used by overload resolution
- Setattr(n, "wrap:name", wname);
- if (overloaded && !Getattr(n, "sym:nextSibling")) {
- dispatchFunction(n);
- }
- Delete(wname);
- wname = NULL;
- if (!(shadow && php_version == 5))
- return SWIG_OK;
- // Handle getters and setters.
- if (wrapperType == membervar) {
- const char *p = Char(iname);
- if (strlen(p) > 4) {
- p += strlen(p) - 4;
- String *varname = Getattr(n, "membervariableHandler:sym:name");
- if (strcmp(p, "_get") == 0) {
- Setattr(shadow_get_vars, varname, iname);
- } else if (strcmp(p, "_set") == 0) {
- Setattr(shadow_set_vars, varname, iname);
- }
- }
- }
- // Only look at non-overloaded methods and the last entry in each overload
- // chain (we check the last so that wrap:parms and wrap:name have been set
- // for them all).
- if (overloaded && Getattr(n, "sym:nextSibling") != 0)
- return SWIG_OK;
- if (!s_oowrappers)
- s_oowrappers = NewStringEmpty();
- if (newobject || wrapperType == memberfn || wrapperType == staticmemberfn || wrapperType == standard) {
- bool handle_as_overload = false;
- String **arg_names;
- String **arg_values;
- bool *arg_case = NULL;
- // Method or static method or plain function.
- const char *methodname = 0;
- String *output = s_oowrappers;
- if (newobject) {
- class_has_ctor = true;
- methodname = "__construct";
- } else if (wrapperType == memberfn) {
- methodname = Char(Getattr(n, "memberfunctionHandler:sym:name"));
- } else if (wrapperType == staticmemberfn) {
- methodname = Char(Getattr(n, "staticmemberfunctionHandler:sym:name"));
- } else { // wrapperType == standard
- methodname = Char(iname);
- if (!s_fakeoowrappers)
- s_fakeoowrappers = NewStringEmpty();
- output = s_fakeoowrappers;
- }
- bool really_overloaded = overloaded ? true : false;
- int min_num_of_arguments = emit_num_required(l);
- int max_num_of_arguments = emit_num_arguments(l);
- // For a function with default arguments, we end up with the fullest
- // parmlist in full_parmlist.
- ParmList *full_parmlist = l;
- Hash *ret_types = NewHash();
- Setattr(ret_types, d, d);
- if (overloaded) {
- // Look at all the overloaded versions of this method in turn to
- // decide if it's really an overloaded method, or just one where some
- // parameters have default values.
- Node *o = Getattr(n, "sym:overloaded");
- while (o) {
- if (o == n) {
- o = Getattr(o, "sym:nextSibling");
- continue;
- }
- SwigType *d2 = Getattr(o, "type");
- if (!d2) {
- assert(constructor);
- } else if (!Getattr(ret_types, d2)) {
- Setattr(ret_types, d2, d2);
- }
- ParmList *l2 = Getattr(o, "wrap:parms");
- int num_arguments = emit_num_arguments(l2);
- int num_required = emit_num_required(l2);
- if (num_required < min_num_of_arguments)
- min_num_of_arguments = num_required;
- if (num_arguments > max_num_of_arguments) {
- max_num_of_arguments = num_arguments;
- full_parmlist = l2;
- }
- o = Getattr(o, "sym:nextSibling");
- }
- o = Getattr(n, "sym:overloaded");
- while (o) {
- if (o == n) {
- o = Getattr(o, "sym:nextSibling");
- continue;
- }
- ParmList *l2 = Getattr(o, "wrap:parms");
- Parm *p = l, *p2 = l2;
- if (wrapperTy…
Large files files are truncated, but you can click here to view the full file