From 9294ea77f79dfbbd21a0db25d375b93d49ffa326 Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 29 Nov 2011 23:25:23 +0000 Subject: [PATCH] interrogate supports wchar_t * and L"foo" --- dtool/src/cppparser/cppPreprocessor.cxx | 15 +++++ dtool/src/interrogate/interfaceMaker.cxx | 3 + .../interfaceMakerPythonNative.cxx | 58 ++++++++++++++----- .../parameterRemapCharStarToString.cxx | 11 ++++ .../parameterRemapCharStarToString.h | 10 ++++ dtool/src/interrogate/typeManager.cxx | 47 +++++++++++++++ dtool/src/interrogate/typeManager.h | 2 + 7 files changed, 131 insertions(+), 15 deletions(-) diff --git a/dtool/src/cppparser/cppPreprocessor.cxx b/dtool/src/cppparser/cppPreprocessor.cxx index ac1e5e176d..9715c26b8f 100644 --- a/dtool/src/cppparser/cppPreprocessor.cxx +++ b/dtool/src/cppparser/cppPreprocessor.cxx @@ -1567,6 +1567,7 @@ get_identifier(int c) { CPPFile first_file = get_file(); int first_line = get_line_number(); int first_col = get_col_number(); + string name(1, (char)c); c = get(); @@ -1574,6 +1575,20 @@ get_identifier(int c) { name += c; c = get(); } + if (c == '\'' || c == '"') { + // This is actually a wide-character or wide-string literal or + // some such: a string with an alphanumeric prefix. We don't + // necessarily try to parse it correctly; for most purposes, we + // don't care. + CPPToken token(0); + if (c == '\'') { + token = get_quoted_char(c); + } else { + token = get_quoted_string(c); + } + token._lloc.first_column = first_col; + return token; + } _last_c = c; diff --git a/dtool/src/interrogate/interfaceMaker.cxx b/dtool/src/interrogate/interfaceMaker.cxx index 5e42af3080..32d510aff2 100644 --- a/dtool/src/interrogate/interfaceMaker.cxx +++ b/dtool/src/interrogate/interfaceMaker.cxx @@ -383,6 +383,9 @@ remap_parameter(CPPType *struct_type, CPPType *param_type) { if (TypeManager::is_char_pointer(param_type)) { return new ParameterRemapCharStarToString(param_type); } + if (TypeManager::is_wchar_pointer(param_type)) { + return new ParameterRemapWCharStarToWString(param_type); + } // If we're exporting a method of basic_string itself, don't // convert basic_string's to atomic strings. diff --git a/dtool/src/interrogate/interfaceMakerPythonNative.cxx b/dtool/src/interrogate/interfaceMakerPythonNative.cxx index dca94f992d..3ef2956c9a 100755 --- a/dtool/src/interrogate/interfaceMakerPythonNative.cxx +++ b/dtool/src/interrogate/interfaceMakerPythonNative.cxx @@ -2096,6 +2096,7 @@ int GetParnetDepth(CPPType *type) } else if (TypeManager::is_integer(type)) { } else if (TypeManager::is_float(type)) { } else if (TypeManager::is_char_pointer(type)) { + } else if (TypeManager::is_wchar_pointer(type)) { } else if (TypeManager::is_pointer_to_PyObject(type)) { } else if (TypeManager::is_pointer(type) ||TypeManager::is_reference(type) || TypeManager::is_struct(type) ) { @@ -2192,6 +2193,7 @@ write_function_forset(ostream &out, InterfaceMaker::Object *obj, CPPType *type = remap->_parameters[pn]._remap->get_new_type(); if (TypeManager::is_char_pointer(type)) { + } else if (TypeManager::is_wchar_pointer(type)) { } else if (TypeManager::is_pointer_to_PyObject(type)) { } else if (TypeManager::is_pointer(type)) { // This is a pointer to an object, so we @@ -2418,6 +2420,16 @@ write_function_instance(ostream &out, InterfaceMaker::Object *obj, format_specifiers += "s"; parameter_list += ", &" + param_name; + } else if (TypeManager::is_wchar_pointer(orig_type)) { + indent(out,indent_level) << "PyUnicodeObject *" << param_name << "\n"; + format_specifiers += "U"; + parameter_list += ", &" + param_name; + + extra_convert += " int " + param_name + "_len = PyUnicode_GetSize((PyObject *)" + param_name + "); wchar_t *" + param_name + "_str = new wchar_t[" + param_name + "_len + 1]; PyUnicode_AsWideChar(" + param_name + ", " + param_name + "_str, " + param_name + "_len); " + param_name + "_str[" + param_name + "_len] = 0;"; + + pexpr_string = param_name + "_str"; + extra_cleanup += " delete[] " + param_name + "_str;"; + } else if (TypeManager::is_wstring(orig_type)) { indent(out,indent_level) << "PyUnicodeObject *" << param_name << "\n"; format_specifiers += "U"; @@ -2842,6 +2854,16 @@ void InterfaceMakerPythonNative::pack_return_value(ostream &out, int indent_leve indent(out, indent_level) << "return PyString_FromString(" << return_expr << ");\n"; + } else if (TypeManager::is_wchar_pointer(orig_type)) { + indent(out, indent_level)<<"if("<< return_expr<< " == NULL)\n"; + indent(out, indent_level)<<"{\n"; + indent(out, indent_level)<<" Py_INCREF(Py_None);\n"; + indent(out, indent_level)<<" return Py_None;\n"; + indent(out, indent_level)<<"}\n"; + indent(out, indent_level) + << "return PyUnicode_FromWideChar(" + << return_expr << ", wcslen(" << return_expr << "));\n"; + } else if (TypeManager::is_wstring(orig_type)) { indent(out, indent_level) << "return PyUnicode_FromWideChar(" @@ -2907,27 +2929,33 @@ void InterfaceMakerPythonNative::pack_return_value(ostream &out, int indent_leve indent(out, indent_level)<<"}\n"; indent(out, indent_level) << "return PyString_FromString(" << return_expr << ");\n"; + + } else if (TypeManager::is_wchar_pointer(type)) { + indent(out, indent_level)<<"if("<< return_expr<< " == NULL)\n"; + indent(out, indent_level)<<"{\n"; + indent(out, indent_level)<<" Py_INCREF(Py_None);\n"; + indent(out, indent_level)<<" return Py_None;\n"; + indent(out, indent_level)<<"}\n"; + indent(out, indent_level) + << "return PyUnicode_FromWideChar(" + << return_expr << ", wcslen(" << return_expr << "));\n"; - } - else if (TypeManager::is_pointer_to_PyObject(type)) - { + } else if (TypeManager::is_pointer_to_PyObject(type)) { indent(out, indent_level) << "return "<< return_expr << ";\n"; - } - else if (TypeManager::is_pointer(type)) - { - string const_flag; - if (TypeManager::is_const_pointer_to_anything(type)) { - const_flag = "true"; - } else { - const_flag = "false"; - } - - if (TypeManager::is_struct(orig_type) || TypeManager::is_ref_to_anything(orig_type)) + } else if (TypeManager::is_pointer(type)) { + string const_flag; + if (TypeManager::is_const_pointer_to_anything(type)) { + const_flag = "true"; + } else { + const_flag = "false"; + } + + if (TypeManager::is_struct(orig_type) || TypeManager::is_ref_to_anything(orig_type)) { if( TypeManager::is_ref_to_anything(orig_type)) - { + { TypeIndex type_index = builder.get_type(TypeManager::unwrap(TypeManager::resolve_type(type)),false); InterrogateDatabase *idb = InterrogateDatabase::get_ptr(); const InterrogateType &itype = idb->get_type(type_index); diff --git a/dtool/src/interrogate/parameterRemapCharStarToString.cxx b/dtool/src/interrogate/parameterRemapCharStarToString.cxx index 4ba152b732..d54e4f90cb 100644 --- a/dtool/src/interrogate/parameterRemapCharStarToString.cxx +++ b/dtool/src/interrogate/parameterRemapCharStarToString.cxx @@ -24,3 +24,14 @@ ParameterRemapCharStarToString(CPPType *orig_type) : ParameterRemapToString(orig_type) { } + +//////////////////////////////////////////////////////////////////// +// Function: ParameterRemapWCharStarToWString::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +ParameterRemapWCharStarToWString:: +ParameterRemapWCharStarToWString(CPPType *orig_type) : + ParameterRemapToWString(orig_type) +{ +} diff --git a/dtool/src/interrogate/parameterRemapCharStarToString.h b/dtool/src/interrogate/parameterRemapCharStarToString.h index 79b468f2b8..2bb9442f0f 100644 --- a/dtool/src/interrogate/parameterRemapCharStarToString.h +++ b/dtool/src/interrogate/parameterRemapCharStarToString.h @@ -29,4 +29,14 @@ public: ParameterRemapCharStarToString(CPPType *orig_type); }; +//////////////////////////////////////////////////////////////////// +// Class : ParameterRemapWCharStarToWString +// Description : Maps from (wchar_t *) or (const wchar_ *) to the atomic +// wide-string type. +//////////////////////////////////////////////////////////////////// +class ParameterRemapWCharStarToWString : public ParameterRemapToWString { +public: + ParameterRemapWCharStarToWString(CPPType *orig_type); +}; + #endif diff --git a/dtool/src/interrogate/typeManager.cxx b/dtool/src/interrogate/typeManager.cxx index 049054a3cf..9188fd7d34 100644 --- a/dtool/src/interrogate/typeManager.cxx +++ b/dtool/src/interrogate/typeManager.cxx @@ -565,6 +565,53 @@ is_string(CPPType *type) { return is_basic_string_wchar(type); } +//////////////////////////////////////////////////////////////////// +// Function: TypeManager::is_wchar +// Access: Public, Static +// Description: Returns true if the indicated type is wchar_t or const +// wchar_t. We don't mind signed or unsigned wchar_t. +//////////////////////////////////////////////////////////////////// +bool TypeManager:: +is_wchar(CPPType *type) { + switch (type->get_subtype()) { + case CPPDeclaration::ST_const: + return is_wchar(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_wchar_t; + } + } + + default: + break; + } + + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: TypeManager::is_wchar_pointer +// Access: Public, Static +// Description: Returns true if the indicated type is wchar_t * or const +// wchar_t * or some such. +//////////////////////////////////////////////////////////////////// +bool TypeManager:: +is_wchar_pointer(CPPType *type) { + switch (type->get_subtype()) { + case CPPDeclaration::ST_const: + return is_wchar_pointer(type->as_const_type()->_wrapped_around); + + case CPPDeclaration::ST_pointer: + return is_wchar(type->as_pointer_type()->_pointing_at); + + default: + return false; + } +} + //////////////////////////////////////////////////////////////////// // Function: TypeManager::is_basic_string_wchar // Access: Public, Static diff --git a/dtool/src/interrogate/typeManager.h b/dtool/src/interrogate/typeManager.h index 1c20782673..5ec362af84 100644 --- a/dtool/src/interrogate/typeManager.h +++ b/dtool/src/interrogate/typeManager.h @@ -69,6 +69,8 @@ public: static bool is_const_ref_to_basic_string_char(CPPType *type); static bool is_const_ptr_to_basic_string_char(CPPType *type); static bool is_string(CPPType *type); + static bool is_wchar(CPPType *type); + static bool is_wchar_pointer(CPPType *type); static bool is_basic_string_wchar(CPPType *type); static bool is_const_basic_string_wchar(CPPType *type); static bool is_const_ref_to_basic_string_wchar(CPPType *type);