Rather big update: turned void* to IntPtr, to avoid problems with .Net and Tao functions directly IntPtr (the object overload would be called and all hell would break loose).

Minor cleanup. Added code to turn ALL_CAPS enums into .Net CamelCase enums - must take care of the extensions before enabling this.
Added a couple new commandline options, and fixed a misspelling (NestedEnumsClass was NestedEunmsClass, ugh!)
This commit is contained in:
the_fiddler 2007-10-21 15:48:52 +00:00
parent f7c5c73aa5
commit 2a89d44071
9 changed files with 289 additions and 266 deletions

View file

@ -32,6 +32,8 @@ namespace Bind.GL2
protected static string loadAllFuncName = "LoadAll"; protected static string loadAllFuncName = "LoadAll";
protected static Regex enumToDotNet = new Regex("_[a-z|A-Z]?", RegexOptions.Compiled);
#endregion #endregion
#region --- Constructors --- #region --- Constructors ---
@ -55,8 +57,11 @@ namespace Bind.GL2
public virtual void Process() public virtual void Process()
{ {
// Matches functions that cannot have their trailing 'v' trimmed for CLS-Compliance reasons.
// Built through trial and error :)
Function.endingsAddV = 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); Bind.Structures.Type.Initialize(glTypemap, csTypemap);
@ -107,10 +112,12 @@ namespace Bind.GL2
protected virtual void Translate() protected virtual void Translate()
{ {
foreach (Bind.Structures.Enum e in Bind.Structures.Enum.GLEnums.Values) Bind.Structures.Enum.GLEnums.Translate();
{
TranslateEnum(e); //foreach (Bind.Structures.Enum e in Bind.Structures.Enum.GLEnums.Values)
} //{
// TranslateEnum(e);
//}
//foreach (Bind.Structures.Delegate d in Bind.Structures.Delegate.Delegates.Values) //foreach (Bind.Structures.Delegate d in Bind.Structures.Delegate.Delegates.Values)
{ {
@ -174,9 +181,9 @@ namespace Bind.GL2
// Get function name: // Get function name:
d.Name = line.Split(Utilities.Separators, StringSplitOptions.RemoveEmptyEntries)[0]; d.Name = line.Split(Utilities.Separators, StringSplitOptions.RemoveEmptyEntries)[0];
if (d.Name.Contains("QueryHyperpipeBestAttribSGIX")) //if (d.Name.Contains("QueryHyperpipeBestAttribSGIX"))
{ //{
} //}
do do
{ {
@ -351,6 +358,33 @@ namespace Bind.GL2
c.Value = words[2]; 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)) //if (!String.IsNullOrEmpty(c.Name) && !e.Members.Contains.Contains(c))
//SpecTranslator.Merge(e.Members, c); //SpecTranslator.Merge(e.Members, c);
if (!e.ConstantCollection.ContainsKey(c.Name)) if (!e.ConstantCollection.ContainsKey(c.Name))
@ -359,13 +393,9 @@ namespace Bind.GL2
} }
else else
{ {
Trace.WriteLine( Trace.WriteLine(String.Format(
String.Format( "Spec error: Constant {0} defined twice in enum {1}, discarding last definition.",
"Spec error: Constant {0} defined twice in enum {1}, discarding last definition.", c.Name, e.Name));
c.Name,
e.Name
)
);
} }
// Insert the current constant in the list of all constants. // 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("partial class {0}", Settings.OutputClass);
sw.WriteLine("{"); sw.WriteLine("{");
sw.Indent(); sw.Indent();
sw.WriteLine();
sw.WriteLine("internal static partial class {0}", Settings.DelegatesClass); sw.WriteLine("internal static partial class {0}", Settings.DelegatesClass);
sw.WriteLine("{"); sw.WriteLine("{");
sw.Indent(); 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) foreach (Bind.Structures.Delegate d in delegates.Values)
{ {
sw.WriteLine("[System.Security.SuppressUnmanagedCodeSecurity()]"); sw.WriteLine("[System.Security.SuppressUnmanagedCodeSecurity()]");
sw.WriteLine("internal {0};", d.ToString()); 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.Unsafe ? "unsafe " : "",
d.Name, d.Name,
Settings.FunctionPrefix); Settings.FunctionPrefix);
// --- End workaround ---s
} }
sw.Unindent(); sw.Unindent();
sw.WriteLine("}"); sw.WriteLine("}");
@ -706,7 +724,7 @@ namespace Bind.GL2
sw.WriteLine(); sw.WriteLine();
foreach (string key in wrappers.Keys) 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])) if (!Char.IsDigit(key[0]))
{ {
@ -732,7 +750,7 @@ namespace Bind.GL2
sw.WriteLine(); sw.WriteLine();
} }
if (Settings.Compatibility == Settings.Legacy.None && key != "Core") if (((Settings.Compatibility & Settings.Legacy.NoSeparateFunctionNamespaces) == Settings.Legacy.None) && key != "Core")
{ {
sw.Unindent(); sw.Unindent();
sw.WriteLine("}"); sw.WriteLine("}");
@ -765,22 +783,28 @@ namespace Bind.GL2
{ {
Trace.WriteLine(String.Format("Writing enums to {0}.{1}", Settings.OutputNamespace, Settings.OutputClass)); 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"); if (!String.IsNullOrEmpty(Settings.NestedEnumsClass))
sw.WriteLine("{"); {
sw.WriteLine("public class Enums");
sw.WriteLine("{");
sw.Indent();
}
sw.Indent();
foreach (Bind.Structures.Enum @enum in enums.Values) foreach (Bind.Structures.Enum @enum in enums.Values)
{ {
sw.Write(@enum); sw.Write(@enum);
sw.WriteLine(); 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. // Tao legacy mode: dump all enums as constants in GLClass.
foreach (Bind.Structures.Constant c in enums[Settings.CompleteEnumName].ConstantCollection.Values) foreach (Bind.Structures.Constant c in enums[Settings.CompleteEnumName].ConstantCollection.Values)

View file

@ -86,18 +86,21 @@ namespace Bind
case "ns": case "ns":
Settings.OutputNamespace = b[1]; Settings.OutputNamespace = b[1];
break; 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": case "class":
Settings.OutputClass = b[1]; Settings.OutputClass = b[1];
break; 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: default:
throw new ArgumentException( throw new ArgumentException(
String.Format("Argument {0} not recognized. Use the '/?' switch for help.", a) String.Format("Argument {0} not recognized. Use the '/?' switch for help.", a)

View file

@ -20,24 +20,27 @@ namespace Bind
public const string DefaultOutputPath = "..\\..\\..\\Source\\OpenTK\\OpenGL\\Bindings"; public const string DefaultOutputPath = "..\\..\\..\\Source\\OpenTK\\OpenGL\\Bindings";
public const string DefaultOutputNamespace = "OpenTK.OpenGL"; 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 FunctionPrefix = "gl";
public static string ConstantPrefix = "GL_"; public static string ConstantPrefix = "GL_";
// TODO: This code is too fragile. // TODO: This code is too fragile.
public static string NestedEunmsClass = "Enums";
private static string normalEnumsClassOverride; private static string normalEnumsClassOverride;
public static string NestedEnumsClass = "Enums";
public static string NormalEnumsClass public static string NormalEnumsClass
{ {
get get
{ {
if (!String.IsNullOrEmpty(normalEnumsClassOverride)) return String.IsNullOrEmpty(NestedEnumsClass) ? OutputClass :
return normalEnumsClassOverride; OutputClass + "." + NestedEnumsClass;
return OutputClass + "." + NestedEunmsClass;
} }
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 DelegatesClass = "Delegates";
public static string ImportsClass = "Imports"; public static string ImportsClass = "Imports";
@ -49,10 +52,18 @@ namespace Bind
/// </summary> /// </summary>
public static string CompleteEnumName = "All"; public static string CompleteEnumName = "All";
[Flags]
public enum Legacy public enum Legacy
{ {
None, None = 0x00,
Tao, 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"; public static string WindowsGDI = "OpenTK.Platform.Windows.API";

View file

@ -151,6 +151,9 @@ namespace Bind.Structures
//set { @unsafe = value; } //set { @unsafe = value; }
get get
{ {
//if ((Settings.Compatibility & Settings.Legacy.NoPublicUnsafeFunctions) != Settings.Legacy.None)
// return false;
if (ReturnType.Pointer) if (ReturnType.Pointer)
return true; return true;
@ -309,7 +312,7 @@ namespace Bind.Structures
sb.Append(ReturnType); sb.Append(ReturnType);
sb.Append(" "); sb.Append(" ");
sb.Append(Name); sb.Append(Name);
sb.Append(Parameters.ToString()); sb.Append(Parameters.ToString(true));
return sb.ToString(); return sb.ToString();
} }
@ -486,102 +489,94 @@ namespace Bind.Structures
{ {
Function f; Function f;
if (function.Parameters[index].WrapperType == WrapperTypes.None) switch (function.Parameters[index].WrapperType)
{ {
// No wrapper needed, visit the next parameter case WrapperTypes.None:
++index; // No wrapper needed, visit the next parameter
WrapParameters(function, wrappers); ++index;
--index; WrapParameters(function, wrappers);
} --index;
else break;
{
switch (function.Parameters[index].WrapperType)
{
case WrapperTypes.ArrayParameter:
// Recurse to the last parameter
++index;
WrapParameters(function, wrappers);
--index;
//if (function.Name == "UseFontOutlinesA") case WrapperTypes.ArrayParameter:
{ // Recurse to the last parameter
} ++index;
WrapParameters(function, wrappers);
--index;
// On stack rewind, create array wrappers // On stack rewind, create array wrappers
f = new Function(function); f = new Function(function);
f.Parameters[index].Reference = false; f.Parameters[index].Reference = false;
f.Parameters[index].Array = 1; f.Parameters[index].Array = 1;
f.Parameters[index].Pointer = false; f.Parameters[index].Pointer = false;
f.Body = CreateBody(f, false); f.Body = CreateBody(f, false);
//f = ReferenceWrapper(new Function(function), index); wrappers.Add(f);
wrappers.Add(f);
// Recurse to the last parameter again, keeping the Array wrappers // Recurse to the last parameter again, keeping the Array wrappers
++index; ++index;
WrapParameters(f, wrappers); WrapParameters(f, wrappers);
--index; --index;
f = new Function(function); // On stack rewind create reference wrappers.
f.Parameters[index].Reference = true; f = new Function(function);
f.Parameters[index].Array = 0; f.Parameters[index].Reference = true;
f.Parameters[index].Pointer = false; f.Parameters[index].Array = 0;
f.Body = CreateBody(f, false); f.Parameters[index].Pointer = false;
//f = ReferenceWrapper(new Function(function), index); f.Body = CreateBody(f, false);
wrappers.Add(f); wrappers.Add(f);
// Keeping the current Ref wrapper, visit all other parameters once more // Keeping the current reference wrapper, revisit all other parameters.
++index; ++index;
WrapParameters(f, wrappers); WrapParameters(f, wrappers);
--index; --index;
break; break;
case WrapperTypes.GenericParameter: case WrapperTypes.GenericParameter:
// Recurse to the last parameter // Recurse to the last parameter
++index; ++index;
WrapParameters(function, wrappers); WrapParameters(function, wrappers);
--index; --index;
// On stack rewind, create array wrappers // On stack rewind, create object wrappers
f = new Function(function); f = new Function(function);
f.Parameters[index].Reference = false; f.Parameters[index].Reference = false;
f.Parameters[index].Array = 0; f.Parameters[index].Array = 0;
f.Parameters[index].Pointer = false; f.Parameters[index].Pointer = false;
f.Parameters[index].CurrentType = "object"; f.Parameters[index].CurrentType = "object";
f.Parameters[index].Flow = Parameter.FlowDirection.Undefined; f.Parameters[index].Flow = Parameter.FlowDirection.Undefined;
f.Body = CreateBody(f, false); f.Body = CreateBody(f, false);
wrappers.Add(f); wrappers.Add(f);
// Keeping the current Object wrapper, visit all other parameters once more // Keeping the current Object wrapper, visit all other parameters once more
++index; ++index;
WrapParameters(f, wrappers); WrapParameters(f, wrappers);
--index; --index;
break; break;
case WrapperTypes.ReferenceParameter: //case WrapperTypes.ReferenceParameter:
// Recurse to the last parameter // // Recurse to the last parameter
++index; // ++index;
WrapParameters(function, wrappers); // WrapParameters(function, wrappers);
--index; // --index;
// On stack rewind, create reference wrappers // // On stack rewind, create reference wrappers
f = new Function(function); // f = new Function(function);
f.Parameters[index].Reference = true; // f.Parameters[index].Reference = true;
f.Parameters[index].Array = 0; // f.Parameters[index].Array = 0;
f.Parameters[index].Pointer = false; // f.Parameters[index].Pointer = false;
f.Body = CreateBody(f, false); // f.Body = CreateBody(f, false);
//f = ReferenceWrapper(new Function(function), index); // //f = ReferenceWrapper(new Function(function), index);
wrappers.Add(f); // wrappers.Add(f);
// Keeping the current Object wrapper, visit all other parameters once more // // Keeping the current Object wrapper, visit all other parameters once more
++index; // ++index;
WrapParameters(f, wrappers); // WrapParameters(f, wrappers);
--index; // --index;
break; // break;
}
} }
} }
} }
@ -592,7 +587,7 @@ namespace Bind.Structures
protected Function DefaultWrapper(Function f) 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( string callString = String.Format(
"{0} {1}{2}; {3}", "{0} {1}{2}; {3}",
Unsafe ? "unsafe {" : "", Unsafe ? "unsafe {" : "",
@ -625,8 +620,8 @@ namespace Bind.Structures
assign_statements.Clear(); assign_statements.Clear();
//if (f.Name == "LoadDisplayColorTableEXT") //if (f.Name == "LoadDisplayColorTableEXT")
{ //{
} //}
// Obtain pointers by pinning the parameters // Obtain pointers by pinning the parameters
foreach (Parameter p in f.Parameters) foreach (Parameter p in f.Parameters)
@ -651,7 +646,10 @@ namespace Bind.Structures
} }
// Note! The following line modifies f.Parameters, *not* this.Parameters // 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 || else if (p.WrapperType == WrapperTypes.PointerParameter ||
p.WrapperType == WrapperTypes.ArrayParameter || p.WrapperType == WrapperTypes.ArrayParameter ||
@ -752,9 +750,7 @@ namespace Bind.Structures
#endregion #endregion
#endregion #region protected virtual void TranslateReturnType()
#region Translate
/// <summary> /// <summary>
/// Translates the opengl return type to the equivalent C# type. /// Translates the opengl return type to the equivalent C# type.
@ -824,18 +820,20 @@ namespace Bind.Structures
ReturnType.CurrentType = ReturnType.GetCLSCompliantType(); ReturnType.CurrentType = ReturnType.GetCLSCompliantType();
} }
#endregion
#region protected virtual void TranslateParameters()
protected virtual void TranslateParameters() protected virtual void TranslateParameters()
{ {
if (this.Name.Contains("SetLayerPaletteEntries")) //if (this.Name.Contains("VertexPointer"))
{ //{
// Console.WriteLine(); // Console.WriteLine();
} //}
for (int i = 0; i < Parameters.Count; i++) for (int i = 0; i < Parameters.Count; i++)
{ {
Parameters[i] = Parameter.Translate(Parameters[i], this.Category); 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")) if (Parameters[i].CurrentType == "UInt16" && Name.Contains("LineStipple"))
{ {
Parameters[i].WrapperType = WrapperTypes.UncheckedParameter; Parameters[i].WrapperType = WrapperTypes.UncheckedParameter;
@ -850,6 +848,8 @@ namespace Bind.Structures
} }
} }
#endregion
internal void Translate() internal void Translate()
{ {
TranslateReturnType(); TranslateReturnType();

View file

@ -139,6 +139,12 @@ namespace Bind.Structures
} }
} }
} }
// Obey .Net naming rules:
if ((Settings.Compatibility & Settings.Legacy.NoAdvancedEnumProcessing) == Settings.Legacy.None)
{
}
} }
} }

View file

@ -63,14 +63,26 @@ namespace Bind.Structures
#endregion #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 #region public override bool Unsafe
public override bool Unsafe public override bool Unsafe
{ {
get get
{ {
if (Settings.Compatibility == Settings.Legacy.Tao) //if ((Settings.Compatibility & Settings.Legacy.NoPublicUnsafeFunctions) != Settings.Legacy.None)
return false; // return false;
return base.Unsafe; return base.Unsafe;
} }
@ -91,22 +103,9 @@ namespace Bind.Structures
#endregion #endregion
#region public string TrimmedName #region public string TrimmedName
/*
string trimmedName;
/// <summary>
/// Gets or sets the name of the opengl function, trimming the excess 234dfubsiv endings.
/// </summary>
public string TrimmedName
{
get { return trimmedName; }
set
{
if (!String.IsNullOrEmpty(value))
trimmedName = value.Trim();
}
}
*/
public string TrimmedName; public string TrimmedName;
#endregion #endregion
#region public override string Name #region public override string Name
@ -123,7 +122,7 @@ namespace Bind.Structures
{ {
base.Name = value; 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, // If we don't need compatibility with Tao,
// remove the Extension and the overload information from the name // remove the Extension and the overload information from the name
@ -134,43 +133,6 @@ namespace Bind.Structures
else else
{ {
TrimmedName = Utilities.StripGL2Extension(value); 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")) //if (Name.Contains("BooleanIndexed"))
{ {
@ -183,10 +145,12 @@ namespace Bind.Structures
m = endings.Match(TrimmedName); m = endings.Match(TrimmedName);
if (m.Length > 0 && m.Index + m.Length == TrimmedName.Length) 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) && if (m.Value[m.Length - 1] == 'v' && endingsAddV.IsMatch(Name) &&
!Name.StartsWith("Get") && !Name.StartsWith("MatrixIndex")) !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"; TrimmedName = TrimmedName.Substring(0, m.Index) + "v";
} }
else else
@ -213,12 +177,12 @@ namespace Bind.Structures
sb.Append(Unsafe ? "unsafe " : ""); sb.Append(Unsafe ? "unsafe " : "");
sb.Append(ReturnType); sb.Append(ReturnType);
sb.Append(" "); sb.Append(" ");
if (Settings.Compatibility == Settings.Legacy.Tao) if ((Settings.Compatibility & Settings.Legacy.NoTrimFunctionEnding) != Settings.Legacy.None)
{ {
sb.Append(Settings.FunctionPrefix); sb.Append(Settings.FunctionPrefix);
} }
sb.Append(!String.IsNullOrEmpty(TrimmedName) ? TrimmedName : Name); sb.Append(!String.IsNullOrEmpty(TrimmedName) ? TrimmedName : Name);
sb.Append(Parameters.ToString(true)); sb.Append(Parameters.ToString(false));
if (Body.Count > 0) if (Body.Count > 0)
{ {
sb.AppendLine(); sb.AppendLine();

View file

@ -18,6 +18,7 @@ namespace Bind.Structures
{ {
string cache; string cache;
bool rebuild; bool rebuild;
bool unsafe_allowed; // True if the cache may contain unsafe types, false otherwise.
#region Constructors #region Constructors
@ -173,19 +174,18 @@ namespace Bind.Structures
#endregion #endregion
#region override public string ToString() public override string ToString()
override public string ToString()
{ {
return ToString(false); return ToString(false);
} }
#endregion #region public string ToString(bool override_unsafe_setting)
#region public string ToString(bool taoCompatible) public string ToString(bool override_unsafe_setting)
public string ToString(bool taoCompatible)
{ {
rebuild |= unsafe_allowed |= override_unsafe_setting;
unsafe_allowed = override_unsafe_setting;
if (!String.IsNullOrEmpty(cache) && !rebuild) if (!String.IsNullOrEmpty(cache) && !rebuild)
{ {
return cache; return cache;
@ -207,7 +207,7 @@ namespace Bind.Structures
sb.Append("ref "); sb.Append("ref ");
} }
if (taoCompatible && Settings.Compatibility == Settings.Legacy.Tao) if (!override_unsafe_setting && ((Settings.Compatibility & Settings.Legacy.NoPublicUnsafeFunctions) != Settings.Legacy.None))
{ {
if (Pointer) if (Pointer)
{ {
@ -228,7 +228,6 @@ namespace Bind.Structures
if (Array > 0) if (Array > 0)
sb.Append("[]"); sb.Append("[]");
} }
if (!String.IsNullOrEmpty(Name)) if (!String.IsNullOrEmpty(Name))
{ {
sb.Append(" "); sb.Append(" ");
@ -262,7 +261,7 @@ namespace Bind.Structures
// Translate enum types // Translate enum types
if ((normal || aux) && @enum.Name != "GLenum") if ((normal || aux) && @enum.Name != "GLenum")
{ {
if (Settings.Compatibility == Settings.Legacy.Tao) if ((Settings.Compatibility & Settings.Legacy.ConstIntEnums) != Settings.Legacy.None)
{ {
p.CurrentType = "int"; p.CurrentType = "int";
} }
@ -284,7 +283,7 @@ namespace Bind.Structures
// check if a better match exists: // check if a better match exists:
if (s.Contains("GLenum") && !String.IsNullOrEmpty(Category)) 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) // Better match: enum.Name == function.Category (e.g. GL_VERSION_1_1 etc)
if (Enum.GLEnums.ContainsKey(Category)) if (Enum.GLEnums.ContainsKey(Category))
@ -346,7 +345,7 @@ namespace Bind.Structures
// p.CurrentType = CSTypes[p.CurrentType]; // p.CurrentType = CSTypes[p.CurrentType];
// Translate pointer parameters // Translate pointer parameters
if (p.Pointer) if (p.Pointer || p.CurrentType == "IntPtr")
{ {
p.WrapperType = WrapperTypes.ArrayParameter; p.WrapperType = WrapperTypes.ArrayParameter;
@ -361,8 +360,10 @@ namespace Bind.Structures
p.Pointer = false; p.Pointer = false;
p.WrapperType = WrapperTypes.None; 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; p.WrapperType = WrapperTypes.GenericParameter;
} }
} }
@ -394,6 +395,7 @@ namespace Bind.Structures
private bool rebuild = true; private bool rebuild = true;
bool hasPointerParameters; bool hasPointerParameters;
bool hasReferenceParameters; bool hasReferenceParameters;
bool unsafe_types_allowed;
private bool Rebuild private bool Rebuild
{ {
get { return rebuild; } get { return rebuild; }
@ -419,14 +421,20 @@ namespace Bind.Structures
#endregion #endregion
#region void BuildCache()
void BuildCache() void BuildCache()
{ {
BuildCallStringCache(); BuildCallStringCache();
BuildToStringCache(); BuildToStringCache(unsafe_types_allowed);
BuildReferenceAndPointerParametersCache(); BuildReferenceAndPointerParametersCache();
Rebuild = false; Rebuild = false;
} }
#endregion
#region public bool HasPointerParameters
public bool HasPointerParameters public bool HasPointerParameters
{ {
get get
@ -442,7 +450,11 @@ namespace Bind.Structures
} }
} }
} }
#endregion
#region public bool HasReferenceParameters
public bool HasReferenceParameters public bool HasReferenceParameters
{ {
get get
@ -459,11 +471,15 @@ namespace Bind.Structures
} }
} }
#endregion
#region void BuildReferenceAndPointerParametersCache()
void BuildReferenceAndPointerParametersCache() void BuildReferenceAndPointerParametersCache()
{ {
foreach (Parameter p in this) foreach (Parameter p in this)
{ {
if (p.Pointer) if (p.Pointer || p.CurrentType.Contains("IntPtr"))
hasPointerParameters = true; hasPointerParameters = true;
if (p.Reference) if (p.Reference)
@ -471,6 +487,8 @@ namespace Bind.Structures
} }
} }
#endregion
#region new public void Add(Parameter p) #region new public void Add(Parameter p)
new public void Add(Parameter p) new public void Add(Parameter p)
@ -481,29 +499,23 @@ namespace Bind.Structures
#endregion #endregion
#region override public string ToString() public override string ToString()
/// <summary>
/// Gets the parameter declaration string.
/// </summary>
/// <returns>The parameter list of an opengl function in the form ( [parameters] )</returns>
override public string ToString()
{ {
return ToString(false); return ToString(false);
} }
#endregion #region public string ToString(bool override_unsafe_setting)
#region public string ToString(bool taoCompatible)
/// <summary> /// <summary>
/// Gets the parameter declaration string. /// Gets the parameter declaration string.
/// </summary> /// </summary>
/// <param name="getCLSCompliant">If true, all types will be replaced by their CLSCompliant C# equivalents</param> /// <param name="override_unsafe_setting">If true, unsafe types will be used even if the Settings.Compatibility.NoPublicUnsafeFunctions flag is set.</param>
/// <param name="CSTypes">The list of C# types equivalent to the OpenGL types.</param>
/// <returns>The parameter list of an opengl function in the form ( [parameters] )</returns> /// <returns>The parameter list of an opengl function in the form ( [parameters] )</returns>
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) if (!Rebuild)
{ {
return cache; return cache;
@ -517,24 +529,19 @@ namespace Bind.Structures
#endregion #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(); StringBuilder sb = new StringBuilder();
sb.Append("("); sb.Append("(");
if (this.Count > 0) if (this.Count > 0)
{ {
foreach (Parameter p in this) foreach (Parameter p in this)
{ {
if (Settings.Compatibility == Settings.Legacy.Tao) sb.Append(p.ToString(override_unsafe_setting));
{
sb.Append(p.ToString(true));
}
else
{
sb.Append(p.ToString());
}
sb.Append(", "); sb.Append(", ");
} }
sb.Replace(", ", ")", sb.Length - 2, 2); sb.Replace(", ", ")", sb.Length - 2, 2);
@ -588,18 +595,15 @@ 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 || p.Array > 0 || p.Reference)
{ {
sb.Append(String.Format("({0}*)", if (((Settings.Compatibility & Settings.Legacy.TurnVoidPointersToIntPtr) != Settings.Legacy.None) &&
p.CurrentType /*, (p.Pointer || p.Array > 0) ? "*" : ""*/)); 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 else
{ {
sb.Append(String.Format("({0})", p.CurrentType)); sb.Append(String.Format("({0})", p.CurrentType));

View file

@ -76,8 +76,8 @@ namespace Bind.Structures
//get { return _type; } //get { return _type; }
get get
{ {
//if (Pointer && Settings.Compatibility == Settings.Legacy.Tao) if (((Settings.Compatibility & Settings.Legacy.TurnVoidPointersToIntPtr) != Settings.Legacy.None) && Pointer && type.Contains("void"))
// return "IntPtr"; return "IntPtr";
return type; return type;
} }
@ -155,11 +155,16 @@ namespace Bind.Structures
{ {
get get
{ {
return !( bool compliant = !(CurrentType.Contains("UInt") || CurrentType.Contains("SByte"));
(Pointer && (Settings.Compatibility != Settings.Legacy.Tao)) || 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("UInt") ||
CurrentType.Contains("SByte")); CurrentType.Contains("SByte")));
*/
/*(Type.Contains("GLu") && !Type.Contains("GLubyte")) || /*(Type.Contains("GLu") && !Type.Contains("GLubyte")) ||
Type == "GLbitfield" || Type == "GLbitfield" ||
@ -187,8 +192,8 @@ namespace Bind.Structures
public string GetFullType(Dictionary<string, string> CSTypes, bool compliant) public string GetFullType(Dictionary<string, string> CSTypes, bool compliant)
{ {
if (Pointer && Settings.Compatibility == Settings.Legacy.Tao) //if (Pointer && ((Settings.Compatibility & Settings.Legacy.NoPublicUnsafeFunctions) != Settings.Legacy.None))
return "IntPtr"; // return "IntPtr";
if (!compliant) if (!compliant)
{ {
@ -230,6 +235,8 @@ namespace Bind.Structures
case "SByte": case "SByte":
case "sbyte": case "sbyte":
return "Byte"; return "Byte";
case "UIntPtr":
return "IntPtr";
} }
} }

View file

@ -9,6 +9,7 @@ using System.Collections.Generic;
using System.Text; using System.Text;
using System.IO; using System.IO;
using Bind.Structures; using Bind.Structures;
using System.Text.RegularExpressions;
namespace Bind namespace Bind
{ {
@ -67,6 +68,9 @@ namespace Bind
public static class Utilities public static class Utilities
{ {
public static readonly char[] Separators = { ' ', '\n', ',', '(', ')', ';', '#' }; 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) #region internal StreamReader OpenSpecFile(string file)