From b1bb3f9056d80b9b64a3d8d5dcc37efd3a619697 Mon Sep 17 00:00:00 2001 From: Mike Kestner Date: Tue, 10 Jul 2007 15:25:14 +0000 Subject: [PATCH] 2007-07-03 Mike Kestner * generator/ImportSignature.cs : use Parameter.NativeSignature prop and refactor out some GError handling. * generator/MethodBody.cs : Refactor logic into Parameters. * generator/Parameters.cs : add ArrayParameter, ArrayCountPair, and ErrorParameter subclasses to refactor spaghetti code in MethodBody. svn path=/trunk/gtk-sharp/; revision=81721 --- ChangeLog | 8 ++ generator/ImportSignature.cs | 6 +- generator/MethodBody.cs | 71 +++--------- generator/Parameters.cs | 214 ++++++++++++++++++++++++++++++++--- 4 files changed, 225 insertions(+), 74 deletions(-) diff --git a/ChangeLog b/ChangeLog index ede218bdd..1315cb27a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2007-07-03 Mike Kestner + + * generator/ImportSignature.cs : use Parameter.NativeSignature + prop and refactor out some GError handling. + * generator/MethodBody.cs : Refactor logic into Parameters. + * generator/Parameters.cs : add ArrayParameter, ArrayCountPair, and + ErrorParameter subclasses to refactor spaghetti code in MethodBody. + 2007-07-03 Mike Kestner * bootstrap-generic : use automake --foreign to make automake-1.10 diff --git a/generator/ImportSignature.cs b/generator/ImportSignature.cs index 4a07cabe8..b072473fa 100644 --- a/generator/ImportSignature.cs +++ b/generator/ImportSignature.cs @@ -44,11 +44,9 @@ namespace GtkSharp.Generation { Parameter p = parameters [i]; parms [i] = ""; - if (p.CType == "GError**") - parms [i] += "out "; - else if (p.PassAs != "") + if (p.PassAs != "") parms [i] += p.PassAs + " "; - parms [i] += p.MarshalType + " " + p.Name; + parms [i] += p.NativeSignature; } string import_sig = String.Join (", ", parms); diff --git a/generator/MethodBody.cs b/generator/MethodBody.cs index a474e302d..ccf0f466a 100644 --- a/generator/MethodBody.cs +++ b/generator/MethodBody.cs @@ -40,60 +40,31 @@ namespace GtkSharp.Generation { return type != "int" ? "(" + type + ") " : ""; } - private string CallArrayLength (string array_name, Parameter length) - { - string result = array_name + " != null ? "; - result += CastFromInt (length.CSType) + array_name + ".Length"; - result += ": 0"; - return length.Generatable.CallByName (result); - } - public string GetCallString (bool is_set) { if (parameters.Count == 0) - return ""; + return String.Empty; string[] result = new string [parameters.Count]; for (int i = 0; i < parameters.Count; i++) { Parameter p = parameters [i]; IGeneratable igen = p.Generatable; - bool is_prop = is_set && (i == 0 || (i == 1 && p.IsArray && parameters[0].IsCount)); - string name = is_prop ? "value" : p.Name; - if (p.IsCount) { - if (i > 0 && parameters [i - 1].IsArray) { - string array_name = (i == 1 && is_set) ? "value" : parameters [i - 1].Name; - result[i] = CallArrayLength (array_name, p); - continue; - } else if (i < parameters.Count - 1 && parameters [i + 1].IsArray) { - string array_name = (i == 0 && is_set) ? "value" : parameters [i + 1].Name; - result[i] = CallArrayLength (array_name, p); - continue; - } - } else if (i > 0 && parameters [i - 1].IsString && p.IsLength) { + bool is_prop = is_set && i == 0; + + if (i > 0 && parameters [i - 1].IsString && p.IsLength) { string string_name = (i == 1 && is_set) ? "value" : parameters [i - 1].Name; result[i] = igen.CallByName (CastFromInt (p.CSType) + "System.Text.Encoding.UTF8.GetByteCount (" + string_name + ")"); continue; - } else if (p.IsArray && p.MarshalType != p.CSType) { - result[i] = "native_" + p.Name; - continue; } - string call_parm = p.CallByName (name); + if (is_prop) + p.CallName = "value"; + else + p.CallName = p.Name; + string call_parm = p.CallString; - if (p.CType == "GError**") { - result [i] += "out "; - } else if (p.PassAs != "") { - result [i] += p.PassAs + " "; - - if (p.CSType != p.MarshalType && !(igen is StructBase || igen is ByRefGen)) - call_parm = p.Name + "_as_native"; - } else if (igen is IManualMarshaler) - call_parm = p.Name + "_as_native"; - - if (p.CType == "GError**") { - call_parm = call_parm.Replace (p.Name, "error"); - } else if (p.IsUserData && parameters.IsHidden (p) && !parameters.HideData && + if (p.IsUserData && parameters.IsHidden (p) && !parameters.HideData && (i == 0 || parameters [i - 1].Scope != "notified")) { call_parm = "IntPtr.Zero"; } @@ -122,19 +93,9 @@ namespace GtkSharp.Generation { if (is_set) name = "value"; - if ((is_get || p.PassAs == "out") && p.CSType != p.MarshalType && !(gen is StructBase || gen is ByRefGen)) - sw.WriteLine(indent + "\t\t\t" + gen.MarshalType + " " + name + "_as_native;"); - else if (p.IsArray && p.MarshalType != p.CSType) { - sw.WriteLine(indent + "\t\t\tint cnt_" + p.Name + " = {0} == null ? 0 : {0}.Length;", name); - sw.WriteLine(indent + "\t\t\t{0}[] native_" + p.Name + " = new {0} [cnt_{1}];", p.MarshalType.TrimEnd('[', ']'), p.Name); - sw.WriteLine(indent + "\t\t\tfor (int i = 0; i < cnt_{0}; i++)", p.Name); - if (gen is IManualMarshaler) - sw.WriteLine(indent + "\t\t\t\tnative_{0} [i] = {1};", p.Name, (gen as IManualMarshaler).AllocNative (name + "[i]")); - else - sw.WriteLine(indent + "\t\t\t\tnative_{0} [i] = {1};", p.Name, p.CallByName (name + "[i]")); - } else if (gen is IManualMarshaler) - sw.WriteLine(indent + "\t\t\t" + gen.MarshalType + " " + p.Name + "_as_native = " + (gen as IManualMarshaler).AllocNative (name) + ";"); - + p.CallName = name; + foreach (string prep in p.CallPreparation) + sw.WriteLine (indent + "\t\t\t" + prep); if (gen is CallbackGen) { CallbackGen cbgen = gen as CallbackGen; @@ -190,10 +151,10 @@ namespace GtkSharp.Generation { if (p.PassAs == "out" && p.CSType != p.MarshalType && !(gen is StructBase || gen is ByRefGen)) sw.WriteLine(indent + "\t\t\t" + p.Name + " = " + p.FromNative (p.Name + "_as_native") + ";"); else if (p.IsArray && gen is IManualMarshaler) { - sw.WriteLine(indent + "\t\t\tfor (int i = 0; i < native_" + p.Name + ".Length; i++)"); - sw.WriteLine(indent + "\t\t\t\t" + (gen as IManualMarshaler).ReleaseNative ("native_" + p.Name + "[i]") + ";"); + sw.WriteLine(indent + "\t\t\tfor (int i = 0; i < native_" + p.CallName + ".Length; i++)"); + sw.WriteLine(indent + "\t\t\t\t" + (gen as IManualMarshaler).ReleaseNative ("native_" + p.CallName + "[i]") + ";"); } else if (gen is IManualMarshaler) - sw.WriteLine(indent + "\t\t\t" + (gen as IManualMarshaler).ReleaseNative (p.Name + "_as_native") + ";"); + sw.WriteLine(indent + "\t\t\t" + (gen as IManualMarshaler).ReleaseNative (p.CallName + "_as_native") + ";"); } } diff --git a/generator/Parameters.cs b/generator/Parameters.cs index 9d53b535e..159606084 100644 --- a/generator/Parameters.cs +++ b/generator/Parameters.cs @@ -36,6 +36,19 @@ namespace GtkSharp.Generation { elem = e; } + string call_name; + public string CallName { + get { + if (call_name == null) + return Name; + else + return call_name; + } + set { + call_name = value; + } + } + public string CType { get { string type = elem.GetAttribute("type"); @@ -179,14 +192,25 @@ namespace GtkSharp.Generation { } } + public virtual string NativeSignature { + get { + return MarshalType + " " + Name; + } + } + public string PropertyName { get { return elem.GetAttribute("property_name"); } } + string pass_as; + public string PassAs { get { + if (pass_as != null) + return pass_as; + if (elem.HasAttribute ("pass_as")) return elem.GetAttribute ("pass_as"); @@ -198,6 +222,9 @@ namespace GtkSharp.Generation { return ""; } + set { + pass_as = value; + } } string scope; @@ -212,18 +239,42 @@ namespace GtkSharp.Generation { } } - public string CallByName (string call_parm_name) - { - string call_parm; - if (Generatable is CallbackGen) - call_parm = SymbolTable.Table.CallByName (CType, call_parm_name + "_wrapper"); - else - call_parm = SymbolTable.Table.CallByName(CType, call_parm_name); - - if (IsArray) - call_parm = call_parm.Replace ("ref ", ""); + public virtual string[] CallPreparation { + get { + IGeneratable gen = Generatable; + if (PassAs == "out" && CSType != MarshalType && !(gen is StructBase || gen is ByRefGen)) + return new string [] { gen.MarshalType + " " + CallName + "_as_native;" }; + else if (gen is IManualMarshaler) + return new string [] { gen.MarshalType + " " + CallName + "_as_native = " + (gen as IManualMarshaler).AllocNative (CallName) + ";" }; - return call_parm; + return new string [0]; + } + } + + public virtual string CallString { + get { + if (IsArray && MarshalType != CSType) + return "native_" + CallName; + + string call_parm; + + IGeneratable gen = Generatable; + if (gen is CallbackGen) + call_parm = SymbolTable.Table.CallByName (CType, CallName + "_wrapper"); + else if (PassAs != String.Empty) { + call_parm = PassAs + " " + CallName; + if (CSType != MarshalType && !(gen is StructBase || gen is ByRefGen)) + call_parm += "_as_native"; + } else if (gen is IManualMarshaler) + call_parm = CallName + "_as_native"; + else + call_parm = SymbolTable.Table.CallByName(CType, CallName); + + if (IsArray) + call_parm = call_parm.Replace ("ref ", ""); + + return call_parm; + } } public string FromNative (string var) @@ -250,6 +301,113 @@ namespace GtkSharp.Generation { } } + public class ArrayParameter : Parameter { + + public ArrayParameter (XmlElement elem) : base (elem) {} + + public override string[] CallPreparation { + get { + if (CSType == MarshalType) + return new string [0]; + + string[] result = new string [4]; + result [0] = String.Format ("int cnt_{0} = {0} == null ? 0 : {0}.Length;", CallName); + result [1] = String.Format ("{0}[] native_{1} = new {0} [cnt_{1}];", MarshalType.TrimEnd('[', ']'), CallName); + result [2] = String.Format ("for (int i = 0; i < cnt_{0}; i++)", CallName); + IGeneratable gen = Generatable; + if (gen is IManualMarshaler) + result [3] = String.Format ("\tnative_{0} [i] = {1};", CallName, (gen as IManualMarshaler).AllocNative (CallName + "[i]")); + else + result [3] = String.Format ("\tnative_{0} [i] = {1};", CallName, gen.CallByName (CallName + "[i]")); + return result; + } + } + + public override string CallString { + get { + if (CSType != MarshalType) + return "native_" + CallName; + else + return CallName; + } + } + } + + public class ArrayCountPair : ArrayParameter { + + XmlElement array_elem; + XmlElement count_elem; + bool invert; + + public ArrayCountPair (XmlElement array_elem, XmlElement count_elem, bool invert) : base (array_elem) + { + this.array_elem = array_elem; + this.count_elem = count_elem; + this.invert = invert; + } + + string CountType { + get { + return SymbolTable.Table.GetCSType(count_elem.GetAttribute("type")); + } + } + + string CountCast { + get { + if (CountType == "int") + return String.Empty; + else + return "(" + CountType + ") "; + } + } + + string CountName { + get { + return SymbolTable.Table.MangleName (count_elem.GetAttribute("name")); + } + } + + string CallCount (string name) + { + string result = name + " == null ? 0 : "; + result += CountCast + name + ".Length"; + IGeneratable gen = SymbolTable.Table[count_elem.GetAttribute("type")]; + return gen.CallByName (result); + } + + public override string CallString { + get { + if (invert) + return CallCount (CallName) + ", " + base.CallString; + else + return base.CallString + ", " + CallCount (CallName); + } + } + + public override string NativeSignature { + get { + if (invert) + return CountType + " " + CountName + ", " + MarshalType + " " + Name; + else + return MarshalType + " " + Name + ", " + CountType + " " + CountName; + } + } + } + + public class ErrorParameter : Parameter { + + public ErrorParameter (XmlElement elem) : base (elem) + { + PassAs = "out"; + } + + public override string CallString { + get { + return "out error"; + } + } + } + public class Parameters : IEnumerable { ArrayList param_list = new ArrayList (); @@ -259,10 +417,36 @@ namespace GtkSharp.Generation { if (elem == null) return; - foreach (XmlNode node in elem.ChildNodes) { - XmlElement parm = node as XmlElement; - if (parm != null && parm.Name == "parameter") - param_list.Add (new Parameter (parm)); + for (int i = 0; i < elem.ChildNodes.Count; i++) { + XmlElement parm = elem.ChildNodes [i] as XmlElement; + if (parm == null || parm.Name != "parameter") + continue; + Parameter p = new Parameter (parm); + if (p.IsArray) { + p = new ArrayParameter (parm); + if (i < elem.ChildNodes.Count - 1) { + XmlElement next = elem.ChildNodes [i + 1] as XmlElement; + if (next != null || next.Name == "parameter") { + Parameter c = new Parameter (next); + if (c.IsCount) { + p = new ArrayCountPair (parm, next, false); + i++; + } + } + } + } else if (p.IsCount && i < elem.ChildNodes.Count - 1) { + Console.WriteLine (elem.GetAttribute ("name")); + XmlElement next = elem.ChildNodes [i + 1] as XmlElement; + if (next != null || next.Name == "parameter") { + Parameter a = new Parameter (next); + if (a.IsArray) { + p = new ArrayCountPair (next, parm, true); + i++; + } + } + } else if (p.CType == "GError**") + p = new ErrorParameter (parm); + param_list.Add (p); } }