// Merges the specified delegate collections. internal static void Merge(DelegateCollection delegates, DelegateCollection new_delegates) { foreach (var d in new_delegates) { Merge(delegates, d.Value); } }
FunctionCollection CreateWrappers(DelegateCollection delegates, EnumCollection enums) { var wrappers = new FunctionCollection(); foreach (var d in delegates.Values.SelectMany(v => v)) { wrappers.AddRange(CreateNormalWrappers(d, enums)); } if ((Settings.Compatibility & Settings.Legacy.KeepUntypedEnums) != 0) { // Generate an "All" overload for every function that takes strongly-typed enums var overloads = new List <Function>(); foreach (var list in wrappers.Values) { overloads.AddRange(list.Where(f => f.Parameters.Any(p => p.IsEnum)).Select(f => { var fnew = new Function(f); fnew.Obsolete = "Use strongly-typed overload instead"; // Note that we can only overload parameters, not the return type foreach (var p in fnew.Parameters) { if (p.IsEnum) { p.CurrentType = Settings.CompleteEnumName; } } return(fnew); })); } wrappers.AddRange(overloads); } return(wrappers); }
public Generator(Settings settings, string dirName) { if (settings == null) throw new ArgumentNullException("settings"); if (dirName == null) dirName = "GL2"; Settings = settings.Clone(); glTypemap = "GL2/gl.tm"; csTypemap = Settings.LanguageTypeMapFile; enumSpec = Path.Combine(dirName, "signatures.xml"); enumSpecExt = String.Empty; glSpec = Path.Combine(dirName, "signatures.xml"); glSpecExt = String.Empty; Settings.OverridesFile = Path.Combine(dirName, "overrides.xml"); Settings.ImportsClass = "Core"; Settings.DelegatesClass = "Delegates"; Settings.OutputClass = "GL"; Delegates = new DelegateCollection(); Enums = new EnumCollection(); Wrappers = new FunctionCollection(); SpecReader = new XmlSpecReader(Settings); }
public virtual void WriteImports(BindStreamWriter sw, DelegateCollection delegates) { Trace.WriteLine(String.Format("Writing imports to:\t{0}.{1}.{2}", Settings.OutputNamespace, Settings.OutputClass, Settings.ImportsClass)); sw.WriteLine("#pragma warning disable 3019"); // CLSCompliant attribute sw.WriteLine("#pragma warning disable 1591"); // Missing doc comments sw.WriteLine(); sw.WriteLine("partial class {0}", Settings.OutputClass); sw.WriteLine("{"); sw.Indent(); sw.WriteLine(); sw.WriteLine("internal static partial class {0}", Settings.ImportsClass); sw.WriteLine("{"); sw.Indent(); //sw.WriteLine("static {0}() {1} {2}", Settings.ImportsClass, "{", "}"); // Disable BeforeFieldInit sw.WriteLine(); foreach (Delegate d in delegates.Values) { sw.WriteLine("[System.Security.SuppressUnmanagedCodeSecurity()]"); sw.WriteLine( "[System.Runtime.InteropServices.DllImport({0}.Library, EntryPoint = \"{1}{2}\"{3})]", Settings.OutputClass, Settings.FunctionPrefix, d.Name, d.Name.EndsWith("W") || d.Name.EndsWith("A") ? ", CharSet = CharSet.Auto" : ", ExactSpelling = true" ); sw.WriteLine("internal extern static {0};", d.DeclarationString()); } sw.Unindent(); sw.WriteLine("}"); sw.Unindent(); sw.WriteLine("}"); }
public virtual void WriteDelegates(BindStreamWriter sw, DelegateCollection delegates) { Trace.WriteLine(String.Format("Writing delegates to:\t{0}.{1}.{2}", Settings.OutputNamespace, Settings.OutputClass, Settings.DelegatesClass)); sw.WriteLine(); sw.WriteLine("partial class {0}", Settings.OutputClass); sw.WriteLine("{"); sw.Indent(); sw.WriteLine("internal static partial class {0}", Settings.DelegatesClass); sw.WriteLine("{"); sw.Indent(); foreach (Bind.Structures.Delegate d in delegates.Values) { sw.WriteLine("[System.Security.SuppressUnmanagedCodeSecurity()]"); sw.WriteLine("internal {0};", d.ToString()); sw.WriteLine("internal {0}static {1} {2}{1};", // = null d.Unsafe ? "unsafe " : "", d.Name, Settings.FunctionPrefix); } sw.Unindent(); sw.WriteLine("}"); sw.Unindent(); sw.WriteLine("}"); }
public FunctionCollection Process(DelegateCollection delegates, EnumCollection enums) { Console.WriteLine("Processing delegates."); var nav = new XPathDocument(Overrides).CreateNavigator(); foreach (var d in delegates.Values) { var function_override = GetFuncOverride(nav, d); if (function_override != null) { string obsolete = function_override.GetAttribute("obsolete", ""); if (!string.IsNullOrEmpty(obsolete)) { d.Obsolete = obsolete; } } TranslateReturnType(nav, d, enums); TranslateParameters(nav, d, enums); } Console.WriteLine("Generating wrappers."); var wrappers = CreateWrappers(delegates, enums); Console.WriteLine("Creating CLS compliant overloads."); wrappers = CreateCLSCompliantWrappers(wrappers, enums); Console.WriteLine("Removing non-CLS compliant duplicates."); return(MarkCLSCompliance(wrappers)); }
public void ReadDelegates(string file, DelegateCollection delegates, string apiname, string apiversions) { var specs = new XPathDocument(file); // The pre-GL4.4 spec format does not distinguish between // different apinames (it is assumed that different APIs // are stored in distinct signature.xml files). // To maintain compatibility, we detect the version of the // signatures.xml file and ignore apiname if it is version 1. var specversion = GetSpecVersion(specs); if (specversion == "1") { apiname = null; } foreach (var apiversion in apiversions.Split('|')) { string xpath_add, xpath_delete; GetSignaturePaths(apiname, apiversion, out xpath_add, out xpath_delete); foreach (XPathNavigator nav in specs.CreateNavigator().Select(xpath_delete)) { foreach (XPathNavigator node in nav.SelectChildren("function", String.Empty)) delegates.Remove(node.GetAttribute("name", String.Empty)); } foreach (XPathNavigator nav in specs.CreateNavigator().Select(xpath_add)) { delegates.AddRange(ReadDelegates(nav, apiversion)); } } }
void WriteBindings(DelegateCollection delegates, FunctionCollection wrappers, EnumCollection enums) { Console.WriteLine("Writing bindings to {0}", Settings.OutputPath); if (!Directory.Exists(Settings.OutputPath)) { Directory.CreateDirectory(Settings.OutputPath); } // Hack: Fix 3dfx extension category so it doesn't start with a digit if (wrappers.ContainsKey("3dfx")) { var three_dee_fx = wrappers["3dfx"]; wrappers.Remove("3dfx"); wrappers.Add(DigitPrefix + "3dfx", three_dee_fx); } using (var sw = sw_h) { WriteLicense(sw); sw.WriteLine("package {0}.{1};", Settings.OutputNamespace, Settings.GLClass); sw.WriteLine(); sw.WriteLine("import java.nio.*;"); sw.WriteLine(); WriteDefinitions(sw, enums, wrappers, Generator.CSTypes); sw.Flush(); sw.Close(); } string output_header = Path.Combine(Settings.OutputPath, OutputFileHeader); Move(sw_h.File, output_header); }
void WriteBindings(DelegateCollection delegates, FunctionCollection wrappers, EnumCollection enums) { Console.WriteLine("Writing bindings to {0}", Settings.OutputPath); if (!Directory.Exists(Settings.OutputPath)) Directory.CreateDirectory(Settings.OutputPath); // Hack: Fix 3dfx extension category so it doesn't start with a digit if (wrappers.ContainsKey("3dfx")) { var three_dee_fx = wrappers["3dfx"]; wrappers.Remove("3dfx"); wrappers.Add(DigitPrefix + "3dfx", three_dee_fx); } using (var sw = sw_h) { WriteLicense(sw); sw.WriteLine("package {0}.{1};", Settings.OutputNamespace, Settings.GLClass); sw.WriteLine(); sw.WriteLine("import java.nio.*;"); sw.WriteLine(); WriteDefinitions(sw, enums, wrappers, Type.CSTypes); sw.Flush(); sw.Close(); } string output_header = Path.Combine(Settings.OutputPath, OutputFileHeader); Move(sw_h.File, output_header); }
public Generator(Settings settings) { if (settings == null) { throw new ArgumentNullException("settings"); } Settings = settings.Clone(); glTypemap = "GL2/gl.tm"; csTypemap = Settings.LanguageTypeMapFile; enumSpec = Path.Combine("GL2", "signatures.xml"); enumSpecExt = String.Empty; glSpec = Path.Combine("GL2", "signatures.xml"); glSpecExt = String.Empty; Settings.ImportsClass = "Core"; Settings.DelegatesClass = "Delegates"; Settings.OutputClass = "GL"; Delegates = new DelegateCollection(); Enums = new EnumCollection(); Wrappers = new FunctionCollection(); SpecReader = new XmlSpecReader(Settings); }
private DelegateCollection ReadDelegates(XPathNavigator specs) { DelegateCollection delegates = new DelegateCollection(); foreach (XPathNavigator node in specs.SelectChildren("function", String.Empty)) { var name = node.GetAttribute("name", String.Empty); // Check whether we are adding to an existing delegate or creating a new one. Delegate d = null; if (delegates.ContainsKey(name)) { d = delegates[name]; } else { d = new Delegate(); d.Name = name; d.Version = node.GetAttribute("version", String.Empty); d.Category = node.GetAttribute("category", String.Empty); d.DeprecatedVersion = node.GetAttribute("deprecated", String.Empty); d.Deprecated = !String.IsNullOrEmpty(d.DeprecatedVersion); d.Obsolete = node.GetAttribute("obsolete", String.Empty); } foreach (XPathNavigator param in node.SelectChildren(XPathNodeType.Element)) { switch (param.Name) { case "returns": d.ReturnType.CurrentType = param.GetAttribute("type", String.Empty); break; case "param": Parameter p = new Parameter(); p.CurrentType = param.GetAttribute("type", String.Empty); p.Name = param.GetAttribute("name", String.Empty); string element_count = param.GetAttribute("elementcount", String.Empty); if (String.IsNullOrEmpty(element_count)) { element_count = param.GetAttribute("count", String.Empty); } if (!String.IsNullOrEmpty(element_count)) { p.ElementCount = Int32.Parse(element_count); } p.Flow = Parameter.GetFlowDirection(param.GetAttribute("flow", String.Empty)); d.Parameters.Add(p); break; } } delegates.Add(d); } return(delegates); }
public void ReadDelegates(string file, DelegateCollection delegates, string apiname, string apiversions) { var specs = new XPathDocument(file); // The pre-GL4.4 spec format does not distinguish between // different apinames (it is assumed that different APIs // are stored in distinct signature.xml files). // To maintain compatibility, we detect the version of the // signatures.xml file and ignore apiname if it is version 1. var specversion = GetSpecVersion(specs); if (specversion == "1") { apiname = null; } foreach (var apiversion in apiversions.Split('|')) { string xpath_add, xpath_delete; GetSignaturePaths(apiname, apiversion, out xpath_add, out xpath_delete); foreach (XPathNavigator nav in specs.CreateNavigator().Select(xpath_delete)) { foreach (XPathNavigator node in nav.SelectChildren("function", String.Empty)) { delegates.Remove(node.GetAttribute("name", String.Empty)); } } foreach (XPathNavigator nav in specs.CreateNavigator().Select(xpath_add)) { delegates.AddRange(ReadDelegates(nav, apiversion)); } } }
public virtual void WriteDelegates(BindStreamWriter sw, DelegateCollection delegates) { Trace.WriteLine(String.Format("Writing delegates to:\t{0}.{1}.{2}", Settings.OutputNamespace, Settings.OutputClass, Settings.DelegatesClass)); sw.WriteLine("#pragma warning disable 3019"); // CLSCompliant attribute sw.WriteLine("#pragma warning disable 1591"); // Missing doc comments sw.WriteLine(); #if !IPHONE sw.WriteLine("partial class {0}", Settings.OutputClass); sw.WriteLine("{"); sw.Indent(); sw.WriteLine("internal static partial class {0}", Settings.DelegatesClass); sw.WriteLine("{"); sw.Indent(); foreach (Delegate d in delegates.Values) { sw.WriteLine("[System.Security.SuppressUnmanagedCodeSecurity()]"); sw.WriteLine("internal {0};", d.ToString()); sw.WriteLine("internal {0}static {1} {2}{1};", // = null d.Unsafe ? "unsafe " : "", d.Name, Settings.FunctionPrefix); } sw.Unindent(); sw.WriteLine("}"); sw.Unindent(); sw.WriteLine("}"); #endif }
public FunctionCollection Process(DelegateCollection delegates, EnumCollection enums) { Console.WriteLine("Processing delegates."); var nav = new XPathDocument(Overrides).CreateNavigator(); foreach (var d in delegates.Values) { var function_override = GetFuncOverride(nav, d); if (function_override != null) { string obsolete = function_override.GetAttribute ("obsolete", ""); if (!string.IsNullOrEmpty (obsolete)) d.Obsolete = obsolete; } TranslateReturnType(nav, d, enums); TranslateParameters(nav, d, enums); } Console.WriteLine("Generating wrappers."); var wrappers = CreateWrappers(delegates, enums); Console.WriteLine("Creating CLS compliant overloads."); wrappers = CreateCLSCompliantWrappers(wrappers, enums); Console.WriteLine("Removing non-CLS compliant duplicates."); return MarkCLSCompliance(wrappers); }
/// <summary> /// Merges the given enum into the enum list. If an enum of the same name exists, /// it merges their respective constants. /// </summary> /// <param name="enums"></param> /// <param name="t"></param> internal static void Merge(DelegateCollection delegates, Delegate t) { if (!delegates.ContainsKey(t.Name)) { delegates.Add(t.Name, t); } }
// When we have a list of overloaded delegates, make sure that // all generated wrappers use the first (original) delegate, not // the overloaded ones. This allows us to reduce the amount // of delegates we need to generate (1 per entry point instead // of 1 per overload), which improves loading times. static void RemoveOverloadedDelegates(DelegateCollection delegates, FunctionCollection wrappers) { foreach (var w in wrappers.Values.SelectMany(w => w)) { var d = delegates[w.Name].First(); w.WrappedDelegate = d; } }
public FunctionCollection Process(EnumProcessor enum_processor, DelegateCollection delegates, EnumCollection enums, string apiname, string apiversion) { Console.WriteLine("Processing delegates."); var nav = new XPathDocument(Overrides).CreateNavigator(); foreach (var version in apiversion.Split('|')) { // Translate each delegate: // 1st using the <replace> elements in overrides.xml // 2nd using the hardcoded rules in FuncProcessor (e.g. char* -> string) foreach (var signatures in delegates.Values) { foreach (var d in signatures) { TranslateExtension(d); TranslateReturnType(enum_processor, nav, d, enums, apiname, version); TranslateParameters(enum_processor, nav, d, enums, apiname, version); TranslateAttributes(nav, d, enums, apiname, version); } } // Create overloads for backwards compatibility, // by resolving <overload> elements var overload_list = new List<Delegate>(); foreach (var d in delegates.Values.Select(v => v.First())) { var overload_element = GetFuncOverload(nav, d, apiname, apiversion); if (overload_element != null) { var overload = new Delegate(d); ApplyParameterReplacement(overload, overload_element); ApplyReturnTypeReplacement(overload, overload_element); overload_list.Add(overload); } } foreach (var overload in overload_list) { delegates.Add(overload); } } Console.WriteLine("Generating convenience overloads."); delegates.AddRange(CreateConvenienceOverloads(delegates)); Console.WriteLine("Generating wrappers."); var wrappers = CreateWrappers(delegates, enums); Console.WriteLine("Generating CLS compliant overloads."); wrappers = CreateCLSCompliantWrappers(wrappers, enums); Console.WriteLine("Removing non-CLS compliant duplicates."); wrappers = MarkCLSCompliance(wrappers); Console.WriteLine("Removing overloaded delegates."); RemoveOverloadedDelegates(delegates, wrappers); return wrappers; }
void WriteBindings(DelegateCollection delegates, FunctionCollection wrappers, EnumCollection enums) { Console.WriteLine("Writing bindings to {0}", Settings.OutputPath); if (!Directory.Exists(Settings.OutputPath)) Directory.CreateDirectory(Settings.OutputPath); // Hack: Fix 3dfx extension category so it doesn't start with a digit if (wrappers.ContainsKey("3dfx")) { var three_dee_fx = wrappers["3dfx"]; wrappers.Remove("3dfx"); wrappers.Add(DigitPrefix + "3dfx", three_dee_fx); } Settings.DefaultOutputNamespace = "OpenTK"; // Enums using (var sw = sw_h_enums) { WriteEnums(sw, enums); sw.Flush(); sw.Close(); } // Core definitions using (var sw = sw_h) { WriteDefinitions(sw, enums, wrappers, Type.CSTypes, false); sw.Flush(); sw.Close(); } // Compatibility definitions using (var sw = sw_h_compat) { WriteDefinitions(sw, enums, wrappers, Type.CSTypes, true); sw.Flush(); sw.Close(); } // Core & compatibility declarations using (var sw = sw_cpp) { WriteDeclarations(sw, wrappers, Type.CSTypes); sw.Flush(); sw.Close(); } string output_header = Path.Combine(Settings.OutputPath, OutputFileHeader); string output_cpp = Path.Combine(Settings.OutputPath, OutputFileCpp); string output_header_compat = Path.Combine(Settings.OutputPath, OutputFileHeaderCompat); string output_header_enums = Path.Combine(Settings.OutputPath, OutputFileHeaderEnums); Move(sw_h.File, output_header); Move(sw_cpp.File, output_cpp); Move(sw_h_compat.File, output_header_compat); Move(sw_h_enums.File, output_header_enums); }
private DelegateCollection ReadDelegates(XPathNavigator specs) { DelegateCollection delegates = new DelegateCollection(); foreach (XPathNavigator node in specs.SelectChildren("function", String.Empty)) { var name = node.GetAttribute("name", String.Empty); // Check whether we are adding to an existing delegate or creating a new one. Delegate d = null; if (delegates.ContainsKey(name)) { d = delegates[name]; } else { d = new Delegate(); d.Name = name; d.Version = node.GetAttribute("version", String.Empty); d.Category = node.GetAttribute("category", String.Empty); d.DeprecatedVersion = node.GetAttribute("deprecated", String.Empty); d.Deprecated = !String.IsNullOrEmpty(d.DeprecatedVersion); d.Obsolete = node.GetAttribute("obsolete", String.Empty); } foreach (XPathNavigator param in node.SelectChildren(XPathNodeType.Element)) { switch (param.Name) { case "returns": d.ReturnType.CurrentType = param.GetAttribute("type", String.Empty); break; case "param": Parameter p = new Parameter(); p.CurrentType = param.GetAttribute("type", String.Empty); p.Name = param.GetAttribute("name", String.Empty); string element_count = param.GetAttribute("elementcount", String.Empty); if (String.IsNullOrEmpty(element_count)) element_count = param.GetAttribute("count", String.Empty); if (!String.IsNullOrEmpty(element_count)) p.ElementCount = Int32.Parse(element_count); p.Flow = Parameter.GetFlowDirection(param.GetAttribute("flow", String.Empty)); d.Parameters.Add(p); break; } } delegates.Add(d); } return delegates; }
static FunctionCollection CreateWrappers(DelegateCollection delegates, EnumCollection enums) { var wrappers = new FunctionCollection(); foreach (var d in delegates.Values) { wrappers.AddRange(CreateNormalWrappers(d, enums)); } return(wrappers); }
public override DelegateCollection ReadDelegates(StreamReader specFile) { DelegateCollection delegates = new DelegateCollection(); XPathDocument specs = new XPathDocument(specFile); XPathDocument overrides = new XPathDocument(new StreamReader(Path.Combine(Settings.InputPath, functionOverridesFile))); foreach (XPathNavigator nav in new XPathNavigator[] { specs.CreateNavigator().SelectSingleNode("/signatures"), overrides.CreateNavigator().SelectSingleNode("/overrides/add") }) { if (nav != null) { foreach (XPathNavigator node in nav.SelectChildren("function", String.Empty)) { Delegate d = new Delegate(); d.Name = node.GetAttribute("name", String.Empty); //d.Extension = node.GetAttribute("extension"); d.Version = node.GetAttribute("version", String.Empty); d.Category = node.GetAttribute("category", String.Empty); foreach (XPathNavigator param in node.SelectChildren(XPathNodeType.Element)) { switch (param.Name) { case "returns": d.ReturnType.CurrentType = param.GetAttribute("type", String.Empty); break; case "param": Parameter p = new Parameter(); p.CurrentType = param.GetAttribute("type", String.Empty); p.Name = param.GetAttribute("name", String.Empty); string element_count = param.GetAttribute("elementcount", String.Empty); if (!String.IsNullOrEmpty(element_count)) { p.ElementCount = Int32.Parse(element_count); } p.Flow = Parameter.GetFlowDirection(param.GetAttribute("flow", String.Empty)); d.Parameters.Add(p); break; } } d.Translate(overrides); delegates.Add(d); } } } return(delegates); }
public void ReadDelegates(string file, DelegateCollection delegates) { var specs = new XPathDocument(file); foreach (XPathNavigator nav in specs.CreateNavigator().Select("/signatures/delete")) { foreach (XPathNavigator node in nav.SelectChildren("function", String.Empty)) delegates.Remove(node.GetAttribute("name", String.Empty)); } foreach (XPathNavigator nav in specs.CreateNavigator().Select("/signatures/add")) { Utilities.Merge(delegates, ReadDelegates(nav)); } }
public override DelegateCollection ReadDelegates(StreamReader specFile) { DelegateCollection delegates = new DelegateCollection(); XPathDocument specs = new XPathDocument(specFile); XPathDocument overrides = new XPathDocument(new StreamReader(Path.Combine(Settings.InputPath, functionOverridesFile))); foreach (XPathNavigator nav in new XPathNavigator[] { specs.CreateNavigator().SelectSingleNode("/signatures"), overrides.CreateNavigator().SelectSingleNode("/overrides/add") }) { if (nav != null) { foreach (XPathNavigator node in nav.SelectChildren("function", String.Empty)) { Delegate d = new Delegate(); d.Name = node.GetAttribute("name", String.Empty); //d.Extension = node.GetAttribute("extension"); d.Version = node.GetAttribute("version", String.Empty); d.Category = node.GetAttribute("category", String.Empty); foreach (XPathNavigator param in node.SelectChildren(XPathNodeType.Element)) { switch (param.Name) { case "returns": d.ReturnType.CurrentType = param.GetAttribute("type", String.Empty); break; case "param": Parameter p = new Parameter(); p.CurrentType = param.GetAttribute("type", String.Empty); p.Name = param.GetAttribute("name", String.Empty); string element_count = param.GetAttribute("elementcount", String.Empty); if (!String.IsNullOrEmpty(element_count)) p.ElementCount = Int32.Parse(element_count); p.Flow = Parameter.GetFlowDirection(param.GetAttribute("flow", String.Empty)); d.Parameters.Add(p); break; } } d.Translate(overrides); delegates.Add(d); } } } return delegates; }
void WriteBindings(DelegateCollection delegates, FunctionCollection wrappers, EnumCollection enums) { Console.WriteLine("Writing bindings to {0}", Settings.OutputPath); if (!Directory.Exists(Settings.OutputPath)) { Directory.CreateDirectory(Settings.OutputPath); } // Hack: Fix 3dfx extension category so it doesn't start with a digit if (wrappers.ContainsKey("3dfx")) { var three_dee_fx = wrappers["3dfx"]; wrappers.Remove("3dfx"); wrappers.Add(DigitPrefix + "3dfx", three_dee_fx); } Settings.DefaultOutputNamespace = "OpenTK"; using (var sw = sw_h) { sw.WriteLine("#pragma once"); sw.WriteLine("#ifndef GLPP_H"); sw.WriteLine("#define GLPP_H"); sw.WriteLine(); WriteLicense(sw); sw.WriteLine("namespace {0}", Settings.OutputNamespace); sw.WriteLine("{"); sw.Indent(); WriteGetAddress(sw); WriteTypes(sw); WriteEnums(sw, enums); WriteDefinitions(sw, enums, wrappers, Generator.CSTypes); // Core definitions sw.Unindent(); sw.WriteLine("}"); sw.WriteLine("#endif"); sw.Flush(); sw.Close(); } string output_header = Path.Combine(Settings.OutputPath, OutputFileHeader); Move(sw_h.File, output_header); }
public Generator(Settings settings, string dirName) { if (settings == null) { throw new ArgumentNullException("settings"); } if (dirName == null) { dirName = "GL2"; } Settings = settings.Clone(); glTypemap = "GL2/gl.tm"; csTypemap = Settings.LanguageTypeMapFile; enumSpec = Path.Combine(dirName, "signatures.xml"); enumSpecExt = String.Empty; glSpec = Path.Combine(dirName, "signatures.xml"); glSpecExt = String.Empty; Settings.OverridesFile = Path.Combine(dirName, "overrides.xml"); Settings.ImportsClass = "Core"; Settings.DelegatesClass = "Delegates"; Settings.OutputClass = "GL"; if (Settings.Compatibility == Settings.Legacy.Tao) { Settings.OutputNamespace = "Tao.OpenGl"; Settings.OutputClass = "Gl"; } else { // Defaults } Settings.DefaultOutputNamespace = "OpenTK.Graphics.OpenGL"; Settings.DefaultImportsFile = "GLCore.cs"; Settings.DefaultDelegatesFile = "GLDelegates.cs"; Settings.DefaultEnumsFile = "GLEnums.cs"; Settings.DefaultWrappersFile = "GL.cs"; Delegates = new DelegateCollection(); Enums = new EnumCollection(); Wrappers = new FunctionCollection(); SpecReader = new XmlSpecReader(Settings); }
public virtual void WriteDelegates(BindStreamWriter sw, DelegateCollection delegates) { Trace.WriteLine(String.Format("Writing delegates to:\t{0}.{1}.{2}", Settings.OutputNamespace, Settings.OutputClass, Settings.DelegatesClass)); sw.WriteLine("#pragma warning disable 3019"); // CLSCompliant attribute sw.WriteLine("#pragma warning disable 1591"); // Missing doc comments sw.WriteLine(); sw.WriteLine("public partial class {0}", Settings.OutputClass); sw.WriteLine("{"); sw.Indent(); sw.WriteLine("public static unsafe partial class {0}", Settings.DelegatesClass); sw.WriteLine("{"); sw.Indent(); // Chela doesn't support P/Invoke style marshalling, so use function pointers. foreach (Delegate d in delegates.Values) { sw.WriteLine("public {0};", d.ToFunctionPointer()); sw.WriteLine("public unsafe static {0} {1}{0};", // = null d.Name, Settings.FunctionPrefix); } // Write load entry points. sw.WriteLine(); sw.WriteLine("public unsafe static void LoadEntryPoints()"); sw.WriteLine("{"); sw.Indent(); foreach (Delegate d in delegates.Values) { sw.WriteLine("{1}{0} = ({0}) GetEntryPoint(c\"{1}{0}\");", d.Name, Settings.FunctionPrefix); } sw.Unindent(); sw.WriteLine("}"); // Finish delegates. sw.Unindent(); sw.WriteLine("}"); sw.Unindent(); sw.WriteLine("}"); }
public void ReadDelegates(string file, DelegateCollection delegates) { var specs = new XPathDocument(file); foreach (XPathNavigator nav in specs.CreateNavigator().Select("/signatures/delete")) { foreach (XPathNavigator node in nav.SelectChildren("function", String.Empty)) { delegates.Remove(node.GetAttribute("name", String.Empty)); } } foreach (XPathNavigator nav in specs.CreateNavigator().Select("/signatures/add")) { Utilities.Merge(delegates, ReadDelegates(nav)); } }
public FunctionCollection Process(DelegateCollection delegates, EnumCollection enums) { Console.WriteLine("Processing delegates."); var nav = new XPathDocument(Overrides).CreateNavigator(); foreach (var d in delegates.Values) { TranslateReturnType(nav, d, enums); TranslateParameters(nav, d, enums); } Console.WriteLine("Generating wrappers."); var wrappers = CreateWrappers(delegates, enums); Console.WriteLine("Creating CLS compliant overloads."); wrappers = CreateCLSCompliantWrappers(wrappers, enums); Console.WriteLine("Removing non-CLS compliant duplicates."); return MarkCLSCompliance(wrappers); }
public FunctionCollection Process(DelegateCollection delegates, EnumCollection enums) { Console.WriteLine("Processing delegates."); var nav = new XPathDocument(Overrides).CreateNavigator(); foreach (var d in delegates.Values) { TranslateReturnType(nav, d, enums); TranslateParameters(nav, d, enums); } Console.WriteLine("Generating wrappers."); var wrappers = CreateWrappers(delegates, enums); Console.WriteLine("Creating CLS compliant overloads."); wrappers = CreateCLSCompliantWrappers(wrappers, enums); Console.WriteLine("Removing non-CLS compliant duplicates."); return(MarkCLSCompliance(wrappers)); }
IEnumerable <Delegate> CreateConvenienceOverloads(DelegateCollection delegates) { foreach (var list in delegates.Values) { var d = list.First(); if (d.Parameters.Count > 0 && d.Parameters.Count <= 2) { var p = d.Parameters.Last(); var r = d.ReturnType; var name = GetTrimmedName(d); bool is_candidate = true; is_candidate &= name.StartsWith("Get") || name.StartsWith("Gen") || name.StartsWith("Delete") || name.StartsWith("New"); is_candidate &= p.Pointer > 0; // if there is a specific count set, such as "4", then this function // returns a vector of specific dimensions and it would be wrong // to generate an overload that returns a value of different size. is_candidate &= p.ElementCount == 0 || p.ElementCount == 1; is_candidate &= r.CurrentType == "void" && r.Pointer == 0; if (is_candidate && p.Flow == FlowDirection.Out) { // Match Gen*|Get*|New*([Out] int[] names) methods var f = CreateReturnTypeConvenienceWrapper(d); yield return(f); } else if (is_candidate && p.Flow != FlowDirection.Out) { // Match *Delete(int count, int[] names) methods if (d.Parameters.Count == 2) { var f = CreateArrayReturnTypeConvencienceWrapper(d); yield return(f); } } } } }
public Generator() { if (Settings.Compatibility == Settings.Legacy.Tao) { Settings.OutputNamespace = "Tao.OpenGl"; Settings.OutputClass = "Gl"; } else { // Defaults } Settings.ImportsFile = "GLCore.cs"; Settings.DelegatesFile = "GLDelegates.cs"; Settings.EnumsFile = "GLEnums.cs"; Settings.WrappersFile = "GL.cs"; Delegates = new DelegateCollection(); Enums = new EnumCollection(); Wrappers = new FunctionCollection(); }
void WriteDelegates(BindStreamWriter sw, DelegateCollection delegates) { Trace.WriteLine(String.Format("Writing delegates to:\t{0}.{1}.{2}", Settings.OutputNamespace, Settings.OutputClass, Settings.DelegatesClass)); sw.WriteLine("#pragma warning disable 3019"); // CLSCompliant attribute sw.WriteLine("#pragma warning disable 1591"); // Missing doc comments sw.WriteLine(); sw.WriteLine("partial class {0}", Settings.OutputClass); sw.WriteLine("{"); sw.Indent(); sw.WriteLine("internal static partial class {0}", Settings.DelegatesClass); sw.WriteLine("{"); sw.Indent(); foreach (var overloads in delegates.Values) { // Generate only one delegate per entry point.. // Overloads are only used for wrapper generation, // so ignore them. var d = overloads.First(); sw.WriteLine("[System.Security.SuppressUnmanagedCodeSecurity()]"); sw.WriteLine("internal {0};", GetDeclarationString(d, true)); sw.WriteLine("internal {0}static {2} {1}{2};", // = null d.Unsafe ? "unsafe " : "", Settings.FunctionPrefix, d.Name); } sw.Unindent(); sw.WriteLine("}"); sw.Unindent(); sw.WriteLine("}"); }
static void GenerateAddressTable(DelegateCollection delegates) { int slot = -1; foreach (var list in delegates.Values) { slot++; foreach (var d in list) { d.Slot = slot; } } }
void WriteWrappers(BindStreamWriter sw, FunctionCollection wrappers, DelegateCollection delegates, EnumCollection enums, IDictionary <string, string> CSTypes) { Trace.WriteLine(String.Format("Writing wrappers to:\t{0}.{1}", Settings.OutputNamespace, Settings.OutputClass)); sw.WriteLine("#pragma warning disable 3019"); // CLSCompliant attribute sw.WriteLine("#pragma warning disable 1591"); // Missing doc comments sw.WriteLine("#pragma warning disable 1572"); // Wrong param comments sw.WriteLine("#pragma warning disable 1573"); // Missing param comments sw.WriteLine("#pragma warning disable 626"); // extern method without DllImport sw.WriteLine(); sw.WriteLine("partial class {0}", Settings.OutputClass); sw.WriteLine("{"); sw.Indent(); // Write constructor sw.WriteLine("static {0}()", Settings.OutputClass); sw.WriteLine("{"); sw.Indent(); sw.WriteLine("EntryPointNames = new string[]", delegates.Count); sw.WriteLine("{"); sw.Indent(); foreach (var d in delegates.Values.Select(d => d.First())) { if (!Settings.IsEnabled(Settings.Legacy.UseDllImports) || d.Extension != "Core") { sw.WriteLine("\"{0}{1}\",", Settings.FunctionPrefix, d.Name); } } sw.Unindent(); sw.WriteLine("};"); sw.WriteLine("EntryPoints = new IntPtr[EntryPointNames.Length];"); sw.Unindent(); sw.WriteLine("}"); sw.WriteLine(); int current_wrapper = 0; foreach (string key in wrappers.Keys) { if (((Settings.Compatibility & Settings.Legacy.NoSeparateFunctionNamespaces) == Settings.Legacy.None) && key != "Core") { if (!Char.IsDigit(key[0])) { sw.WriteLine("public static partial class {0}", key); } else { // Identifiers cannot start with a number: sw.WriteLine("public static partial class {0}{1}", Settings.ConstantPrefix, key); } sw.WriteLine("{"); sw.Indent(); } wrappers[key].Sort(); foreach (Function f in wrappers[key]) { WriteWrapper(sw, f, enums); current_wrapper++; } if (((Settings.Compatibility & Settings.Legacy.NoSeparateFunctionNamespaces) == Settings.Legacy.None) && key != "Core") { sw.Unindent(); sw.WriteLine("}"); sw.WriteLine(); } } // Emit native signatures. // These are required by the patcher. int current_signature = 0; foreach (var d in wrappers.Values.SelectMany(e => e).Select(w => w.WrappedDelegate).Distinct()) { sw.WriteLine("[Slot({0})]", d.Slot); sw.WriteLine("[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]"); sw.WriteLine("static extern {0};", GetDeclarationString(d, false)); current_signature++; } sw.Unindent(); sw.WriteLine("}"); Console.WriteLine("Wrote {0} wrappers for {1} signatures", current_wrapper, current_signature); }
void GenerateAddressTable(DelegateCollection delegates) { // We allocate one slot per entry point. Rules: // - All extensions get a slot // - Core functions get a slot, unless UseDllImports is enabled // - On Windows, core functions with version > 1.1 must be treated as extensions. // This is controlled via the UseWindowsCompatibleGL setting. // Entry points without a slot are assigned the magic slot index -1. // Generator.Rewrite detects this and generates a static DllImport call // instead of a calli instruction for these functions. int slot = -1; foreach (var list in delegates.Values) { var func = list.First(); if (func.RequiresSlot(Settings)) { slot++; foreach (var d in list) { d.Slot = slot; } } else { // Core function routed through DllImport - no slot generated foreach (var d in list) { d.Slot = -1; } } } }
public WeakEventSource() { _handlers = new DelegateCollection(); }
public virtual void WriteDelegates(BindStreamWriter sw, DelegateCollection delegates) { Trace.WriteLine(String.Format("Writing delegates to:\t{0}.{1}.{2}", Settings.OutputNamespace, Settings.OutputClass, Settings.DelegatesClass)); sw.WriteLine("#pragma warning disable 3019"); // CLSCompliant attribute sw.WriteLine("#pragma warning disable 1591"); // Missing doc comments sw.WriteLine(); sw.WriteLine("partial class {0}", Settings.OutputClass); sw.WriteLine("{"); sw.Indent(); sw.WriteLine("internal static partial class {0}", Settings.DelegatesClass); sw.WriteLine("{"); sw.Indent(); foreach (Delegate d in delegates.Values) { sw.WriteLine("[System.Security.SuppressUnmanagedCodeSecurity()]"); sw.WriteLine("internal {0};", d.ToString()); sw.WriteLine("internal {0}static {1} {2}{1};", // = null d.Unsafe ? "unsafe " : "", d.Name, Settings.FunctionPrefix); } sw.Unindent(); sw.WriteLine("}"); sw.Unindent(); sw.WriteLine("}"); }
void WriteBindings(DelegateCollection delegates, FunctionCollection wrappers, EnumCollection enums) { Console.WriteLine("Writing bindings to {0}", Settings.OutputPath); if (!Directory.Exists(Settings.OutputPath)) { Directory.CreateDirectory(Settings.OutputPath); } string temp_enums_file = Path.GetTempFileName(); string temp_wrappers_file = Path.GetTempFileName(); // Enums using (BindStreamWriter sw = new BindStreamWriter(temp_enums_file)) { WriteLicense(sw); sw.WriteLine("using System;"); sw.WriteLine(); if ((Settings.Compatibility & Settings.Legacy.NestedEnums) != Settings.Legacy.None) { sw.WriteLine("namespace {0}", Settings.OutputNamespace); sw.WriteLine("{"); sw.Indent(); sw.WriteLine("static partial class {0}", Settings.OutputClass); } else { sw.WriteLine("namespace {0}", Settings.EnumsOutput); } sw.WriteLine("{"); sw.Indent(); WriteEnums(sw, enums, wrappers); sw.Unindent(); if ((Settings.Compatibility & Settings.Legacy.NestedEnums) != Settings.Legacy.None) { sw.WriteLine("}"); sw.Unindent(); } sw.WriteLine("}"); } // Wrappers using (BindStreamWriter sw = new BindStreamWriter(temp_wrappers_file)) { WriteLicense(sw); sw.WriteLine("namespace {0}", Settings.OutputNamespace); sw.WriteLine("{"); sw.Indent(); sw.WriteLine("using System;"); sw.WriteLine("using System.Text;"); sw.WriteLine("using System.Runtime.InteropServices;"); WriteWrappers(sw, wrappers, delegates, enums, Generator.CSTypes); sw.Unindent(); sw.WriteLine("}"); } string output_enums = Path.Combine(Settings.OutputPath, Settings.EnumsFile); string output_delegates = Path.Combine(Settings.OutputPath, Settings.DelegatesFile); string output_core = Path.Combine(Settings.OutputPath, Settings.ImportsFile); string output_wrappers = Path.Combine(Settings.OutputPath, Settings.WrappersFile); if (File.Exists(output_enums)) { File.Delete(output_enums); } if (File.Exists(output_delegates)) { File.Delete(output_delegates); } if (File.Exists(output_core)) { File.Delete(output_core); } if (File.Exists(output_wrappers)) { File.Delete(output_wrappers); } File.Move(temp_enums_file, output_enums); File.Move(temp_wrappers_file, output_wrappers); }
private DelegateCollection ReadDelegates(XPathNavigator specs, string apiversion) { DelegateCollection delegates = new DelegateCollection(); var extensions = new List <string>(); string path = "function"; foreach (XPathNavigator node in specs.SelectChildren(path, String.Empty)) { var name = node.GetAttribute("name", String.Empty).Trim(); var version = node.GetAttribute("version", String.Empty).Trim(); // Ignore functions that have a higher version number than // our current apiversion. Extensions do not have a version, // so we add them anyway (which is desirable). if (!String.IsNullOrEmpty(version) && !String.IsNullOrEmpty(apiversion) && Decimal.Parse(version, CultureInfo.InvariantCulture) > Decimal.Parse(apiversion, CultureInfo.InvariantCulture)) { continue; } // Check whether we are adding to an existing delegate or creating a new one. var d = new Delegate { Name = name, EntryPoint = name, Version = node.GetAttribute("version", String.Empty).Trim(), Category = node.GetAttribute("category", String.Empty).Trim(), DeprecatedVersion = node.GetAttribute("deprecated", String.Empty).Trim(), Deprecated = !String.IsNullOrEmpty(node.GetAttribute("deprecated", String.Empty)), Extension = node.GetAttribute("extension", String.Empty).Trim() ?? "Core", Obsolete = node.GetAttribute("obsolete", String.Empty).Trim() }; if (!extensions.Contains(d.Extension)) { extensions.Add(d.Extension); } foreach (XPathNavigator param in node.SelectChildren(XPathNodeType.Element)) { switch (param.Name) { case "returns": d.ReturnType.CurrentType = param.GetAttribute("type", String.Empty).Trim(); break; case "param": Parameter p = new Parameter(); p.CurrentType = param.GetAttribute("type", String.Empty).Trim(); p.Name = param.GetAttribute("name", String.Empty).Trim(); p.ComputeSize = param.GetAttribute("count", String.Empty).Trim(); int elementCount; if (Int32.TryParse(p.ComputeSize, out elementCount)) { p.ElementCount = elementCount; } p.Flow = Parameter.GetFlowDirection(param.GetAttribute("flow", String.Empty).Trim()); d.Parameters.Add(p); break; } } delegates.Add(d); } Utilities.AddExtensions(extensions); return(delegates); }
static FunctionCollection CreateWrappers(DelegateCollection delegates, EnumCollection enums) { var wrappers = new FunctionCollection(); foreach (var d in delegates.Values) { wrappers.AddRange(CreateNormalWrappers(d, enums)); } return wrappers; }
void WriteWrappers(BindStreamWriter sw, FunctionCollection wrappers, DelegateCollection delegates, EnumCollection enums, IDictionary <string, string> CSTypes) { Trace.WriteLine(String.Format("Writing wrappers to:\t{0}.{1}", Settings.OutputNamespace, Settings.OutputClass)); sw.WriteLine("#pragma warning disable 3019"); // CLSCompliant attribute sw.WriteLine("#pragma warning disable 1591"); // Missing doc comments sw.WriteLine("#pragma warning disable 1572"); // Wrong param comments sw.WriteLine("#pragma warning disable 1573"); // Missing param comments sw.WriteLine("#pragma warning disable 626"); // extern method without DllImport sw.WriteLine(); sw.WriteLine("partial class {0}", Settings.OutputClass); sw.WriteLine("{"); sw.Indent(); // Write constructor sw.WriteLine("static {0}()", Settings.OutputClass); sw.WriteLine("{"); sw.Indent(); // Write entry point names. // Instead of strings, which are costly to construct, // we use a 1d array of ASCII bytes. Names are laid out // sequentially, with a nul-terminator between them. sw.WriteLine("EntryPointNames = new byte[]", delegates.Count); sw.WriteLine("{"); sw.Indent(); foreach (var d in delegates.Values.Select(d => d.First())) { if (d.RequiresSlot(Settings)) { var name = Settings.FunctionPrefix + d.Name; sw.WriteLine("{0}, 0,", String.Join(", ", System.Text.Encoding.ASCII.GetBytes(name).Select(b => b.ToString()).ToArray())); } } sw.Unindent(); sw.WriteLine("};"); // Write entry point name offsets. // This is an array of offsets into the EntryPointNames[] array above. sw.WriteLine("EntryPointNameOffsets = new int[]", delegates.Count); sw.WriteLine("{"); sw.Indent(); int offset = 0; foreach (var d in delegates.Values.Select(d => d.First())) { if (d.RequiresSlot(Settings)) { sw.WriteLine("{0},", offset); var name = Settings.FunctionPrefix + d.Name; offset += name.Length + 1; } } sw.Unindent(); sw.WriteLine("};"); sw.WriteLine("EntryPoints = new IntPtr[EntryPointNameOffsets.Length];"); sw.Unindent(); sw.WriteLine("}"); sw.WriteLine(); int current_wrapper = 0; foreach (string key in wrappers.Keys) { if (((Settings.Compatibility & Settings.Legacy.NoSeparateFunctionNamespaces) == Settings.Legacy.None) && key != "Core") { if (!Char.IsDigit(key[0])) { sw.WriteLine("public static partial class {0}", key); } else { // Identifiers cannot start with a number: sw.WriteLine("public static partial class {0}{1}", Settings.ConstantPrefix, key); } sw.WriteLine("{"); sw.Indent(); } wrappers[key].Sort(); foreach (Function f in wrappers[key]) { WriteWrapper(sw, f, enums); current_wrapper++; } if (((Settings.Compatibility & Settings.Legacy.NoSeparateFunctionNamespaces) == Settings.Legacy.None) && key != "Core") { sw.Unindent(); sw.WriteLine("}"); sw.WriteLine(); } } // Emit native signatures. // These are required by the patcher. int current_signature = 0; foreach (var d in wrappers.Values.SelectMany(e => e).Select(w => w.WrappedDelegate).Distinct()) { sw.WriteLine("[Slot({0})]", d.Slot); sw.WriteLine("[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]"); sw.WriteLine("static extern {0};", GetDeclarationString(d, false)); current_signature++; } sw.Unindent(); sw.WriteLine("}"); Console.WriteLine("Wrote {0} wrappers for {1} signatures", current_wrapper, current_signature); }
public virtual DelegateCollection ReadDelegates(StreamReader specFile) { Console.WriteLine("Reading function specs."); //List<Bind.Structures.Delegate> delegates = new List<Bind.Structures.Delegate>(); DelegateCollection delegates = new DelegateCollection(); do { string line = NextValidLine(specFile); if (String.IsNullOrEmpty(line)) break; while (line.Contains("(") && !specFile.EndOfStream) { // Get next OpenGL function Bind.Structures.Delegate d = new Bind.Structures.Delegate(); // Get function name: d.Name = line.Split(Utilities.Separators, StringSplitOptions.RemoveEmptyEntries)[0]; //if (d.Name.Contains("QueryHyperpipeBestAttribSGIX")) //{ //} do { // Get function parameters and return value line = specFile.ReadLine(); List<string> words = new List<string>( line.Replace('\t', ' ').Split(Utilities.Separators, StringSplitOptions.RemoveEmptyEntries) ); if (words.Count == 0) break; // Identify line: switch (words[0]) { case "return": // Line denotes return value d.ReturnType.CurrentType = words[1]; break; case "param": // Line denotes parameter Parameter p = new Parameter(); p.Name = Utilities.Keywords.Contains(words[1]) ? "@" + words[1] : words[1]; p.CurrentType = words[2]; p.Pointer = words[4].Contains("array") ? true : words[4].Contains("reference") ? true : false; p.Flow = words[3] == "in" ? Parameter.FlowDirection.In : Parameter.FlowDirection.Out; d.Parameters.Add(p); break; // Version directive is not used. GetTexParameterIivEXT and GetTexParameterIuivEXT define two(!) versions (why?) //case "version": // Line denotes function version (i.e. 1.0, 1.2, 1.5) // d.UserData.Add("version", words[1]); // break; case "category": d.Category = words[1]; break; } } while (!specFile.EndOfStream); d.Translate(); delegates.Add(d); } } while (!specFile.EndOfStream); return delegates; }
public void WriteBindings(DelegateCollection delegates, FunctionCollection functions, EnumCollection enums) { if (!Directory.Exists(Settings.OutputPath)) Directory.CreateDirectory(Settings.OutputPath); using (BindStreamWriter sw = new BindStreamWriter(Path.Combine(Settings.OutputPath, enumsFile))) { sw.WriteLine("namespace {0}", Settings.OutputNamespace); sw.WriteLine("{"); sw.Indent(); if ((Settings.Compatibility & Settings.Legacy.NestedEnums) != Settings.Legacy.None) sw.WriteLine("public static partial class {0}", Settings.OutputClass); else sw.WriteLine("namespace {0}", Settings.EnumsNamespace); sw.WriteLine("{"); sw.Indent(); WriteEnums(sw, Bind.Structures.Enum.GLEnums); sw.Unindent(); sw.WriteLine("}"); sw.Unindent(); sw.WriteLine("}"); } using (BindStreamWriter sw = new BindStreamWriter(Path.Combine(Settings.OutputPath, delegatesFile))) { sw.WriteLine("namespace {0}", Settings.OutputNamespace); sw.WriteLine("{"); sw.Indent(); sw.WriteLine("using System;"); sw.WriteLine("using System.Runtime.InteropServices;"); sw.WriteLine("#pragma warning disable 0649"); WriteDelegates(sw, Bind.Structures.Delegate.Delegates); sw.WriteLine("#pragma warning restore 0649"); sw.Unindent(); sw.WriteLine("}"); } using (BindStreamWriter sw = new BindStreamWriter(Path.Combine(Settings.OutputPath, importsFile))) { sw.WriteLine("namespace {0}", Settings.OutputNamespace); sw.WriteLine("{"); sw.Indent(); //specWriter.WriteTypes(sw, Bind.Structures.Type.CSTypes); sw.WriteLine("using System;"); sw.WriteLine("using System.Runtime.InteropServices;"); WriteImports(sw, Bind.Structures.Delegate.Delegates); sw.Unindent(); sw.WriteLine("}"); } using (BindStreamWriter sw = new BindStreamWriter(Path.Combine(Settings.OutputPath, wrappersFile))) { sw.WriteLine("namespace {0}", Settings.OutputNamespace); sw.WriteLine("{"); sw.Indent(); sw.WriteLine("using System;"); sw.WriteLine("using System.Runtime.InteropServices;"); WriteWrappers(sw, Bind.Structures.Function.Wrappers, Bind.Structures.Type.CSTypes); sw.Unindent(); sw.WriteLine("}"); } }
public void WriteBindings(DelegateCollection delegates, FunctionCollection functions, EnumCollection enums) { Console.WriteLine("Writing bindings to {0}", Settings.OutputPath); if (!Directory.Exists(Settings.OutputPath)) { Directory.CreateDirectory(Settings.OutputPath); } string temp_enums_file = Path.GetTempFileName(); string temp_delegates_file = Path.GetTempFileName(); string temp_core_file = Path.GetTempFileName(); string temp_wrappers_file = Path.GetTempFileName(); // Enums using (BindStreamWriter sw = new BindStreamWriter(temp_enums_file)) { WriteLicense(sw); sw.WriteLine("using System;"); sw.WriteLine(); if ((Settings.Compatibility & Settings.Legacy.NestedEnums) != Settings.Legacy.None) { sw.WriteLine("namespace {0}", Settings.OutputNamespace); sw.WriteLine("{"); sw.Indent(); sw.WriteLine("static partial class {0}", Settings.OutputClass); } else { sw.WriteLine("namespace {0}", Settings.EnumsOutput); } sw.WriteLine("{"); sw.Indent(); WriteEnums(sw, Enum.GLEnums); sw.Unindent(); if ((Settings.Compatibility & Settings.Legacy.NestedEnums) != Settings.Legacy.None) { sw.WriteLine("}"); sw.Unindent(); } sw.WriteLine("}"); } // Delegates using (BindStreamWriter sw = new BindStreamWriter(temp_delegates_file)) { WriteLicense(sw); sw.WriteLine("namespace {0}", Settings.OutputNamespace); sw.WriteLine("{"); sw.Indent(); sw.WriteLine("using System;"); sw.WriteLine("using System.Runtime.InteropServices;"); sw.WriteLine("#pragma warning disable 0649"); WriteDelegates(sw, Delegate.Delegates); sw.Unindent(); sw.WriteLine("}"); } // Core using (BindStreamWriter sw = new BindStreamWriter(temp_core_file)) { WriteLicense(sw); sw.WriteLine("namespace {0}", Settings.OutputNamespace); sw.WriteLine("{"); sw.Indent(); //specWriter.WriteTypes(sw, Bind.Structures.Type.CSTypes); sw.WriteLine("using System;"); sw.WriteLine("using System.Runtime.InteropServices;"); WriteImports(sw, Delegate.Delegates); sw.Unindent(); sw.WriteLine("}"); } // Wrappers using (BindStreamWriter sw = new BindStreamWriter(temp_wrappers_file)) { WriteLicense(sw); sw.WriteLine("namespace {0}", Settings.OutputNamespace); sw.WriteLine("{"); sw.Indent(); sw.WriteLine("using System;"); sw.WriteLine("using System.Runtime.InteropServices;"); WriteWrappers(sw, Function.Wrappers, Type.CSTypes); sw.Unindent(); sw.WriteLine("}"); } string output_enums = Path.Combine(Settings.OutputPath, enumsFile); string output_delegates = Path.Combine(Settings.OutputPath, delegatesFile); string output_core = Path.Combine(Settings.OutputPath, importsFile); string output_wrappers = Path.Combine(Settings.OutputPath, wrappersFile); if (File.Exists(output_enums)) { File.Delete(output_enums); } if (File.Exists(output_delegates)) { File.Delete(output_delegates); } if (File.Exists(output_core)) { File.Delete(output_core); } if (File.Exists(output_wrappers)) { File.Delete(output_wrappers); } File.Move(temp_enums_file, output_enums); File.Move(temp_delegates_file, output_delegates); File.Move(temp_core_file, output_core); File.Move(temp_wrappers_file, output_wrappers); }
void WriteBindings(DelegateCollection delegates, FunctionCollection wrappers, EnumCollection enums) { Console.WriteLine("Writing bindings to {0}", Settings.OutputPath); if (!Directory.Exists(Settings.OutputPath)) Directory.CreateDirectory(Settings.OutputPath); // Hack: Fix 3dfx extension category so it doesn't start with a digit if (wrappers.ContainsKey("3dfx")) { var three_dee_fx = wrappers["3dfx"]; wrappers.Remove("3dfx"); wrappers.Add(DigitPrefix + "3dfx", three_dee_fx); } Settings.DefaultOutputNamespace = "OpenTK"; using (var sw = sw_h) { sw.WriteLine("#pragma once"); sw.WriteLine("#ifndef GLPP_H"); sw.WriteLine("#define GLPP_H"); sw.WriteLine(); WriteLicense(sw); sw.WriteLine("namespace {0}", Settings.OutputNamespace); sw.WriteLine("{"); sw.Indent(); WriteGetAddress(sw); WriteTypes(sw); WriteEnums(sw, enums); WriteDefinitions(sw, enums, wrappers, Generator.CSTypes); // Core definitions sw.Unindent(); sw.WriteLine("}"); sw.WriteLine("#endif"); sw.Flush(); sw.Close(); } string output_header = Path.Combine(Settings.OutputPath, OutputFileHeader); Move(sw_h.File, output_header); }
FunctionCollection CreateWrappers(DelegateCollection delegates, EnumCollection enums) { var wrappers = new FunctionCollection(); foreach (var d in delegates.Values.SelectMany(v => v)) { wrappers.AddRange(CreateNormalWrappers(d, enums)); } if ((Settings.Compatibility & Settings.Legacy.KeepUntypedEnums) != 0) { // Generate an "All" overload for every function that takes strongly-typed enums var overloads = new List<Function>(); foreach (var list in wrappers.Values) { overloads.AddRange(list.Where(f => f.Parameters.Any(p => p.IsEnum)).Select(f => { var fnew = new Function(f); fnew.Obsolete = "Use strongly-typed overload instead"; // Note that we can only overload parameters, not the return type foreach (var p in fnew.Parameters) { if (p.IsEnum) { p.CurrentType = Settings.CompleteEnumName; } } return fnew; })); } wrappers.AddRange(overloads); } return wrappers; }
// Merges the given delegate into the delegate list. internal static void Merge(DelegateCollection delegates, Delegate t) { delegates.Add(t.Name, t); }
void WriteWrappers(BindStreamWriter sw, FunctionCollection wrappers, DelegateCollection delegates, EnumCollection enums, IDictionary<string, string> CSTypes) { Trace.WriteLine(String.Format("Writing wrappers to:\t{0}.{1}", Settings.OutputNamespace, Settings.OutputClass)); sw.WriteLine("#pragma warning disable 3019"); // CLSCompliant attribute sw.WriteLine("#pragma warning disable 1591"); // Missing doc comments sw.WriteLine("#pragma warning disable 1572"); // Wrong param comments sw.WriteLine("#pragma warning disable 1573"); // Missing param comments sw.WriteLine("#pragma warning disable 626"); // extern method without DllImport sw.WriteLine(); sw.WriteLine("partial class {0}", Settings.OutputClass); sw.WriteLine("{"); sw.Indent(); // Write constructor sw.WriteLine("static {0}()", Settings.OutputClass); sw.WriteLine("{"); sw.Indent(); // Write entry point names. // Instead of strings, which are costly to construct, // we use a 1d array of ASCII bytes. Names are laid out // sequentially, with a nul-terminator between them. sw.WriteLine("EntryPointNames = new byte[]", delegates.Count); sw.WriteLine("{"); sw.Indent(); foreach (var d in delegates.Values.Select(d => d.First())) { if (d.RequiresSlot(Settings)) { var name = Settings.FunctionPrefix + d.Name; sw.WriteLine("{0}, 0,", String.Join(", ", System.Text.Encoding.ASCII.GetBytes(name).Select(b => b.ToString()).ToArray())); } } sw.Unindent(); sw.WriteLine("};"); // Write entry point name offsets. // This is an array of offsets into the EntryPointNames[] array above. sw.WriteLine("EntryPointNameOffsets = new int[]", delegates.Count); sw.WriteLine("{"); sw.Indent(); int offset = 0; foreach (var d in delegates.Values.Select(d => d.First())) { if (d.RequiresSlot(Settings)) { sw.WriteLine("{0},", offset); var name = Settings.FunctionPrefix + d.Name; offset += name.Length + 1; } } sw.Unindent(); sw.WriteLine("};"); sw.WriteLine("EntryPoints = new IntPtr[EntryPointNameOffsets.Length];"); sw.Unindent(); sw.WriteLine("}"); sw.WriteLine(); int current_wrapper = 0; foreach (string key in wrappers.Keys) { if (((Settings.Compatibility & Settings.Legacy.NoSeparateFunctionNamespaces) == Settings.Legacy.None) && key != "Core") { if (!Char.IsDigit(key[0])) { sw.WriteLine("public static partial class {0}", key); } else { // Identifiers cannot start with a number: sw.WriteLine("public static partial class {0}{1}", Settings.ConstantPrefix, key); } sw.WriteLine("{"); sw.Indent(); } wrappers[key].Sort(); foreach (Function f in wrappers[key]) { WriteWrapper(sw, f, enums); current_wrapper++; } if (((Settings.Compatibility & Settings.Legacy.NoSeparateFunctionNamespaces) == Settings.Legacy.None) && key != "Core") { sw.Unindent(); sw.WriteLine("}"); sw.WriteLine(); } } // Emit native signatures. // These are required by the patcher. int current_signature = 0; foreach (var d in wrappers.Values.SelectMany(e => e).Select(w => w.WrappedDelegate).Distinct()) { sw.WriteLine("[Slot({0})]", d.Slot); sw.WriteLine("[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]"); sw.WriteLine("static extern {0};", GetDeclarationString(d, false)); current_signature++; } sw.Unindent(); sw.WriteLine("}"); Console.WriteLine("Wrote {0} wrappers for {1} signatures", current_wrapper, current_signature); }
void WriteBindings(DelegateCollection delegates, FunctionCollection wrappers, EnumCollection enums) { Console.WriteLine("Writing bindings to {0}", Settings.OutputPath); if (!Directory.Exists(Settings.OutputPath)) Directory.CreateDirectory(Settings.OutputPath); string temp_enums_file = Path.GetTempFileName(); string temp_wrappers_file = Path.GetTempFileName(); // Enums using (BindStreamWriter sw = new BindStreamWriter(temp_enums_file)) { WriteLicense(sw); sw.WriteLine("using System;"); sw.WriteLine(); if ((Settings.Compatibility & Settings.Legacy.NestedEnums) != Settings.Legacy.None) { sw.WriteLine("namespace {0}", Settings.OutputNamespace); sw.WriteLine("{"); sw.Indent(); sw.WriteLine("static partial class {0}", Settings.OutputClass); } else sw.WriteLine("namespace {0}", Settings.EnumsOutput); sw.WriteLine("{"); sw.Indent(); WriteEnums(sw, enums, wrappers); sw.Unindent(); if ((Settings.Compatibility & Settings.Legacy.NestedEnums) != Settings.Legacy.None) { sw.WriteLine("}"); sw.Unindent(); } sw.WriteLine("}"); } // Wrappers using (BindStreamWriter sw = new BindStreamWriter(temp_wrappers_file)) { WriteLicense(sw); sw.WriteLine("namespace {0}", Settings.OutputNamespace); sw.WriteLine("{"); sw.Indent(); sw.WriteLine("using System;"); sw.WriteLine("using System.Text;"); sw.WriteLine("using System.Runtime.InteropServices;"); WriteWrappers(sw, wrappers, delegates, enums, Generator.CSTypes); sw.Unindent(); sw.WriteLine("}"); } string output_enums = Path.Combine(Settings.OutputPath, Settings.EnumsFile); string output_delegates = Path.Combine(Settings.OutputPath, Settings.DelegatesFile); string output_core = Path.Combine(Settings.OutputPath, Settings.ImportsFile); string output_wrappers = Path.Combine(Settings.OutputPath, Settings.WrappersFile); if (File.Exists(output_enums)) File.Delete(output_enums); if (File.Exists(output_delegates)) File.Delete(output_delegates); if (File.Exists(output_core)) File.Delete(output_core); if (File.Exists(output_wrappers)) File.Delete(output_wrappers); File.Move(temp_enums_file, output_enums); File.Move(temp_wrappers_file, output_wrappers); }
public virtual DelegateCollection ReadDelegates(StreamReader specFile) { Console.WriteLine("Reading function specs."); DelegateCollection delegates = new DelegateCollection(); XPathDocument function_overrides = new XPathDocument(Path.Combine(Settings.InputPath, functionOverridesFile)); do { string line = NextValidLine(specFile); if (String.IsNullOrEmpty(line)) break; while (line.Contains("(") && !specFile.EndOfStream) { // Get next OpenGL function Delegate d = new Delegate(); // Get function name: d.Name = line.Split(Utilities.Separators, StringSplitOptions.RemoveEmptyEntries)[0]; do { // Get function parameters and return value line = specFile.ReadLine(); List<string> words = new List<string>( line.Replace('\t', ' ').Split(Utilities.Separators, StringSplitOptions.RemoveEmptyEntries) ); if (words.Count == 0) break; // Identify line: switch (words[0]) { case "return": // Line denotes return value d.ReturnType.CurrentType = words[1]; break; case "param": // Line denotes parameter Parameter p = new Parameter(); p.Name = Utilities.Keywords.Contains(words[1]) ? "@" + words[1] : words[1]; p.CurrentType = words[2]; p.Pointer += words[4].Contains("array") ? 1 : 0; p.Pointer += words[4].Contains("reference") ? 1 : 0; if (p.Pointer != 0 && words.Count > 5 && words[5].Contains("[1]")) p.ElementCount = 1; p.Flow = words[3] == "in" ? FlowDirection.In : FlowDirection.Out; d.Parameters.Add(p); break; // GetTexParameterIivEXT and GetTexParameterIuivEXT define two(!) versions (why?) case "version": // Line denotes function version (i.e. 1.0, 1.2, 1.5) d.Version = words[1]; break; case "category": d.Category = words[1]; break; } } while (!specFile.EndOfStream); d.Translate(function_overrides); delegates.Add(d); } } while (!specFile.EndOfStream); return delegates; }
public Generator(Settings settings, string dirName) { if (settings == null) throw new ArgumentNullException("settings"); if (dirName == null) dirName = "GL2"; Settings = settings.Clone(); glTypemap = "GL2/gl.tm"; csTypemap = Settings.LanguageTypeMapFile; enumSpec = Path.Combine(dirName, "signatures.xml"); enumSpecExt = String.Empty; glSpec = Path.Combine(dirName, "signatures.xml"); glSpecExt = String.Empty; Settings.OverridesFile = Path.Combine(dirName, "overrides.xml"); Settings.ImportsClass = "Core"; Settings.DelegatesClass = "Delegates"; Settings.OutputClass = "GL"; if (Settings.Compatibility == Settings.Legacy.Tao) { Settings.OutputNamespace = "Tao.OpenGl"; Settings.OutputClass = "Gl"; } else { // Defaults } Settings.DefaultOutputNamespace = "OpenTK.Graphics.OpenGL"; Settings.DefaultImportsFile = "GLCore.cs"; Settings.DefaultDelegatesFile = "GLDelegates.cs"; Settings.DefaultEnumsFile = "GLEnums.cs"; Settings.DefaultWrappersFile = "GL.cs"; Delegates = new DelegateCollection(); Enums = new EnumCollection(); Wrappers = new FunctionCollection(); SpecReader = new XmlSpecReader(Settings); }
public void WriteBindings(DelegateCollection delegates, FunctionCollection functions, EnumCollection enums) { Console.WriteLine("Writing bindings to {0}", Settings.OutputPath); if (!Directory.Exists(Settings.OutputPath)) Directory.CreateDirectory(Settings.OutputPath); string temp_enums_file = Path.GetTempFileName(); string temp_delegates_file = Path.GetTempFileName(); string temp_core_file = Path.GetTempFileName(); string temp_wrappers_file = Path.GetTempFileName(); // Enums using (BindStreamWriter sw = new BindStreamWriter(temp_enums_file)) { WriteLicense(sw); sw.WriteLine("using System;"); sw.WriteLine(); if ((Settings.Compatibility & Settings.Legacy.NestedEnums) != Settings.Legacy.None) { sw.WriteLine("namespace {0}", Settings.OutputNamespace); sw.WriteLine("{"); sw.Indent(); sw.WriteLine("static partial class {0}", Settings.OutputClass); } else sw.WriteLine("namespace {0}", Settings.EnumsOutput); sw.WriteLine("{"); sw.Indent(); WriteEnums(sw, Enum.GLEnums); sw.Unindent(); if ((Settings.Compatibility & Settings.Legacy.NestedEnums) != Settings.Legacy.None) { sw.WriteLine("}"); sw.Unindent(); } sw.WriteLine("}"); } // Delegates using (BindStreamWriter sw = new BindStreamWriter(temp_delegates_file)) { WriteLicense(sw); sw.WriteLine("namespace {0}", Settings.OutputNamespace); sw.WriteLine("{"); sw.Indent(); sw.WriteLine("using System;"); sw.WriteLine("using System.Text;"); sw.WriteLine("using System.Runtime.InteropServices;"); sw.WriteLine("#pragma warning disable 0649"); WriteDelegates(sw, Delegate.Delegates); sw.Unindent(); sw.WriteLine("}"); } // Core using (BindStreamWriter sw = new BindStreamWriter(temp_core_file)) { WriteLicense(sw); sw.WriteLine("namespace {0}", Settings.OutputNamespace); sw.WriteLine("{"); sw.Indent(); //specWriter.WriteTypes(sw, Bind.Structures.Type.CSTypes); sw.WriteLine("using System;"); sw.WriteLine("using System.Text;"); sw.WriteLine("using System.Runtime.InteropServices;"); WriteImports(sw, Delegate.Delegates); sw.Unindent(); sw.WriteLine("}"); } // Wrappers using (BindStreamWriter sw = new BindStreamWriter(temp_wrappers_file)) { WriteLicense(sw); sw.WriteLine("namespace {0}", Settings.OutputNamespace); sw.WriteLine("{"); sw.Indent(); sw.WriteLine("using System;"); sw.WriteLine("using System.Text;"); sw.WriteLine("using System.Runtime.InteropServices;"); WriteWrappers(sw, Function.Wrappers, Type.CSTypes); sw.Unindent(); sw.WriteLine("}"); } string output_enums = Path.Combine(Settings.OutputPath, enumsFile); string output_delegates = Path.Combine(Settings.OutputPath, delegatesFile); string output_core = Path.Combine(Settings.OutputPath, importsFile); string output_wrappers = Path.Combine(Settings.OutputPath, wrappersFile); if (File.Exists(output_enums)) File.Delete(output_enums); if (File.Exists(output_delegates)) File.Delete(output_delegates); if (File.Exists(output_core)) File.Delete(output_core); if (File.Exists(output_wrappers)) File.Delete(output_wrappers); File.Move(temp_enums_file, output_enums); File.Move(temp_delegates_file, output_delegates); File.Move(temp_core_file, output_core); File.Move(temp_wrappers_file, output_wrappers); }
public virtual DelegateCollection ReadDelegates(StreamReader specFile) { Console.WriteLine("Reading function specs."); DelegateCollection delegates = new DelegateCollection(); XPathDocument function_overrides = new XPathDocument(Path.Combine(Settings.InputPath, functionOverridesFile)); do { string line = NextValidLine(specFile); if (String.IsNullOrEmpty(line)) { break; } while (line.Contains("(") && !specFile.EndOfStream) { // Get next OpenGL function Delegate d = new Delegate(); // Get function name: d.Name = line.Split(Utilities.Separators, StringSplitOptions.RemoveEmptyEntries)[0]; do { // Get function parameters and return value line = specFile.ReadLine(); List <string> words = new List <string>( line.Replace('\t', ' ').Split(Utilities.Separators, StringSplitOptions.RemoveEmptyEntries) ); if (words.Count == 0) { break; } // Identify line: switch (words[0]) { case "return": // Line denotes return value d.ReturnType.CurrentType = words[1]; break; case "param": // Line denotes parameter Parameter p = new Parameter(); p.Name = Utilities.Keywords.Contains(words[1]) ? "@" + words[1] : words[1]; p.CurrentType = words[2]; p.Pointer += words[4].Contains("array") ? 1 : 0; p.Pointer += words[4].Contains("reference") ? 1 : 0; if (p.Pointer != 0 && words.Count > 5 && words[5].Contains("[1]")) { p.ElementCount = 1; } p.Flow = words[3] == "in" ? FlowDirection.In : FlowDirection.Out; d.Parameters.Add(p); break; // GetTexParameterIivEXT and GetTexParameterIuivEXT define two(!) versions (why?) case "version": // Line denotes function version (i.e. 1.0, 1.2, 1.5) d.Version = words[1]; break; case "category": d.Category = words[1]; break; } }while (!specFile.EndOfStream); d.Translate(function_overrides); delegates.Add(d); } }while (!specFile.EndOfStream); return(delegates); }