[Gtk-sharp-list] patch for simple pointer types (broken)

Vladimir Vukicevic vladimir@pobox.com
08 Oct 2002 01:22:32 -0700


--=-e4bjs1cv4wnovWlkpsDP
Content-Type: text/plain
Content-Transfer-Encoding: 7bit


So, this started out as me needing to get gdk_drawable_get_size()
working [*].  Its prototype is:

void gdk_drawable_get_size (GdkDrawable *d, int *width, int *height);

So, with only a vague understanding of how the whole generator system
worked, I plunged in, assuming that all such things tend to be written
in similar ways, so it Can't Be That Hard (tm).  I split up simple_types
into native_types and simple_types -- native_types being things that
have a direct 1-1 mapping between C and C# types, such as gint -> int.

The attached patch sort-of works.  gdk_drawable_get_size does indeed
become "Gdk.Drawable.GetSize (out int width, out int height)", with the
appropriate bindings to C Generated.  However, there's a number of
(broken) side effects:

1) It doesn't (and can't) distinguish between out params and input array
params.  It would be /really/ nice if the C api writers forced
themselves to use "gint stuff[]" for input array values and "gint
*stuff" for an output of one gint.  However, in this respect, things
aren't any more broken than they were previously.

2) Signals that have basic pointer types get horribly broken.  You end
up with stuff like:

	object[] _args = new object[1];
	_args[0] = out pixels;
	_managed ((out byte) _args[0]);

3) A few functions for which bindings were generated before don't get
generated.  I'm not sure why this is.

4) Stuff like:

-		static extern unsafe bool gdk_pixbuf_loader_write(IntPtr raw, byte[]
buf, uint count, out IntPtr error);
+		static extern unsafe bool gdk_pixbuf_loader_write(IntPtr raw, out
byte[] buf, uint count, out IntPtr error);
 
 		/// <summary> Write Method </summary>
 		/// <remarks> To be completed </remarks>
-		public unsafe bool Write(byte[] buf, uint count) {
+		public unsafe bool Write(out byte[] buf, uint count) {

(- is old, + is with the patch)

i.e. it's munging stuff that has attributes applied to it from the
metadata (in this case that param has the array attribute applied).

So, it's fairly broken.  I'm only sending it along in case someone is
interested :)

	- Vlad

* I abandoned gdk_drawable_get_size and used the widget's allocation
instead, which has much saner getters/setters.

-- 
Vladimir Vukicevic <vladimir@pobox.com>

--=-e4bjs1cv4wnovWlkpsDP
Content-Disposition: attachment; filename=generator.patch
Content-Transfer-Encoding: quoted-printable
Content-Type: text/x-patch; name=generator.patch; charset=ANSI_X3.4-1968

Index: SymbolTable.cs
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvs/public/gtk-sharp/generator/SymbolTable.cs,v
retrieving revision 1.40
diff -u -w -u -w -r1.40 SymbolTable.cs
--- SymbolTable.cs	1 Sep 2002 04:46:37 -0000	1.40
+++ SymbolTable.cs	8 Oct 2002 09:07:50 -0000
@@ -14,50 +14,60 @@
 		private static Hashtable alias =3D new Hashtable ();
 		private static Hashtable complex_types =3D new Hashtable ();
 		private static Hashtable simple_types;
+                private static Hashtable native_types;
 		private static Hashtable manually_wrapped_types;
 	=09
 		static SymbolTable ()
 		{
+                        native_types =3D new Hashtable ();
+			native_types.Add ("gboolean", "bool");
+			native_types.Add ("gint", "int");
+			native_types.Add ("guint", "uint");
+			native_types.Add ("glong", "long");
+			native_types.Add ("gshort", "short");
+			native_types.Add ("gushort", "ushort");
+			native_types.Add ("guint32", "uint");
+                        native_types.Add ("guint64", "ulong");
+                        native_types.Add ("const-gchar", "sbyte");
+                        native_types.Add ("const-char", "sbyte");
+                        native_types.Add ("char", "sbyte");
+			native_types.Add ("gfloat", "float");
+			native_types.Add ("gdouble", "double");
+			native_types.Add ("gint8", "byte");
+			native_types.Add ("guint8", "byte");
+			native_types.Add ("gint16", "short");
+			native_types.Add ("gint32", "int");
+                        native_types.Add ("gint64", "long");
+			native_types.Add ("guint16", "ushort");
+			native_types.Add ("guint1", "bool");
+			native_types.Add ("guchar", "byte");
+			native_types.Add ("long", "long");
+			native_types.Add ("gulong", "ulong");
+			native_types.Add ("GQuark", "int");
+			native_types.Add ("int", "int");
+			native_types.Add ("double", "double");
+			native_types.Add ("float", "float");
+			native_types.Add ("gunichar", "char");
+			native_types.Add ("GType", "int");
+			native_types.Add ("uint1", "bool");
+			// gsize is a system-specific typedef in glibconfig.h,
+			// but this should work for now
+			native_types.Add ("gsize", "uint");
+			native_types.Add ("gssize", "int");
+			native_types.Add ("size_t", "int");
+
 			simple_types =3D new Hashtable ();
 			simple_types.Add ("void", "void");
-			simple_types.Add ("gboolean", "bool");
-			simple_types.Add ("gint", "int");
-			simple_types.Add ("guint", "uint");
-			simple_types.Add ("glong", "long");
-			simple_types.Add ("gshort", "short");
-			simple_types.Add ("gushort", "ushort");
-			simple_types.Add ("guint32", "uint");
+                        simple_types.Add ("char", "string");
+			simple_types.Add ("const-void", "System.IntPtr");
 			simple_types.Add ("const-gchar", "string");
 			simple_types.Add ("const-char", "string");
 			simple_types.Add ("gchar", "string");
 			simple_types.Add ("GObject", "GLib.Object");
-			simple_types.Add ("gfloat", "float");
-			simple_types.Add ("gdouble", "double");
-			simple_types.Add ("gint8", "byte");
-			simple_types.Add ("guint8", "byte");
-			simple_types.Add ("gint16", "short");
-			simple_types.Add ("gint32", "int");
-			simple_types.Add ("guint16", "ushort");
-			simple_types.Add ("guint1", "bool");
 			simple_types.Add ("gpointer", "System.IntPtr");
-			simple_types.Add ("guchar", "byte");
-			simple_types.Add ("long", "long");
-			simple_types.Add ("gulong", "ulong");
-			simple_types.Add ("GQuark", "int");
-			simple_types.Add ("int", "int");
-			simple_types.Add ("char", "string");
-			simple_types.Add ("double", "double");
-			simple_types.Add ("float", "float");
 			simple_types.Add ("gunichar", "string");
-			simple_types.Add ("uint1", "bool");
 			simple_types.Add ("GPtrArray", "System.IntPtr[]");
-			simple_types.Add ("GType", "int");
 			simple_types.Add ("GError", "IntPtr");
-			// gsize is a system-specific typedef in glibconfig.h,
-			// but this should work for now
-			simple_types.Add ("gsize", "uint");
-			simple_types.Add ("gssize", "int");
-			simple_types.Add ("size_t", "int");
 		=09
 			// FIXME: These ought to be handled properly.
 			simple_types.Add ("GMemChunk", "System.IntPtr");
@@ -88,6 +98,11 @@
 			complex_types [gen.CName] =3D gen;
 		}
 	=09
+                public static void AddNativeType (string cname, string nam=
e)
+                {
+                        native_types.Add (cname, name);
+                }
+
 		public static void AddSimpleType (string cname, string name)
 		{
 			simple_types.Add (cname, name);
@@ -113,15 +128,16 @@
 	=09
 		private static string Trim(string type)
 		{
-			// HACK: If we don't detect this here, there is no
-			// way of indicating it in the symbol table
-			if (type =3D=3D "void*" || type =3D=3D "const-void*") return "gpointer"=
;
-
 			string trim_type =3D type.TrimEnd('*');
 			if (trim_type.StartsWith("const-")) return trim_type.Substring(6);
 			return trim_type;
 		}
=20
+                private static string TrimPointer(string type)
+                {
+                        return type.TrimEnd('*');
+                }
+
 		private static string DeAlias (string type)
 		{
 			while (alias.ContainsKey(type))
@@ -140,12 +156,18 @@
 			return FromNative (c_type, val, false);
 		}
=20
-		public static string FromNative(string c_type, string val, bool ret)
+		public static string FromNative(string c_type_in, string val, bool ret)
 		{
-			c_type =3D Trim(c_type);
-			c_type =3D DeAlias(c_type);
+			string trimmed_type =3D Trim(c_type_in);
+			string c_type =3D DeAlias(trimmed_type);
 			if (simple_types.ContainsKey(c_type)) {
 				return val;
+                        } else if (native_types.ContainsKey(trimmed_type))=
 {
+                                if (IsPointer (c_type_in)) {
+                                        return "out " + val;
+                                } else {
+                                        return val;
+                                }
 			} else if (complex_types.ContainsKey(c_type)) {
 				IGeneratable gen =3D (IGeneratable) complex_types[c_type];
 				if (ret)
@@ -160,12 +182,28 @@
 			}
 		}
 	=09
-		public static string GetCSType(string c_type)
+                public static string GetCSType(string c_type_in)
 		{
-			c_type =3D Trim(c_type);
-			c_type =3D DeAlias(c_type);
+                        return GetCSType (c_type_in, false);
+                }
+
+		public static string GetCSType(string c_type_in, bool ret)
+		{
+			string trimmed_type =3D Trim(c_type_in);
+			string c_type =3D DeAlias(trimmed_type);
+                       =20
 			if (simple_types.ContainsKey(c_type)) {
 				return (string) simple_types[c_type];
+                        } else if (native_types.ContainsKey(trimmed_type))=
 {
+                                if (IsPointer (c_type_in)) {
+                                        if (ret) {
+                                                return "IntPtr";
+                                        } else {
+                                                return "out " + (string) n=
ative_types[c_type];
+                                        }
+                                } else {
+                                        return (string) native_types[c_typ=
e];
+                                }
 			} else if (complex_types.ContainsKey(c_type)) {
 				IGeneratable gen =3D (IGeneratable) complex_types[c_type];
 				return gen.QualifiedName;
@@ -176,10 +214,10 @@
 			}
 		}
 	=09
-		public static string GetName(string c_type)
+		public static string GetName(string c_type_in)
 		{
-			c_type =3D Trim(c_type);
-			c_type =3D DeAlias(c_type);
+			string trimmed_type =3D Trim(c_type_in);
+			string c_type =3D DeAlias(trimmed_type);
 			if (simple_types.ContainsKey(c_type) || manually_wrapped_types.Contains=
Key(c_type)) {
 				string stype;
 				if (simple_types.ContainsKey(c_type))
@@ -192,6 +230,8 @@
 				} else {
 					return stype.Substring(dotidx+1);
 				}
+			} else if (native_types.ContainsKey(c_type)) {
+                                return (string) native_types[c_type];
 			} else if (complex_types.ContainsKey(c_type)) {
 				IGeneratable gen =3D (IGeneratable) complex_types[c_type];
 				return gen.Name;
@@ -210,12 +250,22 @@
 			return GetMarshalType (c_type, false);
 		}
 	=09
-		public static string GetMarshalType(string c_type, bool ret)
+		public static string GetMarshalType(string c_type_in, bool ret)
 		{
-			c_type =3D Trim(c_type);
-			c_type =3D DeAlias(c_type);
+			string trimmed_type =3D Trim(c_type_in);
+			string c_type =3D DeAlias(trimmed_type);
 			if (simple_types.ContainsKey(c_type)) {
 				return (string) simple_types[c_type];
+			} else if (native_types.ContainsKey(c_type)) {
+                                if (IsPointer (c_type_in)) {
+                                        if (ret) {
+                                                return "IntPtr";
+                                        } else {
+                                                return "out " + (string) n=
ative_types[c_type];
+                                        }
+                                } else {
+                                        return (string) native_types[c_typ=
e];
+                                }
 			} else if (manually_wrapped_types.ContainsKey(c_type)) {
 				return "IntPtr";
 			} else if (complex_types.ContainsKey(c_type)) {
@@ -229,12 +279,18 @@
 			}
 		}
 	=09
-		public static string CallByName(string c_type, string var_name)
+		public static string CallByName(string c_type_in, string var_name)
 		{
-			c_type =3D Trim(c_type);
-			c_type =3D DeAlias(c_type);
+			string trimmed_type =3D Trim(c_type_in);
+			string c_type =3D DeAlias(trimmed_type);
 			if (simple_types.ContainsKey(c_type)) {
 				return var_name;
+			} else if (native_types.ContainsKey(c_type)) {
+                                if (IsPointer (c_type_in)) {
+                                        return "out " + var_name;
+                                } else {
+                                        return var_name;
+                                }
 			} else if (manually_wrapped_types.ContainsKey(c_type)) {
 				return var_name + ".Handle";
 			} else if (complex_types.ContainsKey(c_type)) {
@@ -321,6 +377,14 @@
 			return false;
 		}
 	=09
+                public static bool IsPointer(string type)
+                {
+                        // return true only if it's a simple pointer
+                        if (type.EndsWith("*") && !type.EndsWith("**"))
+                                return true;
+                        return false;
+                }
+
 		public static ClassBase GetClassGen(string c_type)
 		{
 			c_type =3D Trim(c_type);

--=-e4bjs1cv4wnovWlkpsDP--