David Rose 20 years ago
parent
commit
ac748503b4

+ 49 - 49
dtool/src/dtoolutil/test_pfstream.cxx

@@ -1,49 +1,49 @@
-// Filename: test_pfstream.cxx
-// Created by:  drose (31Jul02)
-//
-////////////////////////////////////////////////////////////////////
-//
-// PANDA 3D SOFTWARE
-// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
-//
-// All use of this software is subject to the terms of the Panda 3d
-// Software license.  You should have received a copy of this license
-// along with this source code; you will also find a current copy of
-// the license at http://etc.cmu.edu/panda3d/docs/license/ .
-//
-// To contact the maintainers of this program write to
-// [email protected] .
-//
-////////////////////////////////////////////////////////////////////
-
-#include "dtoolbase.h"
-#include "pfstream.h"
-
-int 
-main(int argc, char *argv[]) {
-  if (argc < 2) {
-    cout << "test_pfstream command-line\n";
-    return (1);
-  }
-
-  // Build one command out of the arguments.
-  string cmd;
-  cmd = argv[1];
-  for (int i = 2; i < argc; i++) {
-    cmd += " ";
-    cmd += argv[i];
-  }
-
-  cout << "Executing command:\n" << cmd << "\n";
-  
-  IPipeStream in(cmd);
-
-  char c;
-  c = in.get();
-  while (in && !in.fail() && !in.eof()) {
-    cout.put(toupper(c));
-    c = in.get();
-  }
-
-  return (0);
-}
+// Filename: test_pfstream.cxx
+// Created by:  drose (31Jul02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "dtoolbase.h"
+#include "pfstream.h"
+
+int 
+main(int argc, char *argv[]) {
+  if (argc < 2) {
+    cout << "test_pfstream command-line\n";
+    return (1);
+  }
+
+  // Build one command out of the arguments.
+  string cmd;
+  cmd = argv[1];
+  for (int i = 2; i < argc; i++) {
+    cmd += " ";
+    cmd += argv[i];
+  }
+
+  cout << "Executing command:\n" << cmd << "\n";
+  
+  IPipeStream in(cmd);
+
+  char c;
+  c = in.get();
+  while (in && !in.fail() && !in.eof()) {
+    cout.put(toupper(c));
+    c = in.get();
+  }
+
+  return (0);
+}

+ 8 - 8
dtool/src/interrogate/interfaceMaker.cxx

@@ -147,14 +147,14 @@ generate_wrappers() {
         record_object(type_index);
 
 
-         if(interrogate_type_is_enum(ti))
-         {
-             int enum_count = interrogate_type_number_of_enum_values(ti);
-             for(int xx = 0; xx< enum_count; xx++)
-             {
-//                 printf("   PyModule_AddIntConstant(module,\"%s\",%d)\n",interrogate_type_enum_value_name(ti,xx),interrogate_type_enum_value(ti,xx));
-             }
-         }
+         if(interrogate_type_is_enum(ti))
+         {
+             int enum_count = interrogate_type_number_of_enum_values(ti);
+             for(int xx = 0; xx< enum_count; xx++)
+             {
+//                 printf("   PyModule_AddIntConstant(module,\"%s\",%d)\n",interrogate_type_enum_value_name(ti,xx),interrogate_type_enum_value(ti,xx));
+             }
+         }
 
 
     ++ti;

+ 3 - 3
dtool/src/interrogate/interfaceMakerPython.cxx

@@ -48,9 +48,9 @@ write_includes(ostream &out) {
       << "#else\n"
       << "  #include \"Python.h\"\n"
       << "#endif\n"
-      << "#ifdef HAVE_LONG_LONG\n"
-      << "#undef HAVE_LONG_LONG\n"
-      << "#endif \n";
+      << "#ifdef HAVE_LONG_LONG\n"
+      << "#undef HAVE_LONG_LONG\n"
+      << "#endif \n";
 
 }
 

+ 337 - 337
dtool/src/interrogate/interfaceMakerPythonNative.cxx

@@ -29,26 +29,26 @@
 #include "cppStructType.h"
 #include "vector"
 #include "cppParameterList.h"
-#include "algorithm"
+#include "algorithm"
+
+#include <set>
+#include <map>
+
 
-#include <set>
-#include <map>
-
-
 extern bool     inside_python_native;
 extern          InterrogateType dummy_type;
-extern std::string EXPORT_IMPORT_PREFEX;
+extern std::string EXPORT_IMPORT_PREFEX;
 
 #define         CLASS_PREFEX  "Dtool_"
 #define         INSTANCE_PREFEX "Dtool_"
 #define         BASE_INSTANCE_NAME "Dtool_PyInstDef"
 #define MAX_COMMENT_SIZE  1024
-
-
-/////////////////////////////////////////////////////////
-// Name Remaper...
-//      Snagged from ffi py code....
-/////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////
+// Name Remaper...
+//      Snagged from ffi py code....
+/////////////////////////////////////////////////////////
 struct RenameSet
 {
     char     * _from;
@@ -323,61 +323,61 @@ std::string  methodNameFromCppName(std::string cppName, const std::string &class
 ///////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////
 
-std::string make_safe_comment(const std::string & name_in)
-{
-
-
-    std::string name(name_in.substr(0,MAX_COMMENT_SIZE));
-
-    static const char safe_chars2[] = ",.[](){}:;'`~!@#$%^&*+\\=/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_- ";
-	std::string result = name;
-
-	size_t pos = result.find_first_of("\\");
-	while (pos != std::string::npos)
-	{
-        result.replace(pos,1,"_");
-		pos = result.find_first_of("\\");
-	}
-
-
-
-
-	pos = result.find_first_of("\n");
-	while (pos != std::string::npos)
-	{
-        result.replace(pos,1,"\\n");
-		pos = result.find_first_of("\n");
-	}
-
-
-	pos = result.find_first_not_of(safe_chars2);
-	while (pos != std::string::npos)
-	{
-		result[pos] = ' ';
-		pos = result.find_first_not_of(safe_chars2);
-	}
-
-	return result;
-}
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-std::string make_safe_name(const std::string & name)
-{
-    return InterrogateBuilder::clean_identifier(name);
-
-    static const char safe_chars2[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
-	std::string result = name;
-
-	size_t pos = result.find_first_not_of(safe_chars2);
-	while (pos != std::string::npos)
-	{
-		result[pos] = '_';
-		pos = result.find_first_not_of(safe_chars2);
-	}
-
-	return result;
-}
+std::string make_safe_comment(const std::string & name_in)
+{
+
+
+    std::string name(name_in.substr(0,MAX_COMMENT_SIZE));
+
+    static const char safe_chars2[] = ",.[](){}:;'`~!@#$%^&*+\\=/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_- ";
+	std::string result = name;
+
+	size_t pos = result.find_first_of("\\");
+	while (pos != std::string::npos)
+	{
+        result.replace(pos,1,"_");
+		pos = result.find_first_of("\\");
+	}
+
+
+
+
+	pos = result.find_first_of("\n");
+	while (pos != std::string::npos)
+	{
+        result.replace(pos,1,"\\n");
+		pos = result.find_first_of("\n");
+	}
+
+
+	pos = result.find_first_not_of(safe_chars2);
+	while (pos != std::string::npos)
+	{
+		result[pos] = ' ';
+		pos = result.find_first_not_of(safe_chars2);
+	}
+
+	return result;
+}
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+std::string make_safe_name(const std::string & name)
+{
+    return InterrogateBuilder::clean_identifier(name);
+
+    static const char safe_chars2[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
+	std::string result = name;
+
+	size_t pos = result.find_first_not_of(safe_chars2);
+	while (pos != std::string::npos)
+	{
+		result[pos] = '_';
+		pos = result.find_first_not_of(safe_chars2);
+	}
+
+	return result;
+}
 
 bool isInplaceFunction(const std::string &cppName)
 {
@@ -390,8 +390,8 @@ bool isInplaceFunction(const std::string &cppName)
     return false;
 }
 
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
 void   InterfaceMakerPythonNative::GetValideChildClasses( std::map< std::string ,CastDetails > &answer, CPPStructType * inclass,  const std::string &up_cast_seed, bool downcastposible)
 {
     if(inclass == NULL)
@@ -434,10 +434,10 @@ void   InterfaceMakerPythonNative::GetValideChildClasses( std::map< std::string
         }
     }  
 }
-///////////////////////////////////////////////////////////////////////////////
-//  Function : WriteReturnInstance
-//
-///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+//  Function : WriteReturnInstance
+//
+///////////////////////////////////////////////////////////////////////////////
 void InterfaceMakerPythonNative::WriteReturnInstance(ostream &out, int indent_level, std::string &return_expr, std::string &ows_memory_flag, const std::string &class_name, CPPType *ctype, bool inplace)
 {
     if(inplace == true)
@@ -665,23 +665,23 @@ void InterfaceMakerPythonNative::write_ClasseDetails(ostream &out, Object * obj)
         if( (func))
         {
             ostringstream GetThis;
-            GetThis << "    "<<cClassName  << " * local_this = NULL;\n";
-            GetThis << "    DTOOL_Call_ExtractThisPointerForType(self,&Dtool_"<<  ClassName<<",(void **)&local_this);\n";
-            GetThis << "    if(local_this == NULL)\n";
-            GetThis << "    {\n";
-            GetThis << "      if(!PyTuple_Check(args))\n";
-            GetThis << "      {\n";
-            GetThis << "        PyObject * temp = args;\n";
-            GetThis << "        args = self;\n";
-            GetThis << "        self = temp;\n";    
-            GetThis << "        DTOOL_Call_ExtractThisPointerForType(self,&Dtool_"<<  ClassName<<",(void **)&local_this);\n";
-            GetThis << "      }\n";
-            GetThis << "      if(local_this == NULL)\n";
-            GetThis << "      {\n";
-            GetThis << "        PyErr_SetString(PyExc_TypeError, \"Error extracting 'this' pointer.  Self is not a " << cClassName << "\");\n";
-            GetThis << "        return (PyObject *) NULL;\n" ;
-            GetThis << "      }\n";
-            GetThis << "    };\n";
+            GetThis << "    "<<cClassName  << " * local_this = NULL;\n";
+            GetThis << "    DTOOL_Call_ExtractThisPointerForType(self,&Dtool_"<<  ClassName<<",(void **)&local_this);\n";
+            GetThis << "    if(local_this == NULL)\n";
+            GetThis << "    {\n";
+            GetThis << "      if(!PyTuple_Check(args))\n";
+            GetThis << "      {\n";
+            GetThis << "        PyObject * temp = args;\n";
+            GetThis << "        args = self;\n";
+            GetThis << "        self = temp;\n";    
+            GetThis << "        DTOOL_Call_ExtractThisPointerForType(self,&Dtool_"<<  ClassName<<",(void **)&local_this);\n";
+            GetThis << "      }\n";
+            GetThis << "      if(local_this == NULL)\n";
+            GetThis << "      {\n";
+            GetThis << "        PyErr_SetString(PyExc_TypeError, \"Error extracting 'this' pointer.  Self is not a " << cClassName << "\");\n";
+            GetThis << "        return (PyObject *) NULL;\n" ;
+            GetThis << "      }\n";
+            GetThis << "    };\n";
 
             write_function_for_top(out, func,GetThis.str());
         }
@@ -694,8 +694,8 @@ void InterfaceMakerPythonNative::write_ClasseDetails(ostream &out, Object * obj)
         std::string fname =     "int  Dtool_Init_"+ClassName+"(PyObject *self, PyObject *args, PyObject *kwds)";
         out << fname << "\n";
         out << "{\n";
-        out << "       PyErr_SetString(PyExc_TypeError, \"Error Can Not Init Constant Class (" << cClassName << ")\");\n";
-        out << "       return -1;\n" ;
+        out << "       PyErr_SetString(PyExc_TypeError, \"Error Can Not Init Constant Class (" << cClassName << ")\");\n";
+        out << "       return -1;\n" ;
         out << "}\n";
 
     }
@@ -738,17 +738,17 @@ void InterfaceMakerPythonNative::write_ClasseDetails(ostream &out, Object * obj)
         out << "    }\n";
         out << " \n";
         out << "    "<<cClassName<<" * local_this = (" << cClassName<<" *)((Dtool_PyInstDef *)self)->_ptr_to_object;\n"; 
-        out << "    if(requested_type == &Dtool_"<<ClassName<<")\n";
-        out << "        return local_this;\n";
+        out << "    if(requested_type == &Dtool_"<<ClassName<<")\n";
+        out << "        return local_this;\n";
 
         InterrogateDatabase *idb = InterrogateDatabase::get_ptr();
         for(di = details.begin(); di != details.end(); di++)
         {
             if(di->second._is_legal_py_class)
             {
-                    out << "    if(requested_type == &Dtool_"<<make_safe_name(di->second._to_class_name)<<")\n";
-                    out << "        return "<< di->second._up_cast_string << " local_this;\n";
-            }
+                    out << "    if(requested_type == &Dtool_"<<make_safe_name(di->second._to_class_name)<<")\n";
+                    out << "        return "<< di->second._up_cast_string << " local_this;\n";
+            }
         }
 
         out << "    return NULL;\n";
@@ -764,12 +764,12 @@ void InterfaceMakerPythonNative::write_ClasseDetails(ostream &out, Object * obj)
         {
             if(di->second._can_downcast && di->second._is_legal_py_class)
             {
-                out << "    if(from_type == &Dtool_"<<make_safe_name(di->second._to_class_name)<<")\n";
-                out << "    {\n";
-                out << "          "<< di->second._to_class_name << "* other_this = ("<< di->second._to_class_name <<  "*)from_this;\n" ;
+                out << "    if(from_type == &Dtool_"<<make_safe_name(di->second._to_class_name)<<")\n";
+                out << "    {\n";
+                out << "          "<< di->second._to_class_name << "* other_this = ("<< di->second._to_class_name <<  "*)from_this;\n" ;
                 out << "          return ("<< cClassName << "*)other_this;\n";
-                out << "    }\n";
-            }
+                out << "    }\n";
+            }
         }
         out << "    return (void *) NULL;\n";
         out << "}\n";
@@ -799,23 +799,23 @@ void InterfaceMakerPythonNative::write_ClasseDeclarations(ostream &out, ostream
         }
         else
         {
-            out << "Define_Module_Class("<<_def->module_name << "," << class_name << "," <<class_name <<"_localtype,"<< classNameFromCppName(c_class_name) <<");\n";
-        }
-    }
-    else
-    {
+            out << "Define_Module_Class("<<_def->module_name << "," << class_name << "," <<class_name <<"_localtype,"<< classNameFromCppName(c_class_name) <<");\n";
+        }
+    }
+    else
+    {
         if(TypeManager::is_reference_count(obj->_itype._cpptype))
         {
             out << "Define_Module_ClassRef_Private("<<_def->module_name << "," << class_name << "," << class_name <<"_localtype,"<< classNameFromCppName(c_class_name) <<");\n";
         }
         else
         {
-            out << "Define_Module_Class_Private("<<_def->module_name<< "," << class_name << "," << class_name <<"_localtype,"<< classNameFromCppName(c_class_name) << ");\n";
-        }
-    }
-
-
-    if(out_h != NULL)
+            out << "Define_Module_Class_Private("<<_def->module_name<< "," << class_name << "," << class_name <<"_localtype,"<< classNameFromCppName(c_class_name) << ");\n";
+        }
+    }
+
+
+    if(out_h != NULL)
         *out_h  << "extern \"C\" " << EXPORT_IMPORT_PREFEX << " struct   Dtool_PyTypedObject Dtool_" << class_name <<";\n";
 }
 ////////////////////////////////////////////////////////////////////
@@ -850,17 +850,17 @@ void InterfaceMakerPythonNative::write_module_support(ostream &out,ostream *out_
         Object *object = (*oi).second;
         if(!object->_itype.get_outer_class())
         {
-            if(object->_itype.is_enum())
-            {
-                int enum_count = object->_itype.number_of_enum_values();
-                if(enum_count > 0)
-                {
+            if(object->_itype.is_enum())
+            {
+                int enum_count = object->_itype.number_of_enum_values();
+                if(enum_count > 0)
+                {
                     out << "//********************************************************************\n";
                     out << "//*** Module Enums  .." << object->_itype.get_scoped_name() << "\n";
                     out << "//********************************************************************\n";
                 }
-                for(int xx = 0; xx< enum_count; xx++)
-                    out << "   PyModule_AddIntConstant(module,\"" << classNameFromCppName(object->_itype.get_enum_value_name(xx)) <<"\","<<  object->_itype.get_enum_value(xx) << ");\n";
+                for(int xx = 0; xx< enum_count; xx++)
+                    out << "   PyModule_AddIntConstant(module,\"" << classNameFromCppName(object->_itype.get_enum_value_name(xx)) <<"\","<<  object->_itype.get_enum_value(xx) << ");\n";
             }
         }
     }
@@ -877,9 +877,9 @@ void InterfaceMakerPythonNative::write_module_support(ostream &out,ostream *out_
             record_function(dummy_type, func_index);
         }
         if(iman.has_int_value())
-                    out << "   PyModule_AddIntConstant(module,\"" << classNameFromCppName(iman.get_name()) <<"\","<<  iman.get_int_value() << ");\n";
+                    out << "   PyModule_AddIntConstant(module,\"" << classNameFromCppName(iman.get_name()) <<"\","<<  iman.get_int_value() << ");\n";
         else
-                    out << "   PyModule_AddStringConstant(module,\"" << classNameFromCppName(iman.get_name()) <<"\",\""<<  iman.get_definition().c_str() << "\");\n";
+                    out << "   PyModule_AddStringConstant(module,\"" << classNameFromCppName(iman.get_name()) <<"\",\""<<  iman.get_definition().c_str() << "\");\n";
 
     }    
 
@@ -933,7 +933,7 @@ void InterfaceMakerPythonNative::write_module_support(ostream &out,ostream *out_
     out << "  { NULL, NULL ,0,NULL}\n" << "};\n\n";
 
     out << "struct LibrayDef " << moduledefdef->library_name <<"_moddef = {python_simple_funcs,BuildInstants};\n";
-    if(out_h != NULL)
+    if(out_h != NULL)
         *out_h << "extern struct LibrayDef " << moduledefdef->library_name <<"_moddef;\n";
 }
 /////////////////////////////////////////////////////////////////////////////
@@ -967,175 +967,175 @@ void InterfaceMakerPythonNative::write_module(ostream &out,ostream *out_h, Inter
 //      conventions for the slaot interface..
 ////////////////////////////////////////////////////////////////////
 bool GetSlotedFunctinDef(const std::string &thimputstring, std::string &answer_location, int &wraper_type)
-{                
-    wraper_type = -1;
-
-    if(thimputstring.size() > 4 && thimputstring[0] == '_' && thimputstring[1] == '_')
-    {
-        if(thimputstring == "__add__")
-        {
-            answer_location = "tp_as_number->nb_add";
-            wraper_type = 3;
-            return true;
-        }
-
-        if(thimputstring == "__sub__")
-        {
-            answer_location = "tp_as_number->nb_subtract";
-            wraper_type = 3;
-            return true;        
-        }
-
-        if(thimputstring == "__mul__")
-        {
-            answer_location = "tp_as_number->nb_multiply";
-            wraper_type = 3;
-            return true;
-        }
-
-        if(thimputstring == "__div__")
-        {
-            answer_location = "tp_as_number->nb_divide";
-            wraper_type = 3;
-            return true;
-        }
-
-        if(thimputstring == "__mod__")
-        {
-            answer_location = "tp_as_number->nb_remainder";
-            wraper_type = 3;
-            return true;
-        }
-
-        if(thimputstring == "__lshift__")
-        {
-            answer_location = "tp_as_number->nb_lshift";
-            wraper_type = 3;
-            return true;
-        }
-
-        if(thimputstring == "__rshift__")
-        {
-            answer_location = "tp_as_number->nb_rshift";
-            wraper_type = 3;
-            return true;
-        }
-
-
-        if(thimputstring == "__xor__")
-        {
-            answer_location = "tp_as_number->nb_xor";
-            wraper_type = 3;
-            return true;
-        }
-
-
-        if(thimputstring == "__and__")
-        {
-            answer_location = "tp_as_number->nb_and";
-            wraper_type = 3;
-            return true;
-        }
-
-        if(thimputstring == "__or__")
-        {
-            answer_location = "tp_as_number->nb_or";
-            wraper_type = 3;
-            return true;
-        }
-
-
-        if(thimputstring == "__iadd__")
-        {
-            answer_location = "tp_as_number->nb_inplace_add";
-            wraper_type = 3;
-            return true;
-        }
-
-        if(thimputstring == "__isub__")
-        {
-            answer_location = "tp_as_number->nb_inplace_subtract";
-            wraper_type = 3;
-            return true;
-        }
-
-        if(thimputstring == "__imul__")
-        {
-            answer_location = "tp_as_number->nb_inplace_multiply";
-            wraper_type = 3;
-            return true;
-        }
-
-        if(thimputstring == "__idiv__")
-        {
-            answer_location = "tp_as_number->nb_inplace_divide";
-            wraper_type = 3;
-            return true;
-        }
-
-        if(thimputstring == "__imod__")
-        {
-            answer_location = ".tp_as_number->nb_inplace_remainder";
-            wraper_type = 3;
-            return true;
-        }
-
-
-        if(thimputstring == "__ilshift__")
-        {
-            answer_location = "tp_as_number->nb_inplace_lshift";
-            wraper_type = 3;
-            return true;
-        }
-
-        if(thimputstring == "__irshift__")
-        {
-            answer_location = "tp_as_number->nb_inplace_rshift";
-            wraper_type = 3;
-            return true;
-        }
-
-        if(thimputstring == "__iand__")
-        {
-            answer_location = "tp_as_number->nb_inplace_and";
-            wraper_type = 3;
-            return true;
-        }
-
-        if(thimputstring == "__ixor__")
-        {
-            answer_location = "tp_as_number->nb_inplace_xor";
-            wraper_type = 3;
-            return true;
-        }
-
-        if(thimputstring == "__int__")
-        {
-            answer_location = "tp_as_number->nb_int";
-            wraper_type = 2;
-            return true;
-        }
-
-//        if(thimputstring == "__coerce__")
-//        {
-//            answer_location = "tp_as_number->nb_coerce";
-//            return true;
-//        }
-
-        // mapping methods
-        if(thimputstring == "__getitem__")
-        {
-            answer_location = "tp_as_mapping->mp_subscript";
-            wraper_type = 3;
-            return true;
-        }
-
-        //Direct methods
-        if(thimputstring == "__call__")
-        {
-            answer_location = "tp_call";
-            //wraper_type = 1;
-            return true;
+{                
+    wraper_type = -1;
+
+    if(thimputstring.size() > 4 && thimputstring[0] == '_' && thimputstring[1] == '_')
+    {
+        if(thimputstring == "__add__")
+        {
+            answer_location = "tp_as_number->nb_add";
+            wraper_type = 3;
+            return true;
+        }
+
+        if(thimputstring == "__sub__")
+        {
+            answer_location = "tp_as_number->nb_subtract";
+            wraper_type = 3;
+            return true;        
+        }
+
+        if(thimputstring == "__mul__")
+        {
+            answer_location = "tp_as_number->nb_multiply";
+            wraper_type = 3;
+            return true;
+        }
+
+        if(thimputstring == "__div__")
+        {
+            answer_location = "tp_as_number->nb_divide";
+            wraper_type = 3;
+            return true;
+        }
+
+        if(thimputstring == "__mod__")
+        {
+            answer_location = "tp_as_number->nb_remainder";
+            wraper_type = 3;
+            return true;
+        }
+
+        if(thimputstring == "__lshift__")
+        {
+            answer_location = "tp_as_number->nb_lshift";
+            wraper_type = 3;
+            return true;
+        }
+
+        if(thimputstring == "__rshift__")
+        {
+            answer_location = "tp_as_number->nb_rshift";
+            wraper_type = 3;
+            return true;
+        }
+
+
+        if(thimputstring == "__xor__")
+        {
+            answer_location = "tp_as_number->nb_xor";
+            wraper_type = 3;
+            return true;
+        }
+
+
+        if(thimputstring == "__and__")
+        {
+            answer_location = "tp_as_number->nb_and";
+            wraper_type = 3;
+            return true;
+        }
+
+        if(thimputstring == "__or__")
+        {
+            answer_location = "tp_as_number->nb_or";
+            wraper_type = 3;
+            return true;
+        }
+
+
+        if(thimputstring == "__iadd__")
+        {
+            answer_location = "tp_as_number->nb_inplace_add";
+            wraper_type = 3;
+            return true;
+        }
+
+        if(thimputstring == "__isub__")
+        {
+            answer_location = "tp_as_number->nb_inplace_subtract";
+            wraper_type = 3;
+            return true;
+        }
+
+        if(thimputstring == "__imul__")
+        {
+            answer_location = "tp_as_number->nb_inplace_multiply";
+            wraper_type = 3;
+            return true;
+        }
+
+        if(thimputstring == "__idiv__")
+        {
+            answer_location = "tp_as_number->nb_inplace_divide";
+            wraper_type = 3;
+            return true;
+        }
+
+        if(thimputstring == "__imod__")
+        {
+            answer_location = ".tp_as_number->nb_inplace_remainder";
+            wraper_type = 3;
+            return true;
+        }
+
+
+        if(thimputstring == "__ilshift__")
+        {
+            answer_location = "tp_as_number->nb_inplace_lshift";
+            wraper_type = 3;
+            return true;
+        }
+
+        if(thimputstring == "__irshift__")
+        {
+            answer_location = "tp_as_number->nb_inplace_rshift";
+            wraper_type = 3;
+            return true;
+        }
+
+        if(thimputstring == "__iand__")
+        {
+            answer_location = "tp_as_number->nb_inplace_and";
+            wraper_type = 3;
+            return true;
+        }
+
+        if(thimputstring == "__ixor__")
+        {
+            answer_location = "tp_as_number->nb_inplace_xor";
+            wraper_type = 3;
+            return true;
+        }
+
+        if(thimputstring == "__int__")
+        {
+            answer_location = "tp_as_number->nb_int";
+            wraper_type = 2;
+            return true;
+        }
+
+//        if(thimputstring == "__coerce__")
+//        {
+//            answer_location = "tp_as_number->nb_coerce";
+//            return true;
+//        }
+
+        // mapping methods
+        if(thimputstring == "__getitem__")
+        {
+            answer_location = "tp_as_mapping->mp_subscript";
+            wraper_type = 3;
+            return true;
+        }
+
+        //Direct methods
+        if(thimputstring == "__call__")
+        {
+            answer_location = "tp_call";
+            //wraper_type = 1;
+            return true;
         }
     }
     return false;
@@ -1317,11 +1317,11 @@ void InterfaceMakerPythonNative::write_module_class(ostream &out,  Object *obj)
                 out << "//////////////////\n";
                 out << "static long  DTool_HashKey_"<<ClassName << "(PyObject * self)\n";
                 out << "{\n";
-                out << "    "<<cClassName  << " * local_this = NULL;\n";
-                out << "    DTOOL_Call_ExtractThisPointerForType(self,&Dtool_"<<  ClassName<<",(void **)&local_this);\n";
-                out << "    if(local_this == NULL)\n";
-                out << "    {\n";
-                out << "       return -1;\n";
+                out << "    "<<cClassName  << " * local_this = NULL;\n";
+                out << "    DTOOL_Call_ExtractThisPointerForType(self,&Dtool_"<<  ClassName<<",(void **)&local_this);\n";
+                out << "    if(local_this == NULL)\n";
+                out << "    {\n";
+                out << "       return -1;\n";
                 out << "    };\n";
                 out << "    return local_this->get_key();\n";
                 out << "}\n\n";
@@ -1337,11 +1337,11 @@ void InterfaceMakerPythonNative::write_module_class(ostream &out,  Object *obj)
                     out << "//////////////////\n";
                     out << "static long  DTool_HashKey_"<<ClassName << "(PyObject * self)\n";
                     out << "{\n";
-                    out << "    "<<cClassName  << " * local_this = NULL;\n";
-                    out << "    DTOOL_Call_ExtractThisPointerForType(self,&Dtool_"<<  ClassName<<",(void **)&local_this);\n";
-                    out << "    if(local_this == NULL)\n";
-                    out << "    {\n";
-                    out << "       return -1;\n";
+                    out << "    "<<cClassName  << " * local_this = NULL;\n";
+                    out << "    DTOOL_Call_ExtractThisPointerForType(self,&Dtool_"<<  ClassName<<",(void **)&local_this);\n";
+                    out << "    if(local_this == NULL)\n";
+                    out << "    {\n";
+                    out << "       return -1;\n";
                     out << "    };\n";
                     out << "    return (long)local_this;\n";
                     out << "}\n\n";
@@ -1357,15 +1357,15 @@ void InterfaceMakerPythonNative::write_module_class(ostream &out,  Object *obj)
                 out << "//////////////////\n";
                 out << "static PyObject *  Dtool_Repr_"<<ClassName << "(PyObject * self)\n";
                 out << "{\n";
-                out << "    "<<cClassName  << " * local_this = NULL;\n";
-                out << "    DTOOL_Call_ExtractThisPointerForType(self,&Dtool_"<<  ClassName<<",(void **)&local_this);\n";
-                out << "    if(local_this != NULL)\n";
-                out << "    {\n";
+                out << "    "<<cClassName  << " * local_this = NULL;\n";
+                out << "    DTOOL_Call_ExtractThisPointerForType(self,&Dtool_"<<  ClassName<<",(void **)&local_this);\n";
+                out << "    if(local_this != NULL)\n";
+                out << "    {\n";
                 out << "       ostringstream os;\n";
-                out << "       local_this->output(os);\n";
-//                out << "       return PyString_FromString(os.str().c_str());\n";
-                out << "       std::string ss = os.str();\n";
-                out << "       return PyString_FromStringAndSize(ss.data(),ss.length());\n";
+                out << "       local_this->output(os);\n";
+//                out << "       return PyString_FromString(os.str().c_str());\n";
+                out << "       std::string ss = os.str();\n";
+                out << "       return PyString_FromStringAndSize(ss.data(),ss.length());\n";
                 out << "    };\n";
                 out << "    return Py_BuildValue(\"\");\n";
                 out << "}\n";   
@@ -1381,18 +1381,18 @@ void InterfaceMakerPythonNative::write_module_class(ostream &out,  Object *obj)
                 out << "//////////////////\n";
                 out << "static PyObject *  Dtool_Str_"<<ClassName << "(PyObject * self)\n";
                 out << "{\n";
-                out << "    "<<cClassName  << " * local_this = NULL;\n";
-                out << "    DTOOL_Call_ExtractThisPointerForType(self,&Dtool_"<<  ClassName<<",(void **)&local_this);\n";
-                out << "    if(local_this != NULL)\n";
-                out << "    {\n";
+                out << "    "<<cClassName  << " * local_this = NULL;\n";
+                out << "    DTOOL_Call_ExtractThisPointerForType(self,&Dtool_"<<  ClassName<<",(void **)&local_this);\n";
+                out << "    if(local_this != NULL)\n";
+                out << "    {\n";
                 out << "       ostringstream os;\n";
                 if(need_str == 2)
-                    out << "       local_this->write(os,0);\n";
+                    out << "       local_this->write(os,0);\n";
                 else
-                    out << "       local_this->write(os);\n";
-//                out << "       return PyString_FromString(os.str().c_str());\n";
-                out << "       std::string ss = os.str();\n";
-                out << "       return PyString_FromStringAndSize(ss.data(),ss.length());\n";
+                    out << "       local_this->write(os);\n";
+//                out << "       return PyString_FromString(os.str().c_str());\n";
+                out << "       std::string ss = os.str();\n";
+                out << "       return PyString_FromStringAndSize(ss.data(),ss.length());\n";
                 out << "    };\n";
                 out << "    return Py_BuildValue(\"\");\n";
                 out << "}\n";   
@@ -1506,13 +1506,13 @@ void InterfaceMakerPythonNative::write_module_class(ostream &out,  Object *obj)
           }  
           else
           {
-              if(nested_obj->_itype.is_enum())
-              {
+              if(nested_obj->_itype.is_enum())
+              {
                   out << "        // Enum  "<< nested_obj->_itype.get_scoped_name() << ";\n";
-                  int enum_count = nested_obj->_itype.number_of_enum_values();
-                  for(int xx = 0; xx< enum_count; xx++)
-                      out << "        PyDict_SetItemString(Dtool_" << ClassName << ".As_PyTypeObject().tp_dict,\"" << classNameFromCppName(nested_obj->_itype.get_enum_value_name(xx)) <<"\",PyInt_FromLong("<<  nested_obj->_itype.get_enum_value(xx) << "));\n";
-
+                  int enum_count = nested_obj->_itype.number_of_enum_values();
+                  for(int xx = 0; xx< enum_count; xx++)
+                      out << "        PyDict_SetItemString(Dtool_" << ClassName << ".As_PyTypeObject().tp_dict,\"" << classNameFromCppName(nested_obj->_itype.get_enum_value_name(xx)) <<"\",PyInt_FromLong("<<  nested_obj->_itype.get_enum_value(xx) << "));\n";
+
               }
           }
         }
@@ -1526,7 +1526,7 @@ void InterfaceMakerPythonNative::write_module_class(ostream &out,  Object *obj)
 
         out << "        Py_INCREF(&Dtool_"<< ClassName << ".As_PyTypeObject());\n";
         out << "        PyDict_SetItemString(Dtool_"<<ClassName <<".As_PyTypeObject().tp_dict,\""<<export_calss_name<< "\",&Dtool_"<<ClassName <<".As_PyObject());\n";
-
+
         // static function into dictionary with bogus self..
         //
         std::map<int , Function * >::iterator sfi;
@@ -1538,12 +1538,12 @@ void InterfaceMakerPythonNative::write_module_class(ostream &out,  Object *obj)
             out << "\",PyCFunction_New(&Dtool_Methods_"<< ClassName <<"[" << sfi->first << "],&Dtool_"<< ClassName<< ".As_PyObject()));\n";
         }
 
-
-
-        if(is_runtime_typed)
-            out << "        RegisterRuntimeClass(&Dtool_"<<ClassName<<","<< cClassName <<"::get_class_type().get_index());\n";
-        else
-            out << "        RegisterRuntimeClass(&Dtool_"<<ClassName<<",-1);\n";
+
+
+        if(is_runtime_typed)
+            out << "        RegisterRuntimeClass(&Dtool_"<<ClassName<<","<< cClassName <<"::get_class_type().get_index());\n";
+        else
+            out << "        RegisterRuntimeClass(&Dtool_"<<ClassName<<",-1);\n";
 
         out << "    }\n";
 
@@ -2165,11 +2165,11 @@ void InterfaceMakerPythonNative::write_function_instance(ostream &out, Interface
       if(remap->_parameters.size() == 1 || (remap->_has_this && remap->_parameters.size() == 2))
       {
         indent(out,indent_level+4) << "// Special Case to Make operator work \n";
-        indent(out,indent_level+4) << "if(PyTuple_Check(args) || (kwds != NULL && PyDict_Check(kwds)))\n";
-        indent(out,indent_level+4) << "    (PyArg_ParseTupleAndKeywords(args,kwds, \"" << format_specifiers1<< "\",key_word_list" << parameter_list << "));\n";
-        indent(out,indent_level+4) << "else\n";
-        indent(out,indent_level+4) << "    (PyArg_Parse(args, \"" << format_specifiers1<< "\"" << parameter_list << "));\n";
-        indent(out,indent_level+4) << "if(!PyErr_Occurred())\n";
+        indent(out,indent_level+4) << "if(PyTuple_Check(args) || (kwds != NULL && PyDict_Check(kwds)))\n";
+        indent(out,indent_level+4) << "    (PyArg_ParseTupleAndKeywords(args,kwds, \"" << format_specifiers1<< "\",key_word_list" << parameter_list << "));\n";
+        indent(out,indent_level+4) << "else\n";
+        indent(out,indent_level+4) << "    (PyArg_Parse(args, \"" << format_specifiers1<< "\"" << parameter_list << "));\n";
+        indent(out,indent_level+4) << "if(!PyErr_Occurred())\n";
       }
       else
           indent(out,indent_level+4) << "if (PyArg_ParseTupleAndKeywords(args,kwds, \"" << format_specifiers1 << "\",key_word_list" << parameter_list << "))\n";

+ 651 - 651
dtool/src/interrogate/interfaceMakerPythonObj.cxx

@@ -1,651 +1,651 @@
-// Filename: interfaceMakerPythonObj.cxx
-// Created by:  drose (19Sep01)
-//
-////////////////////////////////////////////////////////////////////
-//
-// PANDA 3D SOFTWARE
-// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
-//
-// All use of this software is subject to the terms of the Panda 3d
-// Software license.  You should have received a copy of this license
-// along with this source code; you will also find a current copy of
-// the license at http://etc.cmu.edu/panda3d/docs/license/ .
-//
-// To contact the maintainers of this program write to
-// [email protected] .
-//
-////////////////////////////////////////////////////////////////////
- 
-#include "interfaceMakerPythonObj.h"
-#include "interrogateBuilder.h"
-#include "interrogate.h"
-#include "functionRemap.h"
-#include "parameterRemapUnchanged.h"
-#include "typeManager.h"
-#include "functionWriterPtrFromPython.h"
-#include "functionWriterPtrToPython.h"
-
-#include "interrogateDatabase.h"
-#include "interrogateType.h"
-#include "interrogateFunction.h"
-#include "cppFunctionType.h"
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonObj::Constructor
-//       Access: Public
-//  Description:
-////////////////////////////////////////////////////////////////////
-InterfaceMakerPythonObj::
-InterfaceMakerPythonObj(InterrogateModuleDef *def) :
-  InterfaceMakerPython(def)
-{
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonObj::Destructor
-//       Access: Public, Virtual
-//  Description:
-////////////////////////////////////////////////////////////////////
-InterfaceMakerPythonObj::
-~InterfaceMakerPythonObj() {
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonObj::write_prototypes
-//       Access: Public, Virtual
-//  Description: Generates the list of function prototypes
-//               corresponding to the functions that will be output in
-//               write_functions().
-////////////////////////////////////////////////////////////////////
-void InterfaceMakerPythonObj::
-write_prototypes(ostream &out,ostream *out_h) {
-  Functions::iterator fi;
-  for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
-    Function *func = (*fi);
-    write_prototype_for(out, func);
-  }
-
-  out << "\n";
-  InterfaceMakerPython::write_prototypes(out,out_h);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonObj::write_functions
-//       Access: Public, Virtual
-//  Description: Generates the list of functions that are appropriate
-//               for this interface.  This function is called *before*
-//               write_prototypes(), above.
-////////////////////////////////////////////////////////////////////
-void InterfaceMakerPythonObj::
-write_functions(ostream &out) {
-  Functions::iterator fi;
-  for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
-    Function *func = (*fi);
-    write_function_for(out, func);
-  }
-
-  InterfaceMakerPython::write_functions(out);
-
-  // Finally, generate all the make-class-wrapper functions.
-  Objects::iterator oi;
-  for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
-    Object *object = (*oi).second;
-
-    write_class_wrapper(out, object);
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonObj::write_module
-//       Access: Public, Virtual
-//  Description: Generates whatever additional code is required to
-//               support a module file.
-////////////////////////////////////////////////////////////////////
-void InterfaceMakerPythonObj::
-write_module(ostream &out,ostream *out_h, InterrogateModuleDef *def) {
-  InterfaceMakerPython::write_module(out,out_h, def);
-
-  out << "static PyMethodDef python_obj_funcs[] = {\n";
-
-  Objects::iterator oi;
-  for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
-    Object *object = (*oi).second;
-
-    Functions::iterator fi;
-    for (fi = object->_constructors.begin(); 
-         fi != object->_constructors.end(); 
-         ++fi) {
-      Function *func = (*fi);
-      out << "  { \"" << func->_ifunc.get_name() << "\", &" << func->_name 
-          << ", METH_VARARGS },\n";
-    }
-  }  
-  out << "  { NULL, NULL }\n"
-      << "};\n\n"
-
-      << "#ifdef _WIN32\n"
-      << "extern \"C\" __declspec(dllexport) void init" << def->library_name << "();\n"
-      << "#else\n"
-      << "extern \"C\" void init" << def->library_name << "();\n"
-      << "#endif\n\n"
-    
-      << "void init" << def->library_name << "() {\n"
-      << "  Py_InitModule(\"" << def->library_name
-      << "\", python_obj_funcs);\n"
-      << "}\n\n";
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonObj::synthesize_this_parameter
-//       Access: Public, Virtual
-//  Description: This method should be overridden and redefined to
-//               return true for interfaces that require the implicit
-//               "this" parameter, if present, to be passed as the
-//               first parameter to any wrapper functions.
-////////////////////////////////////////////////////////////////////
-bool InterfaceMakerPythonObj::
-synthesize_this_parameter() {
-  return true;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonObj::get_builder_name
-//       Access: Public, Static
-//  Description: Returns the name of the InterfaceMaker function
-//               generated to define the Python class for the
-//               indicated struct type.
-////////////////////////////////////////////////////////////////////
-string InterfaceMakerPythonObj::
-get_builder_name(CPPType *struct_type) {
-  return "get_python_class_" + 
-    InterrogateBuilder::clean_identifier(struct_type->get_local_name(&parser));
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonObj::get_wrapper_prefix
-//       Access: Protected, Virtual
-//  Description: Returns the prefix string used to generate wrapper
-//               function names.
-////////////////////////////////////////////////////////////////////
-string InterfaceMakerPythonObj::
-get_wrapper_prefix() {
-  return "wpo_";
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonObj::write_class_wrapper
-//       Access: Private
-//  Description: Writes a function that will define the Python class.
-////////////////////////////////////////////////////////////////////
-void InterfaceMakerPythonObj::
-write_class_wrapper(ostream &out, InterfaceMaker::Object *object) {
-  CPPType *struct_type = object->_itype._cpptype;
-  if (struct_type == (CPPType *)NULL) {
-    return;
-  }
-
-  string name = get_builder_name(struct_type);
-  string python_name =
-    InterrogateBuilder::clean_identifier(struct_type->get_simple_name());
-
-  out << "/*\n"
-      << " * Generate unique Python class for "
-      << struct_type->get_local_name(&parser) << "\n"
-      << " */\n"
-      << "PyObject *\n"
-      << name << "() {\n"
-      << "  static PyObject *wrapper = (PyObject *)NULL;\n"
-      << "  static PyMethodDef methods[] = {\n";
-
-  int methods_size = 0;
-  int class_methods_size = 0;
-
-  Functions::iterator fi;
-  for (fi = object->_methods.begin(); fi != object->_methods.end(); ++fi) {
-    Function *func = (*fi);
-    if (func->_has_this) {
-      out << "  { \"" << func->_ifunc.get_name() << "\", &" << func->_name 
-          << ", METH_VARARGS },\n";
-      methods_size++;
-    }
-  }
-
-  out << "  };\n"
-      << "  static const int methods_size = " << methods_size << ";\n\n"
-      << "  static PyMethodDef class_methods[] = {\n";
-
-  for (fi = object->_methods.begin(); fi != object->_methods.end(); ++fi) {
-    Function *func = (*fi);
-    if (!func->_has_this) {
-      out << "  { \"" << func->_ifunc.get_name() << "\", &" << func->_name 
-          << ", METH_VARARGS },\n";
-      class_methods_size++;
-    }
-  }
-
-  out << "  };\n"
-      << "  static const int class_methods_size = " << class_methods_size << ";\n\n"
-      << "  if (wrapper == (PyObject *)NULL) {\n"
-      << "    int i;\n"
-      << "    PyObject *bases = PyTuple_New(0);\n"
-      << "    PyObject *dict = PyDict_New();\n"
-      << "    PyObject *name = PyString_FromString(\""
-      << python_name << "\");\n"
-      << "    wrapper = PyClass_New(bases, dict, name);\n"
-      << "    for (i = 0; i < methods_size; ++i) {\n"
-      << "      PyObject *function, *method;\n"
-      << "      function = PyCFunction_New(&methods[i], (PyObject *)NULL);\n"
-      << "      method = PyMethod_New(function, (PyObject *)NULL, wrapper);\n"
-      << "      PyDict_SetItemString(dict, methods[i].ml_name, method);\n"
-      << "    }\n"
-      << "    for (i = 0; i < class_methods_size; ++i) {\n"
-      << "      PyObject *function;\n"
-      << "      function = PyCFunction_New(&class_methods[i], (PyObject *)NULL);\n"
-      << "      PyDict_SetItemString(dict, class_methods[i].ml_name, function);\n"
-      << "    }\n"
-      << "  }\n"
-      << "  return wrapper;\n"
-      << "}\n\n";
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonObj::write_prototype_for
-//       Access: Private
-//  Description: Writes the prototype for the indicated function.
-////////////////////////////////////////////////////////////////////
-void InterfaceMakerPythonObj::
-write_prototype_for(ostream &out, InterfaceMaker::Function *func) {
-  out << "static PyObject *"
-      << func->_name << "(PyObject *self, PyObject *args);\n";
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonObj::write_function_for
-//       Access: Private
-//  Description: Writes the definition for a function that will call
-//               the indicated C++ function or method.
-////////////////////////////////////////////////////////////////////
-void InterfaceMakerPythonObj::
-write_function_for(ostream &out, InterfaceMaker::Function *func) {
-  Function::Remaps::const_iterator ri;
-  out << "/*\n"
-      << " * Python object wrapper for\n";
-  for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
-    FunctionRemap *remap = (*ri);
-    out << " * ";
-    remap->write_orig_prototype(out, 0);
-    out << "\n";
-  }
-  out << " */\n";
-
-  out << "static PyObject *"
-      << func->_name << "(PyObject *, PyObject *args) {\n";
-
-  // Now write out each instance of the overloaded function.
-  string expected_params = "Arguments must match one of:";
-
-  for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
-    FunctionRemap *remap = (*ri);
-    expected_params += "\\n  ";
-    write_function_instance(out, 2, func, remap, expected_params);
-  }
-
-  // If we get here in the generated code, none of the parameters were
-  // valid.  Generate an error exception.  (We don't rely on the error
-  // already generated by ParseTuple(), because it only reports the
-  // error for one flavor of the function, whereas we might accept
-  // multiple flavors for the different overloaded C++ function
-  // signatures.
-
-  out << "  PyErr_SetString(PyExc_TypeError, \"" << expected_params << "\");\n"
-      << "  return (PyObject *)NULL;\n";
-
-  out << "}\n\n";
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonObj::write_function_instance
-//       Access: Private
-//  Description: Writes out the part of a function that handles a
-//               single instance of an overloaded function.
-////////////////////////////////////////////////////////////////////
-void InterfaceMakerPythonObj::
-write_function_instance(ostream &out, int indent_level,
-                        InterfaceMaker::Function *func,
-                        FunctionRemap *remap, string &expected_params) {
-  indent(out, indent_level) << "{\n";
-  indent(out, indent_level + 2) << "/* ";
-  remap->write_orig_prototype(out, 0);
-  out << " */\n\n";
-  
-  string format_specifiers;
-  string parameter_list;
-  vector_string pexprs;
-  string extra_convert;
-  string extra_param_check;
-  string extra_cleanup;
-
-  // Make one pass through the parameter list.  We will output a
-  // one-line temporary variable definition for each parameter, while
-  // simultaneously building the ParseTuple() function call and also
-  // the parameter expression list for call_function().
-
-  expected_params += remap->_cppfunc->get_simple_name();
-  expected_params += "(";
-
-  int pn;
-  for (pn = 0; pn < (int)remap->_parameters.size(); pn++) {
-    if (pn != 0) {
-      expected_params += ", ";
-    }
-
-    indent(out, indent_level + 2);
-    CPPType *orig_type = remap->_parameters[pn]._remap->get_orig_type();
-    CPPType *type = remap->_parameters[pn]._remap->get_new_type();
-    string param_name = remap->get_parameter_name(pn);
-    
-    // This is the string to convert our local variable to the
-    // appropriate C++ type.  Normally this is just a cast.
-    string pexpr_string =
-      "(" + type->get_local_name(&parser) + ")" + param_name;
-    
-    if (remap->_parameters[pn]._remap->new_type_is_atomic_string()) {
-      if (TypeManager::is_char_pointer(orig_type)) {
-        out << "char *" << param_name;
-        format_specifiers += "s";
-        parameter_list += ", &" + param_name;
-        
-      } else {
-        out << "char *" << param_name
-            << "_str; int " << param_name << "_len";
-        format_specifiers += "s#";
-        parameter_list += ", &" + param_name
-          + "_str, &" + param_name + "_len";
-        pexpr_string = "basic_string<char>(" +
-          param_name + "_str, " +
-          param_name + "_len)";
-      }
-      expected_params += "string";
-      
-    } else if (TypeManager::is_bool(type)) {
-      out << "PyObject *" << param_name;
-      format_specifiers += "O";
-      parameter_list += ", &" + param_name;
-      pexpr_string = "(PyObject_IsTrue(" + param_name + ")!=0)";
-      expected_params += "bool";
-
-    } else if (TypeManager::is_unsigned_longlong(type)) {
-      out << "PyObject *" << param_name;
-      format_specifiers += "O";
-      parameter_list += ", &" + param_name;
-      extra_convert += " PyObject *" + param_name + "_long = PyNumber_Long(" + param_name + ");";
-      extra_param_check += "|| (" + param_name + "_long == NULL)";
-      pexpr_string = "PyLong_AsUnsignedLongLong(" + param_name + "_long)";
-      extra_cleanup += " Py_XDECREF(" + param_name + "_long);";
-      expected_params += "long";
-
-    } else if (TypeManager::is_longlong(type)) {
-      out << "PyObject *" << param_name;
-      format_specifiers += "O";
-      parameter_list += ", &" + param_name;
-      extra_convert += " PyObject *" + param_name + "_long = PyNumber_Long(" + param_name + ");";
-      extra_param_check += "|| (" + param_name + "_long == NULL)";
-      pexpr_string = "PyLong_AsLongLong(" + param_name + "_long)";
-      extra_cleanup += " Py_XDECREF(" + param_name + "_long);";
-      expected_params += "long";
-
-    } else if (TypeManager::is_unsigned_integer(type)) {
-      out << "PyObject *" << param_name;
-      format_specifiers += "O";
-      parameter_list += ", &" + param_name;
-      extra_convert += " PyObject *" + param_name + "_uint = PyNumber_Long(" + param_name + ");";
-      extra_param_check += "|| (" + param_name + "_uint == NULL)";
-      pexpr_string = "(unsigned int)PyLong_AsUnsignedLong(" + param_name + "_uint)";
-      extra_cleanup += " Py_XDECREF(" + param_name + "_uint);";
-      expected_params += "unsigned int";
-
-    } else if (TypeManager::is_integer(type)) {
-      out << "int " << param_name;
-      format_specifiers += "i";
-      parameter_list += ", &" + param_name;
-      expected_params += "integer";
-
-    } else if (TypeManager::is_float(type)) {
-      out << "double " << param_name;
-      format_specifiers += "d";
-      parameter_list += ", &" + param_name;
-      expected_params += "float";
-
-    } else if (TypeManager::is_char_pointer(type)) {
-      out << "char *" << param_name;
-      format_specifiers += "s";
-      parameter_list += ", &" + param_name;
-      expected_params += "string";
-
-    } else if (TypeManager::is_pointer(type)) {
-      FunctionWriterPtrFromPython *writer = get_ptr_from_python(type);
-      writer->get_pointer_type()->output_instance(out, param_name, &parser);
-      format_specifiers += "O&";
-      parameter_list += ", &" + writer->get_name() + ", &" + param_name;
-      expected_params += writer->get_type()->get_preferred_name();
-
-    } else {
-      // Ignore a parameter.
-      out << "PyObject *" << param_name;
-      format_specifiers += "O";
-      parameter_list += ", &" + param_name;
-      expected_params += "any";
-    }
-
-    if (remap->_parameters[pn]._has_name) {
-      expected_params += " " + remap->_parameters[pn]._name;
-    }
-
-    out << ";\n";
-    pexprs.push_back(pexpr_string);
-  }
-  expected_params += ")";
-
-  indent(out, indent_level + 2)
-    << "if (PyArg_ParseTuple(args, \"" << format_specifiers
-    << "\"" << parameter_list << ")) {\n";
-
-  if (!extra_convert.empty()) {
-    indent(out, indent_level + 3)
-      << extra_convert << "\n";
-  }
-
-  if (!extra_param_check.empty()) {
-    indent(out, indent_level + 4)
-      << "if (" << extra_param_check.substr(3) << ") {\n";
-    if (!extra_cleanup.empty()) {
-      indent(out, indent_level + 5)
-        << extra_cleanup << "\n";
-    }
-    indent(out, indent_level + 6)
-      << "PyErr_SetString(PyExc_TypeError, \"Invalid parameters.\");\n";
-    indent(out, indent_level + 6)
-      << "return (PyObject *)NULL;\n";
-    indent(out, indent_level + 4)
-      << "}\n";
-  }
-
-  if (track_interpreter) {
-    indent(out, indent_level + 4)
-      << "in_interpreter = 0;\n";
-  }
-
-  if (!remap->_void_return && 
-      remap->_return_type->new_type_is_atomic_string()) {
-    // Treat strings as a special case.  We don't want to format the
-    // return expression.
-    string return_expr = 
-      remap->call_function(out, indent_level + 4, false, "param0", pexprs);
-
-    CPPType *type = remap->_return_type->get_orig_type();
-    indent(out, indent_level + 4);
-    type->output_instance(out, "return_value", &parser);
-    out << " = " << return_expr << ";\n";
-
-    if (track_interpreter) {
-      indent(out, indent_level + 4)
-        << "in_interpreter = 1;\n";
-    }
-    if (!extra_cleanup.empty()) {
-      indent(out, indent_level + 3)
-        << extra_cleanup << "\n";
-    }
-
-    return_expr = manage_return_value(out, indent_level + 4, remap, "return_value");
-    test_assert(out, indent_level + 4);
-    pack_return_value(out, indent_level + 4, remap, return_expr);
-
-  } else {
-    string return_expr = 
-      remap->call_function(out, indent_level + 4, true, "param0", pexprs);
-    if (return_expr.empty()) {
-      if (track_interpreter) {
-        indent(out, indent_level + 4)
-          << "in_interpreter = 1;\n";
-      }
-      if (!extra_cleanup.empty()) {
-        indent(out, indent_level + 3)
-          << extra_cleanup << "\n";
-      }
-      test_assert(out, indent_level + 4);
-      indent(out, indent_level + 4)
-        << "return Py_BuildValue(\"\");\n";
-
-    } else {
-      CPPType *type = remap->_return_type->get_temporary_type();
-      indent(out, indent_level + 4);
-      type->output_instance(out, "return_value", &parser);
-      out << " = " << return_expr << ";\n";
-      if (track_interpreter) {
-        indent(out, indent_level + 4)
-          << "in_interpreter = 1;\n";
-      }
-      if (!extra_cleanup.empty()) {
-        indent(out, indent_level + 3)
-          << extra_cleanup << "\n";
-      }
-
-      return_expr = manage_return_value(out, indent_level + 4, remap, "return_value");
-      test_assert(out, indent_level + 4);
-      pack_return_value(out, indent_level + 4, remap, remap->_return_type->temporary_to_return(return_expr));
-    }
-  }
-
-  indent(out, indent_level + 2) << "}\n";
-  indent(out, indent_level + 2)
-    << "PyErr_Clear();\n";  // Clear the error generated by ParseTuple()
-  indent(out, indent_level)
-    << "}\n";
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonObj::pack_return_value
-//       Access: Private
-//  Description: Outputs a command to pack the indicated expression,
-//               of the return_type type, as a Python return value.
-////////////////////////////////////////////////////////////////////
-void InterfaceMakerPythonObj::
-pack_return_value(ostream &out, int indent_level,
-                  FunctionRemap *remap, string return_expr) {
-  CPPType *orig_type = remap->_return_type->get_orig_type();
-  CPPType *type = remap->_return_type->get_new_type();
-
-  if (remap->_return_type->new_type_is_atomic_string()) {
-    if (TypeManager::is_char_pointer(orig_type)) {
-      indent(out, indent_level)
-        << "return PyString_FromString(" << return_expr << ");\n";
-
-    } else {
-      indent(out, indent_level)
-        << "return PyString_FromStringAndSize("
-        << return_expr << ".data(), " << return_expr << ".length());\n";
-    }
-
-  } else if (TypeManager::is_unsigned_longlong(type)) {
-    indent(out, indent_level)
-      << "return PyLong_FromUnsignedLongLong(" << return_expr << ");\n";
-
-  } else if (TypeManager::is_longlong(type)) {
-    indent(out, indent_level)
-      << "return PyLong_FromLongLong(" << return_expr << ");\n";
-
-  } else if (TypeManager::is_unsigned_integer(type)) {
-    indent(out, indent_level)
-      << "return PyLong_FromUnsignedLong(" << return_expr << ");\n";
-
-  } else if (TypeManager::is_integer(type)) {
-    indent(out, indent_level)
-      << "return PyInt_FromLong(" << return_expr << ");\n";
-
-  } else if (TypeManager::is_float(type)) {
-    indent(out, indent_level)
-      << "return PyFloat_FromDouble(" << return_expr << ");\n";
-
-  } else if (TypeManager::is_char_pointer(type)) {
-    indent(out, indent_level)
-      << "return PyString_FromString(" << return_expr << ");\n";
-
-  } else if (TypeManager::is_pointer(type)) {
-    bool caller_manages = remap->_return_value_needs_management;
-
-    FunctionWriterPtrToPython *writer = get_ptr_to_python(type);
-    indent(out, indent_level)
-      << "return " << writer->get_name() << "((" 
-      << writer->get_pointer_type()->get_local_name(&parser) << ")"
-      << return_expr << ", " << caller_manages << ");\n";
-
-  } else {
-    // Return None.
-    indent(out, indent_level)
-      << "return Py_BuildValue(\"\");\n";
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonObj::get_ptr_from_python
-//       Access: Private
-//  Description: Returns a FunctionWriter pointer suitable for
-//               converting from a Python wrapper of the indicated
-//               type to the corresponding C++ pointer.
-////////////////////////////////////////////////////////////////////
-FunctionWriterPtrFromPython *InterfaceMakerPythonObj::
-get_ptr_from_python(CPPType *type) {
-  PtrConverter::iterator ci;
-  ci = _from_python.find(type);
-  if (ci != _from_python.end()) {
-    // We've previously used this type.
-    return (FunctionWriterPtrFromPython *)(*ci).second;
-  }
-
-  FunctionWriter *writer = 
-    _function_writers.add_writer(new FunctionWriterPtrFromPython(type));
-  _from_python.insert(PtrConverter::value_type(type, writer));
-  return (FunctionWriterPtrFromPython *)writer;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonObj::get_ptr_to_python
-//       Access: Private
-//  Description: Returns a FunctionWriter pointer suitable for
-//               converting from a C++ pointer of the indicated
-//               type to the corresponding Python wrapper.
-////////////////////////////////////////////////////////////////////
-FunctionWriterPtrToPython *InterfaceMakerPythonObj::
-get_ptr_to_python(CPPType *type) {
-  PtrConverter::iterator ci;
-  ci = _to_python.find(type);
-  if (ci != _to_python.end()) {
-    // We've previously used this type.
-    return (FunctionWriterPtrToPython *)(*ci).second;
-  }
-
-  FunctionWriter *writer = 
-    _function_writers.add_writer(new FunctionWriterPtrToPython(type));
-  _to_python.insert(PtrConverter::value_type(type, writer));
-  return (FunctionWriterPtrToPython *)writer;
-}
+// Filename: interfaceMakerPythonObj.cxx
+// Created by:  drose (19Sep01)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+ 
+#include "interfaceMakerPythonObj.h"
+#include "interrogateBuilder.h"
+#include "interrogate.h"
+#include "functionRemap.h"
+#include "parameterRemapUnchanged.h"
+#include "typeManager.h"
+#include "functionWriterPtrFromPython.h"
+#include "functionWriterPtrToPython.h"
+
+#include "interrogateDatabase.h"
+#include "interrogateType.h"
+#include "interrogateFunction.h"
+#include "cppFunctionType.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonObj::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+InterfaceMakerPythonObj::
+InterfaceMakerPythonObj(InterrogateModuleDef *def) :
+  InterfaceMakerPython(def)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonObj::Destructor
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+InterfaceMakerPythonObj::
+~InterfaceMakerPythonObj() {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonObj::write_prototypes
+//       Access: Public, Virtual
+//  Description: Generates the list of function prototypes
+//               corresponding to the functions that will be output in
+//               write_functions().
+////////////////////////////////////////////////////////////////////
+void InterfaceMakerPythonObj::
+write_prototypes(ostream &out,ostream *out_h) {
+  Functions::iterator fi;
+  for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
+    Function *func = (*fi);
+    write_prototype_for(out, func);
+  }
+
+  out << "\n";
+  InterfaceMakerPython::write_prototypes(out,out_h);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonObj::write_functions
+//       Access: Public, Virtual
+//  Description: Generates the list of functions that are appropriate
+//               for this interface.  This function is called *before*
+//               write_prototypes(), above.
+////////////////////////////////////////////////////////////////////
+void InterfaceMakerPythonObj::
+write_functions(ostream &out) {
+  Functions::iterator fi;
+  for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
+    Function *func = (*fi);
+    write_function_for(out, func);
+  }
+
+  InterfaceMakerPython::write_functions(out);
+
+  // Finally, generate all the make-class-wrapper functions.
+  Objects::iterator oi;
+  for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
+    Object *object = (*oi).second;
+
+    write_class_wrapper(out, object);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonObj::write_module
+//       Access: Public, Virtual
+//  Description: Generates whatever additional code is required to
+//               support a module file.
+////////////////////////////////////////////////////////////////////
+void InterfaceMakerPythonObj::
+write_module(ostream &out,ostream *out_h, InterrogateModuleDef *def) {
+  InterfaceMakerPython::write_module(out,out_h, def);
+
+  out << "static PyMethodDef python_obj_funcs[] = {\n";
+
+  Objects::iterator oi;
+  for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
+    Object *object = (*oi).second;
+
+    Functions::iterator fi;
+    for (fi = object->_constructors.begin(); 
+         fi != object->_constructors.end(); 
+         ++fi) {
+      Function *func = (*fi);
+      out << "  { \"" << func->_ifunc.get_name() << "\", &" << func->_name 
+          << ", METH_VARARGS },\n";
+    }
+  }  
+  out << "  { NULL, NULL }\n"
+      << "};\n\n"
+
+      << "#ifdef _WIN32\n"
+      << "extern \"C\" __declspec(dllexport) void init" << def->library_name << "();\n"
+      << "#else\n"
+      << "extern \"C\" void init" << def->library_name << "();\n"
+      << "#endif\n\n"
+    
+      << "void init" << def->library_name << "() {\n"
+      << "  Py_InitModule(\"" << def->library_name
+      << "\", python_obj_funcs);\n"
+      << "}\n\n";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonObj::synthesize_this_parameter
+//       Access: Public, Virtual
+//  Description: This method should be overridden and redefined to
+//               return true for interfaces that require the implicit
+//               "this" parameter, if present, to be passed as the
+//               first parameter to any wrapper functions.
+////////////////////////////////////////////////////////////////////
+bool InterfaceMakerPythonObj::
+synthesize_this_parameter() {
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonObj::get_builder_name
+//       Access: Public, Static
+//  Description: Returns the name of the InterfaceMaker function
+//               generated to define the Python class for the
+//               indicated struct type.
+////////////////////////////////////////////////////////////////////
+string InterfaceMakerPythonObj::
+get_builder_name(CPPType *struct_type) {
+  return "get_python_class_" + 
+    InterrogateBuilder::clean_identifier(struct_type->get_local_name(&parser));
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonObj::get_wrapper_prefix
+//       Access: Protected, Virtual
+//  Description: Returns the prefix string used to generate wrapper
+//               function names.
+////////////////////////////////////////////////////////////////////
+string InterfaceMakerPythonObj::
+get_wrapper_prefix() {
+  return "wpo_";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonObj::write_class_wrapper
+//       Access: Private
+//  Description: Writes a function that will define the Python class.
+////////////////////////////////////////////////////////////////////
+void InterfaceMakerPythonObj::
+write_class_wrapper(ostream &out, InterfaceMaker::Object *object) {
+  CPPType *struct_type = object->_itype._cpptype;
+  if (struct_type == (CPPType *)NULL) {
+    return;
+  }
+
+  string name = get_builder_name(struct_type);
+  string python_name =
+    InterrogateBuilder::clean_identifier(struct_type->get_simple_name());
+
+  out << "/*\n"
+      << " * Generate unique Python class for "
+      << struct_type->get_local_name(&parser) << "\n"
+      << " */\n"
+      << "PyObject *\n"
+      << name << "() {\n"
+      << "  static PyObject *wrapper = (PyObject *)NULL;\n"
+      << "  static PyMethodDef methods[] = {\n";
+
+  int methods_size = 0;
+  int class_methods_size = 0;
+
+  Functions::iterator fi;
+  for (fi = object->_methods.begin(); fi != object->_methods.end(); ++fi) {
+    Function *func = (*fi);
+    if (func->_has_this) {
+      out << "  { \"" << func->_ifunc.get_name() << "\", &" << func->_name 
+          << ", METH_VARARGS },\n";
+      methods_size++;
+    }
+  }
+
+  out << "  };\n"
+      << "  static const int methods_size = " << methods_size << ";\n\n"
+      << "  static PyMethodDef class_methods[] = {\n";
+
+  for (fi = object->_methods.begin(); fi != object->_methods.end(); ++fi) {
+    Function *func = (*fi);
+    if (!func->_has_this) {
+      out << "  { \"" << func->_ifunc.get_name() << "\", &" << func->_name 
+          << ", METH_VARARGS },\n";
+      class_methods_size++;
+    }
+  }
+
+  out << "  };\n"
+      << "  static const int class_methods_size = " << class_methods_size << ";\n\n"
+      << "  if (wrapper == (PyObject *)NULL) {\n"
+      << "    int i;\n"
+      << "    PyObject *bases = PyTuple_New(0);\n"
+      << "    PyObject *dict = PyDict_New();\n"
+      << "    PyObject *name = PyString_FromString(\""
+      << python_name << "\");\n"
+      << "    wrapper = PyClass_New(bases, dict, name);\n"
+      << "    for (i = 0; i < methods_size; ++i) {\n"
+      << "      PyObject *function, *method;\n"
+      << "      function = PyCFunction_New(&methods[i], (PyObject *)NULL);\n"
+      << "      method = PyMethod_New(function, (PyObject *)NULL, wrapper);\n"
+      << "      PyDict_SetItemString(dict, methods[i].ml_name, method);\n"
+      << "    }\n"
+      << "    for (i = 0; i < class_methods_size; ++i) {\n"
+      << "      PyObject *function;\n"
+      << "      function = PyCFunction_New(&class_methods[i], (PyObject *)NULL);\n"
+      << "      PyDict_SetItemString(dict, class_methods[i].ml_name, function);\n"
+      << "    }\n"
+      << "  }\n"
+      << "  return wrapper;\n"
+      << "}\n\n";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonObj::write_prototype_for
+//       Access: Private
+//  Description: Writes the prototype for the indicated function.
+////////////////////////////////////////////////////////////////////
+void InterfaceMakerPythonObj::
+write_prototype_for(ostream &out, InterfaceMaker::Function *func) {
+  out << "static PyObject *"
+      << func->_name << "(PyObject *self, PyObject *args);\n";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonObj::write_function_for
+//       Access: Private
+//  Description: Writes the definition for a function that will call
+//               the indicated C++ function or method.
+////////////////////////////////////////////////////////////////////
+void InterfaceMakerPythonObj::
+write_function_for(ostream &out, InterfaceMaker::Function *func) {
+  Function::Remaps::const_iterator ri;
+  out << "/*\n"
+      << " * Python object wrapper for\n";
+  for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
+    FunctionRemap *remap = (*ri);
+    out << " * ";
+    remap->write_orig_prototype(out, 0);
+    out << "\n";
+  }
+  out << " */\n";
+
+  out << "static PyObject *"
+      << func->_name << "(PyObject *, PyObject *args) {\n";
+
+  // Now write out each instance of the overloaded function.
+  string expected_params = "Arguments must match one of:";
+
+  for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
+    FunctionRemap *remap = (*ri);
+    expected_params += "\\n  ";
+    write_function_instance(out, 2, func, remap, expected_params);
+  }
+
+  // If we get here in the generated code, none of the parameters were
+  // valid.  Generate an error exception.  (We don't rely on the error
+  // already generated by ParseTuple(), because it only reports the
+  // error for one flavor of the function, whereas we might accept
+  // multiple flavors for the different overloaded C++ function
+  // signatures.
+
+  out << "  PyErr_SetString(PyExc_TypeError, \"" << expected_params << "\");\n"
+      << "  return (PyObject *)NULL;\n";
+
+  out << "}\n\n";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonObj::write_function_instance
+//       Access: Private
+//  Description: Writes out the part of a function that handles a
+//               single instance of an overloaded function.
+////////////////////////////////////////////////////////////////////
+void InterfaceMakerPythonObj::
+write_function_instance(ostream &out, int indent_level,
+                        InterfaceMaker::Function *func,
+                        FunctionRemap *remap, string &expected_params) {
+  indent(out, indent_level) << "{\n";
+  indent(out, indent_level + 2) << "/* ";
+  remap->write_orig_prototype(out, 0);
+  out << " */\n\n";
+  
+  string format_specifiers;
+  string parameter_list;
+  vector_string pexprs;
+  string extra_convert;
+  string extra_param_check;
+  string extra_cleanup;
+
+  // Make one pass through the parameter list.  We will output a
+  // one-line temporary variable definition for each parameter, while
+  // simultaneously building the ParseTuple() function call and also
+  // the parameter expression list for call_function().
+
+  expected_params += remap->_cppfunc->get_simple_name();
+  expected_params += "(";
+
+  int pn;
+  for (pn = 0; pn < (int)remap->_parameters.size(); pn++) {
+    if (pn != 0) {
+      expected_params += ", ";
+    }
+
+    indent(out, indent_level + 2);
+    CPPType *orig_type = remap->_parameters[pn]._remap->get_orig_type();
+    CPPType *type = remap->_parameters[pn]._remap->get_new_type();
+    string param_name = remap->get_parameter_name(pn);
+    
+    // This is the string to convert our local variable to the
+    // appropriate C++ type.  Normally this is just a cast.
+    string pexpr_string =
+      "(" + type->get_local_name(&parser) + ")" + param_name;
+    
+    if (remap->_parameters[pn]._remap->new_type_is_atomic_string()) {
+      if (TypeManager::is_char_pointer(orig_type)) {
+        out << "char *" << param_name;
+        format_specifiers += "s";
+        parameter_list += ", &" + param_name;
+        
+      } else {
+        out << "char *" << param_name
+            << "_str; int " << param_name << "_len";
+        format_specifiers += "s#";
+        parameter_list += ", &" + param_name
+          + "_str, &" + param_name + "_len";
+        pexpr_string = "basic_string<char>(" +
+          param_name + "_str, " +
+          param_name + "_len)";
+      }
+      expected_params += "string";
+      
+    } else if (TypeManager::is_bool(type)) {
+      out << "PyObject *" << param_name;
+      format_specifiers += "O";
+      parameter_list += ", &" + param_name;
+      pexpr_string = "(PyObject_IsTrue(" + param_name + ")!=0)";
+      expected_params += "bool";
+
+    } else if (TypeManager::is_unsigned_longlong(type)) {
+      out << "PyObject *" << param_name;
+      format_specifiers += "O";
+      parameter_list += ", &" + param_name;
+      extra_convert += " PyObject *" + param_name + "_long = PyNumber_Long(" + param_name + ");";
+      extra_param_check += "|| (" + param_name + "_long == NULL)";
+      pexpr_string = "PyLong_AsUnsignedLongLong(" + param_name + "_long)";
+      extra_cleanup += " Py_XDECREF(" + param_name + "_long);";
+      expected_params += "long";
+
+    } else if (TypeManager::is_longlong(type)) {
+      out << "PyObject *" << param_name;
+      format_specifiers += "O";
+      parameter_list += ", &" + param_name;
+      extra_convert += " PyObject *" + param_name + "_long = PyNumber_Long(" + param_name + ");";
+      extra_param_check += "|| (" + param_name + "_long == NULL)";
+      pexpr_string = "PyLong_AsLongLong(" + param_name + "_long)";
+      extra_cleanup += " Py_XDECREF(" + param_name + "_long);";
+      expected_params += "long";
+
+    } else if (TypeManager::is_unsigned_integer(type)) {
+      out << "PyObject *" << param_name;
+      format_specifiers += "O";
+      parameter_list += ", &" + param_name;
+      extra_convert += " PyObject *" + param_name + "_uint = PyNumber_Long(" + param_name + ");";
+      extra_param_check += "|| (" + param_name + "_uint == NULL)";
+      pexpr_string = "(unsigned int)PyLong_AsUnsignedLong(" + param_name + "_uint)";
+      extra_cleanup += " Py_XDECREF(" + param_name + "_uint);";
+      expected_params += "unsigned int";
+
+    } else if (TypeManager::is_integer(type)) {
+      out << "int " << param_name;
+      format_specifiers += "i";
+      parameter_list += ", &" + param_name;
+      expected_params += "integer";
+
+    } else if (TypeManager::is_float(type)) {
+      out << "double " << param_name;
+      format_specifiers += "d";
+      parameter_list += ", &" + param_name;
+      expected_params += "float";
+
+    } else if (TypeManager::is_char_pointer(type)) {
+      out << "char *" << param_name;
+      format_specifiers += "s";
+      parameter_list += ", &" + param_name;
+      expected_params += "string";
+
+    } else if (TypeManager::is_pointer(type)) {
+      FunctionWriterPtrFromPython *writer = get_ptr_from_python(type);
+      writer->get_pointer_type()->output_instance(out, param_name, &parser);
+      format_specifiers += "O&";
+      parameter_list += ", &" + writer->get_name() + ", &" + param_name;
+      expected_params += writer->get_type()->get_preferred_name();
+
+    } else {
+      // Ignore a parameter.
+      out << "PyObject *" << param_name;
+      format_specifiers += "O";
+      parameter_list += ", &" + param_name;
+      expected_params += "any";
+    }
+
+    if (remap->_parameters[pn]._has_name) {
+      expected_params += " " + remap->_parameters[pn]._name;
+    }
+
+    out << ";\n";
+    pexprs.push_back(pexpr_string);
+  }
+  expected_params += ")";
+
+  indent(out, indent_level + 2)
+    << "if (PyArg_ParseTuple(args, \"" << format_specifiers
+    << "\"" << parameter_list << ")) {\n";
+
+  if (!extra_convert.empty()) {
+    indent(out, indent_level + 3)
+      << extra_convert << "\n";
+  }
+
+  if (!extra_param_check.empty()) {
+    indent(out, indent_level + 4)
+      << "if (" << extra_param_check.substr(3) << ") {\n";
+    if (!extra_cleanup.empty()) {
+      indent(out, indent_level + 5)
+        << extra_cleanup << "\n";
+    }
+    indent(out, indent_level + 6)
+      << "PyErr_SetString(PyExc_TypeError, \"Invalid parameters.\");\n";
+    indent(out, indent_level + 6)
+      << "return (PyObject *)NULL;\n";
+    indent(out, indent_level + 4)
+      << "}\n";
+  }
+
+  if (track_interpreter) {
+    indent(out, indent_level + 4)
+      << "in_interpreter = 0;\n";
+  }
+
+  if (!remap->_void_return && 
+      remap->_return_type->new_type_is_atomic_string()) {
+    // Treat strings as a special case.  We don't want to format the
+    // return expression.
+    string return_expr = 
+      remap->call_function(out, indent_level + 4, false, "param0", pexprs);
+
+    CPPType *type = remap->_return_type->get_orig_type();
+    indent(out, indent_level + 4);
+    type->output_instance(out, "return_value", &parser);
+    out << " = " << return_expr << ";\n";
+
+    if (track_interpreter) {
+      indent(out, indent_level + 4)
+        << "in_interpreter = 1;\n";
+    }
+    if (!extra_cleanup.empty()) {
+      indent(out, indent_level + 3)
+        << extra_cleanup << "\n";
+    }
+
+    return_expr = manage_return_value(out, indent_level + 4, remap, "return_value");
+    test_assert(out, indent_level + 4);
+    pack_return_value(out, indent_level + 4, remap, return_expr);
+
+  } else {
+    string return_expr = 
+      remap->call_function(out, indent_level + 4, true, "param0", pexprs);
+    if (return_expr.empty()) {
+      if (track_interpreter) {
+        indent(out, indent_level + 4)
+          << "in_interpreter = 1;\n";
+      }
+      if (!extra_cleanup.empty()) {
+        indent(out, indent_level + 3)
+          << extra_cleanup << "\n";
+      }
+      test_assert(out, indent_level + 4);
+      indent(out, indent_level + 4)
+        << "return Py_BuildValue(\"\");\n";
+
+    } else {
+      CPPType *type = remap->_return_type->get_temporary_type();
+      indent(out, indent_level + 4);
+      type->output_instance(out, "return_value", &parser);
+      out << " = " << return_expr << ";\n";
+      if (track_interpreter) {
+        indent(out, indent_level + 4)
+          << "in_interpreter = 1;\n";
+      }
+      if (!extra_cleanup.empty()) {
+        indent(out, indent_level + 3)
+          << extra_cleanup << "\n";
+      }
+
+      return_expr = manage_return_value(out, indent_level + 4, remap, "return_value");
+      test_assert(out, indent_level + 4);
+      pack_return_value(out, indent_level + 4, remap, remap->_return_type->temporary_to_return(return_expr));
+    }
+  }
+
+  indent(out, indent_level + 2) << "}\n";
+  indent(out, indent_level + 2)
+    << "PyErr_Clear();\n";  // Clear the error generated by ParseTuple()
+  indent(out, indent_level)
+    << "}\n";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonObj::pack_return_value
+//       Access: Private
+//  Description: Outputs a command to pack the indicated expression,
+//               of the return_type type, as a Python return value.
+////////////////////////////////////////////////////////////////////
+void InterfaceMakerPythonObj::
+pack_return_value(ostream &out, int indent_level,
+                  FunctionRemap *remap, string return_expr) {
+  CPPType *orig_type = remap->_return_type->get_orig_type();
+  CPPType *type = remap->_return_type->get_new_type();
+
+  if (remap->_return_type->new_type_is_atomic_string()) {
+    if (TypeManager::is_char_pointer(orig_type)) {
+      indent(out, indent_level)
+        << "return PyString_FromString(" << return_expr << ");\n";
+
+    } else {
+      indent(out, indent_level)
+        << "return PyString_FromStringAndSize("
+        << return_expr << ".data(), " << return_expr << ".length());\n";
+    }
+
+  } else if (TypeManager::is_unsigned_longlong(type)) {
+    indent(out, indent_level)
+      << "return PyLong_FromUnsignedLongLong(" << return_expr << ");\n";
+
+  } else if (TypeManager::is_longlong(type)) {
+    indent(out, indent_level)
+      << "return PyLong_FromLongLong(" << return_expr << ");\n";
+
+  } else if (TypeManager::is_unsigned_integer(type)) {
+    indent(out, indent_level)
+      << "return PyLong_FromUnsignedLong(" << return_expr << ");\n";
+
+  } else if (TypeManager::is_integer(type)) {
+    indent(out, indent_level)
+      << "return PyInt_FromLong(" << return_expr << ");\n";
+
+  } else if (TypeManager::is_float(type)) {
+    indent(out, indent_level)
+      << "return PyFloat_FromDouble(" << return_expr << ");\n";
+
+  } else if (TypeManager::is_char_pointer(type)) {
+    indent(out, indent_level)
+      << "return PyString_FromString(" << return_expr << ");\n";
+
+  } else if (TypeManager::is_pointer(type)) {
+    bool caller_manages = remap->_return_value_needs_management;
+
+    FunctionWriterPtrToPython *writer = get_ptr_to_python(type);
+    indent(out, indent_level)
+      << "return " << writer->get_name() << "((" 
+      << writer->get_pointer_type()->get_local_name(&parser) << ")"
+      << return_expr << ", " << caller_manages << ");\n";
+
+  } else {
+    // Return None.
+    indent(out, indent_level)
+      << "return Py_BuildValue(\"\");\n";
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonObj::get_ptr_from_python
+//       Access: Private
+//  Description: Returns a FunctionWriter pointer suitable for
+//               converting from a Python wrapper of the indicated
+//               type to the corresponding C++ pointer.
+////////////////////////////////////////////////////////////////////
+FunctionWriterPtrFromPython *InterfaceMakerPythonObj::
+get_ptr_from_python(CPPType *type) {
+  PtrConverter::iterator ci;
+  ci = _from_python.find(type);
+  if (ci != _from_python.end()) {
+    // We've previously used this type.
+    return (FunctionWriterPtrFromPython *)(*ci).second;
+  }
+
+  FunctionWriter *writer = 
+    _function_writers.add_writer(new FunctionWriterPtrFromPython(type));
+  _from_python.insert(PtrConverter::value_type(type, writer));
+  return (FunctionWriterPtrFromPython *)writer;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonObj::get_ptr_to_python
+//       Access: Private
+//  Description: Returns a FunctionWriter pointer suitable for
+//               converting from a C++ pointer of the indicated
+//               type to the corresponding Python wrapper.
+////////////////////////////////////////////////////////////////////
+FunctionWriterPtrToPython *InterfaceMakerPythonObj::
+get_ptr_to_python(CPPType *type) {
+  PtrConverter::iterator ci;
+  ci = _to_python.find(type);
+  if (ci != _to_python.end()) {
+    // We've previously used this type.
+    return (FunctionWriterPtrToPython *)(*ci).second;
+  }
+
+  FunctionWriter *writer = 
+    _function_writers.add_writer(new FunctionWriterPtrToPython(type));
+  _to_python.insert(PtrConverter::value_type(type, writer));
+  return (FunctionWriterPtrToPython *)writer;
+}

+ 497 - 497
dtool/src/interrogate/interfaceMakerPythonSimple.cxx

@@ -1,497 +1,497 @@
-// Filename: interfaceMakerPythonSimple.cxx
-// Created by:  drose (01Oct01)
-//
-////////////////////////////////////////////////////////////////////
-//
-// PANDA 3D SOFTWARE
-// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
-//
-// All use of this software is subject to the terms of the Panda 3d
-// Software license.  You should have received a copy of this license
-// along with this source code; you will also find a current copy of
-// the license at http://etc.cmu.edu/panda3d/docs/license/ .
-//
-// To contact the maintainers of this program    write to
-// [email protected] .
-//
-////////////////////////////////////////////////////////////////////
-
-#include "interfaceMakerPythonSimple.h"
-#include "interrogateBuilder.h"
-#include "interrogate.h"
-#include "functionRemap.h"
-#include "parameterRemapUnchanged.h"
-#include "typeManager.h"
-
-#include "interrogateDatabase.h"
-#include "interrogateType.h"
-#include "interrogateFunction.h"
-#include "cppFunctionType.h"
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonSimple::Constructor
-//       Access: Public
-//  Description:
-////////////////////////////////////////////////////////////////////
-InterfaceMakerPythonSimple::
-InterfaceMakerPythonSimple(InterrogateModuleDef *def) :
-  InterfaceMakerPython(def)
-{
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonSimple::Destructor
-//       Access: Public, Virtual
-//  Description:
-////////////////////////////////////////////////////////////////////
-InterfaceMakerPythonSimple::
-~InterfaceMakerPythonSimple() {
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonSimple::write_prototypes
-//       Access: Public, Virtual
-//  Description: Generates the list of function prototypes
-//               corresponding to the functions that will be output in
-//               write_functions().
-////////////////////////////////////////////////////////////////////
-void InterfaceMakerPythonSimple::
-write_prototypes(ostream &out,ostream *out_h) {
-  Functions::iterator fi;
-  for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
-    Function *func = (*fi);
-    write_prototype_for(out, func);
-  }
-
-  out << "\n";
-  InterfaceMakerPython::write_prototypes(out,out_h);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonSimple::write_functions
-//       Access: Public, Virtual
-//  Description: Generates the list of functions that are appropriate
-//               for this interface.  This function is called *before*
-//               write_prototypes(), above.
-////////////////////////////////////////////////////////////////////
-void InterfaceMakerPythonSimple::
-write_functions(ostream &out) {
-  Functions::iterator fi;
-  for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
-    Function *func = (*fi);
-    write_function_for(out, func);
-  }
-
-  InterfaceMakerPython::write_functions(out);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonSimple::write_module
-//       Access: Public, Virtual
-//  Description: Generates whatever additional code is required to
-//               support a module file.
-////////////////////////////////////////////////////////////////////
-void InterfaceMakerPythonSimple::
-write_module(ostream &out,ostream *out_h, InterrogateModuleDef *def) {
-  InterfaceMakerPython::write_module(out,out_h, def);
-
-  out << "static PyMethodDef python_simple_funcs[] = {\n";
-
-  Functions::iterator fi;
-  for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
-    Function *func = (*fi);
-    Function::Remaps::const_iterator ri;
-    for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
-      FunctionRemap *remap = (*ri);
-      out << "  { \"" << remap->_reported_name << "\", &" 
-          << remap->_wrapper_name << ", METH_VARARGS },\n";
-    }
-  }  
-  out << "  { NULL, NULL }\n"
-      << "};\n\n"
-
-      << "#ifdef _WIN32\n"
-      << "extern \"C\" __declspec(dllexport) void init" << def->library_name << "();\n"
-      << "#else\n"
-      << "extern \"C\" void init" << def->library_name << "();\n"
-      << "#endif\n\n"
-    
-      << "void init" << def->library_name << "() {\n"
-      << "  Py_InitModule(\"" << def->library_name
-      << "\", python_simple_funcs);\n"
-      << "}\n\n";
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonSimple::synthesize_this_parameter
-//       Access: Public, Virtual
-//  Description: This method should be overridden and redefined to
-//               return true for interfaces that require the implicit
-//               "this" parameter, if present, to be passed as the
-//               first parameter to any wrapper functions.
-////////////////////////////////////////////////////////////////////
-bool InterfaceMakerPythonSimple::
-synthesize_this_parameter() {
-  return true;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonSimple::get_wrapper_prefix
-//       Access: Protected, Virtual
-//  Description: Returns the prefix string used to generate wrapper
-//               function names.
-////////////////////////////////////////////////////////////////////
-string InterfaceMakerPythonSimple::
-get_wrapper_prefix() {
-  return "_inP";
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonSimple::get_unique_prefix
-//       Access: Protected, Virtual
-//  Description: Returns the prefix string used to generate unique
-//               symbolic names, which are not necessarily C-callable
-//               function names.
-////////////////////////////////////////////////////////////////////
-string InterfaceMakerPythonSimple::
-get_unique_prefix() {
-  return "p";
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonSimple::record_function_wrapper
-//       Access: Protected, Virtual
-//  Description: Associates the function wrapper with its function in
-//               the appropriate structures in the database.
-////////////////////////////////////////////////////////////////////
-void InterfaceMakerPythonSimple::
-record_function_wrapper(InterrogateFunction &ifunc, 
-                        FunctionWrapperIndex wrapper_index) {
-  ifunc._python_wrappers.push_back(wrapper_index);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonSimple::write_prototype_for
-//       Access: Private
-//  Description: Writes the prototype for the indicated function.
-////////////////////////////////////////////////////////////////////
-void InterfaceMakerPythonSimple::
-write_prototype_for(ostream &out, InterfaceMaker::Function *func) {
-  Function::Remaps::const_iterator ri;
-
-  for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
-    FunctionRemap *remap = (*ri);
-    if (!output_function_names) {
-      // If we're not saving the function names, don't export it from
-      // the library.
-      out << "static ";
-    } else {
-      out << "extern \"C\" ";
-    }
-    out << "PyObject *"
-        << remap->_wrapper_name << "(PyObject *self, PyObject *args);\n";
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonSimple::write_function_for
-//       Access: Private
-//  Description: Writes the definition for a function that will call
-//               the indicated C++ function or method.
-////////////////////////////////////////////////////////////////////
-void InterfaceMakerPythonSimple::
-write_function_for(ostream &out, InterfaceMaker::Function *func) {
-  Function::Remaps::const_iterator ri;
-
-  for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
-    FunctionRemap *remap = (*ri);
-    write_function_instance(out, func, remap);
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonSimple::write_function_instance
-//       Access: Private
-//  Description: Writes out the particular function that handles a
-//               single instance of an overloaded function.
-////////////////////////////////////////////////////////////////////
-void InterfaceMakerPythonSimple::write_function_instance(ostream &out, InterfaceMaker::Function *func,
-                        FunctionRemap *remap) {
-  out << "/*\n"
-      << " * Python simple wrapper for\n"
-      << " * ";
-  remap->write_orig_prototype(out, 0);
-  out << "\n"
-      << " */\n";
-
-  if (!output_function_names) {
-    // If we're not saving the function names, don't export it from
-    // the library.
-    out << "static ";
-  }
-
-  out << "PyObject *\n"
-      << remap->_wrapper_name << "(PyObject *, PyObject *args) {\n";
-
-  if (generate_spam) {
-    write_spam_message(out, remap);
-  }
-
-  string format_specifiers;
-  string parameter_list;
-  string container;
-  vector_string pexprs;
-  string extra_convert;
-  string extra_param_check;
-  string extra_cleanup;
-
-  // Make one pass through the parameter list.  We will output a
-  // one-line temporary variable definition for each parameter, while
-  // simultaneously building the ParseTuple() function call and also
-  // the parameter expression list for call_function().
-
-  int pn;
-  for (pn = 0; pn < (int)remap->_parameters.size(); ++pn) {
-    indent(out, 2);
-    CPPType *orig_type = remap->_parameters[pn]._remap->get_orig_type();
-    CPPType *type = remap->_parameters[pn]._remap->get_new_type();
-    string param_name = remap->get_parameter_name(pn);
-    
-    // This is the string to convert our local variable to the
-    // appropriate C++ type.  Normally this is just a cast.
-    string pexpr_string =
-      "(" + type->get_local_name(&parser) + ")" + param_name;
-    
-    if (remap->_parameters[pn]._remap->new_type_is_atomic_string()) {
-      if (TypeManager::is_char_pointer(orig_type)) {
-        out << "char *" << param_name;
-        format_specifiers += "s";
-        parameter_list += ", &" + param_name;
-        
-      } else {
-        out << "char *" << param_name
-            << "_str; int " << param_name << "_len";
-        format_specifiers += "s#";
-        parameter_list += ", &" + param_name
-          + "_str, &" + param_name + "_len";
-        pexpr_string = "basic_string<char>(" +
-          param_name + "_str, " +
-          param_name + "_len)";
-      }
-      
-    } else if (TypeManager::is_bool(type)) {
-      out << "PyObject *" << param_name;
-      format_specifiers += "O";
-      parameter_list += ", &" + param_name;
-      pexpr_string = "(PyObject_IsTrue(" + param_name + ")!=0)";
-
-    } else if (TypeManager::is_unsigned_longlong(type)) {
-      out << "PyObject *" << param_name;
-      format_specifiers += "O";
-      parameter_list += ", &" + param_name;
-      extra_convert += " PyObject *" + param_name + "_long = PyNumber_Long(" + param_name + ");";
-      extra_param_check += "|| (" + param_name + "_long == NULL)";
-      pexpr_string = "PyLong_AsUnsignedLongLong(" + param_name + "_long)";
-      extra_cleanup += " Py_XDECREF(" + param_name + "_long);";
-
-    } else if (TypeManager::is_longlong(type)) {
-      out << "PyObject *" << param_name;
-      format_specifiers += "O";
-      parameter_list += ", &" + param_name;
-      extra_convert += " PyObject *" + param_name + "_long = PyNumber_Long(" + param_name + ");";
-      extra_param_check += "|| (" + param_name + "_long == NULL)";
-      pexpr_string = "PyLong_AsLongLong(" + param_name + "_long)";
-      extra_cleanup += " Py_XDECREF(" + param_name + "_long);";
-
-    } else if (TypeManager::is_unsigned_integer(type)) {
-      out << "PyObject *" << param_name;
-      format_specifiers += "O";
-      parameter_list += ", &" + param_name;
-      extra_convert += " PyObject *" + param_name + "_uint = PyNumber_Long(" + param_name + ");";
-      extra_param_check += "|| (" + param_name + "_uint == NULL)";
-      pexpr_string = "(unsigned int)PyLong_AsUnsignedLong(" + param_name + "_uint)";
-      extra_cleanup += " Py_XDECREF(" + param_name + "_uint);";
-
-    } else if (TypeManager::is_integer(type)) {
-      out << "int " << param_name;
-      format_specifiers += "i";
-      parameter_list += ", &" + param_name;
-
-    } else if (TypeManager::is_float(type)) {
-      out << "double " << param_name;
-      format_specifiers += "d";
-      parameter_list += ", &" + param_name;
-
-    } else if (TypeManager::is_char_pointer(type)) {
-      out << "char *" << param_name;
-      format_specifiers += "s";
-      parameter_list += ", &" + param_name;
-
-    } else if (TypeManager::is_pointer_to_PyObject(type)) {
-      out << "PyObject *" << param_name;
-      format_specifiers += "O";
-      parameter_list += ", &" + param_name;
-      pexpr_string = param_name;
-
-    } else if (TypeManager::is_pointer(type)) {
-      out << "int " << param_name;
-      format_specifiers += "i";
-      parameter_list += ", &" + param_name;
-
-    } else {
-      // Ignore a parameter.
-      out << "PyObject *" << param_name;
-      format_specifiers += "O";
-      parameter_list += ", &" + param_name;
-    }
-
-    out << ";\n";
-    if (remap->_has_this && pn == 0) {
-      // The "this" parameter gets passed in separately.
-      container = pexpr_string;
-    }
-    pexprs.push_back(pexpr_string);
-  }
-
-  out << "  if (PyArg_ParseTuple(args, \"" << format_specifiers
-      << "\"" << parameter_list << ")) {\n";
-
-  if (!extra_convert.empty()) {
-    out << "   " << extra_convert << "\n";
-  }
-
-  if (!extra_param_check.empty()) {
-    out << "    if (" << extra_param_check.substr(3) << ") {\n";
-    if (!extra_cleanup.empty()) {
-      out << "     " << extra_cleanup << "\n";
-    }
-    out << "      PyErr_SetString(PyExc_TypeError, \"Invalid parameters.\");\n"
-        << "      return (PyObject *)NULL;\n"
-        << "    }\n";
-  }
-  
-  if (track_interpreter) {
-    out << "    in_interpreter = 0;\n";
-  }
-
-  if (!remap->_void_return && 
-      remap->_return_type->new_type_is_atomic_string()) {
-    // Treat strings as a special case.  We don't want to format the
-    // return expression.
-    string return_expr = remap->call_function(out, 4, false, container, pexprs);
-    CPPType *type = remap->_return_type->get_orig_type();
-    out << "    ";
-    type->output_instance(out, "return_value", &parser);
-    out << " = " << return_expr << ";\n";
-    
-    if (track_interpreter) {
-      out << "    in_interpreter = 1;\n";
-    }
-    if (!extra_cleanup.empty()) {
-      out << "   " << extra_cleanup << "\n";
-    }
-    
-    return_expr = manage_return_value(out, 4, remap, "return_value");
-    test_assert(out, 4);
-    pack_return_value(out, 4, remap, return_expr);
-    
-  } else {
-    string return_expr = remap->call_function(out, 4, true, container, pexprs);
-    if (return_expr.empty()) {
-      if (track_interpreter) {
-        out << "    in_interpreter = 1;\n";
-      }
-      if (!extra_cleanup.empty()) {
-        out << "   " << extra_cleanup << "\n";
-      }
-      test_assert(out, 4);
-      out << "    return Py_BuildValue(\"\");\n";
-      
-    } else {
-      CPPType *type = remap->_return_type->get_temporary_type();
-      out << "    ";
-      type->output_instance(out, "return_value", &parser);
-      out << " = " << return_expr << ";\n";
-      if (track_interpreter) {
-        out << "    in_interpreter = 1;\n";
-      }
-      if (!extra_cleanup.empty()) {
-        out << "   " << extra_cleanup << "\n";
-      }
-      
-      return_expr = manage_return_value(out, 4, remap, "return_value");
-      test_assert(out, 4);
-      pack_return_value(out, 4, remap, remap->_return_type->temporary_to_return(return_expr));
-    }
-  }
-  
-  out << "  }\n";
-  
-  out << "  return (PyObject *)NULL;\n";
-  out << "}\n\n";
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: InterfaceMakerPythonSimple::pack_return_value
-//       Access: Private
-//  Description: Outputs a command to pack the indicated expression,
-//               of the return_type type, as a Python return value.
-////////////////////////////////////////////////////////////////////
-void InterfaceMakerPythonSimple::
-pack_return_value(ostream &out, int indent_level,
-                  FunctionRemap *remap, string return_expr) {
-  CPPType *orig_type = remap->_return_type->get_orig_type();
-  CPPType *type = remap->_return_type->get_new_type();
-
-  if (remap->_return_type->new_type_is_atomic_string()) 
-  {
-    if (TypeManager::is_char_pointer(orig_type)) {
-      indent(out, indent_level)
-        << "return PyString_FromString(" << return_expr << ");\n";
-
-    } else {
-      indent(out, indent_level)
-        << "return PyString_FromStringAndSize("
-        << return_expr << ".data(), " << return_expr << ".length());\n";
-    }
-
-  } else if (TypeManager::is_unsigned_longlong(type)) 
-  {
-    indent(out, indent_level)
-      << "return PyLong_FromUnsignedLongLong(" << return_expr << ");\n";
-
-  } else if (TypeManager::is_longlong(type)) 
-  {
-    indent(out, indent_level)
-      << "return PyLong_FromLongLong(" << return_expr << ");\n";
-
-  } else if (TypeManager::is_unsigned_integer(type)) {
-    indent(out, indent_level)
-      << "return PyLong_FromUnsignedLong(" << return_expr << ");\n";
-
-  } else if (TypeManager::is_integer(type)) {
-    indent(out, indent_level)
-      << "return PyInt_FromLong(" << return_expr << ");\n";
-
-  } else if (TypeManager::is_float(type)) {
-    indent(out, indent_level)
-      << "return PyFloat_FromDouble(" << return_expr << ");\n";
-
-  } else if (TypeManager::is_char_pointer(type)) {
-    indent(out, indent_level)
-      << "return PyString_FromString(" << return_expr << ");\n";
-
-  } else if (TypeManager::is_pointer_to_PyObject(type)) {
-    indent(out, indent_level)
-      << "return " << return_expr << ";\n";
-    
-  } else if (TypeManager::is_pointer(type)) {
-    indent(out, indent_level)
-      << "return PyInt_FromLong((int)" << return_expr << ");\n";
-
-  } else {
-    // Return None.
-    indent(out, indent_level)
-      << "return Py_BuildValue(\"\");\n";
-  }
-}
+// Filename: interfaceMakerPythonSimple.cxx
+// Created by:  drose (01Oct01)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program    write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "interfaceMakerPythonSimple.h"
+#include "interrogateBuilder.h"
+#include "interrogate.h"
+#include "functionRemap.h"
+#include "parameterRemapUnchanged.h"
+#include "typeManager.h"
+
+#include "interrogateDatabase.h"
+#include "interrogateType.h"
+#include "interrogateFunction.h"
+#include "cppFunctionType.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonSimple::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+InterfaceMakerPythonSimple::
+InterfaceMakerPythonSimple(InterrogateModuleDef *def) :
+  InterfaceMakerPython(def)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonSimple::Destructor
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+InterfaceMakerPythonSimple::
+~InterfaceMakerPythonSimple() {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonSimple::write_prototypes
+//       Access: Public, Virtual
+//  Description: Generates the list of function prototypes
+//               corresponding to the functions that will be output in
+//               write_functions().
+////////////////////////////////////////////////////////////////////
+void InterfaceMakerPythonSimple::
+write_prototypes(ostream &out,ostream *out_h) {
+  Functions::iterator fi;
+  for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
+    Function *func = (*fi);
+    write_prototype_for(out, func);
+  }
+
+  out << "\n";
+  InterfaceMakerPython::write_prototypes(out,out_h);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonSimple::write_functions
+//       Access: Public, Virtual
+//  Description: Generates the list of functions that are appropriate
+//               for this interface.  This function is called *before*
+//               write_prototypes(), above.
+////////////////////////////////////////////////////////////////////
+void InterfaceMakerPythonSimple::
+write_functions(ostream &out) {
+  Functions::iterator fi;
+  for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
+    Function *func = (*fi);
+    write_function_for(out, func);
+  }
+
+  InterfaceMakerPython::write_functions(out);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonSimple::write_module
+//       Access: Public, Virtual
+//  Description: Generates whatever additional code is required to
+//               support a module file.
+////////////////////////////////////////////////////////////////////
+void InterfaceMakerPythonSimple::
+write_module(ostream &out,ostream *out_h, InterrogateModuleDef *def) {
+  InterfaceMakerPython::write_module(out,out_h, def);
+
+  out << "static PyMethodDef python_simple_funcs[] = {\n";
+
+  Functions::iterator fi;
+  for (fi = _functions.begin(); fi != _functions.end(); ++fi) {
+    Function *func = (*fi);
+    Function::Remaps::const_iterator ri;
+    for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
+      FunctionRemap *remap = (*ri);
+      out << "  { \"" << remap->_reported_name << "\", &" 
+          << remap->_wrapper_name << ", METH_VARARGS },\n";
+    }
+  }  
+  out << "  { NULL, NULL }\n"
+      << "};\n\n"
+
+      << "#ifdef _WIN32\n"
+      << "extern \"C\" __declspec(dllexport) void init" << def->library_name << "();\n"
+      << "#else\n"
+      << "extern \"C\" void init" << def->library_name << "();\n"
+      << "#endif\n\n"
+    
+      << "void init" << def->library_name << "() {\n"
+      << "  Py_InitModule(\"" << def->library_name
+      << "\", python_simple_funcs);\n"
+      << "}\n\n";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonSimple::synthesize_this_parameter
+//       Access: Public, Virtual
+//  Description: This method should be overridden and redefined to
+//               return true for interfaces that require the implicit
+//               "this" parameter, if present, to be passed as the
+//               first parameter to any wrapper functions.
+////////////////////////////////////////////////////////////////////
+bool InterfaceMakerPythonSimple::
+synthesize_this_parameter() {
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonSimple::get_wrapper_prefix
+//       Access: Protected, Virtual
+//  Description: Returns the prefix string used to generate wrapper
+//               function names.
+////////////////////////////////////////////////////////////////////
+string InterfaceMakerPythonSimple::
+get_wrapper_prefix() {
+  return "_inP";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonSimple::get_unique_prefix
+//       Access: Protected, Virtual
+//  Description: Returns the prefix string used to generate unique
+//               symbolic names, which are not necessarily C-callable
+//               function names.
+////////////////////////////////////////////////////////////////////
+string InterfaceMakerPythonSimple::
+get_unique_prefix() {
+  return "p";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonSimple::record_function_wrapper
+//       Access: Protected, Virtual
+//  Description: Associates the function wrapper with its function in
+//               the appropriate structures in the database.
+////////////////////////////////////////////////////////////////////
+void InterfaceMakerPythonSimple::
+record_function_wrapper(InterrogateFunction &ifunc, 
+                        FunctionWrapperIndex wrapper_index) {
+  ifunc._python_wrappers.push_back(wrapper_index);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonSimple::write_prototype_for
+//       Access: Private
+//  Description: Writes the prototype for the indicated function.
+////////////////////////////////////////////////////////////////////
+void InterfaceMakerPythonSimple::
+write_prototype_for(ostream &out, InterfaceMaker::Function *func) {
+  Function::Remaps::const_iterator ri;
+
+  for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
+    FunctionRemap *remap = (*ri);
+    if (!output_function_names) {
+      // If we're not saving the function names, don't export it from
+      // the library.
+      out << "static ";
+    } else {
+      out << "extern \"C\" ";
+    }
+    out << "PyObject *"
+        << remap->_wrapper_name << "(PyObject *self, PyObject *args);\n";
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonSimple::write_function_for
+//       Access: Private
+//  Description: Writes the definition for a function that will call
+//               the indicated C++ function or method.
+////////////////////////////////////////////////////////////////////
+void InterfaceMakerPythonSimple::
+write_function_for(ostream &out, InterfaceMaker::Function *func) {
+  Function::Remaps::const_iterator ri;
+
+  for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) {
+    FunctionRemap *remap = (*ri);
+    write_function_instance(out, func, remap);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonSimple::write_function_instance
+//       Access: Private
+//  Description: Writes out the particular function that handles a
+//               single instance of an overloaded function.
+////////////////////////////////////////////////////////////////////
+void InterfaceMakerPythonSimple::write_function_instance(ostream &out, InterfaceMaker::Function *func,
+                        FunctionRemap *remap) {
+  out << "/*\n"
+      << " * Python simple wrapper for\n"
+      << " * ";
+  remap->write_orig_prototype(out, 0);
+  out << "\n"
+      << " */\n";
+
+  if (!output_function_names) {
+    // If we're not saving the function names, don't export it from
+    // the library.
+    out << "static ";
+  }
+
+  out << "PyObject *\n"
+      << remap->_wrapper_name << "(PyObject *, PyObject *args) {\n";
+
+  if (generate_spam) {
+    write_spam_message(out, remap);
+  }
+
+  string format_specifiers;
+  string parameter_list;
+  string container;
+  vector_string pexprs;
+  string extra_convert;
+  string extra_param_check;
+  string extra_cleanup;
+
+  // Make one pass through the parameter list.  We will output a
+  // one-line temporary variable definition for each parameter, while
+  // simultaneously building the ParseTuple() function call and also
+  // the parameter expression list for call_function().
+
+  int pn;
+  for (pn = 0; pn < (int)remap->_parameters.size(); ++pn) {
+    indent(out, 2);
+    CPPType *orig_type = remap->_parameters[pn]._remap->get_orig_type();
+    CPPType *type = remap->_parameters[pn]._remap->get_new_type();
+    string param_name = remap->get_parameter_name(pn);
+    
+    // This is the string to convert our local variable to the
+    // appropriate C++ type.  Normally this is just a cast.
+    string pexpr_string =
+      "(" + type->get_local_name(&parser) + ")" + param_name;
+    
+    if (remap->_parameters[pn]._remap->new_type_is_atomic_string()) {
+      if (TypeManager::is_char_pointer(orig_type)) {
+        out << "char *" << param_name;
+        format_specifiers += "s";
+        parameter_list += ", &" + param_name;
+        
+      } else {
+        out << "char *" << param_name
+            << "_str; int " << param_name << "_len";
+        format_specifiers += "s#";
+        parameter_list += ", &" + param_name
+          + "_str, &" + param_name + "_len";
+        pexpr_string = "basic_string<char>(" +
+          param_name + "_str, " +
+          param_name + "_len)";
+      }
+      
+    } else if (TypeManager::is_bool(type)) {
+      out << "PyObject *" << param_name;
+      format_specifiers += "O";
+      parameter_list += ", &" + param_name;
+      pexpr_string = "(PyObject_IsTrue(" + param_name + ")!=0)";
+
+    } else if (TypeManager::is_unsigned_longlong(type)) {
+      out << "PyObject *" << param_name;
+      format_specifiers += "O";
+      parameter_list += ", &" + param_name;
+      extra_convert += " PyObject *" + param_name + "_long = PyNumber_Long(" + param_name + ");";
+      extra_param_check += "|| (" + param_name + "_long == NULL)";
+      pexpr_string = "PyLong_AsUnsignedLongLong(" + param_name + "_long)";
+      extra_cleanup += " Py_XDECREF(" + param_name + "_long);";
+
+    } else if (TypeManager::is_longlong(type)) {
+      out << "PyObject *" << param_name;
+      format_specifiers += "O";
+      parameter_list += ", &" + param_name;
+      extra_convert += " PyObject *" + param_name + "_long = PyNumber_Long(" + param_name + ");";
+      extra_param_check += "|| (" + param_name + "_long == NULL)";
+      pexpr_string = "PyLong_AsLongLong(" + param_name + "_long)";
+      extra_cleanup += " Py_XDECREF(" + param_name + "_long);";
+
+    } else if (TypeManager::is_unsigned_integer(type)) {
+      out << "PyObject *" << param_name;
+      format_specifiers += "O";
+      parameter_list += ", &" + param_name;
+      extra_convert += " PyObject *" + param_name + "_uint = PyNumber_Long(" + param_name + ");";
+      extra_param_check += "|| (" + param_name + "_uint == NULL)";
+      pexpr_string = "(unsigned int)PyLong_AsUnsignedLong(" + param_name + "_uint)";
+      extra_cleanup += " Py_XDECREF(" + param_name + "_uint);";
+
+    } else if (TypeManager::is_integer(type)) {
+      out << "int " << param_name;
+      format_specifiers += "i";
+      parameter_list += ", &" + param_name;
+
+    } else if (TypeManager::is_float(type)) {
+      out << "double " << param_name;
+      format_specifiers += "d";
+      parameter_list += ", &" + param_name;
+
+    } else if (TypeManager::is_char_pointer(type)) {
+      out << "char *" << param_name;
+      format_specifiers += "s";
+      parameter_list += ", &" + param_name;
+
+    } else if (TypeManager::is_pointer_to_PyObject(type)) {
+      out << "PyObject *" << param_name;
+      format_specifiers += "O";
+      parameter_list += ", &" + param_name;
+      pexpr_string = param_name;
+
+    } else if (TypeManager::is_pointer(type)) {
+      out << "int " << param_name;
+      format_specifiers += "i";
+      parameter_list += ", &" + param_name;
+
+    } else {
+      // Ignore a parameter.
+      out << "PyObject *" << param_name;
+      format_specifiers += "O";
+      parameter_list += ", &" + param_name;
+    }
+
+    out << ";\n";
+    if (remap->_has_this && pn == 0) {
+      // The "this" parameter gets passed in separately.
+      container = pexpr_string;
+    }
+    pexprs.push_back(pexpr_string);
+  }
+
+  out << "  if (PyArg_ParseTuple(args, \"" << format_specifiers
+      << "\"" << parameter_list << ")) {\n";
+
+  if (!extra_convert.empty()) {
+    out << "   " << extra_convert << "\n";
+  }
+
+  if (!extra_param_check.empty()) {
+    out << "    if (" << extra_param_check.substr(3) << ") {\n";
+    if (!extra_cleanup.empty()) {
+      out << "     " << extra_cleanup << "\n";
+    }
+    out << "      PyErr_SetString(PyExc_TypeError, \"Invalid parameters.\");\n"
+        << "      return (PyObject *)NULL;\n"
+        << "    }\n";
+  }
+  
+  if (track_interpreter) {
+    out << "    in_interpreter = 0;\n";
+  }
+
+  if (!remap->_void_return && 
+      remap->_return_type->new_type_is_atomic_string()) {
+    // Treat strings as a special case.  We don't want to format the
+    // return expression.
+    string return_expr = remap->call_function(out, 4, false, container, pexprs);
+    CPPType *type = remap->_return_type->get_orig_type();
+    out << "    ";
+    type->output_instance(out, "return_value", &parser);
+    out << " = " << return_expr << ";\n";
+    
+    if (track_interpreter) {
+      out << "    in_interpreter = 1;\n";
+    }
+    if (!extra_cleanup.empty()) {
+      out << "   " << extra_cleanup << "\n";
+    }
+    
+    return_expr = manage_return_value(out, 4, remap, "return_value");
+    test_assert(out, 4);
+    pack_return_value(out, 4, remap, return_expr);
+    
+  } else {
+    string return_expr = remap->call_function(out, 4, true, container, pexprs);
+    if (return_expr.empty()) {
+      if (track_interpreter) {
+        out << "    in_interpreter = 1;\n";
+      }
+      if (!extra_cleanup.empty()) {
+        out << "   " << extra_cleanup << "\n";
+      }
+      test_assert(out, 4);
+      out << "    return Py_BuildValue(\"\");\n";
+      
+    } else {
+      CPPType *type = remap->_return_type->get_temporary_type();
+      out << "    ";
+      type->output_instance(out, "return_value", &parser);
+      out << " = " << return_expr << ";\n";
+      if (track_interpreter) {
+        out << "    in_interpreter = 1;\n";
+      }
+      if (!extra_cleanup.empty()) {
+        out << "   " << extra_cleanup << "\n";
+      }
+      
+      return_expr = manage_return_value(out, 4, remap, "return_value");
+      test_assert(out, 4);
+      pack_return_value(out, 4, remap, remap->_return_type->temporary_to_return(return_expr));
+    }
+  }
+  
+  out << "  }\n";
+  
+  out << "  return (PyObject *)NULL;\n";
+  out << "}\n\n";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: InterfaceMakerPythonSimple::pack_return_value
+//       Access: Private
+//  Description: Outputs a command to pack the indicated expression,
+//               of the return_type type, as a Python return value.
+////////////////////////////////////////////////////////////////////
+void InterfaceMakerPythonSimple::
+pack_return_value(ostream &out, int indent_level,
+                  FunctionRemap *remap, string return_expr) {
+  CPPType *orig_type = remap->_return_type->get_orig_type();
+  CPPType *type = remap->_return_type->get_new_type();
+
+  if (remap->_return_type->new_type_is_atomic_string()) 
+  {
+    if (TypeManager::is_char_pointer(orig_type)) {
+      indent(out, indent_level)
+        << "return PyString_FromString(" << return_expr << ");\n";
+
+    } else {
+      indent(out, indent_level)
+        << "return PyString_FromStringAndSize("
+        << return_expr << ".data(), " << return_expr << ".length());\n";
+    }
+
+  } else if (TypeManager::is_unsigned_longlong(type)) 
+  {
+    indent(out, indent_level)
+      << "return PyLong_FromUnsignedLongLong(" << return_expr << ");\n";
+
+  } else if (TypeManager::is_longlong(type)) 
+  {
+    indent(out, indent_level)
+      << "return PyLong_FromLongLong(" << return_expr << ");\n";
+
+  } else if (TypeManager::is_unsigned_integer(type)) {
+    indent(out, indent_level)
+      << "return PyLong_FromUnsignedLong(" << return_expr << ");\n";
+
+  } else if (TypeManager::is_integer(type)) {
+    indent(out, indent_level)
+      << "return PyInt_FromLong(" << return_expr << ");\n";
+
+  } else if (TypeManager::is_float(type)) {
+    indent(out, indent_level)
+      << "return PyFloat_FromDouble(" << return_expr << ");\n";
+
+  } else if (TypeManager::is_char_pointer(type)) {
+    indent(out, indent_level)
+      << "return PyString_FromString(" << return_expr << ");\n";
+
+  } else if (TypeManager::is_pointer_to_PyObject(type)) {
+    indent(out, indent_level)
+      << "return " << return_expr << ";\n";
+    
+  } else if (TypeManager::is_pointer(type)) {
+    indent(out, indent_level)
+      << "return PyInt_FromLong((int)" << return_expr << ");\n";
+
+  } else {
+    // Return None.
+    indent(out, indent_level)
+      << "return Py_BuildValue(\"\");\n";
+  }
+}

+ 2 - 2
dtool/src/interrogate/interrogateBuilder.cxx

@@ -326,8 +326,8 @@ void InterrogateBuilder::write_code(ostream &out_code,ostream * out_include, Int
 
 
   EXPORT_IMPORT_PREFEX = std::string("EXPCL_") + def->module_name;
-  for (size_t i=0; i<EXPORT_IMPORT_PREFEX.size(); i++)
-      EXPORT_IMPORT_PREFEX[i] = toupper(EXPORT_IMPORT_PREFEX[i]);
+  for (size_t i=0; i<EXPORT_IMPORT_PREFEX.size(); i++)
+      EXPORT_IMPORT_PREFEX[i] = toupper(EXPORT_IMPORT_PREFEX[i]);
 
 
   InterfaceMakers::iterator mi;

+ 12 - 12
dtool/src/interrogatedb/interrogateType.cxx

@@ -229,18 +229,18 @@ remap_indices(const IndexRemapper &remap) {
 ////////////////////////////////////////////////////////////////////
 //     Function: GetRunTimeDictionary
 ////////////////////////////////////////////////////////////////////
-EXPCL_DTOOLCONFIG RunTimeTypeDictionary & GetRunTimeDictionary()
-{
-    static RunTimeTypeDictionary dict;
-    return dict;
-};
-
+EXPCL_DTOOLCONFIG RunTimeTypeDictionary & GetRunTimeDictionary()
+{
+    static RunTimeTypeDictionary dict;
+    return dict;
+};
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GetRunTimeTypeList
-////////////////////////////////////////////////////////////////////
-EXPCL_DTOOLCONFIG RunTimeTypeList & GetRunTimeTypeList()
-{
-    static RunTimeTypeList list;
-    return list;
-};
+////////////////////////////////////////////////////////////////////
+EXPCL_DTOOLCONFIG RunTimeTypeList & GetRunTimeTypeList()
+{
+    static RunTimeTypeList list;
+    return list;
+};
 

+ 6 - 6
dtool/src/interrogatedb/interrogateType.h

@@ -225,12 +225,12 @@ INLINE istream &operator >> (istream &in, InterrogateType::EnumValue &d);
 
 #include <set>
 #include <map>
-struct Dtool_PyTypedObject;
-typedef std::map< int , Dtool_PyTypedObject *>   RunTimeTypeDictionary;
-typedef std::set<int >                           RunTimeTypeList;
-
-EXPCL_DTOOLCONFIG  RunTimeTypeDictionary & GetRunTimeDictionary();
-EXPCL_DTOOLCONFIG  RunTimeTypeList & GetRunTimeTypeList();
+struct Dtool_PyTypedObject;
+typedef std::map< int , Dtool_PyTypedObject *>   RunTimeTypeDictionary;
+typedef std::set<int >                           RunTimeTypeList;
+
+EXPCL_DTOOLCONFIG  RunTimeTypeDictionary & GetRunTimeDictionary();
+EXPCL_DTOOLCONFIG  RunTimeTypeList & GetRunTimeTypeList();
 
 
 #endif

File diff suppressed because it is too large
+ 507 - 507
dtool/src/interrogatedb/py_panda.h


+ 4 - 4
dtool/src/pystub/pystub.cxx

@@ -83,16 +83,16 @@ extern "C" {
   EXPCL_DTOOLCONFIG int PyObject_GenericGetAttr(...);
   EXPCL_DTOOLCONFIG int PyArg_Parse(...);
   EXPCL_DTOOLCONFIG int PyDict_Type(...);
-  EXPCL_DTOOLCONFIG int PyArg_ParseTupleAndKeywords(...);
-  EXPCL_DTOOLCONFIG int PyDict_Size(...);
+  EXPCL_DTOOLCONFIG int PyArg_ParseTupleAndKeywords(...);
+  EXPCL_DTOOLCONFIG int PyDict_Size(...);
 
   EXPCL_DTOOLCONFIG extern void *PyExc_AssertionError;
   EXPCL_DTOOLCONFIG extern void *_Py_NoneStruct;
 };
 
 
-int PyArg_ParseTupleAndKeywords(...) { return 0; }
-int PyDict_Size(...){ return 0; }
+int PyArg_ParseTupleAndKeywords(...) { return 0; }
+int PyDict_Size(...){ return 0; }
 int PyArg_ParseTuple(...) { return 0; }
 int PyErr_Occurred(...) { return 0; }
 int PyErr_SetString(...) { return 0; }

Some files were not shown because too many files changed in this diff