Generate ABI compatible structures for unions

This commit is contained in:
Thibault Saunier 2017-09-06 12:17:13 -03:00 committed by Harry
parent 9a9ef4b60b
commit 9de231db82
4 changed files with 101 additions and 0 deletions

View file

@ -90,6 +90,9 @@ namespace GtkSharp.Generation {
abi_field = new StructABIField (member, this);
abi_fields.Add (abi_field);
}
} else if (node.Name == "union") {
abi_field = new UnionABIField (member, this);
abi_fields.Add (abi_field);
}
if (member.GetAttributeAsBoolean ("hidden"))

View file

@ -109,6 +109,7 @@ PropertyBase: Abstract base class for property-like elements
ObjectField: Handles <field> elements in objects
StructField: Handles <field> elements in structs
StructABIField: Handles <fields> to generate ABI compatible structures
UnionABIField: Handles <union> to generate ABI compatible structures
ClassField: Handles <field> elements in classes
Property: Handles <property> elements
ChildProperty: Handles <childprop> elements

View file

@ -0,0 +1,96 @@
namespace GtkSharp.Generation {
using System;
using System.Collections;
using System.IO;
using System.Xml;
using System.Collections.Generic;
public class UnionSubstruct {
List<StructABIField> fields;
XmlElement Elem;
bool is_valid;
bool unique_field;
public UnionSubstruct(XmlElement elem, ClassBase container_type) {
fields = new List<StructABIField> ();
Elem = elem;
is_valid = true;
unique_field = false;
if (Elem.Name == "struct") {
foreach (XmlElement child_field in elem.ChildNodes) {
if (child_field.Name != "field") {
is_valid = false;
continue;
}
fields.Add(new StructABIField (child_field, container_type));
}
} else if (Elem.Name == "field") {
fields.Add(new StructABIField (Elem, container_type));
unique_field = true;
}
}
public void Generate(GenerationInfo gen_info, string indent){
StreamWriter sw = gen_info.Writer;
var name = Elem.GetAttribute("name");
var cname = Elem.GetAttribute("cname");
if (unique_field) {
sw.WriteLine (indent + "[FieldOffset(0)]");
foreach (StructABIField field in fields)
field.Generate(gen_info, indent);
return;
}
sw.WriteLine (indent + "struct __" + name + "{");
foreach (StructABIField field in fields) {
field.Generate(gen_info, indent + "\t");
}
sw.WriteLine (indent + "}");
sw.WriteLine (indent + "[FieldOffset(0)]");
sw.WriteLine (indent + "private __" + name + " " + cname + ";");
}
}
public class UnionABIField : StructABIField {
bool is_valid;
XmlElement Elem;
protected List<UnionSubstruct> substructs = new List<UnionSubstruct> ();
public UnionABIField (XmlElement elem, ClassBase container_type) : base (elem, container_type) {
Elem = elem;
is_valid = true;
foreach (XmlElement union_child in elem.ChildNodes) {
substructs.Add(new UnionSubstruct(union_child, container_type));
}
}
public override void Generate (GenerationInfo gen_info, string indent) {
StreamWriter sw = gen_info.Writer;
var name = Elem.GetAttribute("name");
var cname = Elem.GetAttribute("cname");
sw.WriteLine (indent + "[StructLayout(LayoutKind.Explicit)]");
sw.WriteLine (indent + "struct __" + name + " {");
foreach (UnionSubstruct _struct in substructs) {
_struct.Generate(gen_info, indent + "\t");
}
sw.WriteLine (indent + "}");
sw.WriteLine (indent + "private __" + name + " " + cname + ";");
}
public override bool Validate (LogWriter log)
{
if (!is_valid) {
log.Warn("Can't generate ABI compatible union");
}
return is_valid;
}
}
}

View file

@ -62,6 +62,7 @@ gapi_codegen = executable('gapi_codegen',
'StructField.cs',
'StructGen.cs',
'SymbolTable.cs',
'UnionABIField.cs',
'UnionGen.cs',
'VirtualMethod.cs',
'VMSignature.cs',