mirror of https://github.com/mono/CppSharp.git
commit
08ce0faeeb
5 changed files with 1801 additions and 0 deletions
@ -0,0 +1,171 @@ |
|||||||
|
using System; |
||||||
|
using NDesk.Options; |
||||||
|
using System.IO; |
||||||
|
using System.Text; |
||||||
|
using System.Xml; |
||||||
|
using System.Xml.XPath; |
||||||
|
using System.Xml.Linq; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
|
||||||
|
namespace CPPInterop { |
||||||
|
class Generator { |
||||||
|
|
||||||
|
public string Source { get; set; } |
||||||
|
public Dictionary<string, string> Classes; |
||||||
|
public string Dir {get; set;} |
||||||
|
|
||||||
|
string templateClass; |
||||||
|
string templateStruct; |
||||||
|
string templateInterface; |
||||||
|
|
||||||
|
public static void Main (string[] args) |
||||||
|
{ |
||||||
|
bool help = false; |
||||||
|
Generator gen = new Generator (); |
||||||
|
var p = new OptionSet () { |
||||||
|
{ "h|?|help", v => help = v != null }, |
||||||
|
{ "f=", v => gen.Source = v }, |
||||||
|
{ "o=", v => gen.Dir = v } |
||||||
|
}; |
||||||
|
|
||||||
|
List<string> extra = null; |
||||||
|
try { |
||||||
|
extra = p.Parse(args); |
||||||
|
} catch (OptionException){ |
||||||
|
Console.WriteLine ("Try `generator --help' for more information."); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (gen.Source == null) { |
||||||
|
Console.Error.WriteLine ("-f required"); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (gen.Dir == null) |
||||||
|
gen.Dir = "output"; |
||||||
|
Directory.CreateDirectory (gen.Dir); |
||||||
|
|
||||||
|
gen.Run (); |
||||||
|
} |
||||||
|
|
||||||
|
public Generator () |
||||||
|
{ |
||||||
|
Classes = new Dictionary<string, string>(); |
||||||
|
templateClass = File.ReadAllText ("class.template"); |
||||||
|
templateStruct = File.ReadAllText ("struct.template"); |
||||||
|
templateInterface = File.ReadAllText ("interface.template"); |
||||||
|
} |
||||||
|
|
||||||
|
XmlNode find (XmlNode root, XmlAttribute att) |
||||||
|
{ |
||||||
|
if (att != null) |
||||||
|
return find (root, att.Value); |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
XmlNode find (XmlNode root, string id) |
||||||
|
{ |
||||||
|
XmlNode n = root.SelectSingleNode ("/GCC_XML/*[@id='" + id + "']"); |
||||||
|
if (n.Name == "Typedef") |
||||||
|
return n; |
||||||
|
if (n.Attributes["type"] != null) |
||||||
|
return find (root, n.Attributes["type"].Value); |
||||||
|
return n; |
||||||
|
} |
||||||
|
|
||||||
|
public void Run () |
||||||
|
{ |
||||||
|
|
||||||
|
XmlDocument xmldoc = new XmlDocument (); |
||||||
|
xmldoc.Load (Source); |
||||||
|
XmlNodeList namespaces = xmldoc.SelectNodes ("/GCC_XML/Namespace[@name != '::' and @name != '' and @name != 'std']"); |
||||||
|
XmlNodeList classes = xmldoc.SelectNodes ("/GCC_XML/Class[not(@incomplete)]"); |
||||||
|
|
||||||
|
foreach (XmlNode clas in classes) { |
||||||
|
var f = xmldoc.SelectSingleNode ("/GCC_XML/File[@id='" + clas.Attributes["file"].Value + "']/@name"); |
||||||
|
if (f != null && f.Value.StartsWith ("/")) |
||||||
|
continue; |
||||||
|
|
||||||
|
string name = clas.Attributes["name"].Value; |
||||||
|
if (Classes.ContainsKey (name)) |
||||||
|
continue; |
||||||
|
|
||||||
|
string size = clas.Attributes["size"].Value; |
||||||
|
string members = clas.Attributes["members"].Value; |
||||||
|
|
||||||
|
StringBuilder str = new StringBuilder(); |
||||||
|
foreach (string id in members.Split(new char[]{' '})) { |
||||||
|
if (id.Equals (String.Empty)) |
||||||
|
continue; |
||||||
|
XmlNode n = find (xmldoc.DocumentElement, id); |
||||||
|
|
||||||
|
switch (n.Name) { |
||||||
|
case "Method": |
||||||
|
break; |
||||||
|
default: |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
if (n.Attributes["access"] == null || n.Attributes["access"].Value != "public") |
||||||
|
continue; |
||||||
|
|
||||||
|
str.Append ("\t\t\t"); |
||||||
|
string mname = n.Attributes["name"].Value; |
||||||
|
|
||||||
|
XmlNode ret = find (xmldoc.DocumentElement, n.Attributes["returns"]); |
||||||
|
|
||||||
|
string rett = ret.Attributes["name"].Value; |
||||||
|
bool virt = ret.Attributes["virtual"] != null && ret.Attributes["virtual"].Value == "1"; |
||||||
|
|
||||||
|
if (virt) |
||||||
|
str.Append ("[Virtual] "); |
||||||
|
str.Append (rett + " " + mname + " (CppInstancePtr @this"); |
||||||
|
|
||||||
|
|
||||||
|
int c = 0; |
||||||
|
foreach (XmlNode arg in n.SelectNodes ("Argument")) { |
||||||
|
string argname; |
||||||
|
if (arg.Attributes["name"] == null) |
||||||
|
argname = "arg" + c; |
||||||
|
else |
||||||
|
argname = arg.Attributes["name"].Value; |
||||||
|
|
||||||
|
XmlNode argt = find (xmldoc.DocumentElement, arg.Attributes["type"].Value); |
||||||
|
string argtype = argt.Attributes["name"].Value; |
||||||
|
str.Append (", " + argtype + " " + argname); |
||||||
|
c++; |
||||||
|
} |
||||||
|
|
||||||
|
str.AppendLine (");"); |
||||||
|
} |
||||||
|
|
||||||
|
Classes.Add (name, sanitize(name) + ".cs"); |
||||||
|
|
||||||
|
FileStream fs = File.Create (Path.Combine (Dir, Classes[name])); |
||||||
|
StreamWriter sw = new StreamWriter(fs); |
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder(); |
||||||
|
string strstruct = String.Format (templateStruct, name); |
||||||
|
string strinterface = String.Format (templateInterface, name, "", str.ToString()); |
||||||
|
sb.Append (string.Format (templateClass, |
||||||
|
"Qt.Core", |
||||||
|
name, |
||||||
|
"ICppObject", |
||||||
|
strinterface, |
||||||
|
strstruct, |
||||||
|
size)); |
||||||
|
sw.Write (sb.ToString()); |
||||||
|
sw.Flush (); |
||||||
|
sw.Close (); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static string sanitize (string name) |
||||||
|
{ |
||||||
|
return name.Replace ("<", "_").Replace (">", "_").Replace(":", "_").Replace("*", "_").Replace (",", "_").Replace(" ", "_"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
using System; |
||||||
|
using Mono.VisualC.Interop; |
||||||
|
|
||||||
|
namespace {0} {{ |
||||||
|
public class {1} : {2} {{ |
||||||
|
// interface |
||||||
|
{3} |
||||||
|
|
||||||
|
// struct |
||||||
|
{4} |
||||||
|
|
||||||
|
public {1} (IntPtr native) : base (native) |
||||||
|
{{ |
||||||
|
}} |
||||||
|
|
||||||
|
public override int NativeSize {{ |
||||||
|
get {{ return {5}; }} |
||||||
|
}} |
||||||
|
|
||||||
|
public override void Dispose () |
||||||
|
{{ |
||||||
|
throw new Exception ("This should never be called!"); |
||||||
|
}} |
||||||
|
}} |
||||||
|
}} |
||||||
|
|
||||||
|
|
@ -0,0 +1,3 @@ |
|||||||
|
public interface I{0} : ICppClassOverridable<{0}> {1} {{ |
||||||
|
{2} |
||||||
|
}} |
Loading…
Reference in new issue