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 000bdf71ef
commit cdde2893f6
7 changed files with 107 additions and 72 deletions

View file

@ -32,10 +32,15 @@ namespace Bind.CL
Settings.DelegatesClass = "Delegates"; Settings.DelegatesClass = "Delegates";
Settings.FunctionPrefix = "cl"; Settings.FunctionPrefix = "cl";
Settings.ConstantPrefix = "CL_";
Settings.EnumPrefix = "Cl";
Settings.OutputClass = "CL"; Settings.OutputClass = "CL";
Settings.OutputNamespace = "OpenTK.Compute." + name; Settings.OutputNamespace = "OpenTK.Compute." + name;
Settings.OutputPath = Path.Combine("../../Source/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) 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) public override Bind.Structures.EnumCollection ReadEnums(StreamReader specFile)
{ {
XPathDocument overrides = new XPathDocument(new StreamReader(Path.Combine(Settings.InputPath, functionOverridesFile)));
EnumCollection enums = new EnumCollection(); EnumCollection enums = new EnumCollection();
Bind.Structures.Enum all = new Bind.Structures.Enum(Settings.CompleteEnumName); Bind.Structures.Enum all = new Bind.Structures.Enum(Settings.CompleteEnumName);
XPathDocument doc = new XPathDocument(specFile); XPathDocument doc = new XPathDocument(specFile);
@ -117,7 +124,7 @@ namespace Bind.CL
} }
Utilities.Merge(enums, all); Utilities.Merge(enums, all);
enums.Translate(); enums.Translate(overrides);
return enums; return enums;
} }
} }

View file

@ -97,6 +97,8 @@ namespace Bind.ES
Bind.Structures.Enum all = new Bind.Structures.Enum(Settings.CompleteEnumName); Bind.Structures.Enum all = new Bind.Structures.Enum(Settings.CompleteEnumName);
XPathDocument doc = new XPathDocument(specFile); XPathDocument doc = new XPathDocument(specFile);
XPathNavigator nav = doc.CreateNavigator().SelectSingleNode("/signatures"); 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)) foreach (XPathNavigator node in nav.SelectChildren("enum", String.Empty))
{ {
@ -115,7 +117,7 @@ namespace Bind.ES
} }
Utilities.Merge(enums, all); Utilities.Merge(enums, all);
enums.Translate(); enums.Translate(overrides);
return enums; return enums;
} }
} }

View file

@ -70,7 +70,7 @@ namespace Bind.GL2
Bind.Structures.Type.Initialize(glTypemap, csTypemap); Bind.Structures.Type.Initialize(glTypemap, csTypemap);
Bind.Structures.Enum.Initialize(enumSpec, enumSpecExt); 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.Function.Initialize();
Bind.Structures.Delegate.Initialize(glSpec, glSpecExt); Bind.Structures.Delegate.Initialize(glSpec, glSpecExt);
@ -242,35 +242,6 @@ namespace Bind.GL2
} }
c.Name = words[0]; 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]; c.Value = words[2];
} }
else if (words[0] == "use") else if (words[0] == "use")

View file

@ -507,29 +507,17 @@ namespace Bind.Structures
#region TranslateReturnType #region TranslateReturnType
/// <summary> // Translates the opengl return type to the equivalent C# type.
/// Translates the opengl return type to the equivalent C# type. //
/// </summary> // First, we use the official typemap (gl.tm) to get the correct type.
/// <param name="d">The opengl function to translate.</param> // Then we override this, when it is:
/// <remarks> // 1) A string (we have to use Marshal.PtrToStringAnsi, to avoid heap corruption)
/// First, we use the official typemap (gl.tm) to get the correct type. // 2) An array (translates to IntPtr)
/// Then we override this, when it is: // 3) A generic object or void* (translates to IntPtr)
/// 1) A string (we have to use Marshal.PtrToStringAnsi, to avoid heap corruption) // 4) A GLenum (translates to int on Legacy.Tao or GL.Enums.GLenum otherwise).
/// 2) An array (translates to IntPtr) // Return types must always be CLS-compliant, because .Net does not support overloading on return types.
/// 3) A generic object or void* (translates to IntPtr) void TranslateReturnType(XPathNavigator overrides, XPathNavigator function_override)
/// 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)
{ {
/*
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) if (function_override != null)
{ {
XPathNavigator return_override = function_override.SelectSingleNode("returns"); 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) if (ReturnType.CurrentType.ToLower().Contains("void") && ReturnType.Pointer != 0)
{ {
@ -574,7 +562,7 @@ namespace Bind.Structures
#region TranslateParameters #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++) 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")) if (Parameters[i].CurrentType == "UInt16" && Name.Contains("LineStipple"))
Parameters[i].WrapperType = WrapperTypes.UncheckedParameter; Parameters[i].WrapperType = WrapperTypes.UncheckedParameter;
@ -616,9 +604,9 @@ namespace Bind.Structures
string path = "/overrides/function[@name='{0}' and @extension='{1}']"; string path = "/overrides/function[@name='{0}' and @extension='{1}']";
string name = TrimName(Name, false); string name = TrimName(Name, false);
XPathNavigator function_override = overrides.CreateNavigator().SelectSingleNode(String.Format(path, name, Extension)); XPathNavigator function_override = overrides.CreateNavigator().SelectSingleNode(String.Format(path, name, Extension));
TranslateReturnType(function_override); TranslateReturnType(overrides.CreateNavigator(), function_override);
TranslateParameters(function_override); TranslateParameters(overrides.CreateNavigator(), function_override);
CreateWrappers(); CreateWrappers();
} }

View file

@ -9,6 +9,7 @@ using System.Collections.Generic;
using System.Text; using System.Text;
using System.IO; using System.IO;
using System.Globalization; using System.Globalization;
using System.Xml.XPath;
namespace Bind.Structures namespace Bind.Structures
{ {
@ -157,7 +158,11 @@ namespace Bind.Structures
translator.Replace("Pname", "PName"); translator.Replace("Pname", "PName");
translator.Replace("SRgb", "Srgb"); 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 #endregion
@ -210,14 +215,31 @@ namespace Bind.Structures
Utilities.Merge(this, e); 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. // Translate enum names.
{ {
List<string> keys_to_update = new List<string>(); List<string> keys_to_update = new List<string>();
foreach (Enum e in this.Values) 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) if (name != e.Name)
{ {
keys_to_update.Add(e.Name); keys_to_update.Add(e.Name);
@ -237,8 +259,26 @@ namespace Bind.Structures
foreach (Enum e in this.Values) foreach (Enum e in this.Values)
{ {
XPathNavigator enum_override = overrides.CreateNavigator().SelectSingleNode(String.Format(path, e.Name));
foreach (Constant c in e.ConstantCollection.Values) 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. // 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) // (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). // 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.Collections.Generic;
using System.Text; using System.Text;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Xml.XPath;
namespace Bind.Structures namespace Bind.Structures
{ {
@ -280,11 +281,11 @@ namespace Bind.Structures
#endregion #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. // Find out the necessary wrapper types.
if (Pointer != 0)/* || CurrentType == "IntPtr")*/ if (Pointer != 0)/* || CurrentType == "IntPtr")*/
@ -589,13 +590,19 @@ namespace Bind.Structures
sb.Append(String.Format("({0}{1})", sb.Append(String.Format("({0}{1})",
p.CurrentType, (p.Array > 0) ? "[]" : "")); 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) && if (((Settings.Compatibility & Settings.Legacy.TurnVoidPointersToIntPtr) != Settings.Legacy.None) &&
p.Pointer != 0 && p.CurrentType.Contains("void")) p.Pointer != 0 && p.CurrentType.Contains("void"))
sb.Append("(IntPtr)"); sb.Append("(IntPtr)");
else else
sb.Append(String.Format("({0}*)", p.CurrentType)); {
sb.Append("(");
sb.Append(p.CurrentType);
for (int i = 0; i < p.IndirectionLevel; i++)
sb.Append("*");
sb.Append(")");
}
} }
else else
{ {

View file

@ -8,6 +8,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.IO; using System.IO;
using System.Xml.XPath;
namespace Bind.Structures namespace Bind.Structures
{ {
@ -156,7 +157,19 @@ namespace Bind.Structures
public int Pointer public int Pointer
{ {
get { return 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 #endregion
@ -261,9 +274,9 @@ namespace Bind.Structures
#endregion #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; Enum @enum;
string s; string s;
@ -346,6 +359,13 @@ namespace Bind.Structures
Bind.Structures.Type.CSTypes.ContainsKey(CurrentType) ? Bind.Structures.Type.CSTypes.ContainsKey(CurrentType) ?
Bind.Structures.Type.CSTypes[CurrentType] : 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)) if (CurrentType == "IntPtr" && String.IsNullOrEmpty(PreviousType))
Pointer = 0; Pointer = 0;
} }