diff --git a/dtool/src/interrogate/interfaceMakerPythonNative.cxx b/dtool/src/interrogate/interfaceMakerPythonNative.cxx index 1078582d53..5a2dd24e41 100644 --- a/dtool/src/interrogate/interfaceMakerPythonNative.cxx +++ b/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) diff --git a/dtool/src/interrogate/typeManager.cxx b/dtool/src/interrogate/typeManager.cxx index fa78d89664..ab048b52c8 100644 --- a/dtool/src/interrogate/typeManager.cxx +++ b/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 diff --git a/dtool/src/interrogate/typeManager.h b/dtool/src/interrogate/typeManager.h index 16b9dfda22..4b29845971 100644 --- a/dtool/src/interrogate/typeManager.h +++ b/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); diff --git a/dtool/src/interrogatedb/py_panda.h b/dtool/src/interrogatedb/py_panda.h index 7ad2e5857a..0c4c47f3f3 100644 --- a/dtool/src/interrogatedb/py_panda.h +++ b/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 diff --git a/dtool/src/parser-inc/iostream b/dtool/src/parser-inc/iostream index 87fd92ebcd..fac16148b4 100644 --- a/dtool/src/parser-inc/iostream +++ b/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; diff --git a/dtool/src/parser-inc/stdint.h b/dtool/src/parser-inc/stdint.h index 060dbf82e7..11fba7a776 100644 --- a/dtool/src/parser-inc/stdint.h +++ b/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