diff --git a/Source/Bind/GL2/Generator.cs b/Source/Bind/GL2/Generator.cs index 34ab240e..ca8b86b1 100644 --- a/Source/Bind/GL2/Generator.cs +++ b/Source/Bind/GL2/Generator.cs @@ -32,6 +32,8 @@ namespace Bind.GL2 protected static string loadAllFuncName = "LoadAll"; + protected static Regex enumToDotNet = new Regex("_[a-z|A-Z]?", RegexOptions.Compiled); + #endregion #region --- Constructors --- @@ -55,8 +57,11 @@ namespace Bind.GL2 public virtual void Process() { + // Matches functions that cannot have their trailing 'v' trimmed for CLS-Compliance reasons. + // Built through trial and error :) Function.endingsAddV = - new Regex(@"(Coord1|Attrib(I?)1(u?)|Stream1|Uniform2(u?)|(Point|Convolution|Transform|Sprite|List|Combiner|Tex)Parameter|Fog(Coord)?.*|VertexWeight|(Fragment)?Light(Model)?|Material|ReplacementCodeu?b?|Tex(Gen|Env)|Indexu?.v)", RegexOptions.Compiled); + new Regex(@"(Coord1|Attrib(I?)1(u?)|Stream1|Uniform2(u?)|(Point|Convolution|Transform|Sprite|List|Combiner|Tex)Parameter|Fog(Coord)?.*|VertexWeight|(Fragment)?Light(Model)?|Material|ReplacementCodeu?b?|Tex(Gen|Env)|Indexu?.v)", + RegexOptions.Compiled); Bind.Structures.Type.Initialize(glTypemap, csTypemap); @@ -107,10 +112,12 @@ namespace Bind.GL2 protected virtual void Translate() { - foreach (Bind.Structures.Enum e in Bind.Structures.Enum.GLEnums.Values) - { - TranslateEnum(e); - } + Bind.Structures.Enum.GLEnums.Translate(); + + //foreach (Bind.Structures.Enum e in Bind.Structures.Enum.GLEnums.Values) + //{ + // TranslateEnum(e); + //} //foreach (Bind.Structures.Delegate d in Bind.Structures.Delegate.Delegates.Values) { @@ -174,9 +181,9 @@ namespace Bind.GL2 // Get function name: d.Name = line.Split(Utilities.Separators, StringSplitOptions.RemoveEmptyEntries)[0]; - if (d.Name.Contains("QueryHyperpipeBestAttribSGIX")) - { - } + //if (d.Name.Contains("QueryHyperpipeBestAttribSGIX")) + //{ + //} do { @@ -351,6 +358,33 @@ namespace Bind.GL2 c.Value = words[2]; } +#if false + // Translate the enum's name to match .Net naming conventions + if ((Settings.Compatibility & Settings.Legacy.AllCapsEnums) == Settings.Legacy.None) + { + int pos; + // e.Name = enumToDotNet.Replace(e.Name, + while ((pos = e.Name.IndexOf("_")) != -1) + { + e.Name = e.Name.Insert(pos, Char.ToUpper(e.Name[pos + 1]).ToString()); + e.Name = e.Name.Remove(pos + 1, 2); + } + //e.Name = e.Name.Replace("_", ""); + } +#endif + // Translate the constant's name to match .Net naming conventions + if ((Settings.Compatibility & Settings.Legacy.NoAdvancedEnumProcessing) == Settings.Legacy.None) + { + int pos; + + c.Name = c.Name[0] + c.Name.Substring(1).ToLower(); + while ((pos = c.Name.IndexOf("_")) != -1) + { + c.Name = c.Name.Insert(pos, Char.ToUpper(c.Name[pos + 1]).ToString()); + c.Name = c.Name.Remove(pos + 1, 2); + } + } + //if (!String.IsNullOrEmpty(c.Name) && !e.Members.Contains.Contains(c)) //SpecTranslator.Merge(e.Members, c); if (!e.ConstantCollection.ContainsKey(c.Name)) @@ -359,13 +393,9 @@ namespace Bind.GL2 } else { - Trace.WriteLine( - String.Format( - "Spec error: Constant {0} defined twice in enum {1}, discarding last definition.", - c.Name, - e.Name - ) - ); + Trace.WriteLine(String.Format( + "Spec error: Constant {0} defined twice in enum {1}, discarding last definition.", + c.Name, e.Name)); } // Insert the current constant in the list of all constants. @@ -616,33 +646,21 @@ namespace Bind.GL2 sw.WriteLine("partial class {0}", Settings.OutputClass); sw.WriteLine("{"); sw.Indent(); - sw.WriteLine(); + sw.WriteLine("internal static partial class {0}", Settings.DelegatesClass); sw.WriteLine("{"); - sw.Indent(); - // Disable BeforeFieldInit - //sw.WriteLine("static {0}()", Settings.DelegatesClass); - //sw.WriteLine("{"); - // --- Workaround for mono gmcs 1.2.4 issue, where static initalization fails. --- - //sw.Indent(); - //sw.WriteLine("{0}.{1}();", Settings.OutputClass, loadAllFuncName); - //sw.Unindent(); - // --- End workaround --- - //sw.WriteLine("}"); - sw.WriteLine(); + foreach (Bind.Structures.Delegate d in delegates.Values) { sw.WriteLine("[System.Security.SuppressUnmanagedCodeSecurity()]"); sw.WriteLine("internal {0};", d.ToString()); - // --- Workaround for mono gmcs 1.2.4 issue, where static initalization fails. --- - sw.WriteLine( - "internal {0}static {1} {2}{1};", // = null + sw.WriteLine("internal {0}static {1} {2}{1};", // = null d.Unsafe ? "unsafe " : "", d.Name, Settings.FunctionPrefix); - // --- End workaround ---s } + sw.Unindent(); sw.WriteLine("}"); @@ -706,7 +724,7 @@ namespace Bind.GL2 sw.WriteLine(); foreach (string key in wrappers.Keys) { - if (Settings.Compatibility == Settings.Legacy.None && key != "Core") + if (((Settings.Compatibility & Settings.Legacy.NoSeparateFunctionNamespaces) == Settings.Legacy.None) && key != "Core") { if (!Char.IsDigit(key[0])) { @@ -732,7 +750,7 @@ namespace Bind.GL2 sw.WriteLine(); } - if (Settings.Compatibility == Settings.Legacy.None && key != "Core") + if (((Settings.Compatibility & Settings.Legacy.NoSeparateFunctionNamespaces) == Settings.Legacy.None) && key != "Core") { sw.Unindent(); sw.WriteLine("}"); @@ -765,22 +783,28 @@ namespace Bind.GL2 { Trace.WriteLine(String.Format("Writing enums to {0}.{1}", Settings.OutputNamespace, Settings.OutputClass)); - if (Settings.Compatibility == Settings.Legacy.None) + if ((Settings.Compatibility & Settings.Legacy.ConstIntEnums) == Settings.Legacy.None) { - sw.WriteLine("public class Enums"); - sw.WriteLine("{"); + if (!String.IsNullOrEmpty(Settings.NestedEnumsClass)) + { + sw.WriteLine("public class Enums"); + sw.WriteLine("{"); + sw.Indent(); + } - sw.Indent(); foreach (Bind.Structures.Enum @enum in enums.Values) { sw.Write(@enum); sw.WriteLine(); } - sw.Unindent(); - sw.WriteLine("}"); + if (!String.IsNullOrEmpty(Settings.NestedEnumsClass)) + { + sw.Unindent(); + sw.WriteLine("}"); + } } - else if (Settings.Compatibility == Settings.Legacy.Tao) + else { // Tao legacy mode: dump all enums as constants in GLClass. foreach (Bind.Structures.Constant c in enums[Settings.CompleteEnumName].ConstantCollection.Values) diff --git a/Source/Bind/Main.cs b/Source/Bind/Main.cs index ae78d878..1a9f4164 100644 --- a/Source/Bind/Main.cs +++ b/Source/Bind/Main.cs @@ -86,18 +86,21 @@ namespace Bind case "ns": Settings.OutputNamespace = b[1]; break; - //case "gl": - // Settings.OutputClass = b[1]; - // break; - //case "glu": - // Settings.OutputClass = b[1]; - // break; - case "legacy": - Settings.Compatibility = b[1].ToLower() == "tao" ? Settings.Legacy.Tao : Settings.Legacy.None; - break; case "class": Settings.OutputClass = b[1]; break; + case "gl": + Settings.GLClass = b[1]; + break; + case "legacy": + Settings.Compatibility |= b[1].ToLower().Contains("tao") ? Settings.Legacy.Tao : Settings.Legacy.None; + Settings.Compatibility |= b[1].ToLower().Contains("enums") ? Settings.Legacy.NoAdvancedEnumProcessing : Settings.Legacy.None; + Settings.Compatibility |= b[1].ToLower().Contains("safe") ? Settings.Legacy.NoPublicUnsafeFunctions : Settings.Legacy.None; + //Settings.Compatibility |= b[1].ToLower().Contains("novoid") ? Settings.Legacy.TurnVoidPointersToIntPtr : Settings.Legacy.None; + break; + case "enum": + Settings.NestedEnumsClass = b[1]; + break; default: throw new ArgumentException( String.Format("Argument {0} not recognized. Use the '/?' switch for help.", a) diff --git a/Source/Bind/Settings.cs b/Source/Bind/Settings.cs index 02640496..08515f9e 100644 --- a/Source/Bind/Settings.cs +++ b/Source/Bind/Settings.cs @@ -20,24 +20,27 @@ namespace Bind public const string DefaultOutputPath = "..\\..\\..\\Source\\OpenTK\\OpenGL\\Bindings"; public const string DefaultOutputNamespace = "OpenTK.OpenGL"; - public static string OutputClass = "GL"; + public static string GLClass = "GL"; // Needed by Glu for the AuxEnumsClass. Can be set through -gl:"xxx". + public static string OutputClass = "GL"; // The real output class. Can be set through -class:"xxx". public static string FunctionPrefix = "gl"; public static string ConstantPrefix = "GL_"; // TODO: This code is too fragile. - public static string NestedEunmsClass = "Enums"; private static string normalEnumsClassOverride; + public static string NestedEnumsClass = "Enums"; public static string NormalEnumsClass { get { - if (!String.IsNullOrEmpty(normalEnumsClassOverride)) - return normalEnumsClassOverride; - return OutputClass + "." + NestedEunmsClass; + return String.IsNullOrEmpty(NestedEnumsClass) ? OutputClass : + OutputClass + "." + NestedEnumsClass; } - set { normalEnumsClassOverride = value; } } - public static string AuxEnumsClass = "GL." + NestedEunmsClass; + + public static string AuxEnumsClass + { + get { return GLClass + NestedEnumsClass; } + } public static string DelegatesClass = "Delegates"; public static string ImportsClass = "Imports"; @@ -49,10 +52,18 @@ namespace Bind /// public static string CompleteEnumName = "All"; + [Flags] public enum Legacy { - None, - Tao, + None = 0x00, + ConstIntEnums = 0x01, + NoAdvancedEnumProcessing = 0x02, + NoPublicUnsafeFunctions = 0x04, + NoTrimFunctionEnding = NoPublicUnsafeFunctions, + NoTrimFunctionPrefix = 0x08, + NoSeparateFunctionNamespaces = 0x10, + TurnVoidPointersToIntPtr = 0x20, + Tao = ConstIntEnums | NoAdvancedEnumProcessing | NoPublicUnsafeFunctions | NoTrimFunctionEnding | NoTrimFunctionPrefix | NoSeparateFunctionNamespaces | TurnVoidPointersToIntPtr, } public static string WindowsGDI = "OpenTK.Platform.Windows.API"; diff --git a/Source/Bind/Structures/Delegate.cs b/Source/Bind/Structures/Delegate.cs index fea78f31..25be95cc 100644 --- a/Source/Bind/Structures/Delegate.cs +++ b/Source/Bind/Structures/Delegate.cs @@ -151,6 +151,9 @@ namespace Bind.Structures //set { @unsafe = value; } get { + //if ((Settings.Compatibility & Settings.Legacy.NoPublicUnsafeFunctions) != Settings.Legacy.None) + // return false; + if (ReturnType.Pointer) return true; @@ -309,7 +312,7 @@ namespace Bind.Structures sb.Append(ReturnType); sb.Append(" "); sb.Append(Name); - sb.Append(Parameters.ToString()); + sb.Append(Parameters.ToString(true)); return sb.ToString(); } @@ -486,102 +489,94 @@ namespace Bind.Structures { Function f; - if (function.Parameters[index].WrapperType == WrapperTypes.None) + switch (function.Parameters[index].WrapperType) { - // No wrapper needed, visit the next parameter - ++index; - WrapParameters(function, wrappers); - --index; - } - else - { - switch (function.Parameters[index].WrapperType) - { - case WrapperTypes.ArrayParameter: - // Recurse to the last parameter - ++index; - WrapParameters(function, wrappers); - --index; + case WrapperTypes.None: + // No wrapper needed, visit the next parameter + ++index; + WrapParameters(function, wrappers); + --index; + break; - //if (function.Name == "UseFontOutlinesA") - { - } + case WrapperTypes.ArrayParameter: + // Recurse to the last parameter + ++index; + WrapParameters(function, wrappers); + --index; - // On stack rewind, create array wrappers - f = new Function(function); - f.Parameters[index].Reference = false; - f.Parameters[index].Array = 1; - f.Parameters[index].Pointer = false; - f.Body = CreateBody(f, false); - //f = ReferenceWrapper(new Function(function), index); - wrappers.Add(f); + // On stack rewind, create array wrappers + f = new Function(function); + f.Parameters[index].Reference = false; + f.Parameters[index].Array = 1; + f.Parameters[index].Pointer = false; + f.Body = CreateBody(f, false); + wrappers.Add(f); - // Recurse to the last parameter again, keeping the Array wrappers - ++index; - WrapParameters(f, wrappers); - --index; + // Recurse to the last parameter again, keeping the Array wrappers + ++index; + WrapParameters(f, wrappers); + --index; - f = new Function(function); - f.Parameters[index].Reference = true; - f.Parameters[index].Array = 0; - f.Parameters[index].Pointer = false; - f.Body = CreateBody(f, false); - //f = ReferenceWrapper(new Function(function), index); - wrappers.Add(f); + // On stack rewind create reference wrappers. + f = new Function(function); + f.Parameters[index].Reference = true; + f.Parameters[index].Array = 0; + f.Parameters[index].Pointer = false; + f.Body = CreateBody(f, false); + wrappers.Add(f); - // Keeping the current Ref wrapper, visit all other parameters once more - ++index; - WrapParameters(f, wrappers); - --index; + // Keeping the current reference wrapper, revisit all other parameters. + ++index; + WrapParameters(f, wrappers); + --index; - break; + break; - case WrapperTypes.GenericParameter: - // Recurse to the last parameter - ++index; - WrapParameters(function, wrappers); - --index; + case WrapperTypes.GenericParameter: + // Recurse to the last parameter + ++index; + WrapParameters(function, wrappers); + --index; - // On stack rewind, create array wrappers - f = new Function(function); - f.Parameters[index].Reference = false; - f.Parameters[index].Array = 0; - f.Parameters[index].Pointer = false; - f.Parameters[index].CurrentType = "object"; - f.Parameters[index].Flow = Parameter.FlowDirection.Undefined; + // On stack rewind, create object wrappers + f = new Function(function); + f.Parameters[index].Reference = false; + f.Parameters[index].Array = 0; + f.Parameters[index].Pointer = false; + f.Parameters[index].CurrentType = "object"; + f.Parameters[index].Flow = Parameter.FlowDirection.Undefined; - f.Body = CreateBody(f, false); - wrappers.Add(f); + f.Body = CreateBody(f, false); + wrappers.Add(f); - // Keeping the current Object wrapper, visit all other parameters once more - ++index; - WrapParameters(f, wrappers); - --index; + // Keeping the current Object wrapper, visit all other parameters once more + ++index; + WrapParameters(f, wrappers); + --index; - break; + break; - case WrapperTypes.ReferenceParameter: - // Recurse to the last parameter - ++index; - WrapParameters(function, wrappers); - --index; + //case WrapperTypes.ReferenceParameter: + // // Recurse to the last parameter + // ++index; + // WrapParameters(function, wrappers); + // --index; - // On stack rewind, create reference wrappers - f = new Function(function); - f.Parameters[index].Reference = true; - f.Parameters[index].Array = 0; - f.Parameters[index].Pointer = false; - f.Body = CreateBody(f, false); - //f = ReferenceWrapper(new Function(function), index); - wrappers.Add(f); + // // On stack rewind, create reference wrappers + // f = new Function(function); + // f.Parameters[index].Reference = true; + // f.Parameters[index].Array = 0; + // f.Parameters[index].Pointer = false; + // f.Body = CreateBody(f, false); + // //f = ReferenceWrapper(new Function(function), index); + // wrappers.Add(f); - // Keeping the current Object wrapper, visit all other parameters once more - ++index; - WrapParameters(f, wrappers); - --index; + // // Keeping the current Object wrapper, visit all other parameters once more + // ++index; + // WrapParameters(f, wrappers); + // --index; - break; - } + // break; } } } @@ -592,7 +587,7 @@ namespace Bind.Structures protected Function DefaultWrapper(Function f) { - bool returns = f.ReturnType.CurrentType.ToLower().Contains("void") && !f.ReturnType.Pointer; + bool returns = f.ReturnType.CurrentType.ToLower().Contains("void");// && !f.ReturnType.Pointer; string callString = String.Format( "{0} {1}{2}; {3}", Unsafe ? "unsafe {" : "", @@ -625,8 +620,8 @@ namespace Bind.Structures assign_statements.Clear(); //if (f.Name == "LoadDisplayColorTableEXT") - { - } + //{ + //} // Obtain pointers by pinning the parameters foreach (Parameter p in f.Parameters) @@ -651,7 +646,10 @@ namespace Bind.Structures } // Note! The following line modifies f.Parameters, *not* this.Parameters - p.Name = "(void*)" + p.Name + "_ptr.AddrOfPinnedObject()"; + //if ((Settings.Compatibility & Settings.Legacy.TurnVoidPointersToIntPtr) != Settings.Legacy.None) + p.Name = "(IntPtr)" + p.Name + "_ptr.AddrOfPinnedObject()"; + //else + //p.Name = "(void*)" + p.Name + "_ptr.AddrOfPinnedObject()"; } else if (p.WrapperType == WrapperTypes.PointerParameter || p.WrapperType == WrapperTypes.ArrayParameter || @@ -752,9 +750,7 @@ namespace Bind.Structures #endregion - #endregion - - #region Translate + #region protected virtual void TranslateReturnType() /// /// Translates the opengl return type to the equivalent C# type. @@ -824,18 +820,20 @@ namespace Bind.Structures ReturnType.CurrentType = ReturnType.GetCLSCompliantType(); } + #endregion + + #region protected virtual void TranslateParameters() + protected virtual void TranslateParameters() { - if (this.Name.Contains("SetLayerPaletteEntries")) - { - // Console.WriteLine(); - } + //if (this.Name.Contains("VertexPointer")) + //{ + // Console.WriteLine(); + //} for (int i = 0; i < Parameters.Count; i++) { Parameters[i] = Parameter.Translate(Parameters[i], this.Category); - // Special cases: glLineStipple and gl(Get)ShaderSource: - // Check for LineStipple (should be unchecked) if (Parameters[i].CurrentType == "UInt16" && Name.Contains("LineStipple")) { Parameters[i].WrapperType = WrapperTypes.UncheckedParameter; @@ -850,6 +848,8 @@ namespace Bind.Structures } } + #endregion + internal void Translate() { TranslateReturnType(); diff --git a/Source/Bind/Structures/Enum.cs b/Source/Bind/Structures/Enum.cs index a4cb4cb8..c35acc72 100644 --- a/Source/Bind/Structures/Enum.cs +++ b/Source/Bind/Structures/Enum.cs @@ -139,6 +139,12 @@ namespace Bind.Structures } } } + + // Obey .Net naming rules: + if ((Settings.Compatibility & Settings.Legacy.NoAdvancedEnumProcessing) == Settings.Legacy.None) + { + + } } } diff --git a/Source/Bind/Structures/Function.cs b/Source/Bind/Structures/Function.cs index 3524309d..4bb81088 100644 --- a/Source/Bind/Structures/Function.cs +++ b/Source/Bind/Structures/Function.cs @@ -63,14 +63,26 @@ namespace Bind.Structures #endregion + public void TurnVoidPointersToIntPtr() + { + foreach (Parameter p in this.Parameters) + { + if (p.Pointer && p.CurrentType == "void") + { + p.CurrentType = "IntPtr"; + p.Pointer = false; + } + } + } + #region public override bool Unsafe public override bool Unsafe { get { - if (Settings.Compatibility == Settings.Legacy.Tao) - return false; + //if ((Settings.Compatibility & Settings.Legacy.NoPublicUnsafeFunctions) != Settings.Legacy.None) + // return false; return base.Unsafe; } @@ -91,22 +103,9 @@ namespace Bind.Structures #endregion #region public string TrimmedName - /* - string trimmedName; - /// - /// Gets or sets the name of the opengl function, trimming the excess 234dfubsiv endings. - /// - public string TrimmedName - { - get { return trimmedName; } - set - { - if (!String.IsNullOrEmpty(value)) - trimmedName = value.Trim(); - } - } - */ + public string TrimmedName; + #endregion #region public override string Name @@ -123,7 +122,7 @@ namespace Bind.Structures { base.Name = value; - if (Settings.Compatibility == Settings.Legacy.Tao) + if ((Settings.Compatibility & Settings.Legacy.NoTrimFunctionEnding) != Settings.Legacy.None) { // If we don't need compatibility with Tao, // remove the Extension and the overload information from the name @@ -134,43 +133,6 @@ namespace Bind.Structures else { TrimmedName = Utilities.StripGL2Extension(value); - - //if (TrimmedName.Contains("Uniform2iv")) - //{ - // Console.Write("niar"); - //} - - // Remove overload - /* - for (int i = 3; i >= 1; i--) - { - if (endings.Contains(TrimmedName.Substring(TrimmedName.Length - i))) - { - // If there is a digit before the ending (e.g. 3fv) then we will remove - // the ending (some functions are blacklisted for CLS-Compliance). - // Otherwise, if there is no digit, but it ends with a 'v', do not remove - // the 'v' (CLS-Compliance). If no digit and it ends with a (plural) 's', - // do not remove anything (e.g. glCallLists) - // TODO: Add better handling for CLS-Compliance on ref ('v') functions. - if (Char.IsDigit(TrimmedName[TrimmedName.Length - (i + 1)])) - { - if (!endingsAddV.IsMatch(Name)) - { - TrimmedName = TrimmedName.Substring(0, TrimmedName.Length - i); - } - else - { - Console.WriteLine("Function {0} blacklisted from trimming (CLS-Compliance).", Name); - } - } - else if (TrimmedName.EndsWith("v")) - { - TrimmedName = TrimmedName.Substring(0, TrimmedName.Length - i) + "v"; - } - return; - } - } - */ //if (Name.Contains("BooleanIndexed")) { @@ -183,10 +145,12 @@ namespace Bind.Structures m = endings.Match(TrimmedName); if (m.Length > 0 && m.Index + m.Length == TrimmedName.Length) - { // Only trim endings, not internal matches. + { + // Only trim endings, not internal matches. if (m.Value[m.Length - 1] == 'v' && endingsAddV.IsMatch(Name) && !Name.StartsWith("Get") && !Name.StartsWith("MatrixIndex")) - { // Only trim ending 'v' when there is a number + { + // Only trim ending 'v' when there is a number TrimmedName = TrimmedName.Substring(0, m.Index) + "v"; } else @@ -213,12 +177,12 @@ namespace Bind.Structures sb.Append(Unsafe ? "unsafe " : ""); sb.Append(ReturnType); sb.Append(" "); - if (Settings.Compatibility == Settings.Legacy.Tao) + if ((Settings.Compatibility & Settings.Legacy.NoTrimFunctionEnding) != Settings.Legacy.None) { sb.Append(Settings.FunctionPrefix); } sb.Append(!String.IsNullOrEmpty(TrimmedName) ? TrimmedName : Name); - sb.Append(Parameters.ToString(true)); + sb.Append(Parameters.ToString(false)); if (Body.Count > 0) { sb.AppendLine(); diff --git a/Source/Bind/Structures/Parameter.cs b/Source/Bind/Structures/Parameter.cs index a298d699..67ba5b68 100644 --- a/Source/Bind/Structures/Parameter.cs +++ b/Source/Bind/Structures/Parameter.cs @@ -18,6 +18,7 @@ namespace Bind.Structures { string cache; bool rebuild; + bool unsafe_allowed; // True if the cache may contain unsafe types, false otherwise. #region Constructors @@ -173,19 +174,18 @@ namespace Bind.Structures #endregion - #region override public string ToString() - - override public string ToString() + public override string ToString() { return ToString(false); } - #endregion + #region public string ToString(bool override_unsafe_setting) - #region public string ToString(bool taoCompatible) - - public string ToString(bool taoCompatible) + public string ToString(bool override_unsafe_setting) { + rebuild |= unsafe_allowed |= override_unsafe_setting; + unsafe_allowed = override_unsafe_setting; + if (!String.IsNullOrEmpty(cache) && !rebuild) { return cache; @@ -207,7 +207,7 @@ namespace Bind.Structures sb.Append("ref "); } - if (taoCompatible && Settings.Compatibility == Settings.Legacy.Tao) + if (!override_unsafe_setting && ((Settings.Compatibility & Settings.Legacy.NoPublicUnsafeFunctions) != Settings.Legacy.None)) { if (Pointer) { @@ -228,7 +228,6 @@ namespace Bind.Structures if (Array > 0) sb.Append("[]"); } - if (!String.IsNullOrEmpty(Name)) { sb.Append(" "); @@ -262,7 +261,7 @@ namespace Bind.Structures // Translate enum types if ((normal || aux) && @enum.Name != "GLenum") { - if (Settings.Compatibility == Settings.Legacy.Tao) + if ((Settings.Compatibility & Settings.Legacy.ConstIntEnums) != Settings.Legacy.None) { p.CurrentType = "int"; } @@ -284,7 +283,7 @@ namespace Bind.Structures // check if a better match exists: if (s.Contains("GLenum") && !String.IsNullOrEmpty(Category)) { - if (Settings.Compatibility == Settings.Legacy.None) + if ((Settings.Compatibility & Settings.Legacy.ConstIntEnums) == Settings.Legacy.None) { // Better match: enum.Name == function.Category (e.g. GL_VERSION_1_1 etc) if (Enum.GLEnums.ContainsKey(Category)) @@ -346,7 +345,7 @@ namespace Bind.Structures // p.CurrentType = CSTypes[p.CurrentType]; // Translate pointer parameters - if (p.Pointer) + if (p.Pointer || p.CurrentType == "IntPtr") { p.WrapperType = WrapperTypes.ArrayParameter; @@ -361,8 +360,10 @@ namespace Bind.Structures p.Pointer = false; p.WrapperType = WrapperTypes.None; } - else if (p.CurrentType.ToLower().Contains("void")) + else if (p.CurrentType.ToLower().Contains("void") || p.CurrentType.Contains("IntPtr")) { + p.CurrentType = "IntPtr"; + p.Pointer = false; p.WrapperType = WrapperTypes.GenericParameter; } } @@ -394,6 +395,7 @@ namespace Bind.Structures private bool rebuild = true; bool hasPointerParameters; bool hasReferenceParameters; + bool unsafe_types_allowed; private bool Rebuild { get { return rebuild; } @@ -419,14 +421,20 @@ namespace Bind.Structures #endregion + #region void BuildCache() + void BuildCache() { BuildCallStringCache(); - BuildToStringCache(); + BuildToStringCache(unsafe_types_allowed); BuildReferenceAndPointerParametersCache(); Rebuild = false; } + #endregion + + #region public bool HasPointerParameters + public bool HasPointerParameters { get @@ -442,7 +450,11 @@ namespace Bind.Structures } } } - + + #endregion + + #region public bool HasReferenceParameters + public bool HasReferenceParameters { get @@ -459,11 +471,15 @@ namespace Bind.Structures } } + #endregion + + #region void BuildReferenceAndPointerParametersCache() + void BuildReferenceAndPointerParametersCache() { foreach (Parameter p in this) { - if (p.Pointer) + if (p.Pointer || p.CurrentType.Contains("IntPtr")) hasPointerParameters = true; if (p.Reference) @@ -471,6 +487,8 @@ namespace Bind.Structures } } + #endregion + #region new public void Add(Parameter p) new public void Add(Parameter p) @@ -481,29 +499,23 @@ namespace Bind.Structures #endregion - #region override public string ToString() - - /// - /// Gets the parameter declaration string. - /// - /// The parameter list of an opengl function in the form ( [parameters] ) - override public string ToString() + public override string ToString() { return ToString(false); } - #endregion - - #region public string ToString(bool taoCompatible) + #region public string ToString(bool override_unsafe_setting) /// /// Gets the parameter declaration string. /// - /// If true, all types will be replaced by their CLSCompliant C# equivalents - /// The list of C# types equivalent to the OpenGL types. + /// If true, unsafe types will be used even if the Settings.Compatibility.NoPublicUnsafeFunctions flag is set. /// The parameter list of an opengl function in the form ( [parameters] ) - public string ToString(bool taoCompatible) + public string ToString(bool override_unsafe_setting) { + Rebuild |= unsafe_types_allowed != override_unsafe_setting; + unsafe_types_allowed = override_unsafe_setting; + if (!Rebuild) { return cache; @@ -517,24 +529,19 @@ namespace Bind.Structures #endregion - #region void BuildToStringCache() + #region void BuildToStringCache(bool override_unsafe_setting) - void BuildToStringCache() + void BuildToStringCache(bool override_unsafe_setting) { + unsafe_types_allowed = override_unsafe_setting; + StringBuilder sb = new StringBuilder(); sb.Append("("); if (this.Count > 0) { foreach (Parameter p in this) { - if (Settings.Compatibility == Settings.Legacy.Tao) - { - sb.Append(p.ToString(true)); - } - else - { - sb.Append(p.ToString()); - } + sb.Append(p.ToString(override_unsafe_setting)); sb.Append(", "); } sb.Replace(", ", ")", sb.Length - 2, 2); @@ -588,18 +595,15 @@ namespace Bind.Structures { sb.Append(String.Format("({0}{1})", p.CurrentType, (p.Array > 0) ? "[]" : "")); - } else if (p.Pointer || p.Array > 0 || p.Reference) { - sb.Append(String.Format("({0}*)", - p.CurrentType /*, (p.Pointer || p.Array > 0) ? "*" : ""*/)); + if (((Settings.Compatibility & Settings.Legacy.TurnVoidPointersToIntPtr) != Settings.Legacy.None) && + p.Pointer && p.CurrentType.Contains("void")) + sb.Append("(IntPtr)"); + else + sb.Append(String.Format("({0}*)", p.CurrentType)); } - //else if (p.Reference) - //{ - // sb.Append(String.Format("{0} ({1})", - // p.Flow == Parameter.FlowDirection.Out ? "out" : "ref", p.CurrentType)); - //} else { sb.Append(String.Format("({0})", p.CurrentType)); diff --git a/Source/Bind/Structures/Type.cs b/Source/Bind/Structures/Type.cs index 2f4b48cf..e9a0b140 100644 --- a/Source/Bind/Structures/Type.cs +++ b/Source/Bind/Structures/Type.cs @@ -76,8 +76,8 @@ namespace Bind.Structures //get { return _type; } get { - //if (Pointer && Settings.Compatibility == Settings.Legacy.Tao) - // return "IntPtr"; + if (((Settings.Compatibility & Settings.Legacy.TurnVoidPointersToIntPtr) != Settings.Legacy.None) && Pointer && type.Contains("void")) + return "IntPtr"; return type; } @@ -155,11 +155,16 @@ namespace Bind.Structures { get { - return !( - (Pointer && (Settings.Compatibility != Settings.Legacy.Tao)) || + bool compliant = !(CurrentType.Contains("UInt") || CurrentType.Contains("SByte")); + return compliant && (!Pointer || CurrentType.Contains("IntPtr")); + //return compliant && !(Pointer && ((Settings.Compatibility & Settings.Legacy.NoPublicUnsafeFunctions) == Settings.Legacy.None)); + + /* + * return !( + (Pointer && ((Settings.Compatibility & Settings.Legacy.NoPublicUnsafeFunctions) == Settings.Legacy.None ) || CurrentType.Contains("UInt") || - CurrentType.Contains("SByte")); - + CurrentType.Contains("SByte"))); + */ /*(Type.Contains("GLu") && !Type.Contains("GLubyte")) || Type == "GLbitfield" || @@ -187,8 +192,8 @@ namespace Bind.Structures public string GetFullType(Dictionary CSTypes, bool compliant) { - if (Pointer && Settings.Compatibility == Settings.Legacy.Tao) - return "IntPtr"; + //if (Pointer && ((Settings.Compatibility & Settings.Legacy.NoPublicUnsafeFunctions) != Settings.Legacy.None)) + // return "IntPtr"; if (!compliant) { @@ -230,6 +235,8 @@ namespace Bind.Structures case "SByte": case "sbyte": return "Byte"; + case "UIntPtr": + return "IntPtr"; } } diff --git a/Source/Bind/Utilities.cs b/Source/Bind/Utilities.cs index cd3d1c22..50edde51 100644 --- a/Source/Bind/Utilities.cs +++ b/Source/Bind/Utilities.cs @@ -9,6 +9,7 @@ using System.Collections.Generic; using System.Text; using System.IO; using Bind.Structures; +using System.Text.RegularExpressions; namespace Bind { @@ -67,6 +68,9 @@ namespace Bind public static class Utilities { public static readonly char[] Separators = { ' ', '\n', ',', '(', ')', ';', '#' }; + public static readonly Regex Extensions = new Regex( + "(ARB|EXT|ATI|NV|SUNX|SUN|SGIS|SGIX|SGI|MESA|3DFX|IBM|GREMEDY|HP|INTEL|PGI|INGR|APPLE|OML|I3D)", + RegexOptions.Compiled); #region internal StreamReader OpenSpecFile(string file)