2007-07-03 Mike Kestner <mkestner@novell.com>

* 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
This commit is contained in:
Mike Kestner 2007-07-10 15:25:14 +00:00
parent 761a85b0ef
commit b1bb3f9056
4 changed files with 225 additions and 74 deletions

View file

@ -1,3 +1,11 @@
2007-07-03 Mike Kestner <mkestner@novell.com>
* 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 <mkestner@novell.com>
* bootstrap-generic : use automake --foreign to make automake-1.10

View file

@ -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);

View file

@ -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") + ";");
}
}

View file

@ -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,19 +239,43 @@ namespace GtkSharp.Generation {
}
}
public string CallByName (string call_parm_name)
{
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 new string [0];
}
}
public virtual string CallString {
get {
if (IsArray && MarshalType != CSType)
return "native_" + CallName;
string call_parm;
if (Generatable is CallbackGen)
call_parm = SymbolTable.Table.CallByName (CType, call_parm_name + "_wrapper");
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, call_parm_name);
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);
}
}