Modified Type.Pointer property to be an integer instead of a boolean.

Improved handling of string arrays.
Added handling of flow direction to ESGenerator and Delegate.TranslateParameters().
Moved FlowDirection enum outside of Parameter class.
This commit is contained in:
the_fiddler 2009-07-15 22:33:26 +00:00
parent 300c7e06e7
commit ab26b80e2d
7 changed files with 122 additions and 77 deletions

View file

@ -41,8 +41,9 @@ namespace Bind.ES
DelegateCollection delegates = new DelegateCollection(); DelegateCollection delegates = new DelegateCollection();
XPathDocument overrides = new XPathDocument(new StreamReader(Path.Combine(Settings.InputPath, functionOverridesFile))); XPathDocument overrides = new XPathDocument(new StreamReader(Path.Combine(Settings.InputPath, functionOverridesFile)));
XPathDocument doc = new XPathDocument(specFile);
XPathNavigator nav = doc.CreateNavigator().SelectSingleNode("/signatures"); XPathNavigator nav = new XPathDocument(specFile).CreateNavigator().SelectSingleNode("/signatures");
foreach (XPathNavigator node in nav.SelectChildren("function", String.Empty)) foreach (XPathNavigator node in nav.SelectChildren("function", String.Empty))
{ {
Bind.Structures.Delegate d = new Bind.Structures.Delegate(); Bind.Structures.Delegate d = new Bind.Structures.Delegate();
@ -62,9 +63,13 @@ namespace Bind.ES
Parameter p = new Parameter(); Parameter p = new Parameter();
p.CurrentType = param.GetAttribute("type", String.Empty); p.CurrentType = param.GetAttribute("type", String.Empty);
p.Name = param.GetAttribute("name", String.Empty); p.Name = param.GetAttribute("name", String.Empty);
string element_count = param.GetAttribute("elementcount", String.Empty); string element_count = param.GetAttribute("elementcount", String.Empty);
if (!String.IsNullOrEmpty(element_count)) if (!String.IsNullOrEmpty(element_count))
p.ElementCount = Int32.Parse(element_count); p.ElementCount = Int32.Parse(element_count);
p.Flow = Parameter.GetFlowDirection(param.GetAttribute("flow", String.Empty));
d.Parameters.Add(p); d.Parameters.Add(p);
break; break;
} }

View file

@ -142,11 +142,11 @@ namespace Bind.GL2
p.Name = Utilities.Keywords.Contains(words[1]) ? "@" + words[1] : words[1]; p.Name = Utilities.Keywords.Contains(words[1]) ? "@" + words[1] : words[1];
p.CurrentType = words[2]; p.CurrentType = words[2];
p.Pointer |= words[4].Contains("array"); p.Pointer += words[4].Contains("array") ? 1 : 0;
p.Pointer |= words[4].Contains("reference"); p.Pointer += words[4].Contains("reference") ? 1 : 0;
if (p.Pointer && words.Count > 5 && words[5].Contains("[1]")) if (p.Pointer != 0 && words.Count > 5 && words[5].Contains("[1]"))
p.ElementCount = 1; p.ElementCount = 1;
p.Flow = words[3] == "in" ? Parameter.FlowDirection.In : Parameter.FlowDirection.Out; p.Flow = words[3] == "in" ? FlowDirection.In : FlowDirection.Out;
d.Parameters.Add(p); d.Parameters.Add(p);
break; break;
@ -671,7 +671,6 @@ namespace Bind.GL2
sw.WriteLine(); sw.WriteLine();
int current = 0; int current = 0;
int y = Console.CursorTop;
foreach (string key in wrappers.Keys) foreach (string key in wrappers.Keys)
{ {
if (((Settings.Compatibility & Settings.Legacy.NoSeparateFunctionNamespaces) == Settings.Legacy.None) && key != "Core") if (((Settings.Compatibility & Settings.Legacy.NoSeparateFunctionNamespaces) == Settings.Legacy.None) && key != "Core")

View file

@ -176,12 +176,12 @@ namespace Bind.Structures
//if ((Settings.Compatibility & Settings.Legacy.NoPublicUnsafeFunctions) != Settings.Legacy.None) //if ((Settings.Compatibility & Settings.Legacy.NoPublicUnsafeFunctions) != Settings.Legacy.None)
// return false; // return false;
if (ReturnType.Pointer) if (ReturnType.Pointer != 0)
return true; return true;
foreach (Parameter p in Parameters) foreach (Parameter p in Parameters)
{ {
if (p.Pointer) if (p.Pointer != 0)
{ {
return true; return true;
} }
@ -532,7 +532,7 @@ namespace Bind.Structures
if (function_override != null) if (function_override != null)
{ {
XPathNavigator return_override = function_override.SelectSingleNode("return"); XPathNavigator return_override = function_override.SelectSingleNode("returns");
if (return_override != null) if (return_override != null)
{ {
ReturnType.CurrentType = return_override.Value; ReturnType.CurrentType = return_override.Value;
@ -541,7 +541,7 @@ namespace Bind.Structures
ReturnType.Translate(this.Category); ReturnType.Translate(this.Category);
if (ReturnType.CurrentType.ToLower().Contains("void") && ReturnType.Pointer) if (ReturnType.CurrentType.ToLower().Contains("void") && ReturnType.Pointer != 0)
{ {
ReturnType.CurrentType = "IntPtr"; ReturnType.CurrentType = "IntPtr";
ReturnType.WrapperType = WrapperTypes.GenericReturnType; ReturnType.WrapperType = WrapperTypes.GenericReturnType;
@ -589,13 +589,13 @@ namespace Bind.Structures
{ {
case "type": Parameters[i].CurrentType = (string)node.TypedValue; break; case "type": Parameters[i].CurrentType = (string)node.TypedValue; break;
case "name": Parameters[i].Name = (string)node.TypedValue; break; case "name": Parameters[i].Name = (string)node.TypedValue; break;
case "flow": Parameters[i].Flow = Parameter.GetFlowDirection((string)node.TypedValue); break;
} }
} }
} }
} }
Parameters[i].Translate(this.Category); Parameters[i].Translate(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,6 +616,7 @@ 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(function_override);
TranslateParameters(function_override); TranslateParameters(function_override);

View file

@ -0,0 +1,42 @@
#region License
//
// The Open Toolkit Library License
//
// Copyright (c) 2006 - 2009 the Open Toolkit library.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
#endregion
using System;
namespace Bind.Structures
{
/// <summary>
/// Enumarates the possible flows of a parameter (ie. is this parameter
/// used as input or as output?)
/// </summary>
public enum FlowDirection
{
Undefined = 0,
In,
Out
}
}

View file

@ -76,10 +76,10 @@ namespace Bind.Structures
{ {
foreach (Parameter p in this.Parameters) foreach (Parameter p in this.Parameters)
{ {
if (p.Pointer && p.CurrentType == "void") if (p.Pointer != 0 && p.CurrentType == "void")
{ {
p.CurrentType = "IntPtr"; p.CurrentType = "IntPtr";
p.Pointer = false; p.Pointer = 0;
} }
} }
} }
@ -253,7 +253,7 @@ namespace Bind.Structures
{ {
p.Reference = false; p.Reference = false;
p.Array = 1; p.Array = 1;
p.Pointer = false; p.Pointer = 0;
} }
} }
f = new Function(this); f = new Function(this);
@ -268,7 +268,7 @@ namespace Bind.Structures
{ {
p.Reference = true; p.Reference = true;
p.Array = 0; p.Array = 0;
p.Pointer = false; p.Pointer = 0;
} }
} }
f = new Function(this); f = new Function(this);
@ -285,7 +285,7 @@ namespace Bind.Structures
{ {
p.Reference = false; p.Reference = false;
p.Array = 0; p.Array = 0;
p.Pointer = true; p.Pointer++;
} }
} }
f = new Function(this); f = new Function(this);
@ -320,40 +320,40 @@ namespace Bind.Structures
// On stack rewind, create generic wrappers // On stack rewind, create generic wrappers
Parameters[index].Reference = true; Parameters[index].Reference = true;
Parameters[index].Array = 0; Parameters[index].Array = 0;
Parameters[index].Pointer = false; Parameters[index].Pointer = 0;
Parameters[index].Generic = true; Parameters[index].Generic = true;
Parameters[index].CurrentType = "T" + index.ToString(); Parameters[index].CurrentType = "T" + index.ToString();
Parameters[index].Flow = Parameter.FlowDirection.Undefined; Parameters[index].Flow = FlowDirection.Undefined;
Parameters.Rebuild = true; Parameters.Rebuild = true;
CreateBody(false); CreateBody(false);
wrappers.Add(new Function(this)); wrappers.Add(new Function(this));
Parameters[index].Reference = false; Parameters[index].Reference = false;
Parameters[index].Array = 1; Parameters[index].Array = 1;
Parameters[index].Pointer = false; Parameters[index].Pointer = 0;
Parameters[index].Generic = true; Parameters[index].Generic = true;
Parameters[index].CurrentType = "T" + index.ToString(); Parameters[index].CurrentType = "T" + index.ToString();
Parameters[index].Flow = Parameter.FlowDirection.Undefined; Parameters[index].Flow = FlowDirection.Undefined;
Parameters.Rebuild = true; Parameters.Rebuild = true;
CreateBody(false); CreateBody(false);
wrappers.Add(new Function(this)); wrappers.Add(new Function(this));
Parameters[index].Reference = false; Parameters[index].Reference = false;
Parameters[index].Array = 2; Parameters[index].Array = 2;
Parameters[index].Pointer = false; Parameters[index].Pointer = 0;
Parameters[index].Generic = true; Parameters[index].Generic = true;
Parameters[index].CurrentType = "T" + index.ToString(); Parameters[index].CurrentType = "T" + index.ToString();
Parameters[index].Flow = Parameter.FlowDirection.Undefined; Parameters[index].Flow = FlowDirection.Undefined;
Parameters.Rebuild = true; Parameters.Rebuild = true;
CreateBody(false); CreateBody(false);
wrappers.Add(new Function(this)); wrappers.Add(new Function(this));
Parameters[index].Reference = false; Parameters[index].Reference = false;
Parameters[index].Array = 3; Parameters[index].Array = 3;
Parameters[index].Pointer = false; Parameters[index].Pointer = 0;
Parameters[index].Generic = true; Parameters[index].Generic = true;
Parameters[index].CurrentType = "T" + index.ToString(); Parameters[index].CurrentType = "T" + index.ToString();
Parameters[index].Flow = Parameter.FlowDirection.Undefined; Parameters[index].Flow = FlowDirection.Undefined;
Parameters.Rebuild = true; Parameters.Rebuild = true;
CreateBody(false); CreateBody(false);
wrappers.Add(new Function(this)); wrappers.Add(new Function(this));
@ -420,7 +420,7 @@ namespace Bind.Structures
handle_release_statements.Add(String.Format("{0}_ptr.Free();", p.Name)); handle_release_statements.Add(String.Format("{0}_ptr.Free();", p.Name));
if (p.Flow == Parameter.FlowDirection.Out) if (p.Flow == FlowDirection.Out)
{ {
assign_statements.Add(String.Format( assign_statements.Add(String.Format(
"{0} = ({1}){0}_ptr.Target;", "{0} = ({1}){0}_ptr.Target;",
@ -441,7 +441,7 @@ namespace Bind.Structures
p.Name + "_ptr", p.Name + "_ptr",
p.Array > 0 ? p.Name : "&" + p.Name)); p.Array > 0 ? p.Name : "&" + p.Name));
if (p.Flow == Parameter.FlowDirection.Out && p.Array == 0) // Fixed Arrays of blittable types don't need explicit assignment. if (p.Flow == FlowDirection.Out && p.Array == 0) // Fixed Arrays of blittable types don't need explicit assignment.
{ {
assign_statements.Add(String.Format("{0} = *{0}_ptr;", p.Name)); assign_statements.Add(String.Format("{0} = *{0}_ptr;", p.Name));
} }

View file

@ -64,10 +64,10 @@ namespace Bind.Structures
{ {
if (_name != value) if (_name != value)
{ {
if (value.StartsWith("*")) while (value.StartsWith("*"))
{ {
Pointer = true; Pointer++;
value = value.TrimStart("*".ToCharArray()); value = value.Substring(1);
} }
_name = value; _name = value;
rebuild = true; rebuild = true;
@ -100,17 +100,6 @@ namespace Bind.Structures
#region public FlowDirection Flow #region public FlowDirection Flow
/// <summary>
/// Enumarates the possible flows of a parameter (ie. is this parameter
/// used as input or as output?)
/// </summary>
public enum FlowDirection
{
Undefined = 0,
In,
Out
}
FlowDirection _flow; FlowDirection _flow;
/// <summary> /// <summary>
@ -203,8 +192,8 @@ namespace Bind.Structures
{ {
return return
CurrentType == other.CurrentType && CurrentType == other.CurrentType &&
(Reference && !(other.Reference || other.Array > 0 || other.Pointer) || (Reference && !(other.Reference || other.Array > 0 || other.Pointer != 0) ||
other.Reference && !(Reference || Array > 0 || Pointer)); other.Reference && !(Reference || Array > 0 || Pointer != 0));
} }
#endregion #endregion
@ -248,7 +237,7 @@ namespace Bind.Structures
if (!override_unsafe_setting && ((Settings.Compatibility & Settings.Legacy.NoPublicUnsafeFunctions) != Settings.Legacy.None)) if (!override_unsafe_setting && ((Settings.Compatibility & Settings.Legacy.NoPublicUnsafeFunctions) != Settings.Legacy.None))
{ {
if (Pointer) if (Pointer != 0)
{ {
sb.Append("IntPtr"); sb.Append("IntPtr");
} }
@ -267,7 +256,7 @@ namespace Bind.Structures
else else
{ {
sb.Append(CurrentType); sb.Append(CurrentType);
if (Pointer) for (int i = 0; i < Pointer; i++)
sb.Append("*"); sb.Append("*");
if (Array > 0) if (Array > 0)
{ {
@ -298,35 +287,35 @@ namespace Bind.Structures
base.Translate(category); base.Translate(category);
// Find out the necessary wrapper types. // Find out the necessary wrapper types.
if (Pointer)/* || CurrentType == "IntPtr")*/ if (Pointer != 0)/* || CurrentType == "IntPtr")*/
{ {
if (CurrentType.ToLower().Contains("char")) if (CurrentType.ToLower().Contains("string"))
{
// char* -> [In] String or [Out] StringBuilder
CurrentType =
Flow == Parameter.FlowDirection.Out ?
"System.Text.StringBuilder" :
"String";
Pointer = false;
WrapperType = WrapperTypes.None;
}
else if (CurrentType.ToLower().Contains("string"))
{ {
// string* -> [In] String[] or [Out] StringBuilder[] // string* -> [In] String[] or [Out] StringBuilder[]
CurrentType = CurrentType =
Flow == Parameter.FlowDirection.Out ? Flow == FlowDirection.Out ?
"System.Text.StringBuilder[]" : "System.Text.StringBuilder[]" :
"String[]"; "String[]";
Pointer = false; Pointer = 0;
WrapperType = WrapperTypes.None;
}
else if (CurrentType.ToLower().Contains("char"))
{
// char* -> [In] String or [Out] StringBuilder
CurrentType =
Flow == FlowDirection.Out ?
"System.Text.StringBuilder" :
"String";
Pointer = 0;
WrapperType = WrapperTypes.None; WrapperType = WrapperTypes.None;
} }
else if (CurrentType.ToLower().Contains("void") || else if (CurrentType.ToLower().Contains("void") ||
(!String.IsNullOrEmpty(PreviousType) && PreviousType.ToLower().Contains("void"))) /*|| CurrentType.Contains("IntPtr"))*/ (!String.IsNullOrEmpty(PreviousType) && PreviousType.ToLower().Contains("void"))) /*|| CurrentType.Contains("IntPtr"))*/
{ {
CurrentType = "IntPtr"; CurrentType = "IntPtr";
Pointer = false; Pointer = 0;
WrapperType = WrapperTypes.GenericParameter; WrapperType = WrapperTypes.GenericParameter;
} }
else else
@ -347,6 +336,17 @@ namespace Bind.Structures
} }
#endregion #endregion
#region Static Members
// Returns the FlowDirection that matches the specified string
// ("out" or "in", otherwise undefined).
public static FlowDirection GetFlowDirection(string direction)
{
return direction == "out" ? FlowDirection.Out : direction == "in" ? FlowDirection.In : FlowDirection.Undefined;
}
#endregion
} }
/// <summary> /// <summary>
@ -462,7 +462,7 @@ namespace Bind.Structures
{ {
foreach (Parameter p in this) foreach (Parameter p in this)
{ {
if (p.Pointer || p.CurrentType.Contains("IntPtr")) if (p.Pointer != 0 || p.CurrentType.Contains("IntPtr"))
hasPointerParameters = true; hasPointerParameters = true;
if (p.Reference) if (p.Reference)
@ -587,10 +587,10 @@ 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 || p.Array > 0 || p.Reference) else if (p.Pointer != 0 || p.Array > 0 || p.Reference)
{ {
if (((Settings.Compatibility & Settings.Legacy.TurnVoidPointersToIntPtr) != Settings.Legacy.None) && if (((Settings.Compatibility & Settings.Legacy.TurnVoidPointersToIntPtr) != Settings.Legacy.None) &&
p.Pointer && 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(String.Format("({0}*)", p.CurrentType));

View file

@ -77,7 +77,7 @@ namespace Bind.Structures
//get { return _type; } //get { return _type; }
get get
{ {
if (((Settings.Compatibility & Settings.Legacy.TurnVoidPointersToIntPtr) != Settings.Legacy.None) && Pointer && type.Contains("void")) if (((Settings.Compatibility & Settings.Legacy.TurnVoidPointersToIntPtr) != Settings.Legacy.None) && Pointer != 0 && type.Contains("void"))
return "IntPtr"; return "IntPtr";
return type; return type;
@ -89,12 +89,10 @@ namespace Bind.Structures
if (!String.IsNullOrEmpty(value)) if (!String.IsNullOrEmpty(value))
type = value.Trim(); type = value.Trim();
//Translate(); while (type.EndsWith("*"))
if (type.EndsWith("*"))
{ {
type = type.TrimEnd('*'); type = type.Substring(0, type.Length - 1);
Pointer = true; Pointer++;
} }
} }
} }
@ -151,11 +149,11 @@ namespace Bind.Structures
#endregion #endregion
#region public bool Pointer #region public int Pointer
bool pointer; int pointer;
public bool Pointer public int Pointer
{ {
get { return pointer; } get { return pointer; }
set { pointer = value; } set { pointer = value; }
@ -170,7 +168,7 @@ namespace Bind.Structures
get get
{ {
bool compliant = !(CurrentType.Contains("UInt") || CurrentType.Contains("SByte")); bool compliant = !(CurrentType.Contains("UInt") || CurrentType.Contains("SByte"));
if (Pointer) if (Pointer != 0)
{ {
compliant &= CurrentType.Contains("IntPtr"); // IntPtr's are CLSCompliant. compliant &= CurrentType.Contains("IntPtr"); // IntPtr's are CLSCompliant.
// If the NoPublicUnsageFunctions is set, the pointer will be CLSCompliant. // If the NoPublicUnsageFunctions is set, the pointer will be CLSCompliant.
@ -227,7 +225,7 @@ namespace Bind.Structures
{ {
if (!CLSCompliant) if (!CLSCompliant)
{ {
if (Pointer && Settings.Compatibility == Settings.Legacy.Tao) if (Pointer != 0 && Settings.Compatibility == Settings.Legacy.Tao)
return "IntPtr"; return "IntPtr";
switch (CurrentType) switch (CurrentType)
@ -292,7 +290,7 @@ namespace Bind.Structures
CurrentType = CurrentType.Insert(0, String.Format("{0}.", Settings.EnumsAuxOutput)); CurrentType = CurrentType.Insert(0, String.Format("{0}.", Settings.EnumsAuxOutput));
} }
} }
else if (Bind.Structures.Type.GLTypes.TryGetValue(CurrentType, out s)) else if (GLTypes.TryGetValue(CurrentType, out s))
{ {
// Check if the parameter is a generic GLenum. If it is, search for a better match, // Check if the parameter is a generic GLenum. If it is, search for a better match,
// otherwise fallback to Settings.CompleteEnumName (named 'All' by default). // otherwise fallback to Settings.CompleteEnumName (named 'All' by default).
@ -349,7 +347,7 @@ namespace Bind.Structures
Bind.Structures.Type.CSTypes[CurrentType] : CurrentType; Bind.Structures.Type.CSTypes[CurrentType] : CurrentType;
if (CurrentType == "IntPtr" && String.IsNullOrEmpty(PreviousType)) if (CurrentType == "IntPtr" && String.IsNullOrEmpty(PreviousType))
Pointer = false; Pointer = 0;
} }
#endregion #endregion