Added support for enum overrides.

Enabled enum overrides in the CL and ES generators.
Function parameters now follow enum overrides (for example, if function Foo takes enum Bar and enum Bar is overriden to Baz, this change will be reflected on function Foo).
Changed default CLGenerator settings to not generate debug helpers.
This commit is contained in:
the_fiddler 2009-08-11 14:12:20 +00:00
parent 3661428bce
commit 3ec5303e37
7 changed files with 107 additions and 72 deletions

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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")

View file

@ -507,29 +507,17 @@ namespace Bind.Structures
#region TranslateReturnType
/// <summary>
/// Translates the opengl return type to the equivalent C# type.
/// </summary>
/// <param name="d">The opengl function to translate.</param>
/// <remarks>
/// 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.
/// </remarks>
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();
}

View file

@ -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<string> keys_to_update = new List<string>();
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).

View file

@ -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
{

View file

@ -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;
}