diff --git a/dtool/src/interrogate/interfaceMakerPythonNative.cxx b/dtool/src/interrogate/interfaceMakerPythonNative.cxx index 605c8e1343..a6daee775b 100644 --- a/dtool/src/interrogate/interfaceMakerPythonNative.cxx +++ b/dtool/src/interrogate/interfaceMakerPythonNative.cxx @@ -4929,7 +4929,9 @@ write_function_instance(ostream &out, FunctionRemap *remap, expected_params += "long"; only_pyobjects = false; - } else if (TypeManager::is_unsigned_short(type)) { + } else if (TypeManager::is_unsigned_short(type) || + TypeManager::is_unsigned_char(type) || TypeManager::is_signed_char(type)) { + if (args_type == AT_single_arg) { type_check = "PyLongOrInt_Check(arg)"; extra_convert @@ -4945,12 +4947,25 @@ write_function_instance(ostream &out, FunctionRemap *remap, // The "H" format code, unlike "h", does not do overflow checking, so // we have to do it ourselves (except in release builds). extra_convert - << "#ifndef NDEBUG\n" - << "if (" << param_name << " < 0 || " << param_name << " > USHRT_MAX) {\n"; + << "#ifndef NDEBUG\n"; + + if (TypeManager::is_unsigned_short(type)) { + extra_convert << "if (" << param_name << " < 0 || " << param_name << " > USHRT_MAX) {\n"; + error_raise_return(extra_convert, 2, return_flags, "OverflowError", + "value %ld out of range for unsigned short integer", + param_name); + } else if (TypeManager::is_unsigned_char(type)) { + extra_convert << "if (" << param_name << " < 0 || " << param_name << " > UCHAR_MAX) {\n"; + error_raise_return(extra_convert, 2, return_flags, "OverflowError", + "value %ld out of range for unsigned byte", + param_name); + } else { + extra_convert << "if (" << param_name << " < CHAR_MIN || " << param_name << " > CHAR_MAX) {\n"; + error_raise_return(extra_convert, 2, return_flags, "OverflowError", + "value %ld out of range for signed byte", + param_name); + } - error_raise_return(extra_convert, 2, return_flags, "OverflowError", - "value %ld out of range for unsigned short integer", - param_name); extra_convert << "}\n" << "#endif\n"; diff --git a/dtool/src/interrogate/typeManager.cxx b/dtool/src/interrogate/typeManager.cxx index 05372ab30c..c8e6dce9c7 100644 --- a/dtool/src/interrogate/typeManager.cxx +++ b/dtool/src/interrogate/typeManager.cxx @@ -638,6 +638,40 @@ is_unsigned_char(CPPType *type) { return false; } +//////////////////////////////////////////////////////////////////// +// Function: TypeManager::is_signed_char +// Access: Public, Static +// Description: Returns true if the indicated type is signed char, +// but not unsigned or 'plain' char. +//////////////////////////////////////////////////////////////////// +bool TypeManager:: +is_signed_char(CPPType *type) { + switch (type->get_subtype()) { + case CPPDeclaration::ST_const: + return is_signed_char(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_char) && + (simple_type->_flags & CPPSimpleType::F_signed) != 0; + } + } + break; + + case CPPDeclaration::ST_typedef: + return is_signed_char(type->as_typedef_type()->_type); + + default: + break; + } + + return false; +} + //////////////////////////////////////////////////////////////////// // Function: TypeManager::is_char_pointer // Access: Public, Static diff --git a/dtool/src/interrogate/typeManager.h b/dtool/src/interrogate/typeManager.h index 848f3907ca..29b29eb2c7 100644 --- a/dtool/src/interrogate/typeManager.h +++ b/dtool/src/interrogate/typeManager.h @@ -67,6 +67,7 @@ public: static bool is_pointable(CPPType *type); static bool is_char(CPPType *type); static bool is_unsigned_char(CPPType *type); + static bool is_signed_char(CPPType *type); static bool is_char_pointer(CPPType *type); static bool is_const_char_pointer(CPPType *type); static bool is_unsigned_char_pointer(CPPType *type);