From 3bb3c5e4ff016d97d753627d9170bc73806edfd6 Mon Sep 17 00:00:00 2001 From: Rachel Hestilow Date: Fri, 14 Jun 2002 18:27:04 +0000 Subject: [PATCH] 2002-06-14 Rachel Hestilow * glib/GException.cs: Added. * generator/Ctor.cs, Method.cs: Tag function as unsafe if it throws an exception. Call parms.HandleException. * generator/Paramaters.cs: Add property ThrowsException (based on a trailing GError**). If ThrowsException, mask GError in the signature, initialize a GError in Initialize, and add new method HandleException to throw an exception if error != null. * generator/SymbolTable.cs: Add gdk-pixbuf DLL, and GError type. * gdk.imaging, gdk.imaging/Makefile.in, gdk.imaging/makefile.win32: Added. * configure.in, Makefile, makefile.win32: Build gdk.imaging. * gtk/Makefile.in, gtk/makefile.win32: Link against gdk.imaging. * parser/gapi2xml.pl: Support namespace renaming. * parser/build.pl: Build gdk-pixbuf as gdk.imaging. svn path=/trunk/gtk-sharp/; revision=5281 --- ChangeLog | 25 ++++++++++++++++++ configure.in | 1 + generator/Ctor.cs | 24 ++++++++++++++---- generator/GenBase.cs | 1 + generator/Method.cs | 20 +++++++++++---- generator/Parameters.cs | 55 ++++++++++++++++++++++++++++++++++------ generator/SymbolTable.cs | 2 ++ generator/gtkapi.xml | 2 +- glib/GException.cs | 40 +++++++++++++++++++++++++++++ gtk/Makefile.in | 4 +-- makefile | 2 +- makefile.win32 | 2 +- parser/build.pl | 8 +++++- parser/gapi2xml.pl | 10 ++++++-- 14 files changed, 170 insertions(+), 26 deletions(-) create mode 100644 glib/GException.cs diff --git a/ChangeLog b/ChangeLog index e5775cf36..e3952a2a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2002-06-14 Rachel Hestilow + + * glib/GException.cs: Added. + + * generator/Ctor.cs, Method.cs: Tag function as unsafe if it throws + an exception. Call parms.HandleException. + + * generator/Paramaters.cs: Add property ThrowsException (based + on a trailing GError**). If ThrowsException, mask GError in the + signature, initialize a GError in Initialize, and add new method + HandleException to throw an exception if error != null. + + * generator/SymbolTable.cs: Add gdk-pixbuf DLL, and GError type. + + * gdk.imaging, gdk.imaging/Makefile.in, gdk.imaging/makefile.win32: + Added. + + * configure.in, Makefile, makefile.win32: Build gdk.imaging. + + * gtk/Makefile.in, gtk/makefile.win32: Link against gdk.imaging. + + * parser/gapi2xml.pl: Support namespace renaming. + + * parser/build.pl: Build gdk-pixbuf as gdk.imaging. + 2002-06-09 Rachel Hestilow * generator/GenBase.cs: new method AppendCustom, moved from ObjectGen. diff --git a/configure.in b/configure.in index 3c5fdbd24..c5fb59181 100644 --- a/configure.in +++ b/configure.in @@ -80,6 +80,7 @@ glib/Makefile pango/Makefile atk/Makefile gdk/Makefile +gdk.imaging/Makefile gtk/Makefile sample/Makefile ]) diff --git a/generator/Ctor.cs b/generator/Ctor.cs index a75836629..20ed5413f 100644 --- a/generator/Ctor.cs +++ b/generator/Ctor.cs @@ -58,9 +58,14 @@ namespace GtkSharp.Generation { string cname = elem.GetAttribute("cname"); string name = ((XmlElement)elem.ParentNode).GetAttribute("name"); - + string safety; + if (parms != null && parms.ThrowsException) + safety = "unsafe "; + else + safety = ""; + sw.WriteLine("\t\t[DllImport(\"" + SymbolTable.GetDllName(ns) + "\")]"); - sw.WriteLine("\t\tstatic extern IntPtr " + cname + isig); + sw.WriteLine("\t\tstatic extern " + safety + "IntPtr " + cname + isig); sw.WriteLine(); if (clash) { @@ -71,13 +76,22 @@ namespace GtkSharp.Generation { mname = mname.Substring(0, idx) + mname.Substring(idx+1, 1).ToUpper() + mname.Substring(idx+2); } - sw.WriteLine("\t\tpublic static " + name + " " + mname + sig); + sw.WriteLine("\t\tpublic static " + safety + name + " " + mname + sig); sw.WriteLine("\t\t{"); - sw.WriteLine("\t\t\treturn new " + name + "(" + cname + call + ");"); + if (parms != null) + parms.Initialize(sw, false); + sw.WriteLine("\t\t\tIntPtr ret = " + cname + call + ";"); + if (parms != null) + parms.HandleException (sw); + sw.WriteLine("\t\t\treturn new " + name + "(ret);"); } else { - sw.WriteLine("\t\tpublic " + name + sig); + sw.WriteLine("\t\tpublic " + safety + name + sig); sw.WriteLine("\t\t{"); + if (parms != null) + parms.Initialize(sw, false); sw.WriteLine("\t\t\tRaw = " + cname + call + ";"); + if (parms != null) + parms.HandleException (sw); } sw.WriteLine("\t\t}"); diff --git a/generator/GenBase.cs b/generator/GenBase.cs index 045867aab..154975b2d 100644 --- a/generator/GenBase.cs +++ b/generator/GenBase.cs @@ -56,6 +56,7 @@ namespace GtkSharp.Generation { char sep = Path.DirectorySeparatorChar; string dir = ".." + sep + ns.ToLower() + sep + "generated"; if (!Directory.Exists(dir)) { + Console.WriteLine ("creating " + dir); Directory.CreateDirectory(dir); } String filename = dir + sep + Name + ".cs"; diff --git a/generator/Method.cs b/generator/Method.cs index 1dd0ba982..304b86fd4 100644 --- a/generator/Method.cs +++ b/generator/Method.cs @@ -123,13 +123,19 @@ namespace GtkSharp.Generation { Statistics.ThrottledCount++; return; } + + string safety; + if (parms != null && parms.ThrowsException) + safety = "unsafe "; + else + safety = ""; sw.WriteLine("\t\t[DllImport(\"" + SymbolTable.GetDllName(ns) + "\", CallingConvention=CallingConvention.Cdecl)]"); - sw.Write("\t\tstatic extern " + m_ret + " " + cname + isig); + sw.Write("\t\tstatic extern " + safety + m_ret + " " + cname + isig); sw.WriteLine(); - sw.Write("\t\tpublic "); + sw.Write("\t\tpublic " + safety); bool is_get = (parms != null && parms.IsAccessor && Name.Substring(0, 3) == "Get"); if (is_get) { s_ret = parms.AccessorReturnType; @@ -149,12 +155,16 @@ namespace GtkSharp.Generation { if (is_get || m_ret == "void") { sw.WriteLine(cname + call + ";"); } else { - sw.WriteLine("return " + SymbolTable.FromNative(rettype, cname + call) + ";"); + sw.WriteLine(s_ret + " ret = " + SymbolTable.FromNative(rettype, cname + call) + ";"); } - if (is_get) - sw.WriteLine ("\t\t\treturn " + parms.AccessorName + ";"); + if (parms != null) + parms.HandleException (sw); + if (is_get) + sw.WriteLine ("\t\t\treturn " + parms.AccessorName + ";"); + else if (m_ret != "void") + sw.WriteLine ("\t\t\treturn ret;"); sw.Write("\t\t}"); if (is_get) diff --git a/generator/Parameters.cs b/generator/Parameters.cs index 92eb00890..6c06cfb97 100644 --- a/generator/Parameters.cs +++ b/generator/Parameters.cs @@ -69,7 +69,7 @@ namespace GtkSharp.Generation { Console.Write("Name: " + name + " Type: " + type + " "); return false; } - + if (p_elem.HasAttribute("array")) { cs_type += "[]"; m_type += "[]"; @@ -77,9 +77,12 @@ namespace GtkSharp.Generation { if (need_sep) { call_string += ", "; - signature += ", "; import_sig += ", "; - signature_types += ":"; + if (type != "GError**") + { + signature += ", "; + signature_types += ":"; + } } else { need_sep = true; } @@ -87,9 +90,14 @@ namespace GtkSharp.Generation { if (p_elem.HasAttribute("pass_as")) { signature += p_elem.GetAttribute("pass_as") + " "; } - - signature += (cs_type + " " + name); - signature_types += cs_type; + + if (type == "GError**") + call_string += "&"; + else + { + signature += (cs_type + " " + name); + signature_types += cs_type; + } call_string += call_parm; import_sig += (m_type + " " + name); } @@ -99,6 +107,7 @@ namespace GtkSharp.Generation { public void Initialize (StreamWriter sw, bool is_get) { + string name; foreach (XmlNode parm in elem.ChildNodes) { if (parm.Name != "parameter") { continue; @@ -107,7 +116,7 @@ namespace GtkSharp.Generation { XmlElement p_elem = (XmlElement) parm; string type = SymbolTable.GetCSType(p_elem.GetAttribute ("type")); - string name = MangleName(p_elem.GetAttribute("name")); + name = MangleName(p_elem.GetAttribute("name")); if (is_get) { sw.WriteLine ("\t\t\t" + type + " " + name + ";"); } @@ -116,9 +125,18 @@ namespace GtkSharp.Generation { sw.WriteLine("\t\t\t" + name + " = new " + type + "();"); } } - + + if (ThrowsException) + sw.WriteLine ("\t\t\tGLib.GError* {0} = null;", name); } + public void HandleException (StreamWriter sw) + { + if (!ThrowsException) + return; + sw.WriteLine ("\t\t\tif (error != null) throw new GLib.GException (error);"); + } + public bool IsAccessor { get { int length = 0; @@ -140,6 +158,27 @@ namespace GtkSharp.Generation { } } + public bool ThrowsException { + get { + int i = 0; + XmlNode last_parm = null; + foreach (XmlNode parm in elem.ChildNodes) { + if (parm.Name != "parameter") { + continue; + } + + last_parm = parm; + } + + if (last_parm == null) + return false; + + XmlElement p_elem = (XmlElement) last_parm; + string type = p_elem.GetAttribute("type"); + return (type == "GError**"); + } + } + public string AccessorReturnType { get { foreach (XmlNode parm in elem.ChildNodes) { diff --git a/generator/SymbolTable.cs b/generator/SymbolTable.cs index 8872c1f20..81dd1a741 100644 --- a/generator/SymbolTable.cs +++ b/generator/SymbolTable.cs @@ -52,6 +52,7 @@ namespace GtkSharp.Generation { simple_types.Add ("uint1", "bool"); simple_types.Add ("GPtrArray", "System.IntPtr[]"); simple_types.Add ("GType", "int"); + simple_types.Add ("GError", "GLib.GError**"); // FIXME: These ought to be handled properly. simple_types.Add ("GList", "System.IntPtr"); @@ -70,6 +71,7 @@ namespace GtkSharp.Generation { dlls.Add("Pango", "pango-1.0"); dlls.Add("Atk", "atk-1.0"); dlls.Add("Gdk", "gdk-x11-2.0"); + dlls.Add("Gdk.Imaging", "gdk_pixbuf-2.0"); dlls.Add("Gtk", "gtk-x11-2.0"); } diff --git a/generator/gtkapi.xml b/generator/gtkapi.xml index 49300e81c..bb443b61c 100644 --- a/generator/gtkapi.xml +++ b/generator/gtkapi.xml @@ -1,2 +1,2 @@ - + diff --git a/glib/GException.cs b/glib/GException.cs new file mode 100644 index 000000000..08e97b43f --- /dev/null +++ b/glib/GException.cs @@ -0,0 +1,40 @@ +// GException.cs : GError handling +// +// Authors: Rachel Hestilow +// +// (c) 2002 Rachel Hestilow + +namespace GLib { + + using System; + using System.Runtime.InteropServices; + + [StructLayout(LayoutKind.Sequential)] + public unsafe struct GError + { + [MarshalAs (UnmanagedType.U4)] + public uint domain; + [MarshalAs (UnmanagedType.I4)] + public int code; + [MarshalAs (UnmanagedType.LPStr)] + public string message; + } + + public unsafe class GException : Exception + { + GError *errptr; + + unsafe public GException (GError *errptr) : base (errptr->message) + { + this.errptr = errptr; + } + + [DllImport("glib-2.0")] + unsafe static extern void g_clear_error (GError **errptr); + ~GException () + { + unsafe { g_clear_error (&errptr); } + } + } +} + diff --git a/gtk/Makefile.in b/gtk/Makefile.in index e792c782b..ccecdd545 100755 --- a/gtk/Makefile.in +++ b/gtk/Makefile.in @@ -3,12 +3,12 @@ MCS=mcs all: linux windows: - $(CSC) /unsafe /target:library /r:../glib/glib-sharp.dll /r:../pango/pango-sharp.dll /r:../atk/atk-sharp.dll /r:../gdk/gdk-sharp.dll /out:gtk-sharp.dll /recurse:*.cs + $(CSC) /unsafe /target:library /r:../glib/glib-sharp.dll /r:../pango/pango-sharp.dll /r:../atk/atk-sharp.dll /r:../gdk/gdk-sharp.dll /r:../gdk/gdk-imaging-sharp.dll /out:gtk-sharp.dll /recurse:*.cs linux: gtk-sharp.dll gtk-sharp.dll: *.cs generated/*.cs - $(MCS) --unsafe --target library -r System.Drawing -L ../glib -L ../pango -L ../atk -L ../gdk -r glib-sharp -r pango-sharp -r atk-sharp -r gdk-sharp -o gtk-sharp.dll --recurse '*.cs' + $(MCS) --unsafe --target library -r System.Drawing -L ../glib -L ../pango -L ../atk -L ../gdk -r glib-sharp -r pango-sharp -r atk-sharp -r gdk-sharp -r gdk-imaging-sharp -o gtk-sharp.dll --recurse '*.cs' clean: rm -f *.dll diff --git a/makefile b/makefile index d9586f63c..10bfd069f 100644 --- a/makefile +++ b/makefile @@ -1,4 +1,4 @@ -DIRS=generator glib pango atk gdk gtk sample +DIRS=generator glib pango atk gdk gdk.imaging gtk sample ROOT=/cygdrive/$(subst \,/,$(subst :\,/,$(SYSTEMROOT))) CSC=$(ROOT)/microsoft.net/framework/v1.0.3705/csc.exe MCS=mcs diff --git a/makefile.win32 b/makefile.win32 index 90248043b..de0076b6a 100755 --- a/makefile.win32 +++ b/makefile.win32 @@ -1,4 +1,4 @@ -DIRS=generator glib pango atk gdk gtk sample +DIRS=generator glib pango atk gdk gdk.imaging gtk sample ROOT=/cygdrive/$(subst \,/,$(subst :\,/,$(SYSTEMROOT))) CSC=$(ROOT)/microsoft.net/framework/v1.0.3705/csc.exe diff --git a/parser/build.pl b/parser/build.pl index 94f9e0163..81f4759a2 100755 --- a/parser/build.pl +++ b/parser/build.pl @@ -7,10 +7,16 @@ unlink ($file); %ns = ( "Atk" => "atk-1.0.2/atk", "Pango" => "pango-1.0.2/pango", "Gdk" => "gtk+-2.0.3/gdk", + "Gdk.Imaging" => "gtk+-2.0.3/gdk-pixbuf", "Gtk" => "gtk+-2.0.3/gtk"); +%c_ns = ( "Gdk.Imaging" => "Gdk"); + foreach $key (keys %ns) { $dir = $ns{$key}; - system ("./gapi_pp.pl $dir | ./gapi2xml.pl $key $file"); + if (not ($c_key = $c_ns{$key})) { + $c_key = $key; + } + system ("./gapi_pp.pl $dir | ./gapi2xml.pl $c_key $file --out-ns $key"); } diff --git a/parser/gapi2xml.pl b/parser/gapi2xml.pl index 740c4a58e..8dfe0b50f 100755 --- a/parser/gapi2xml.pl +++ b/parser/gapi2xml.pl @@ -13,11 +13,17 @@ use XML::LibXML; use Metadata; if (!$ARGV[0]) { - die "Usage: gapi_pp.pl | gapi2xml.pl \n"; + die "Usage: gapi_pp.pl | gapi2xml.pl [--out-ns outns]\n"; } $ns = $ARGV[0]; +if ($ARGV[2] && $ARGV[2] eq "--out-ns") { + $out_ns = $ARGV[3]; +} else { + $out_ns = $ns; +} + ############################################################## # If a filename was provided see if it exists. We parse existing files into # a tree and append the namespace to the root node. If the file doesn't @@ -35,7 +41,7 @@ if ($ARGV[1] && -e $ARGV[1]) { } $ns_elem = $doc->createElement('namespace'); -$ns_elem->setAttribute('name', $ns); +$ns_elem->setAttribute('name', $out_ns); $root->appendChild($ns_elem); ##############################################################