diff --git a/Source/Bind/CL/CLGenerator.cs b/Source/Bind/CL/CLGenerator.cs index 7ceedf47..9545b5c4 100644 --- a/Source/Bind/CL/CLGenerator.cs +++ b/Source/Bind/CL/CLGenerator.cs @@ -32,10 +32,15 @@ namespace Bind.CL Settings.DelegatesClass = "Delegates"; Settings.FunctionPrefix = "cl"; + Settings.ConstantPrefix = "CL_"; + Settings.EnumPrefix = "Cl"; Settings.OutputClass = "CL"; Settings.OutputNamespace = "OpenTK.Compute." + name; Settings.OutputPath = Path.Combine("../../Source/OpenTK/Compute", name); + + //Settings.Compatibility &= ~Settings.Legacy.TurnVoidPointersToIntPtr; + Settings.Compatibility |= Settings.Legacy.NoDebugHelpers; } public override Bind.Structures.DelegateCollection ReadDelegates(System.IO.StreamReader specFile) @@ -95,6 +100,8 @@ namespace Bind.CL public override Bind.Structures.EnumCollection ReadEnums(StreamReader specFile) { + XPathDocument overrides = new XPathDocument(new StreamReader(Path.Combine(Settings.InputPath, functionOverridesFile))); + EnumCollection enums = new EnumCollection(); Bind.Structures.Enum all = new Bind.Structures.Enum(Settings.CompleteEnumName); XPathDocument doc = new XPathDocument(specFile); @@ -117,7 +124,7 @@ namespace Bind.CL } Utilities.Merge(enums, all); - enums.Translate(); + enums.Translate(overrides); return enums; } } diff --git a/Source/Bind/ES/ESGenerator.cs b/Source/Bind/ES/ESGenerator.cs index 00a48529..22f3cac7 100644 --- a/Source/Bind/ES/ESGenerator.cs +++ b/Source/Bind/ES/ESGenerator.cs @@ -97,6 +97,8 @@ namespace Bind.ES Bind.Structures.Enum all = new Bind.Structures.Enum(Settings.CompleteEnumName); XPathDocument doc = new XPathDocument(specFile); XPathNavigator nav = doc.CreateNavigator().SelectSingleNode("/signatures"); + + XPathDocument overrides = new XPathDocument(new StreamReader(Path.Combine(Settings.InputPath, functionOverridesFile))); foreach (XPathNavigator node in nav.SelectChildren("enum", String.Empty)) { @@ -115,7 +117,7 @@ namespace Bind.ES } Utilities.Merge(enums, all); - enums.Translate(); + enums.Translate(overrides); return enums; } } diff --git a/Source/Bind/GL2/Generator.cs b/Source/Bind/GL2/Generator.cs index 19442c69..5754c064 100644 --- a/Source/Bind/GL2/Generator.cs +++ b/Source/Bind/GL2/Generator.cs @@ -70,7 +70,7 @@ namespace Bind.GL2 Bind.Structures.Type.Initialize(glTypemap, csTypemap); Bind.Structures.Enum.Initialize(enumSpec, enumSpecExt); - Bind.Structures.Enum.GLEnums.Translate(); + Bind.Structures.Enum.GLEnums.Translate(new XPathDocument(Path.Combine(Settings.InputPath, functionOverridesFile))); Bind.Structures.Function.Initialize(); Bind.Structures.Delegate.Initialize(glSpec, glSpecExt); @@ -242,35 +242,6 @@ namespace Bind.GL2 } c.Name = words[0]; - - uint number; - // Trim the unsigned or long specifiers used in C constants ('u' or 'ull'). - if (words[2].ToLower().StartsWith("0x")) - { - if (words[2].ToLower().EndsWith("ull")) - words[2] = words[2].Substring(0, words[2].Length - 3); - if (words[2].ToLower().EndsWith("u")) - words[2] = words[2].Substring(0, words[2].Length - 1); - } - if (UInt32.TryParse(words[2].Replace("0x", String.Empty), System.Globalization.NumberStyles.AllowHexSpecifier, null, out number)) - { - // The value is a number, check if it should be unchecked. - if (number > 0x7FFFFFFF) - c.Unchecked = true; - } - else - { - // The value is not a number. Strip the prefix. - if (words[2].StartsWith(Settings.ConstantPrefix)) - words[2] = words[2].Substring(Settings.ConstantPrefix.Length); - - // If the name now starts with a digit (doesn't matter whether we - // stripped "GL_" above), add a "GL_" prefix. - // (e.g. GL_4_BYTES). - if (Char.IsDigit(words[2][0])) - words[2] = Settings.ConstantPrefix + words[2]; - } - c.Value = words[2]; } else if (words[0] == "use") diff --git a/Source/Bind/Structures/Delegate.cs b/Source/Bind/Structures/Delegate.cs index ccb8ce67..0c4f4c64 100644 --- a/Source/Bind/Structures/Delegate.cs +++ b/Source/Bind/Structures/Delegate.cs @@ -507,29 +507,17 @@ namespace Bind.Structures #region TranslateReturnType - /// - /// Translates the opengl return type to the equivalent C# type. - /// - /// The opengl function to translate. - /// - /// First, we use the official typemap (gl.tm) to get the correct type. - /// Then we override this, when it is: - /// 1) A string (we have to use Marshal.PtrToStringAnsi, to avoid heap corruption) - /// 2) An array (translates to IntPtr) - /// 3) A generic object or void* (translates to IntPtr) - /// 4) A GLenum (translates to int on Legacy.Tao or GL.Enums.GLenum otherwise). - /// Return types must always be CLS-compliant, because .Net does not support overloading on return types. - /// - void TranslateReturnType(XPathNavigator function_override) + // Translates the opengl return type to the equivalent C# type. + // + // First, we use the official typemap (gl.tm) to get the correct type. + // Then we override this, when it is: + // 1) A string (we have to use Marshal.PtrToStringAnsi, to avoid heap corruption) + // 2) An array (translates to IntPtr) + // 3) A generic object or void* (translates to IntPtr) + // 4) A GLenum (translates to int on Legacy.Tao or GL.Enums.GLenum otherwise). + // Return types must always be CLS-compliant, because .Net does not support overloading on return types. + void TranslateReturnType(XPathNavigator overrides, XPathNavigator function_override) { - /* - if (Bind.Structures.Type.GLTypes.ContainsKey(ReturnType.CurrentType)) - ReturnType.CurrentType = Bind.Structures.Type.GLTypes[ReturnType.CurrentType]; - - if (Bind.Structures.Type.CSTypes.ContainsKey(ReturnType.CurrentType)) - ReturnType.CurrentType = Bind.Structures.Type.CSTypes[ReturnType.CurrentType]; - */ - if (function_override != null) { XPathNavigator return_override = function_override.SelectSingleNode("returns"); @@ -539,7 +527,7 @@ namespace Bind.Structures } } - ReturnType.Translate(this.Category); + ReturnType.Translate(overrides, this.Category); if (ReturnType.CurrentType.ToLower().Contains("void") && ReturnType.Pointer != 0) { @@ -574,7 +562,7 @@ namespace Bind.Structures #region TranslateParameters - protected virtual void TranslateParameters(XPathNavigator function_override) + protected virtual void TranslateParameters(XPathNavigator overrides, XPathNavigator function_override) { for (int i = 0; i < Parameters.Count; i++) { @@ -595,7 +583,7 @@ namespace Bind.Structures } } - Parameters[i].Translate(this.Category); + Parameters[i].Translate(overrides, this.Category); if (Parameters[i].CurrentType == "UInt16" && Name.Contains("LineStipple")) Parameters[i].WrapperType = WrapperTypes.UncheckedParameter; @@ -616,9 +604,9 @@ namespace Bind.Structures string path = "/overrides/function[@name='{0}' and @extension='{1}']"; string name = TrimName(Name, false); XPathNavigator function_override = overrides.CreateNavigator().SelectSingleNode(String.Format(path, name, Extension)); - - TranslateReturnType(function_override); - TranslateParameters(function_override); + + TranslateReturnType(overrides.CreateNavigator(), function_override); + TranslateParameters(overrides.CreateNavigator(), function_override); CreateWrappers(); } diff --git a/Source/Bind/Structures/Enum.cs b/Source/Bind/Structures/Enum.cs index 1cbef38e..0485f375 100644 --- a/Source/Bind/Structures/Enum.cs +++ b/Source/Bind/Structures/Enum.cs @@ -9,6 +9,7 @@ using System.Collections.Generic; using System.Text; using System.IO; using System.Globalization; +using System.Xml.XPath; namespace Bind.Structures { @@ -157,7 +158,11 @@ namespace Bind.Structures translator.Replace("Pname", "PName"); translator.Replace("SRgb", "Srgb"); - return translator.ToString(); + + string ret = translator.ToString(); + if (ret.StartsWith(Settings.EnumPrefix)) + return ret.Substring(Settings.EnumPrefix.Length); + return ret; } #endregion @@ -210,14 +215,31 @@ namespace Bind.Structures Utilities.Merge(this, e); } - internal void Translate() + internal void Translate(XPathDocument overrides) { + if (overrides == null) + throw new ArgumentNullException("overrides"); + + string path = "/overrides/enum[@name='{0}']"; + // Translate enum names. { List keys_to_update = new List(); foreach (Enum e in this.Values) { - string name = Enum.TranslateName(e.Name); + string name = e.Name; + + XPathNavigator enum_override = overrides.CreateNavigator().SelectSingleNode(String.Format(path, name)); + if (enum_override != null) + { + XPathNavigator name_override = enum_override.SelectSingleNode("name"); + if (name_override != null) + { + name = name_override.Value; + } + } + + name = Enum.TranslateName(name); if (name != e.Name) { keys_to_update.Add(e.Name); @@ -237,8 +259,26 @@ namespace Bind.Structures foreach (Enum e in this.Values) { + XPathNavigator enum_override = overrides.CreateNavigator().SelectSingleNode(String.Format(path, e.Name)); foreach (Constant c in e.ConstantCollection.Values) { + if (enum_override != null) + { + XPathNavigator constant_override = enum_override.SelectSingleNode(String.Format("token[@name='{0}']", c.PreviousName)) ?? + enum_override.SelectSingleNode(String.Format("token[@name={0}]", c.Name)); + if (constant_override != null) + { + foreach (XPathNavigator node in constant_override.SelectChildren(XPathNodeType.Element)) + { + switch (node.Name) + { + case "name": c.Name = (string)node.TypedValue; break; + case "value": c.Value = (string)node.TypedValue; break; + } + } + } + } + // There are cases when a value is an aliased constant, with no enum specified. // (e.g. FOG_COORD_ARRAY_TYPE = GL_FOG_COORDINATE_ARRAY_TYPE) // In this case try searching all enums for the correct constant to alias (stupid opengl specs). diff --git a/Source/Bind/Structures/Parameter.cs b/Source/Bind/Structures/Parameter.cs index 1dd287f0..df596e64 100644 --- a/Source/Bind/Structures/Parameter.cs +++ b/Source/Bind/Structures/Parameter.cs @@ -8,6 +8,7 @@ using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; +using System.Xml.XPath; namespace Bind.Structures { @@ -280,11 +281,11 @@ namespace Bind.Structures #endregion - #region override public void Translate(string category) + #region override public void Translate(XPathNavigator overrides, string category) - override public void Translate(string category) + override public void Translate(XPathNavigator overrides, string category) { - base.Translate(category); + base.Translate(overrides, category); // Find out the necessary wrapper types. if (Pointer != 0)/* || CurrentType == "IntPtr")*/ @@ -589,13 +590,19 @@ namespace Bind.Structures sb.Append(String.Format("({0}{1})", p.CurrentType, (p.Array > 0) ? "[]" : "")); } - else if (p.Pointer != 0 || p.Array > 0 || p.Reference) + else if (p.IndirectionLevel != 0) { if (((Settings.Compatibility & Settings.Legacy.TurnVoidPointersToIntPtr) != Settings.Legacy.None) && p.Pointer != 0 && p.CurrentType.Contains("void")) sb.Append("(IntPtr)"); - else - sb.Append(String.Format("({0}*)", p.CurrentType)); + else + { + sb.Append("("); + sb.Append(p.CurrentType); + for (int i = 0; i < p.IndirectionLevel; i++) + sb.Append("*"); + sb.Append(")"); + } } else { diff --git a/Source/Bind/Structures/Type.cs b/Source/Bind/Structures/Type.cs index e0c17e98..758d8e22 100644 --- a/Source/Bind/Structures/Type.cs +++ b/Source/Bind/Structures/Type.cs @@ -8,6 +8,7 @@ using System; using System.Collections.Generic; using System.Text; using System.IO; +using System.Xml.XPath; namespace Bind.Structures { @@ -156,7 +157,19 @@ namespace Bind.Structures public int Pointer { get { return pointer; } - set { pointer = value; } + set { pointer = value > 0 ? value : 0; } + } + + #endregion + + #region IndirectionLevel + + // Gets the the level of indirection for this type. For example, + // type 'foo' has indirection level = 0, while 'ref foo*[]' has + // an indirection level of 3. + public int IndirectionLevel + { + get { return Pointer + Array + (Reference ? 1 : 0); } } #endregion @@ -261,9 +274,9 @@ namespace Bind.Structures #endregion - #region public virtual void Translate(string category) + #region public virtual void Translate(XPathNavigator overrides, string category) - public virtual void Translate(string category) + public virtual void Translate(XPathNavigator overrides, string category) { Enum @enum; string s; @@ -346,6 +359,13 @@ namespace Bind.Structures Bind.Structures.Type.CSTypes.ContainsKey(CurrentType) ? Bind.Structures.Type.CSTypes[CurrentType] : CurrentType; + // Make sure that enum parameters follow enum overrides, i.e. + // if enum ErrorCodes is overriden to ErrorCode, then parameters + // of type ErrorCodes should also be overriden to ErrorCode. + XPathNavigator enum_override = overrides.SelectSingleNode(String.Format("/overrides/enum[@name='{0}']/name", CurrentType)); + if (enum_override != null) + CurrentType = enum_override.Value; + if (CurrentType == "IntPtr" && String.IsNullOrEmpty(PreviousType)) Pointer = 0; }