mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
interrogate should support long long
This commit is contained in:
parent
95bdf94020
commit
e2a27fabda
@ -20,6 +20,7 @@ AT_bool = 4
|
||||
AT_char = 5
|
||||
AT_void = 6
|
||||
AT_string = 7
|
||||
AT_longlong = 8
|
||||
|
||||
def cullOverloadedMethods(fullMethodDict):
|
||||
"""
|
||||
@ -65,6 +66,9 @@ def getTypeName(classTypeDesc, typeDesc):
|
||||
(typeDesc.atomicType == AT_double)):
|
||||
return 'types.FloatType'
|
||||
|
||||
elif ((typeDesc.atomicType == AT_longlong)):
|
||||
return 'types.LongType'
|
||||
|
||||
# Strings are treated as Python strings
|
||||
elif ((typeDesc.atomicType == AT_string)):
|
||||
return 'types.StringType'
|
||||
@ -416,8 +420,9 @@ class FFIMethodArgumentTree:
|
||||
# Otherwise, we'll check the particular type of
|
||||
# the object.
|
||||
condition = '(isinstance(_args[' + `level` + '], ' + typeName + '))'
|
||||
# If it is looking for a float, make it accept an integer too
|
||||
if (typeName == 'types.FloatType'):
|
||||
# If it is looking for a float or a long, make it
|
||||
# accept an integer too
|
||||
if (typeName == 'types.FloatType' or typeName == 'types.LongType'):
|
||||
condition += (' or (isinstance(_args[' + `level` + '], '
|
||||
+ 'types.IntType'
|
||||
+ '))')
|
||||
|
@ -41,13 +41,18 @@ class FunctionSpecification:
|
||||
typeName = FFIOverload.getTypeName(methodClass, typeDesc)
|
||||
|
||||
# Special case:
|
||||
# If it is looking for a float, accept an int as well
|
||||
# If it is looking for a float or a long, accept an int as well
|
||||
# C++ will cast it properly, and it is much more convenient
|
||||
if (typeName == 'types.FloatType'):
|
||||
indent(file, nesting, 'assert((isinstance(' +
|
||||
methodArgSpec.name + ', types.FloatType) or isinstance(' +
|
||||
methodArgSpec.name + ', types.IntType)))\n')
|
||||
|
||||
elif (typeName == 'types.LongType'):
|
||||
indent(file, nesting, 'assert((isinstance(' +
|
||||
methodArgSpec.name + ', types.LongType) or isinstance(' +
|
||||
methodArgSpec.name + ', types.IntType)))\n')
|
||||
|
||||
elif typeDesc.__class__ != FFITypes.PyObjectTypeDescriptor:
|
||||
# Get the real return type (not derived)
|
||||
if ((not typeDesc.isNested) and
|
||||
|
@ -56,6 +56,7 @@ class BaseTypeDescriptor:
|
||||
# AT_char = 5
|
||||
# AT_void = 6
|
||||
# AT_string = 7
|
||||
# AT_longlong = 8
|
||||
# By default this type is not atomic
|
||||
self.atomicType = 0
|
||||
|
||||
|
@ -321,6 +321,9 @@ write_function_instance(ostream &out, int indent_level,
|
||||
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
|
||||
@ -371,6 +374,26 @@ write_function_instance(ostream &out, int indent_level,
|
||||
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_integer(type)) {
|
||||
out << "int " << param_name;
|
||||
format_specifiers += "i";
|
||||
@ -417,6 +440,26 @@ write_function_instance(ostream &out, int indent_level,
|
||||
<< "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";
|
||||
@ -438,6 +481,10 @@ write_function_instance(ostream &out, int indent_level,
|
||||
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);
|
||||
@ -451,6 +498,10 @@ write_function_instance(ostream &out, int indent_level,
|
||||
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";
|
||||
@ -464,6 +515,10 @@ write_function_instance(ostream &out, int indent_level,
|
||||
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);
|
||||
@ -501,6 +556,14 @@ pack_return_value(ostream &out, int indent_level,
|
||||
<< 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_integer(type)) {
|
||||
indent(out, indent_level)
|
||||
<< "return PyInt_FromLong(" << return_expr << ");\n";
|
||||
|
@ -242,6 +242,9 @@ write_function_instance(ostream &out, InterfaceMaker::Function *func,
|
||||
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
|
||||
@ -283,6 +286,24 @@ write_function_instance(ostream &out, InterfaceMaker::Function *func,
|
||||
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_integer(type)) {
|
||||
out << "int " << param_name;
|
||||
format_specifiers += "i";
|
||||
@ -327,6 +348,20 @@ write_function_instance(ostream &out, InterfaceMaker::Function *func,
|
||||
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";
|
||||
}
|
||||
@ -336,7 +371,6 @@ write_function_instance(ostream &out, InterfaceMaker::Function *func,
|
||||
// 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);
|
||||
@ -345,6 +379,9 @@ write_function_instance(ostream &out, InterfaceMaker::Function *func,
|
||||
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);
|
||||
@ -356,6 +393,9 @@ write_function_instance(ostream &out, InterfaceMaker::Function *func,
|
||||
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";
|
||||
|
||||
@ -367,6 +407,9 @@ write_function_instance(ostream &out, InterfaceMaker::Function *func,
|
||||
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);
|
||||
@ -403,6 +446,14 @@ pack_return_value(ostream &out, int indent_level,
|
||||
<< 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_integer(type)) {
|
||||
indent(out, indent_level)
|
||||
<< "return PyInt_FromLong(" << return_expr << ");\n";
|
||||
|
@ -1787,7 +1787,11 @@ define_atomic_type(InterrogateType &itype, CPPSimpleType *cpptype) {
|
||||
break;
|
||||
|
||||
case CPPSimpleType::T_int:
|
||||
if ((cpptype->_flags & CPPSimpleType::F_longlong) != 0) {
|
||||
itype._atomic_token = AT_longlong;
|
||||
} else {
|
||||
itype._atomic_token = AT_int;
|
||||
}
|
||||
break;
|
||||
|
||||
case CPPSimpleType::T_float:
|
||||
|
@ -489,6 +489,7 @@ is_bool(CPPType *type) {
|
||||
simple_type->_type == CPPSimpleType::T_bool;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@ -523,6 +524,67 @@ is_integer(CPPType *type) {
|
||||
simple_type->_type == CPPSimpleType::T_int);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TypeManager::is_unsigned_longlong
|
||||
// Access: Public, Static
|
||||
// Description: Returns true if the indicated type is an unsigned
|
||||
// "long long" type or larger, or at least a 64-bit
|
||||
// unsigned integer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool TypeManager::
|
||||
is_unsigned_longlong(CPPType *type) {
|
||||
switch (type->get_subtype()) {
|
||||
case CPPDeclaration::ST_const:
|
||||
return is_unsigned_longlong(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_longlong | CPPSimpleType::F_unsigned)) == (CPPSimpleType::F_longlong | CPPSimpleType::F_unsigned));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TypeManager::is_longlong
|
||||
// Access: Public, Static
|
||||
// Description: Returns true if the indicated type is the "long long"
|
||||
// type or larger, or at least a 64-bit integer, whether
|
||||
// signed or unsigned.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool TypeManager::
|
||||
is_longlong(CPPType *type) {
|
||||
switch (type->get_subtype()) {
|
||||
case CPPDeclaration::ST_const:
|
||||
return is_longlong(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_longlong) != 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@ -553,6 +615,7 @@ is_float(CPPType *type) {
|
||||
simple_type->_type == CPPSimpleType::T_double);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@ -609,10 +672,13 @@ is_reference_count(CPPType *type) {
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -70,6 +70,8 @@ public:
|
||||
static bool is_const_ref_to_basic_string_char(CPPType *type);
|
||||
static bool is_bool(CPPType *type);
|
||||
static bool is_integer(CPPType *type);
|
||||
static bool is_unsigned_longlong(CPPType *type);
|
||||
static bool is_longlong(CPPType *type);
|
||||
static bool is_float(CPPType *type);
|
||||
static bool is_void(CPPType *type);
|
||||
static bool is_reference_count(CPPType *type);
|
||||
|
@ -85,7 +85,9 @@ enum AtomicToken {
|
||||
// convention wrappers, atomic string means (const char *); for
|
||||
// other calling convention wrappers, atomic string means whatever
|
||||
// the native string representation is.
|
||||
AT_string = 7
|
||||
AT_string = 7,
|
||||
|
||||
AT_longlong = 8
|
||||
};
|
||||
|
||||
EXPCL_DTOOLCONFIG void interrogate_add_search_directory(const char *dirname);
|
||||
|
Loading…
x
Reference in New Issue
Block a user