Forráskód Böngészése

interrogate supports wchar_t * and L"foo"

David Rose 14 éve
szülő
commit
9294ea77f7

+ 15 - 0
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;
 

+ 3 - 0
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<char> itself, don't
     // convert basic_string<char>'s to atomic strings.

+ 43 - 15
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);    

+ 11 - 0
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)
+{
+}

+ 10 - 0
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

+ 47 - 0
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

+ 2 - 0
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);