Added GetOverridesPath method

GetOverridesPath encapsulates the code that retrieves an override enum
or function from overrides.xml. Additionally, it now supports names and
extensions with multiple values (e.g. extension="Core|Ext").
This commit is contained in:
Stefanos A 2013-11-03 01:20:17 +01:00
parent 61a6a2bec0
commit c5b9dbc83e
2 changed files with 88 additions and 35 deletions

View file

@ -39,7 +39,6 @@ namespace Bind
{ {
class EnumProcessor class EnumProcessor
{ {
const string Path = "/signatures/replace/enum[@name='{0}']";
string Overrides { get; set; } string Overrides { get; set; }
IBind Generator { get; set; } IBind Generator { get; set; }
@ -56,15 +55,36 @@ namespace Bind
Overrides = overrides; Overrides = overrides;
} }
public EnumCollection Process(EnumCollection enums) public EnumCollection Process(EnumCollection enums, string apiname)
{ {
var nav = new XPathDocument(Overrides).CreateNavigator(); var nav = new XPathDocument(Overrides).CreateNavigator();
enums = ProcessNames(enums, nav); enums = ProcessNames(enums, nav, apiname);
enums = ProcessConstants(enums, nav); enums = ProcessConstants(enums, nav, apiname);
return enums; return enums;
} }
EnumCollection ProcessNames(EnumCollection enums, XPathNavigator nav) public static string GetOverridesPath(string apiname, string enumeration)
{
if (enumeration == null)
throw new ArgumentNullException("enumeration");
var path = new StringBuilder();
path.Append("/signatures/replace");
if (apiname != null)
{
path.Append(String.Format("[contains(concat('|', @name, '|'), '|{0}|')]", apiname));
}
path.Append(String.Format(
"/enum[contains(concat('|', @name, '|'), '|{0}|')]",
enumeration));
return path.ToString();
}
#region Private Members
EnumCollection ProcessNames(EnumCollection enums, XPathNavigator nav, string apiname)
{ {
EnumCollection processed_enums = new EnumCollection(); EnumCollection processed_enums = new EnumCollection();
foreach (var e in enums.Values) foreach (var e in enums.Values)
@ -73,7 +93,7 @@ namespace Bind
// so we keep a list of modified enums and remove/readd the // so we keep a list of modified enums and remove/readd the
// modified items to refresh their keys. // modified items to refresh their keys.
string name = e.Name; string name = e.Name;
name = ReplaceName(nav, name); name = ReplaceName(nav, apiname, name);
name = TranslateEnumName(name); name = TranslateEnumName(name);
e.Name = name; e.Name = name;
processed_enums.Add(e.Name, e); processed_enums.Add(e.Name, e);
@ -81,9 +101,9 @@ namespace Bind
return processed_enums; return processed_enums;
} }
static string ReplaceName(XPathNavigator nav, string name) static string ReplaceName(XPathNavigator nav, string apiname, string name)
{ {
var enum_override = nav.SelectSingleNode(String.Format(Path, name)); var enum_override = nav.SelectSingleNode(GetOverridesPath(apiname, name));
if (enum_override != null) if (enum_override != null)
{ {
var name_override = enum_override.SelectSingleNode("name"); var name_override = enum_override.SelectSingleNode("name");
@ -171,7 +191,7 @@ namespace Bind
return name; return name;
} }
EnumCollection ProcessConstants(EnumCollection enums, XPathNavigator nav) EnumCollection ProcessConstants(EnumCollection enums, XPathNavigator nav, string apiname)
{ {
foreach (var e in enums.Values) foreach (var e in enums.Values)
{ {
@ -186,7 +206,7 @@ namespace Bind
} }
e.ConstantCollection = processed_constants; e.ConstantCollection = processed_constants;
var enum_override = nav.SelectSingleNode(String.Format(Path, e.Name)); var enum_override = nav.SelectSingleNode(GetOverridesPath(apiname, e.Name));
foreach (Constant c in e.ConstantCollection.Values) foreach (Constant c in e.ConstantCollection.Values)
{ {
ReplaceConstant(enum_override, c); ReplaceConstant(enum_override, c);
@ -360,5 +380,7 @@ namespace Bind
} }
return is_number; return is_number;
} }
#endregion
} }
} }

View file

@ -30,6 +30,7 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Xml.XPath; using System.Xml.XPath;
using Bind.Structures; using Bind.Structures;
@ -42,7 +43,6 @@ namespace Bind
class FuncProcessor class FuncProcessor
{ {
const string Path = "/signatures/replace/function[@name='{0}' and @extension='{1}']";
static readonly Regex Endings = static readonly Regex Endings =
new Regex(@"((((d|f|fi)|(L?(u?i?64)?u?[isb]))_?(64)?v?)|v)", RegexOptions.Compiled | RegexOptions.RightToLeft); new Regex(@"((((d|f|fi)|(L?(u?i?64)?u?[isb]))_?(64)?v?)|v)", RegexOptions.Compiled | RegexOptions.RightToLeft);
static readonly Regex EndingsNotToTrim = static readonly Regex EndingsNotToTrim =
@ -65,16 +65,16 @@ namespace Bind
Overrides = overrides; Overrides = overrides;
} }
public FunctionCollection Process(EnumProcessor enum_processor, DelegateCollection delegates, EnumCollection enums) public FunctionCollection Process(EnumProcessor enum_processor, DelegateCollection delegates, EnumCollection enums, string apiname)
{ {
Console.WriteLine("Processing delegates."); Console.WriteLine("Processing delegates.");
var nav = new XPathDocument(Overrides).CreateNavigator(); var nav = new XPathDocument(Overrides).CreateNavigator();
foreach (var d in delegates.Values) foreach (var d in delegates.Values)
{ {
TranslateExtension(d); TranslateExtension(d);
TranslateReturnType(enum_processor, nav, d, enums); TranslateReturnType(enum_processor, nav, d, enums, apiname);
TranslateParameters(enum_processor, nav, d, enums); TranslateParameters(enum_processor, nav, d, enums, apiname);
TranslateAttributes(nav, d, enums); TranslateAttributes(nav, d, enums, apiname);
} }
Console.WriteLine("Generating wrappers."); Console.WriteLine("Generating wrappers.");
@ -86,9 +86,39 @@ namespace Bind
return MarkCLSCompliance(wrappers); return MarkCLSCompliance(wrappers);
} }
#region TranslateType public static string GetOverridesPath(string apiname, string function, string extension)
{
if (function == null)
throw new ArgumentNullException("function");
void TranslateType(Bind.Structures.Type type, EnumProcessor enum_processor, XPathNavigator overrides, string category, EnumCollection enums) var path = new StringBuilder();
path.Append("/signatures/replace");
if (apiname != null)
{
path.Append(String.Format("[contains(concat('|', @name, '|'), '|{0}|')]", apiname));
}
if (extension != null)
{
path.Append(String.Format(
"/function[contains(concat('|', @name, '|'), '|{0}|') and contains(concat('|', @extension, '|'), '|{1}|')]",
function,
extension));
}
else
{
path.Append(String.Format(
"/function[contains(concat('|', @name, '|'), '|{0}|')]",
function));
}
return path.ToString();
}
#region Private Members
void TranslateType(Bind.Structures.Type type, EnumProcessor enum_processor, XPathNavigator overrides, EnumCollection enums,
string category, string apiname)
{ {
Bind.Structures.Enum @enum; Bind.Structures.Enum @enum;
string s; string s;
@ -162,8 +192,7 @@ namespace Bind
// if enum ErrorCodes is overriden to ErrorCode, then parameters // if enum ErrorCodes is overriden to ErrorCode, then parameters
// of type ErrorCodes should also be overriden to ErrorCode. // of type ErrorCodes should also be overriden to ErrorCode.
XPathNavigator enum_override = overrides.SelectSingleNode( XPathNavigator enum_override = overrides.SelectSingleNode(
String.Format("/signatures/replace/enum[@name='{0}']/name", EnumProcessor.GetOverridesPath(apiname, type.CurrentType));
type.CurrentType));
if (enum_override != null) if (enum_override != null)
{ {
// For consistency - many overrides use string instead of String. // For consistency - many overrides use string instead of String.
@ -186,8 +215,6 @@ namespace Bind
} }
} }
#endregion
void TranslateExtension(Delegate d) void TranslateExtension(Delegate d)
{ {
var extension = d.Extension.ToUpper(); var extension = d.Extension.ToUpper();
@ -249,16 +276,16 @@ namespace Bind
return trimmed_name; return trimmed_name;
} }
static XPathNavigator GetFuncOverride(XPathNavigator nav, Delegate d) static XPathNavigator GetFuncOverride(XPathNavigator nav, Delegate d, string apiname)
{ {
string ext = d.Extension; string ext = d.Extension;
string trimmed_name = GetTrimmedName(d); string trimmed_name = GetTrimmedName(d);
string extensionless_name = GetTrimmedExtension(d.Name, ext); string extensionless_name = GetTrimmedExtension(d.Name, ext);
var function_override = var function_override =
nav.SelectSingleNode(String.Format(Path, d.Name, ext)) ?? nav.SelectSingleNode(GetOverridesPath(apiname, d.Name, ext)) ??
nav.SelectSingleNode(String.Format(Path, extensionless_name, ext)) ?? nav.SelectSingleNode(GetOverridesPath(apiname, extensionless_name, ext)) ??
nav.SelectSingleNode(String.Format(Path, trimmed_name, ext)); nav.SelectSingleNode(GetOverridesPath(apiname, trimmed_name, ext));
return function_override; return function_override;
} }
@ -276,9 +303,9 @@ namespace Bind
// 3) A generic object or void* (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). // 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. // Return types must always be CLS-compliant, because .Net does not support overloading on return types.
void TranslateReturnType(EnumProcessor enum_processor, XPathNavigator nav, Delegate d, EnumCollection enums) void TranslateReturnType(EnumProcessor enum_processor, XPathNavigator nav, Delegate d, EnumCollection enums, string apiname)
{ {
var function_override = GetFuncOverride(nav, d); var function_override = GetFuncOverride(nav, d, apiname);
if (function_override != null) if (function_override != null)
{ {
@ -289,7 +316,7 @@ namespace Bind
} }
} }
TranslateType(d.ReturnType, enum_processor, nav, d.Category, enums); TranslateType(d.ReturnType, enum_processor, nav, enums, d.Category, apiname);
if (d.ReturnType.CurrentType.ToLower().Contains("void") && d.ReturnType.Pointer != 0) if (d.ReturnType.CurrentType.ToLower().Contains("void") && d.ReturnType.Pointer != 0)
{ {
@ -337,9 +364,10 @@ namespace Bind
} }
void TranslateParameters(EnumProcessor enum_processor, XPathNavigator nav, Delegate d, EnumCollection enums) void TranslateParameters(EnumProcessor enum_processor,
XPathNavigator nav, Delegate d, EnumCollection enums, string apiname)
{ {
var function_override = GetFuncOverride(nav, d); var function_override = GetFuncOverride(nav, d, apiname);
for (int i = 0; i < d.Parameters.Count; i++) for (int i = 0; i < d.Parameters.Count; i++)
{ {
@ -372,16 +400,17 @@ namespace Bind
} }
} }
TranslateParameter(d.Parameters[i], enum_processor, nav, d.Category, enums); TranslateParameter(d.Parameters[i], enum_processor, nav, enums, d.Category, apiname);
if (d.Parameters[i].CurrentType == "UInt16" && d.Name.Contains("LineStipple")) if (d.Parameters[i].CurrentType == "UInt16" && d.Name.Contains("LineStipple"))
d.Parameters[i].WrapperType = WrapperTypes.UncheckedParameter; d.Parameters[i].WrapperType = WrapperTypes.UncheckedParameter;
} }
} }
void TranslateParameter(Parameter p, EnumProcessor enum_processor, void TranslateParameter(Parameter p, EnumProcessor enum_processor,
XPathNavigator overrides, string category, EnumCollection enums) XPathNavigator overrides, EnumCollection enums,
string category, string apiname)
{ {
TranslateType(p, enum_processor, overrides, category, enums); TranslateType(p, enum_processor, overrides, enums, category, apiname);
// Find out the necessary wrapper types. // Find out the necessary wrapper types.
if (p.Pointer != 0)/* || CurrentType == "IntPtr")*/ if (p.Pointer != 0)/* || CurrentType == "IntPtr")*/
@ -434,9 +463,9 @@ namespace Bind
// WrapperType = WrapperTypes.BoolParameter; // WrapperType = WrapperTypes.BoolParameter;
} }
void TranslateAttributes(XPathNavigator nav, Delegate d, EnumCollection enums) void TranslateAttributes(XPathNavigator nav, Delegate d, EnumCollection enums, string apiname)
{ {
var function_override = GetFuncOverride(nav, d); var function_override = GetFuncOverride(nav, d, apiname);
if (function_override != null) if (function_override != null)
{ {
@ -766,5 +795,7 @@ namespace Bind
break; break;
} }
} }
#endregion
} }
} }