Browse Source

Fix interrogate issues with long, streampos, streamoff, streamsize and ptrdiff_t

rdb 10 years ago
parent
commit
fcd3bfd15c

+ 30 - 20
dtool/src/interrogate/interfaceMakerPythonNative.cxx

@@ -4848,17 +4848,32 @@ write_function_instance(ostream &out, FunctionRemap *remap,
       // Windows, where longs are the same size as ints.
       // BUG: does not catch negative values on Windows when going through
       // the PyArg_ParseTuple case.
-      extra_convert
-        << "#if (SIZEOF_LONG > SIZEOF_INT) && !defined(NDEBUG)\n"
-        << "if (" << param_name << " > UINT_MAX) {\n";
+      if (!TypeManager::is_long(type)) {
+        extra_convert
+          << "#if (SIZEOF_LONG > SIZEOF_INT) && !defined(NDEBUG)\n"
+          << "if (" << param_name << " > UINT_MAX) {\n";
 
-      error_raise_return(extra_convert, 2, return_flags, "OverflowError",
-                         "value %lu out of range for unsigned integer",
-                         param_name);
-      extra_convert
-        << "}\n"
-        << "#endif\n";
+        error_raise_return(extra_convert, 2, return_flags, "OverflowError",
+                           "value %lu out of range for unsigned integer",
+                           param_name);
 
+        extra_convert
+          << "}\n"
+          << "#endif\n";
+      }
+      expected_params += "int";
+      only_pyobjects = false;
+
+    } else if (TypeManager::is_long(type)) {
+      // Signed longs are equivalent to Python's int type.
+      if (args_type == AT_single_arg) {
+        pexpr_string = "PyLongOrInt_AS_LONG(arg)";
+        type_check = "PyLongOrInt_Check(arg)";
+      } else {
+        indent(out, indent_level) << "long " << param_name << default_expr << ";\n";
+        format_specifiers += "l";
+        parameter_list += ", &" + param_name;
+      }
       expected_params += "int";
       only_pyobjects = false;
 
@@ -4877,6 +4892,7 @@ write_function_instance(ostream &out, FunctionRemap *remap,
         error_raise_return(extra_convert, 2, return_flags, "OverflowError",
                            "value %ld out of range for signed integer",
                            "arg_val");
+
         extra_convert
           << "}\n"
           << "#endif\n";
@@ -5934,6 +5950,10 @@ pack_return_value(ostream &out, int indent_level, FunctionRemap *remap,
     indent(out, indent_level)
       << "return PyBool_FromLong(" << return_expr << ");\n";
 
+  } else if (TypeManager::is_ssize(type)) {
+    indent(out, indent_level)
+      << "return PyLongOrInt_FromSsize_t(" << return_expr << ");\n";
+
   } else if (TypeManager::is_size(type)) {
     indent(out, indent_level)
       << "return PyLongOrInt_FromSize_t(" << return_expr << ");\n";
@@ -5960,22 +5980,12 @@ pack_return_value(ostream &out, int indent_level, FunctionRemap *remap,
       << "return PyLong_FromLongLong(" << return_expr << ");\n";
 
   } else if (TypeManager::is_unsigned_integer(type)){
-    out << "#if PY_MAJOR_VERSION >= 3\n";
-    indent(out, indent_level)
-      << "return PyLong_FromUnsignedLong(" << return_expr << ");\n";
-    out << "#else\n";
     indent(out, indent_level)
       << "return PyLongOrInt_FromUnsignedLong(" << return_expr << ");\n";
-    out << "#endif\n";
 
   } else if (TypeManager::is_integer(type)) {
-    out << "#if PY_MAJOR_VERSION >= 3\n";
-    indent(out, indent_level)
-      << "return PyLong_FromLong(" << return_expr << ");\n";
-    out << "#else\n";
     indent(out, indent_level)
-      << "return PyInt_FromLong(" << return_expr << ");\n";
-    out << "#endif\n";
+      << "return PyLongOrInt_FromLong(" << return_expr << ");\n";
 
   } else if (TypeManager::is_float(type)) {
     indent(out, indent_level)

+ 38 - 1
dtool/src/interrogate/typeManager.cxx

@@ -1142,6 +1142,9 @@ is_size(CPPType *type) {
 //       Access: Public, Static
 //  Description: Returns true if the indicated type is the "ssize_t"
 //               type, or a const ssize_t, or a typedef to either.
+//               ptrdiff_t and streamsize are also accepted, since
+//               they are usually also defined as the signed
+//               counterpart to size_t.
 ////////////////////////////////////////////////////////////////////
 bool TypeManager::
 is_ssize(CPPType *type) {
@@ -1151,7 +1154,9 @@ is_ssize(CPPType *type) {
 
   case CPPDeclaration::ST_typedef:
     if (type->get_simple_name() == "Py_ssize_t" ||
-        type->get_simple_name() == "ssize_t") {
+        type->get_simple_name() == "ssize_t" ||
+        type->get_simple_name() == "ptrdiff_t" ||
+        type->get_simple_name() == "streamsize") {
       return is_integer(type->as_typedef_type()->_type);
     } else {
       return is_ssize(type->as_typedef_type()->_type);
@@ -1164,6 +1169,38 @@ is_ssize(CPPType *type) {
   return false;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: TypeManager::is_long
+//       Access: Public, Static
+//  Description: Returns true if the indicated type is the "long"
+//               type, whether signed or unsigned.
+////////////////////////////////////////////////////////////////////
+bool TypeManager::
+is_long(CPPType *type) {
+  switch (type->get_subtype()) {
+  case CPPDeclaration::ST_const:
+    return is_long(type->as_const_type()->_wrapped_around);
+
+  case CPPDeclaration::ST_simple:
+    {
+      CPPSimpleType *simple_type = type->as_simple_type();
+      if (simple_type != (CPPSimpleType *)NULL) {
+        return (simple_type->_type == CPPSimpleType::T_int &&
+                (simple_type->_flags & CPPSimpleType::F_long) != 0);
+      }
+    }
+    break;
+
+  case CPPDeclaration::ST_typedef:
+    return is_long(type->as_typedef_type()->_type);
+
+  default:
+    break;
+  }
+
+  return false;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: TypeManager::is_short
 //       Access: Public, Static

+ 1 - 0
dtool/src/interrogate/typeManager.h

@@ -89,6 +89,7 @@ public:
   static bool is_unsigned_integer(CPPType *type);
   static bool is_size(CPPType *type);
   static bool is_ssize(CPPType *type);
+  static bool is_long(CPPType *type);
   static bool is_short(CPPType *type);
   static bool is_unsigned_short(CPPType *type);
   static bool is_longlong(CPPType *type);

+ 2 - 0
dtool/src/interrogatedb/py_panda.h

@@ -112,6 +112,7 @@ inline PyObject* doPy_RETURN_FALSE()
 
 #define PyLongOrInt_Check(x) PyLong_Check(x)
 #define PyLongOrInt_FromSize_t PyLong_FromSize_t
+#define PyLongOrInt_FromSsize_t PyLong_FromSsize_t
 #define PyLongOrInt_FromLong PyLong_FromLong
 #define PyLongOrInt_FromUnsignedLong PyLong_FromUnsignedLong
 #define PyLongOrInt_AS_LONG PyLong_AS_LONG
@@ -122,6 +123,7 @@ inline PyObject* doPy_RETURN_FALSE()
 #define PyLongOrInt_Check(x) (PyInt_Check(x) || PyLong_Check(x))
 // PyInt_FromSize_t automatically picks the right type.
 #define PyLongOrInt_FromSize_t PyInt_FromSize_t
+#define PyLongOrInt_FromSsize_t PyInt_FromSsize_t
 #define PyLongOrInt_FromLong PyInt_FromLong
 #define PyLongOrInt_AS_LONG PyInt_AsLong
 

+ 8 - 0
dtool/src/parser-inc/iostream

@@ -47,8 +47,16 @@ __published:
 class ios : public ios_base {
 __published:
   typedef long fmtflags;
+#ifdef _WIN64
+  typedef unsigned __int64 streampos;
+  typedef __int64 streamoff;
+#elif defined(_WIN32)
   typedef unsigned long streampos;
   typedef long streamoff;
+#else
+  typedef unsigned long long streampos;
+  typedef long long streamoff;
+#endif
 
   bool good() const;
   bool eof() const;

+ 1 - 1
dtool/src/parser-inc/stdint.h

@@ -15,7 +15,7 @@
 #ifndef _STDINT_H
 #define _STDINT_H
 
-#ifdef _LP64
+#if defined(_LP64) || defined(_WIN64)
 #define __WORDSIZE 64
 #else
 #define __WORDSIZE 32