protected string GetTypeMap(SpecField field) { if (field.MapType != null) { return(field.MapType); } string result = null; string type; if (!string.IsNullOrEmpty(field.Attribute)) { result += field.Attribute + " "; } if (string.Equals(field.Type.Name, "void", StringComparison.InvariantCultureIgnoreCase)) { type = "IntPtr"; result += "IntPtr"; } else { type = field.Type.FinalTypeName(); if (field.IsPointer && !(field.Attribute != null && (field.Attribute.Contains("out") || field.Attribute.Contains("ref")))) { type += "*"; } result += type; } return(result); }
protected string WriteParameter2(SpecField parameter) { string result = null; string type; if (!string.IsNullOrEmpty(parameter.Attribute)) { result += parameter.Attribute + " "; } if (string.Equals(parameter.Type.Name, "void", StringComparison.InvariantCultureIgnoreCase)) { type = "IntPtr"; result += "IntPtr"; } else { type = parameter.Type.FinalTypeName(); if (parameter.IsPointer && !(parameter.Attribute != null && (parameter.Attribute.Contains("out") || parameter.Attribute.Contains("ref")))) { type += "*"; } result += type; } result += " " + parameter.MapName; if (parameter.Optional) { result += " = default(" + type + ")"; } return(result); }
static void ParseCommand(XPathNavigator node) { var result = new SpecCommand(); result.Successcodes = node.GetAttribute("successcodes"); result.Errorcodes = node.GetAttribute("errorcodes"); var proto = node.SelectSingleNode("proto"); var rType = proto.SelectSingleNode("type"); result.Return = GetSpecType(rType.Value); result.ReturnIsPointer = proto.InnerXml.Contains("*"); result.Name = result.MapName = proto.SelectSingleNode("name").Value; commandMap.Add(result.Name, result); result.Parameters = new List <SpecField> (); foreach (XPathNavigator param in node.Select("param")) { var field = new SpecField(); //field.Optional = param.ReadAttribute<bool> ( "optional" ); XPathNavigator paramNode; paramNode = param.SelectSingleNode("type"); field.Type = GetSpecType(paramNode.Value); if (paramNode.MoveToNext(XPathNodeType.Text)) { field.IsPointer = paramNode.Value.Contains("*"); } paramNode = param.SelectSingleNode("name"); field.Name = field.MapName = paramNode.Value; result.Parameters.Add(field); } //foreach ( XmlNode param in node.SelectNodes ( "validity/usage" ) ) //{ // result.Summary += param.InnerText + "\n"; //} }
static void ParseStruct(Category category, XPathNavigator node) { var result = new SpecStruct { Union = category == Category.Union, ReadOnly = node.GetAttribute <bool> ("returnedonly") }; result.Name = result.MapName = node.GetAttribute("name"); GetSpecType(result.Name).TypeObject = result; structMap.Add(result.Name, result); foreach (XPathNavigator member in node.Select("member")) { SpecField field = new SpecField(); var comment = member.CreateNavigator(); if (comment.MoveToNext(XPathNodeType.Comment)) { field.Comment = comment.Value; } var memberNode = member.SelectSingleNode("type"); if (memberNode != null) { field.Type = GetSpecType(memberNode.Value); if (memberNode.MoveToNext(XPathNodeType.Text)) { field.IsPointer = memberNode.Value.Contains("*"); } } else { Console.WriteLine("Missing type? " + result.Name); } memberNode = member.SelectSingleNode("name"); if (memberNode != null) { field.Name = field.MapName = memberNode.Value; // check field size if (memberNode.MoveToNext(XPathNodeType.Text)) { var txt = memberNode.Value; var match = Regex.Match(txt, @"[(\d+)]", RegexOptions.CultureInvariant); if (match.Success) { field.FixedSize = int.Parse(match.Value, CultureInfo.InvariantCulture); result.HasFixedSizeField = true; } } } // check field enum const size memberNode = member.SelectSingleNode("enum"); if (memberNode != null) { var enumMem = enumMemberMap[memberNode.Value]; //var enumNode = member.OwnerDocument.SelectSingleNode ( "//enum[@name='" + memberNode.InnerText + "']" ); //field.FixedSize = enumNode.ReadAttribute<int> ( "value" ); field.FixedSize = int.Parse(enumMem.Value, CultureInfo.InvariantCulture); field.FixedSizeEnum = memberNode.Value; result.HasFixedSizeField = true; } field.Visibility = "public"; result.Members.Add(field); } }
static void Main(string[] args) { string input = "vk.xml"; string mapping = "mapping.xml"; string export = ""; string api = "vulkan"; string version = "1.0"; if (args.Length >= 4) { input = args[0]; mapping = args[1]; export = args[2]; api = args[3]; version = args[4]; } System.Diagnostics.Debugger.Launch(); var ser = new XmlSerializer(typeof(Mappings)); Mappings maps; using (var file = System.IO.File.OpenRead(mapping)) { maps = (Mappings)ser.Deserialize(file); } XPathDocument specDoc; var set = new XmlReaderSettings() { IgnoreWhitespace = true, IgnoreProcessingInstructions = true }; using (var reader = XmlReader.Create(input, set)) { specDoc = new XPathDocument(reader); } var root = specDoc.CreateNavigator(); foreach (XPathNavigator item in root.Select(@"//enums")) { ParseEnum(item); } foreach (XPathNavigator item in root.Select(@"//types/type")) { var category = item.GetAttribute <Category> ("category"); if (category == Category.Funcpointer) { ParseDelegate(item); } else if (category == Category.Struct || category == Category.Union) { ParseStruct(category, item); } else if (category != Category.Include && category != Category.Define) { ParseTypes(category, item); } } foreach (XPathNavigator item in root.Select(@"//commands/command")) { ParseCommand(item); } var featureNodes = root.Select(@"//feature[@api = '" + api + "' and @number <= '" + version + "']/*/*"); var extensionNodes = root.Select(@"//extensions/extension/*/*"); foreach (XPathNavigator node in extensionNodes) { var extension = node.CreateNavigator(); extension.MoveToParent(); extension.MoveToParent(); var exsupported = extension.GetAttribute("supported"); if (!Regex.IsMatch(api, "^(" + exsupported + ")$", RegexOptions.CultureInvariant)) { continue; } var exname = extension.GetAttribute("name"); var exnumber = extension.GetAttribute <int> ("number"); var spec = GetSpecExtension(exname); spec.Number = exnumber; if (node.Name == "enum") { var name = node.GetAttribute("name"); var extends = node.GetAttribute("extends"); var dir = node.GetAttribute("dir"); var offset = node.GetAttributeNullable <int> ("offset"); var value = node.GetAttribute("value"); var bitpos = node.GetAttributeNullable <int> ("bitpos"); var comment = node.GetAttribute("comment"); if (extends != null) { if (offset.HasValue) { var mem = GetSpecEnumMember(name); mem.Value = dir + ExtensionEnumOffset(exnumber, offset.Value); mem.Comment = comment; enumMap[extends].Members.Add(mem); } if (bitpos.HasValue) { var mem = GetSpecEnumMember(name); mem.BitPos = bitpos.Value; mem.Comment = comment; enumMap[extends].Members.Add(mem); } } if (value != null) { SpecEnumMember mem; if (enumMemberMap.TryGetValue(value, out mem)) { var field = new SpecField { Visibility = "public const", Name = name, MapName = name, MapType = "int", Value = mem.Value, }; spec.Members.Add(field); } else { var field = new SpecField { Visibility = "public const", Name = name, MapName = name, MapType = value.Contains("\"") ? "string" : "int", Value = value, }; spec.Members.Add(field); } } } if (node.Name == "command") { var name = node.GetAttribute("name"); spec.Commands.Add(commandMap[name]); } } foreach (var item in extensionMap.Values) { item.Commands.Sort((a, b) => string.Compare(a.Name, b.Name)); } foreach (var mapType in typeMap.Values) { foreach (var map in maps.Maps) { if (map.Type == null) { continue; } var match = Regex.Match(mapType.MapName, map.Type, RegexOptions.CultureInvariant); if (match.Success) { if (map.MapName != null) { if (map.MapName.Contains("$")) { mapType.MapName = match.Result(map.MapName); } else { mapType.MapName = map.MapName; } } if (map.MapType != null) { mapType.MapType = map.MapType; } mapType.TypeHandle |= map.TypeHandle; mapType.TypeHandle64 |= map.TypeHandle64; } } } #region Enum Mapping foreach (var item in enumMap.Values) { item.MapName = maps.MapNameMatches((a) => a.Enum, null, item.MapName); for (int i = 0; i < item.Members.Count; i++) { var member = item.Members[i]; member.MapName = maps.MapNameMatches((a) => a.EnumItem, item.Name, member.MapName); foreach (var membMap in maps.FindMatch((a) => a.Field, item.Name, member.Name)) { if (membMap.MapType != null) { member.MapType = membMap.MapType; } if (membMap.Visibility != null) { member.Visibility = membMap.Visibility; } } } } #endregion #region Command Mapping foreach (var item in commandMap.Values) { item.MapName = maps.MapNameMatches((a) => a.Command, null, item.MapName); for (int i = 0; i < item.Parameters.Count; i++) { var param = item.Parameters[i]; param.MapName = maps.MapNameMatches((a) => a.Param, item.Name, param.MapName); foreach (var membMap in maps.FindMatch((a) => a.Param, item.Name, param.Name)) { if (membMap.MapType != null) { param.MapType = membMap.MapType; } if (membMap.Attribute != null) { param.Attribute = membMap.Attribute; } param.Optional |= membMap.Optional; } } } #endregion #region Delegate Mapping foreach (var item in delegateMap.Values) { item.MapName = maps.MapNameMatches((a) => a.Command, null, item.MapName); for (int i = 0; i < item.Parameters.Count; i++) { var param = item.Parameters[i]; param.MapName = maps.MapNameMatches((a) => a.Param, item.Name, param.MapName); foreach (var membMap in maps.FindMatch((a) => a.Param, item.Name, param.Name)) { if (membMap.MapType != null) { param.MapType = membMap.MapType; } if (membMap.Attribute != null) { param.Attribute = membMap.Attribute; } param.Optional |= membMap.Optional; } } } #endregion #region Struct Mapping foreach (var item in structMap.Values) { item.MapName = maps.MapNameMatches((a) => a.Struct, null, item.MapName); for (int i = 0; i < item.Members.Count; i++) { var member = item.Members[i]; member.MapName = maps.MapNameMatches((a) => a.Field, item.Name, member.MapName); foreach (var membMap in maps.FindMatch((a) => a.Field, item.Name, member.Name)) { if (membMap.MapType != null) { member.MapType = membMap.MapType; } if (membMap.FixedSize != 0) { member.FixedSize = membMap.FixedSize; member.FixedSizeEnum = null; } } } } #endregion foreach (var item in extensionMap.Values) { item.MapName = maps.MapNameMatches((a) => a.Extension, null, item.MapName); foreach (var member in item.Members) { member.MapName = maps.MapNameMatches((a) => a.Field, item.Name, member.MapName); } } foreach (var mapType in typeMap.Values) { var maptype = mapType.FindType(); if (maptype == null && mapType.TypeObject == null) { Console.WriteLine("Missing type mapping {0}", mapType.Name); } foreach (var map in mapType.IteratorParents()) { if (map.TypeHandle || map.TypeHandle64) { var spec = new SpecStruct() { Name = mapType.Name, MapName = mapType.MapName, TypeHandle = map.TypeHandle, TypeHandle64 = map.TypeHandle64 }; structMap.Add(mapType.Name, spec); break; } } } if (!string.IsNullOrWhiteSpace(export) && !Directory.Exists(export)) { Directory.CreateDirectory(export); } string text; CodeGenerator gen; var tmp = new ClassTemplate() { Namespace = "Crow.Graphics.Vulkan", Accessor = null }; //tmp.Objects.AddRange ( structMap.Values.OrderBy ( (a) => a.MapName ) ); //tmp.Objects.AddRange ( enumMap.Values.OrderBy ( (a) => a.MapName ) ); //tmp.Objects.AddRange ( delegateMap.Values.OrderBy ( (a) => a.MapName ) ); //tmp.Objects.AddRange ( extensionMap.Values.OrderBy ( (a) => a.MapName ) ); //Enumerations.cs tmp.Objects.AddRange(enumMap.Values.OrderBy((a) => a.MapName)); gen = new CodeGenerator(); gen.Classes.Add(tmp); text = gen.TransformText(); System.IO.File.WriteAllText(Path.Combine(export, "Enumerations.cs"), text); tmp.Objects.Clear(); //Structures.cs tmp.Objects.AddRange(structMap.Values.OrderBy((a) => a.MapName)); gen = new CodeGenerator(); gen.Classes.Add(tmp); text = gen.TransformText(); System.IO.File.WriteAllText(Path.Combine(export, "Structures.cs"), text); tmp.Objects.Clear(); //Delegates.cs tmp.Objects.AddRange(delegateMap.Values.OrderBy((a) => a.MapName)); gen = new CodeGenerator(); gen.Classes.Add(tmp); text = gen.TransformText(); System.IO.File.WriteAllText(Path.Combine(export, "Delegates.cs"), text); tmp.Objects.Clear(); //Functions.cs tmp.Objects.AddRange(extensionMap.Values.OrderBy((a) => a.MapName)); var dic = new Dictionary <string, ClassTemplate> (); foreach (XPathNavigator item in featureNodes) { var feature = item.CreateNavigator(); feature.MoveToParent(); feature.MoveToParent(); var feaName = feature.GetAttribute("name"); string className = null; string fileNamespace = null; string file = null; foreach (var map in maps.FindMatch((a) => a.Feature, null, feaName)) { className = map.MapName ?? className; fileNamespace = map.Namespace ?? fileNamespace; file = map.File ?? file; } ClassTemplate classTemp; if (!dic.TryGetValue(file, out classTemp)) { classTemp = new ClassTemplate(); dic.Add(file, classTemp); } classTemp.Namespace = fileNamespace; classTemp.Name = className; if (item.Name == "command") { var name = item.GetAttribute("name"); classTemp.Objects.Add(commandMap[name]); } } foreach (var item in dic.Values) { item.Objects.Sort((a, b) => string.Compare(((SpecCommand)a).MapName, ((SpecCommand)b).MapName)); } tmp.NestedClass.AddRange(dic.Values); gen = new CodeGenerator(); gen.Classes.Add(tmp); text = gen.TransformText(); System.IO.File.WriteAllText(Path.Combine(export, "Functions.cs"), text); //tmp.Objects.Clear (); Console.WriteLine("done"); //Console.ReadKey (); }