Index: Source/Modules/php4.cxx
===================================================================
RCS file: /cvsroot/swig/SWIG/Source/Modules/php4.cxx,v
retrieving revision 1.34
diff -p -u -r1.34 php4.cxx
--- Source/Modules/php4.cxx	20 Mar 2006 00:24:39 -0000	1.34
+++ Source/Modules/php4.cxx	20 Apr 2006 04:16:12 -0000
@@ -23,12 +23,13 @@ PHP4 Options (available with -php4)\n\
      -cppext         - cpp file extension (default to .cpp)\n\
      -noproxy        - Don't generate proxy classes.\n\
      -dlname <name>  - Set module prefix to <name>\n\
+     -prefix <name>  - Set a prefix <name> to be prepended to all classnames\n\
      -make           - Create simple makefile\n\
      -phpfull        - Create full make files\n\
-     -withincs <libs>- With -phpfull writes needed incs in config.m4\n\
+     -withincs <incs>- With -phpfull writes needed incs in config.m4\n\
      -withlibs <libs>- With -phpfull writes needed libs in config.m4\n\
-     -withc <libs>   - With -phpfull makes extra c files in Makefile.in\n\
-     -withcxx <libs> - With -phpfull makes extra c++ files in Makefile.in\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";
 
 static int constructors=0;
@@ -37,6 +38,7 @@ static Node *classnode=0;
 static String *module = 0;
 static String *cap_module = 0;
 static String *dlname = 0;
+static String *prefix = 0;
 static String *withlibs = 0;
 static String *withincs = 0;
 static String *withc = 0;
@@ -68,6 +70,9 @@ 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 String     *class_name = 0;
@@ -79,7 +84,13 @@ static Hash     *shadow_set_vars;
 static int      native_constructor=0;
 static Hash     *zend_types = 0;
 
-static int        shadow        = 1;
+static int        shadow        = 0;
+static bool       new_shadow    = true;
+
+static bool     class_has_ctor = false;
+
+static int min_num_of_arguments = -1, max_num_of_arguments = -1;
+static ParmList * full_parmlist = 0;
 
 // These static variables are used to pass some state from Handlers into functionWrapper
 static enum {
@@ -211,6 +222,15 @@ public:
           } else {
             Swig_arg_error();
           }
+	} 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]);
@@ -259,6 +279,7 @@ public:
         }  else if((strcmp(argv[i], "-noshadow") == 0)
                    || (strcmp(argv[i],"-noproxy") == 0)) {
           shadow = 0;
+	  new_shadow = false;
           Swig_mark_arg(i);
         } else if(strcmp(argv[i], "-make") == 0) {
           gen_make = 1;
@@ -546,6 +567,7 @@ public:
     s_cinit = NewString("/* cinit subsection */\n");
     s_oinit = NewString("/* oinit subsection */\n");
     pragma_phpinfo = NewString("");
+    s_phpclasses = NewString("/* PHP Proxy Classes */\n");
     
     /* Register file targets with the SWIG file handler */
     Swig_register_filebyname("runtime",f_runtime);
@@ -559,13 +581,14 @@ public:
     /* Set the module name */
     module = Copy(Getattr(n,"name"));
     cap_module = NewStringf("%(upper)s",module);
-    
+    if (!prefix) prefix = Copy(module);
+
     /* Set the dlname */
     if (!dlname) {
 #if defined(_WIN32) || defined(__WIN32__)
-      dlname = NewStringf("php_%s.dll", module);
+      dlname = NewStringf("%s.dll", module);
 #else
-      dlname = NewStringf("php_%s.so", module);
+      dlname = NewStringf("%s.so", module);
 #endif
     }
     
@@ -584,15 +607,13 @@ public:
     
     Swig_banner(f_phpcode);
     
-    Printf(f_phpcode,"global $%s_LOADED__;\n", cap_module);
-    Printf(f_phpcode,"if ($%s_LOADED__) return;\n", cap_module);
-    Printf(f_phpcode,"$%s_LOADED__ = true;\n\n", cap_module);
-    Printf(f_phpcode,"/* if our extension has not been loaded, do what we can */\n");
-    Printf(f_phpcode,"if (!extension_loaded(\"php_%s\")) {\n", module);
+//    Printf(f_phpcode,"/* Check if this file has already been read in */\n");
+//    Printf(f_phpcode,"if (class_exists(\"%sSwigBase\") ) return;\n", prefix);
+    Printf(f_phpcode,"/* Try to load our extension if it isn't already loaded */\n");
+    Printf(f_phpcode,"if (!extension_loaded(\"%s\")) {\n", module);
     Printf(f_phpcode,"  if (!dl(\"%s\")) return;\n", dlname);
     Printf(f_phpcode,"}\n\n");
     
-    
     /* sub-sections of the php file */
     pragma_code = NewString("");
     pragma_incl = NewString("");
@@ -803,7 +824,30 @@ public:
     Delete(s_init);
     Delete(s_vdecl);
     Close(f_runtime);
-    Printf(f_phpcode, "%s\n%s\n?>\n", pragma_incl, pragma_code);
+
+    Printf(pragma_code, "function swig_wrap_return($res) {\n");
+    Printf(pragma_code, "\tif (is_resource($res)) {\n");
+    Printf(pragma_code, "\t\t$type=explode('_', get_resource_type($res));\n");
+    Printf(pragma_code, "\t\tif (count($type) >= 5 && $type[2] == 'Xapian') {\n");
+    Printf(pragma_code, "\t\t\t$class='Xapian'.$type[4];\n");
+    Printf(pragma_code, "\t\t\treturn new $class($res);\n");
+    Printf(pragma_code, "\t\t}\n");
+    Printf(pragma_code, "\t}\n");
+    Printf(pragma_code, "\treturn $res;\n");
+    Printf(pragma_code, "}\n\n");
+
+    Printf(pragma_code, "abstract class %sSwigBase {\n", prefix);
+    Printf(pragma_code, "}\n\n");
+
+    Printf(f_phpcode, "%s\n%s\n", pragma_incl, pragma_code);
+    if (s_fakeoowrappers) {
+      Printf(f_phpcode, "abstract class %s {\n", prefix);
+      Printf(f_phpcode, "%s", s_fakeoowrappers);
+      Printf(f_phpcode, "}\n\n", prefix);
+      Delete(s_fakeoowrappers);
+      s_fakeoowrappers = NULL;
+    }
+    Printf(f_phpcode, "%s\n?>\n", s_phpclasses);
     Close(f_phpcode); 
     
     if ( gen_extra ) {
@@ -821,9 +865,9 @@ public:
 */
 
   void create_command(String *cname, String *iname) {
-    
+
     Printf(f_h, "ZEND_NAMED_FUNCTION(%s);\n", iname);
-    
+
     // This is for the single main function_entry record
     if (cs_entry) {
       Printf(cs_entry," ZEND_NAMED_FE(%(lower)s,%s, NULL)\n", cname,iname );
@@ -892,6 +936,17 @@ public:
    * functionWrapper()
    * ------------------------------------------------------------ */
 
+  /* Helper method for PHP4::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");
@@ -963,7 +1018,7 @@ public:
     
     String *outarg = NewString("");
     String *cleanup = NewString("");
-    
+
     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);
@@ -1027,7 +1082,7 @@ public:
     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");
@@ -1048,13 +1103,13 @@ public:
     }
     
     /* Now convert from php to C variables */
-    // At this point, argcount if used is the number of deliberatly passed args
+    // 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
+    // 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 the and not the first argument
+    // _this and not the first argument.
     // This may mean looking at Lang::memberfunctionhandler
 
     for (i = 0, p = l; i < num_arguments; i++) {
@@ -1208,7 +1263,7 @@ public:
       Printv(f->code,cleanup,NIL);
     }
     
-    // Whats this bit for?
+    // What's this bit for?
     if((tm = Swig_typemap_lookup_new("ret",n,"result",0))) {
       Printf(f->code,"%s\n", tm);
     }
@@ -1244,6 +1299,178 @@ public:
       dispatchFunction(n);
     }
 
+    if (min_num_of_arguments == -1 || 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 = l;
+    }
+
+    // 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) {
+      bool really_overloaded = overloaded;
+      if (overloaded) {
+	Node * o = Getattr(n, "sym:overloaded");
+	while (o) {
+	  if (o == n) {
+	    o = Getattr(o,"sym:nextSibling");
+	    continue;
+	  }
+
+	  ParmList *l2 = Getattr(o,"parms");
+	  Parm * p = l, * p2 = l2;
+	  if (wrapperType == memberfn) p = nextSibling(p);
+	  while (p && p2) {
+	    if (Cmp(Getattr(p, "type"), Getattr(p2, "type")) != 0) break;
+	    if (Cmp(Getattr(p, "name"), Getattr(p2, "name")) != 0) break;
+	    String *value = Getattr(p, "value");
+	    String *value2 = Getattr(p2, "value");
+	    if (value && !value2) break;
+	    if (!value && value2) break;
+	    if (value) {
+	      if (Cmp(value, value2) != 0) break;
+	      // FIXME: check that value is valid in PHP.
+	    }
+	    p = nextSibling(p);
+	    p2 = nextSibling(p2);
+	  }
+	  if (p && p2) break;
+	  // One parameter list is a prefix of the other, so check that all
+	  // remaining parameters of the longer list are optional.
+	  if (p2) p = p2;
+	  while (p && Getattr(p, "value")) p = nextSibling(p);
+	  if (p) break;
+	  o = Getattr(o,"sym:nextSibling");
+	}
+	if (!o) {
+	  // This "overloaded method" is really just one with default args.
+	  really_overloaded = false;
+	  if (l != full_parmlist) {
+	    l = full_parmlist;
+	    if (wrapperType == memberfn) l = nextSibling(l);
+	  }
+	}
+      }
+
+      String * classname = shadow_classname;
+      if (!s_oowrappers) s_oowrappers = NewString("");
+      if (newobject) class_has_ctor = true;
+      if (newobject || wrapperType == memberfn || wrapperType == staticmemberfn || wrapperType == standard) {
+	  // Method or static method or plain function.
+	  String * methodname = 0;
+	  String * args = 0;
+	  String * output;
+	  if (newobject) {
+	    methodname = NewString("__construct");
+	    args = NewString("$h=null");
+	    output = s_oowrappers;
+	  } else if (wrapperType != standard) {
+	    const char *p = strchr(Char(iname), '_');
+	    if (p) methodname = NewString(p + 1);
+	    output = s_oowrappers;
+	  } else {
+	    methodname = NewString(iname);
+	    if (!s_fakeoowrappers) s_fakeoowrappers = NewString("");
+	    output = s_fakeoowrappers;
+	  }
+
+	  if (!methodname) {
+	    Printf(output, "\n/* Skipping method %s because it doesn't have an underscore in */\n", iname);
+	  } else if (strcmp(Char(methodname), "empty") == 0 ||
+	    strcmp(Char(methodname), "clone") == 0) {
+	    Printf(output, "\n/* Skipping method %s because it's a PHP reserved word */\n", methodname);
+	  } else {
+	    String * invoke = NewString("");
+	    if (!args) args = NewString("");
+
+	    if (wrapperType == memberfn) {
+	      // Allow for the "this" pointer.
+	      --min_num_of_arguments;
+	      --max_num_of_arguments;
+	    }
+
+	    if (min_num_of_arguments == max_num_of_arguments) {
+	      if (newobject && min_num_of_arguments == 1) {
+		// The constructor only takes a single argument (or has several
+		// overloaded forms which all only take a single argument.)
+		Printf(invoke, "%s($h)", iname);
+	      } else {
+		for (int i = 0; i < min_num_of_arguments; ++i) {
+		  if (i) Printf(args, ",");
+		  Printf(args, "$arg%d", i);
+		}
+		Printf(invoke, "%s(", iname);
+		if (wrapperType == memberfn) {
+		  Printf(invoke, "$this->swig_ptr");
+		  if (min_num_of_arguments > 0) Printf(invoke, ",");
+		}
+		Printf(invoke, "%s)", args);
+	      }
+	    } else if (!really_overloaded) {
+	      Printf(invoke, "%s(", iname);
+	      if (wrapperType == memberfn) {
+		Printf(invoke, "$this->swig_ptr");
+	      }
+	      for (Parm *p = l; p; p = nextSibling(p)) {
+//		SwigType *type  = Getattr(p,"type");
+		String   *name  = Getattr(p,"name");
+		String   *value = Getattr(p,"value");
+
+		if (p != l) Printf(args, ",");
+		if (p != l || wrapperType == memberfn) Printf(invoke, ",");
+		if (value) {
+		  Printf(args, "$%s=%s", name, value);
+		} else {
+		  Printf(args, "$%s", name);
+		}
+		Printf(invoke, "$%s", name);
+	      }
+	      Printf(invoke, ")");
+	    }
+
+	    Printf(output, "\n");
+	    if (wrapperType == memberfn || newobject) {
+	      Printf(output, "\tpublic function %s(%s) {\n", methodname, args);
+	      if (newobject) {
+		Printf(s_oowrappers, "\t\tif (is_resource($h) && get_resource_type($h) == \"_p_%s__%s\") {\n", module, classname);
+		Printf(s_oowrappers, "\t\t\t$this->swig_ptr=$h;\n");
+		Printf(s_oowrappers, "\t\t\treturn;\n");
+		Printf(s_oowrappers, "\t\t}\n");
+	      }
+	    } else {
+	      Printf(output, "\tpublic static function %s(%s) {\n", methodname, args);
+	    }
+	    Delete(args);
+	    args = NULL;
+
+	    if (really_overloaded && min_num_of_arguments != max_num_of_arguments) {
+	      Printf(output, "\t\t$a=func_get_args();\n");
+	      if (wrapperType == memberfn)
+		Printf(output, "\t\tarray_unshift($a,$this->swig_ptr);\n");
+	      Printf(invoke, "call_user_func_array('%s',$a)", iname);
+	    }
+	    if (newobject) {
+	      Printf(output, "\t\t$this->swig_ptr=%s;\n", invoke);
+	    } else if (Cmp(d, "void") == 0) {
+	      Printf(output, "\t\t%s;\n", invoke);
+	    } else if (is_class(d)) {
+	      Printf(output, "\t\treturn swig_wrap_return(%s);\n", invoke);
+	    } else {
+	      Printf(output, "\t\treturn %s;\n", invoke);
+	    }
+	    Printf(output, "\t}\n");
+	    Delete(invoke);
+	  }
+	  Delete(methodname);
+	  methodname = 0;
+      }
+      min_num_of_arguments = max_num_of_arguments = -1;
+      full_parmlist = 0;
+    }
+
     return SWIG_OK;
   }
   
@@ -1438,6 +1665,43 @@ public:
       /* Write out class init code */
       Printf(s_vdecl,"static zend_class_entry ce_swig_%s;\n",shadow_classname);
       Printf(s_vdecl,"static zend_class_entry* ptr_ce_swig_%s=NULL;\n",shadow_classname);
+    } else if (new_shadow) {
+      char *rename = GetChar(n, "sym:name");
+
+      if (!addSymbol(rename,n)) return SWIG_ERROR;
+      shadow_classname = Swig_copy_string(rename);
+
+//      if(Strcmp(shadow_classname, module) == 0) {
+//        Printf(stderr, "class name cannot be equal to module name: %s\n", shadow_classname);
+//        SWIG_exit(1);
+//      }
+//
+//      shadow_get_vars = NewHash();
+//      shadow_set_vars = NewHash();
+//
+      /* Deal with inheritance */
+      List *baselist = Getattr(n,"bases");
+      if (baselist) {
+	Iterator base = First(baselist);
+	while(base.item && GetFlag(base.item,"feature:ignore")) {
+	  base = Next(base);
+	}
+	base = Next(base);
+	if (base.item) {
+	  /* Warn about multiple inheritance for additional base class(es) */
+	  while (base.item) {
+	    if (GetFlag(base.item,"feature:ignore")) {
+	      base = Next(base);
+	      continue;
+	    }
+	    String *proxyclassname = SwigType_str(Getattr(n,"classtypeobj"),0);
+	    String *baseclassname = SwigType_str(Getattr(base.item,"name"),0);
+	    Swig_warning(WARN_PHP4_MULTIPLE_INHERITANCE, input_file, line_number, 
+		"Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Php4.\n", proxyclassname, baseclassname);
+	    base = Next(base);
+	  }
+	}
+      }
     }
 
     classnode=n;
@@ -1535,7 +1799,7 @@ public:
         Printf(s_propset," else");
       }
 
-      // If there is a base class then chain it's handler else set directly
+      // If there is a base class then chain its handler else set directly
       // try each base class handler, else set directly...
       if (base.item) {
         Printf(s_propset,  "  {\n    /* chain to base class */\n");
@@ -1626,7 +1890,7 @@ public:
         Printf(s_propget," else");
       }
 
-      // If there is a base class then chain it's handler else return null
+      // If there is a base class then chain its handler else return null
       if (base.item) {
         Printf(s_propget,  "  {\n    /* chain to base class */\n");
         while(base.item) {
@@ -1681,6 +1945,111 @@ public:
       Printf(all_cs_entry,"%s   { NULL, NULL, NULL}\n};\n",cs_entry);
       //??delete cs_entry;
       cs_entry=NULL;
+    } else if (new_shadow) {
+      DOH *key;
+      int gcount, scount;
+      String      *s_propget=NewString("");
+      String      *s_propset=NewString("");
+      List *baselist = Getattr(n, "bases");
+      Iterator ki, base;
+
+
+      // If no constructor was generated (abstract class) we had better
+      // generate a constructor that raises an error about instantiating
+      // abstract classes
+//      if (Getattr(n,"abstract") && constructors==0 ) {
+//        // have to write out fake constructor which raises an error when called
+//        abstractConstructorHandler(n);
+//      }
+
+#if 0
+      // ******** Write property SET handlers
+      Printf(s_header,"static int _wrap_propset_%s(zend_property_reference *property_reference, pval *value);\n",
+             shadow_classname);
+      Printf(s_header,"static int _propset_%s(zend_property_reference *property_reference, pval *value);\n",
+             shadow_classname);
+
+      Printf(s_propset,"static int _wrap_propset_%s(zend_property_reference *property_reference, pval *value) { \n",
+             shadow_classname);
+      Printf(s_propset,"  zval * _value;\n");
+      Printf(s_propset,"  zend_llist_element *element = property_reference->elements_list->head;\n");
+      Printf(s_propset,"  zend_overloaded_element *property=(zend_overloaded_element *)element->data;\n");
+      Printf(s_propset,"  if (_propset_%s(property_reference, value)==SUCCESS) return SUCCESS;\n", shadow_classname);
+      Printf(s_propset,"  /* set it ourselves as it is %s */\n",shadow_classname);
+      Printf(s_propset,"  MAKE_STD_ZVAL(_value);\n");
+      Printf(s_propset,"  *_value=*value;\n");
+      Printf(s_propset,"  INIT_PZVAL(_value);\n");
+      Printf(s_propset,"  zval_copy_ctor(_value);\n");
+      Printf(s_propset,"  return add_property_zval_ex(property_reference->object,Z_STRVAL_P(&(property->element)),1+Z_STRLEN_P(&(property->element)),_value);\n");
+      Printf(s_propset,"}\n");
+      Printf(s_propset,"static int _propset_%s(zend_property_reference *property_reference, pval *value) {\n",
+             shadow_classname);
+#endif
+
+      if (baselist) {
+        base=First(baselist);
+      }
+      else {
+        base.item = NULL;
+      }
+
+      while(base.item && GetFlag(base.item,"feature:ignore")) {
+        base = Next(base);
+      }
+
+      String *baseclass = 0;
+      if (base.item) {
+	baseclass = Swig_copy_string(GetChar(base.item, "sym:name"));
+      } else {
+	baseclass = NewString("SwigBase");
+      }
+      Printf(s_phpclasses, "class %s%s extends %s%s {\n", prefix, shadow_classname, prefix, baseclass);
+      Printf(s_phpclasses, "\tpublic $swig_ptr=null;\n");
+
+      // Write property SET handlers
+      ki = First(shadow_set_vars);
+
+      while (ki.key) {
+        key = ki.key;
+        Printf(s_phpclasses, "\t/* FIXME: property setters for %s (key %s) needs emitting */\n", Getattr(shadow_set_vars,key), key);
+
+        ki=Next(ki);
+      }
+
+      // Write property GET handlers
+      ki = First(shadow_get_vars);
+
+      while (ki.key) {
+        key = ki.key;
+        Printf(s_phpclasses, "\t/* FIXME: property setters for %s (key %s) needs emitting */\n", Getattr(shadow_get_vars,key), key);
+
+        ki=Next(ki);
+      }
+
+      // Write the enum initialisation code in a static block
+      // These are all the enums defined within the C++ class.
+      // FIXME: ...
+
+      if (!class_has_ctor) {
+	Printf(s_phpclasses, "\tpublic function __construct($h=null) {\n");
+	Printf(s_phpclasses, "\t\t$this->swig_ptr=$h;\n");
+	Printf(s_phpclasses, "\t}\n");
+      }
+
+      if (s_oowrappers) {
+	Printf(s_phpclasses, "%s", s_oowrappers);
+	Delete(s_oowrappers);
+	s_oowrappers = NULL;
+      }
+      class_has_ctor = false;
+
+      Printf(s_phpclasses, "}\n\n");
+
+      free(shadow_classname);
+      shadow_classname = NULL;
+
+      Delete(shadow_set_vars); shadow_set_vars = NULL;
+      Delete(shadow_get_vars); shadow_get_vars = NULL;
     }
     return SWIG_OK;
   }
@@ -1800,7 +2169,9 @@ public:
     char *name = GetChar(n, "name");
     char *iname = GetChar(n, "sym:name");
     
+    wrapperType = staticmemberfn;
     Language::staticmemberfunctionHandler(n);
+    wrapperType = standard;
     
     if(shadow) {
       String *symname = Getattr(n, "sym:name");
@@ -2045,5 +2416,3 @@ static Language * new_swig_php() {
 extern "C" Language * swig_php(void) {
   return new_swig_php();
 }
- 
-
Index: Lib/php4/php4run.swg
===================================================================
RCS file: /cvsroot/swig/SWIG/Lib/php4/php4run.swg,v
retrieving revision 1.14
diff -p -u -r1.14 php4run.swg
--- Lib/php4/php4run.swg	7 Mar 2006 00:14:09 -0000	1.14
+++ Lib/php4/php4run.swg	20 Apr 2006 04:16:12 -0000
@@ -167,7 +167,11 @@ SWIG_ZTS_ConvertPtr(zval *z, void **ptr,
        else if ((*_cPtr)->type==IS_RESOURCE) {
          return SWIG_ZTS_ConvertResourcePtr(*_cPtr,ptr,ty, flags TSRMLS_CC);
        } else goto type_error; /* _cPtr was not string or resource property */
-     } else goto type_error; /* can't find property _cPtr */
+     } else if ((val = zend_read_property(zend_get_class_entry(z), z, "swig_ptr", 8, false)) != NULL) {
+       return SWIG_ZTS_ConvertResourcePtr(val,ptr,ty,flags TSRMLS_CC);
+     } else {
+       goto type_error; /* can't find property _cPtr */
+     }
    } else if (z->type==IS_RESOURCE) {
      return SWIG_ZTS_ConvertResourcePtr(z,ptr,ty, flags TSRMLS_CC);
    } if (z->type==IS_NULL ) {
