2009-08-12 10:12:16 +00:00
|
|
|
#region --- License ---
|
2009-02-22 10:43:35 +00:00
|
|
|
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
|
|
|
|
* See license.txt for license info
|
|
|
|
*/
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Diagnostics;
|
2009-08-17 12:28:22 +00:00
|
|
|
using System.IO;
|
2009-10-27 22:37:05 +00:00
|
|
|
using System.Linq;
|
2009-02-22 10:43:35 +00:00
|
|
|
using System.Text.RegularExpressions;
|
2009-05-29 15:57:01 +00:00
|
|
|
using System.Xml.XPath;
|
2009-08-17 12:28:22 +00:00
|
|
|
using Bind.Structures;
|
2009-08-21 20:28:14 +00:00
|
|
|
using Delegate=Bind.Structures.Delegate;
|
|
|
|
using Enum=Bind.Structures.Enum;
|
|
|
|
using Type=Bind.Structures.Type;
|
2009-02-22 10:43:35 +00:00
|
|
|
|
|
|
|
namespace Bind.GL2
|
|
|
|
{
|
|
|
|
class Generator : IBind
|
|
|
|
{
|
|
|
|
#region --- Fields ---
|
|
|
|
|
2009-03-08 18:08:35 +00:00
|
|
|
protected static string glTypemap = "GL2/gl.tm";
|
2009-02-22 10:43:35 +00:00
|
|
|
protected static string csTypemap = "csharp.tm";
|
2009-03-08 18:08:35 +00:00
|
|
|
protected static string enumSpec = "GL2/enum.spec";
|
|
|
|
protected static string enumSpecExt = "GL2/enumext.spec";
|
|
|
|
protected static string glSpec = "GL2/gl.spec";
|
2009-02-22 10:43:35 +00:00
|
|
|
protected static string glSpecExt = "";
|
2009-02-28 19:29:34 +00:00
|
|
|
|
2009-02-22 10:43:35 +00:00
|
|
|
protected static string importsFile = "GLCore.cs";
|
2009-02-28 19:29:34 +00:00
|
|
|
protected static string delegatesFile = "GLDelegates.cs";
|
|
|
|
protected static string enumsFile = "GLEnums.cs";
|
|
|
|
protected static string wrappersFile = "GL.cs";
|
2009-02-22 10:43:35 +00:00
|
|
|
|
2009-06-30 08:39:35 +00:00
|
|
|
protected static string functionOverridesFile = "GL2/gloverrides.xml";
|
2009-05-29 15:57:01 +00:00
|
|
|
|
2009-02-22 10:43:35 +00:00
|
|
|
protected static string loadAllFuncName = "LoadAll";
|
|
|
|
|
|
|
|
protected static Regex enumToDotNet = new Regex("_[a-z|A-Z]?", RegexOptions.Compiled);
|
|
|
|
|
2009-03-21 21:44:07 +00:00
|
|
|
protected static readonly char[] numbers = "0123456789".ToCharArray();
|
|
|
|
//protected static readonly Dictionary<string, string> doc_replacements;
|
2009-02-22 10:43:35 +00:00
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region --- Constructors ---
|
|
|
|
|
|
|
|
public Generator()
|
|
|
|
{
|
|
|
|
if (Settings.Compatibility == Settings.Legacy.Tao)
|
|
|
|
{
|
|
|
|
Settings.OutputNamespace = "Tao.OpenGl";
|
|
|
|
Settings.OutputClass = "Gl";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Defaults
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region public void Process()
|
|
|
|
|
|
|
|
public virtual void Process()
|
|
|
|
{
|
2010-10-13 21:41:06 +00:00
|
|
|
var overrides = new XPathDocument(Path.Combine(Settings.InputPath, functionOverridesFile));
|
2009-02-22 10:43:35 +00:00
|
|
|
|
2009-08-21 20:28:14 +00:00
|
|
|
Type.Initialize(glTypemap, csTypemap);
|
2010-10-13 21:41:06 +00:00
|
|
|
var enums = ReadEnums(new StreamReader(Path.Combine(Settings.InputPath, enumSpec)));
|
|
|
|
var delegates = ReadDelegates(new StreamReader(Path.Combine(Settings.InputPath, glSpec)));
|
|
|
|
|
|
|
|
enums = new EnumProcessor(overrides).Process(enums);
|
|
|
|
var wrappers = new FuncProcessor(overrides).Process(delegates, enums);
|
|
|
|
|
|
|
|
WriteBindings(delegates, wrappers, enums);
|
2009-02-22 10:43:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region private void Translate()
|
|
|
|
#if false
|
|
|
|
protected virtual void Translate()
|
|
|
|
{
|
|
|
|
Bind.Structures.Enum.GLEnums.Translate();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region ISpecReader Members
|
|
|
|
|
|
|
|
#region public virtual DelegateCollection ReadDelegates(StreamReader specFile)
|
|
|
|
|
|
|
|
public virtual DelegateCollection ReadDelegates(StreamReader specFile)
|
|
|
|
{
|
|
|
|
Console.WriteLine("Reading function specs.");
|
|
|
|
|
|
|
|
DelegateCollection delegates = new DelegateCollection();
|
|
|
|
|
2009-06-30 08:39:35 +00:00
|
|
|
XPathDocument function_overrides = new XPathDocument(Path.Combine(Settings.InputPath, functionOverridesFile));
|
|
|
|
|
2009-02-22 10:43:35 +00:00
|
|
|
do
|
|
|
|
{
|
|
|
|
string line = NextValidLine(specFile);
|
|
|
|
if (String.IsNullOrEmpty(line))
|
|
|
|
break;
|
|
|
|
|
|
|
|
while (line.Contains("(") && !specFile.EndOfStream)
|
|
|
|
{
|
|
|
|
// Get next OpenGL function
|
|
|
|
|
2009-08-21 20:28:14 +00:00
|
|
|
Delegate d = new Delegate();
|
2009-02-22 10:43:35 +00:00
|
|
|
|
|
|
|
// Get function name:
|
|
|
|
d.Name = line.Split(Utilities.Separators, StringSplitOptions.RemoveEmptyEntries)[0];
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
// Get function parameters and return value
|
|
|
|
|
|
|
|
line = specFile.ReadLine();
|
|
|
|
List<string> words = new List<string>(
|
|
|
|
line.Replace('\t', ' ').Split(Utilities.Separators, StringSplitOptions.RemoveEmptyEntries)
|
|
|
|
);
|
|
|
|
|
|
|
|
if (words.Count == 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
// Identify line:
|
|
|
|
switch (words[0])
|
|
|
|
{
|
|
|
|
case "return": // Line denotes return value
|
|
|
|
d.ReturnType.CurrentType = words[1];
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "param": // Line denotes parameter
|
|
|
|
Parameter p = new Parameter();
|
|
|
|
|
|
|
|
p.Name = Utilities.Keywords.Contains(words[1]) ? "@" + words[1] : words[1];
|
|
|
|
p.CurrentType = words[2];
|
2009-07-15 22:33:26 +00:00
|
|
|
p.Pointer += words[4].Contains("array") ? 1 : 0;
|
|
|
|
p.Pointer += words[4].Contains("reference") ? 1 : 0;
|
|
|
|
if (p.Pointer != 0 && words.Count > 5 && words[5].Contains("[1]"))
|
2009-04-15 13:14:41 +00:00
|
|
|
p.ElementCount = 1;
|
2009-07-15 22:33:26 +00:00
|
|
|
p.Flow = words[3] == "in" ? FlowDirection.In : FlowDirection.Out;
|
2009-02-28 19:29:34 +00:00
|
|
|
|
2009-02-22 10:43:35 +00:00
|
|
|
d.Parameters.Add(p);
|
|
|
|
break;
|
|
|
|
|
2009-02-28 19:29:34 +00:00
|
|
|
// GetTexParameterIivEXT and GetTexParameterIuivEXT define two(!) versions (why?)
|
|
|
|
case "version": // Line denotes function version (i.e. 1.0, 1.2, 1.5)
|
|
|
|
d.Version = words[1];
|
|
|
|
break;
|
2009-02-22 10:43:35 +00:00
|
|
|
|
|
|
|
case "category":
|
|
|
|
d.Category = words[1];
|
|
|
|
break;
|
2010-10-10 12:28:27 +00:00
|
|
|
|
|
|
|
case "deprecated":
|
|
|
|
d.Deprecated = true;
|
|
|
|
d.DeprecatedVersion = words[1];
|
|
|
|
break;
|
2009-02-22 10:43:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
while (!specFile.EndOfStream);
|
|
|
|
|
|
|
|
delegates.Add(d);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (!specFile.EndOfStream);
|
|
|
|
|
|
|
|
return delegates;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region public virtual EnumCollection ReadEnums(StreamReader specFile)
|
|
|
|
|
|
|
|
public virtual EnumCollection ReadEnums(StreamReader specFile)
|
|
|
|
{
|
|
|
|
Trace.WriteLine("Reading opengl enumerant specs.");
|
|
|
|
Trace.Indent();
|
|
|
|
|
|
|
|
EnumCollection enums = new EnumCollection();
|
|
|
|
|
|
|
|
// complete_enum contains all opengl enumerants.
|
2009-08-21 20:28:14 +00:00
|
|
|
Enum complete_enum = new Enum();
|
2009-02-22 10:43:35 +00:00
|
|
|
complete_enum.Name = Settings.CompleteEnumName;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
string line = NextValidLine(specFile);
|
|
|
|
if (String.IsNullOrEmpty(line))
|
|
|
|
break;
|
|
|
|
|
|
|
|
line = line.Replace('\t', ' ');
|
|
|
|
|
|
|
|
// We just encountered the start of a new enumerant:
|
|
|
|
while (!String.IsNullOrEmpty(line) && line.Contains("enum"))
|
|
|
|
{
|
|
|
|
string[] words = line.Split(Utilities.Separators, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
if (words.Length == 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// Declare a new enumerant
|
2009-08-21 20:28:14 +00:00
|
|
|
Enum e = new Enum();
|
2009-02-22 10:43:35 +00:00
|
|
|
e.Name = Char.IsDigit(words[0][0]) ? Settings.ConstantPrefix + words[0] : words[0];
|
|
|
|
|
|
|
|
// And fill in the values for this enumerant
|
|
|
|
do
|
|
|
|
{
|
|
|
|
line = NextValidLine(specFile);
|
|
|
|
|
|
|
|
if (String.IsNullOrEmpty(line) || line.StartsWith("#"))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (line.Contains("enum:") || specFile.EndOfStream)
|
|
|
|
break;
|
|
|
|
|
|
|
|
line = line.Replace('\t', ' ');
|
|
|
|
words = line.Split(Utilities.Separators, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
|
|
|
|
if (words.Length == 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// If we reach this point, we have found a new value for the current enumerant
|
|
|
|
Constant c = new Constant();
|
|
|
|
if (line.Contains("="))
|
|
|
|
{
|
|
|
|
// Trim the name's prefix, but only if not in Tao compat mode.
|
|
|
|
if (Settings.Compatibility == Settings.Legacy.Tao)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (words[0].StartsWith(Settings.ConstantPrefix))
|
|
|
|
words[0] = words[0].Substring(Settings.ConstantPrefix.Length);
|
|
|
|
|
|
|
|
if (Char.IsDigit(words[0][0]))
|
|
|
|
words[0] = Settings.ConstantPrefix + words[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
c.Name = words[0];
|
|
|
|
c.Value = words[2];
|
|
|
|
}
|
|
|
|
else if (words[0] == "use")
|
|
|
|
{
|
|
|
|
// Trim the prefix.
|
|
|
|
if (words[2].StartsWith(Settings.ConstantPrefix))
|
|
|
|
words[2] = words[2].Substring(Settings.ConstantPrefix.Length);
|
|
|
|
|
|
|
|
// If the remaining string starts with a digit, we were wrong above.
|
|
|
|
// Re-add the "GL_"
|
|
|
|
if (Char.IsDigit(words[2][0]))
|
|
|
|
words[2] = Settings.ConstantPrefix + words[2];
|
|
|
|
|
|
|
|
c.Name = words[2];
|
|
|
|
c.Reference = words[1];
|
|
|
|
c.Value = words[2];
|
|
|
|
}
|
2009-09-07 17:49:06 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// Typical cause is hand-editing the specs and forgetting to add an '=' sign.
|
|
|
|
throw new InvalidOperationException(String.Format(
|
|
|
|
"[Error] Invalid constant definition: \"{0}\"", line));
|
|
|
|
}
|
2009-02-22 10:43:35 +00:00
|
|
|
|
|
|
|
//if (!String.IsNullOrEmpty(c.Name) && !e.Members.Contains.Contains(c))
|
|
|
|
//SpecTranslator.Merge(e.Members, c);
|
|
|
|
if (!e.ConstantCollection.ContainsKey(c.Name))
|
|
|
|
e.ConstantCollection.Add(c.Name, c);
|
|
|
|
else
|
|
|
|
Trace.WriteLine(String.Format(
|
|
|
|
"Spec error: Constant {0} defined twice in enum {1}, discarding last definition.",
|
|
|
|
c.Name, e.Name));
|
|
|
|
|
|
|
|
// Insert the current constant in the list of all constants.
|
|
|
|
//SpecTranslator.Merge(complete_enum.Members, c);
|
|
|
|
complete_enum = Utilities.Merge(complete_enum, c);
|
|
|
|
}
|
|
|
|
while (!specFile.EndOfStream);
|
|
|
|
|
|
|
|
// At this point, the complete value list for the current enumerant has been read, so add this
|
|
|
|
// enumerant to the list.
|
|
|
|
//e.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "public enum " + e.Name));
|
|
|
|
//e.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, "public enum " + e.Name));
|
|
|
|
|
|
|
|
// (disabled) Hack - discard Boolean enum, it fsucks up the fragile translation code ahead.
|
|
|
|
//if (!e.Name.Contains("Bool"))
|
|
|
|
//Utilities.Merge(enums, e);
|
|
|
|
|
|
|
|
//e.Translate();
|
|
|
|
|
|
|
|
if (!enums.ContainsKey(e.Name))
|
|
|
|
enums.Add(e.Name, e);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// The enum already exists, merge constants.
|
|
|
|
foreach (Constant t in e.ConstantCollection.Values)
|
|
|
|
Utilities.Merge(enums[e.Name], t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (!specFile.EndOfStream);
|
|
|
|
|
|
|
|
enums.Add(complete_enum.Name, complete_enum);
|
|
|
|
|
|
|
|
Trace.Unindent();
|
|
|
|
|
|
|
|
return enums;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region public virtual Dictionary<string, string> ReadTypeMap(StreamReader specFile)
|
|
|
|
|
|
|
|
public virtual Dictionary<string, string> ReadTypeMap(StreamReader specFile)
|
|
|
|
{
|
|
|
|
Console.WriteLine("Reading opengl types.");
|
|
|
|
Dictionary<string, string> GLTypes = new Dictionary<string, string>();
|
|
|
|
|
2009-08-11 15:33:17 +00:00
|
|
|
if (specFile == null)
|
|
|
|
return GLTypes;
|
|
|
|
|
2009-02-22 10:43:35 +00:00
|
|
|
do
|
|
|
|
{
|
|
|
|
string line = specFile.ReadLine();
|
|
|
|
|
|
|
|
if (String.IsNullOrEmpty(line) || line.StartsWith("#"))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
string[] words = line.Split(" ,*\t".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
|
|
|
|
if (words[0].ToLower() == "void")
|
|
|
|
{
|
|
|
|
// Special case for "void" -> "". We make it "void" -> "void"
|
|
|
|
GLTypes.Add(words[0], "void");
|
|
|
|
}
|
|
|
|
else if (words[0] == "VoidPointer" || words[0] == "ConstVoidPointer")
|
|
|
|
{
|
|
|
|
// "(Const)VoidPointer" -> "void*"
|
|
|
|
GLTypes.Add(words[0], "void*");
|
|
|
|
}
|
2009-06-29 18:32:51 +00:00
|
|
|
else if (words[0] == "CharPointer" || words[0] == "charPointerARB")
|
2009-02-22 10:43:35 +00:00
|
|
|
{
|
2009-06-29 18:32:51 +00:00
|
|
|
// The typematching logic cannot handle pointers to pointers, e.g. CharPointer* -> char** -> string* -> string[].
|
|
|
|
// Hence we give it a push.
|
|
|
|
// Note: When both CurrentType == "String" and Pointer == true, the typematching is hardcoded to use
|
2009-10-27 22:37:05 +00:00
|
|
|
// String[] or StringBuilder[].
|
|
|
|
GLTypes.Add(words[0], "String");
|
2009-02-22 10:43:35 +00:00
|
|
|
}
|
2009-06-29 18:32:51 +00:00
|
|
|
/*else if (words[0].Contains("Pointer"))
|
2009-02-22 10:43:35 +00:00
|
|
|
{
|
|
|
|
GLTypes.Add(words[0], words[1].Replace("Pointer", "*"));
|
|
|
|
}*/
|
|
|
|
else if (words[1].Contains("GLvoid"))
|
|
|
|
{
|
|
|
|
GLTypes.Add(words[0], "void");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GLTypes.Add(words[0], words[1]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (!specFile.EndOfStream);
|
|
|
|
|
|
|
|
return GLTypes;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region public virtual Dictionary<string, string> ReadCSTypeMap(StreamReader specFile)
|
|
|
|
|
|
|
|
public virtual Dictionary<string, string> ReadCSTypeMap(StreamReader specFile)
|
|
|
|
{
|
|
|
|
Dictionary<string, string> CSTypes = new Dictionary<string, string>();
|
|
|
|
Console.WriteLine("Reading C# types.");
|
|
|
|
|
|
|
|
while (!specFile.EndOfStream)
|
|
|
|
{
|
|
|
|
string line = specFile.ReadLine();
|
|
|
|
if (String.IsNullOrEmpty(line) || line.StartsWith("#"))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
string[] words = line.Split(" ,\t".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
if (words.Length < 2)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (((Settings.Compatibility & Settings.Legacy.NoBoolParameters) != Settings.Legacy.None) && words[1] == "bool")
|
|
|
|
words[1] = "Int32";
|
|
|
|
|
|
|
|
CSTypes.Add(words[0], words[1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return CSTypes;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region private string NextValidLine(StreamReader sr)
|
|
|
|
|
2009-08-21 20:28:14 +00:00
|
|
|
private string NextValidLine(StreamReader sr)
|
2009-02-22 10:43:35 +00:00
|
|
|
{
|
|
|
|
string line;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if (sr.EndOfStream)
|
|
|
|
return null;
|
|
|
|
|
|
|
|
line = sr.ReadLine().Trim();
|
|
|
|
|
|
|
|
if (String.IsNullOrEmpty(line) ||
|
|
|
|
line.StartsWith("#") || // Disregard comments.
|
|
|
|
line.StartsWith("passthru") || // Disregard passthru statements.
|
|
|
|
line.StartsWith("required-props:") ||
|
|
|
|
line.StartsWith("param:") ||
|
|
|
|
line.StartsWith("dlflags:") ||
|
|
|
|
line.StartsWith("glxflags:") ||
|
|
|
|
line.StartsWith("vectorequiv:") ||
|
|
|
|
//line.StartsWith("category:") ||
|
|
|
|
line.StartsWith("version:") ||
|
|
|
|
line.StartsWith("glxsingle:") ||
|
|
|
|
line.StartsWith("glxropcode:") ||
|
|
|
|
line.StartsWith("glxvendorpriv:") ||
|
|
|
|
line.StartsWith("glsflags:") ||
|
|
|
|
line.StartsWith("glsopcode:") ||
|
|
|
|
line.StartsWith("glsalias:") ||
|
|
|
|
line.StartsWith("wglflags:") ||
|
|
|
|
line.StartsWith("extension:") ||
|
|
|
|
line.StartsWith("alias:") ||
|
|
|
|
line.StartsWith("offset:"))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
return line;
|
|
|
|
}
|
|
|
|
while (true);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region ISpecWriter Members
|
|
|
|
|
|
|
|
#region void WriteBindings
|
2009-02-28 19:29:34 +00:00
|
|
|
|
2010-10-13 21:41:06 +00:00
|
|
|
public void WriteBindings(DelegateCollection delegates, FunctionCollection wrappers, EnumCollection enums)
|
2009-02-22 10:43:35 +00:00
|
|
|
{
|
2009-03-08 18:08:35 +00:00
|
|
|
Console.WriteLine("Writing bindings to {0}", Settings.OutputPath);
|
2009-02-22 10:43:35 +00:00
|
|
|
if (!Directory.Exists(Settings.OutputPath))
|
|
|
|
Directory.CreateDirectory(Settings.OutputPath);
|
|
|
|
|
2009-05-30 15:28:52 +00:00
|
|
|
string temp_enums_file = Path.GetTempFileName();
|
|
|
|
string temp_delegates_file = Path.GetTempFileName();
|
|
|
|
string temp_core_file = Path.GetTempFileName();
|
|
|
|
string temp_wrappers_file = Path.GetTempFileName();
|
|
|
|
|
2009-03-08 00:46:58 +00:00
|
|
|
// Enums
|
2009-05-30 15:28:52 +00:00
|
|
|
using (BindStreamWriter sw = new BindStreamWriter(temp_enums_file))
|
2009-02-22 10:43:35 +00:00
|
|
|
{
|
2009-03-08 18:08:35 +00:00
|
|
|
WriteLicense(sw);
|
2009-05-05 21:00:48 +00:00
|
|
|
|
|
|
|
sw.WriteLine("using System;");
|
|
|
|
sw.WriteLine();
|
|
|
|
|
2009-02-22 10:43:35 +00:00
|
|
|
if ((Settings.Compatibility & Settings.Legacy.NestedEnums) != Settings.Legacy.None)
|
|
|
|
{
|
|
|
|
sw.WriteLine("namespace {0}", Settings.OutputNamespace);
|
|
|
|
sw.WriteLine("{");
|
|
|
|
sw.Indent();
|
|
|
|
sw.WriteLine("static partial class {0}", Settings.OutputClass);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
sw.WriteLine("namespace {0}", Settings.EnumsOutput);
|
|
|
|
|
|
|
|
sw.WriteLine("{");
|
2009-02-28 19:29:34 +00:00
|
|
|
|
2009-02-22 10:43:35 +00:00
|
|
|
sw.Indent();
|
2010-10-13 21:41:06 +00:00
|
|
|
WriteEnums(sw, enums);
|
2009-02-22 10:43:35 +00:00
|
|
|
sw.Unindent();
|
|
|
|
|
|
|
|
if ((Settings.Compatibility & Settings.Legacy.NestedEnums) != Settings.Legacy.None)
|
|
|
|
{
|
|
|
|
sw.WriteLine("}");
|
|
|
|
sw.Unindent();
|
|
|
|
}
|
|
|
|
|
|
|
|
sw.WriteLine("}");
|
|
|
|
}
|
2009-03-08 00:46:58 +00:00
|
|
|
|
|
|
|
// Delegates
|
2009-05-30 15:28:52 +00:00
|
|
|
using (BindStreamWriter sw = new BindStreamWriter(temp_delegates_file))
|
2009-02-22 10:43:35 +00:00
|
|
|
{
|
2009-03-08 18:08:35 +00:00
|
|
|
WriteLicense(sw);
|
2009-02-22 10:43:35 +00:00
|
|
|
sw.WriteLine("namespace {0}", Settings.OutputNamespace);
|
|
|
|
sw.WriteLine("{");
|
|
|
|
sw.Indent();
|
|
|
|
|
|
|
|
sw.WriteLine("using System;");
|
2009-10-27 22:37:05 +00:00
|
|
|
sw.WriteLine("using System.Text;");
|
2009-02-22 10:43:35 +00:00
|
|
|
sw.WriteLine("using System.Runtime.InteropServices;");
|
|
|
|
|
|
|
|
sw.WriteLine("#pragma warning disable 0649");
|
2010-10-13 21:41:06 +00:00
|
|
|
WriteDelegates(sw, delegates);
|
2009-02-22 10:43:35 +00:00
|
|
|
|
|
|
|
sw.Unindent();
|
|
|
|
sw.WriteLine("}");
|
|
|
|
}
|
2009-03-08 00:46:58 +00:00
|
|
|
|
|
|
|
// Core
|
2009-05-30 15:28:52 +00:00
|
|
|
using (BindStreamWriter sw = new BindStreamWriter(temp_core_file))
|
2009-02-22 10:43:35 +00:00
|
|
|
{
|
2009-03-08 18:08:35 +00:00
|
|
|
WriteLicense(sw);
|
2009-02-22 10:43:35 +00:00
|
|
|
sw.WriteLine("namespace {0}", Settings.OutputNamespace);
|
|
|
|
sw.WriteLine("{");
|
|
|
|
sw.Indent();
|
|
|
|
//specWriter.WriteTypes(sw, Bind.Structures.Type.CSTypes);
|
|
|
|
sw.WriteLine("using System;");
|
2009-10-27 22:37:05 +00:00
|
|
|
sw.WriteLine("using System.Text;");
|
2009-02-22 10:43:35 +00:00
|
|
|
sw.WriteLine("using System.Runtime.InteropServices;");
|
2009-02-28 19:29:34 +00:00
|
|
|
|
2010-10-13 21:41:06 +00:00
|
|
|
WriteImports(sw, delegates);
|
2009-02-22 10:43:35 +00:00
|
|
|
|
|
|
|
sw.Unindent();
|
|
|
|
sw.WriteLine("}");
|
|
|
|
}
|
2009-03-08 00:46:58 +00:00
|
|
|
|
|
|
|
// Wrappers
|
2009-05-30 15:28:52 +00:00
|
|
|
using (BindStreamWriter sw = new BindStreamWriter(temp_wrappers_file))
|
2009-02-22 10:43:35 +00:00
|
|
|
{
|
2009-03-08 18:08:35 +00:00
|
|
|
WriteLicense(sw);
|
2009-02-22 10:43:35 +00:00
|
|
|
sw.WriteLine("namespace {0}", Settings.OutputNamespace);
|
|
|
|
sw.WriteLine("{");
|
|
|
|
sw.Indent();
|
|
|
|
|
|
|
|
sw.WriteLine("using System;");
|
2009-10-27 22:37:05 +00:00
|
|
|
sw.WriteLine("using System.Text;");
|
2009-02-22 10:43:35 +00:00
|
|
|
sw.WriteLine("using System.Runtime.InteropServices;");
|
|
|
|
|
2010-10-13 21:41:06 +00:00
|
|
|
WriteWrappers(sw, wrappers, Type.CSTypes);
|
2009-02-22 10:43:35 +00:00
|
|
|
|
|
|
|
sw.Unindent();
|
|
|
|
sw.WriteLine("}");
|
|
|
|
}
|
2009-05-30 15:28:52 +00:00
|
|
|
|
2009-07-15 15:01:55 +00:00
|
|
|
string output_enums = Path.Combine(Settings.OutputPath, enumsFile);
|
|
|
|
string output_delegates = Path.Combine(Settings.OutputPath, delegatesFile);
|
|
|
|
string output_core = Path.Combine(Settings.OutputPath, importsFile);
|
|
|
|
string output_wrappers = Path.Combine(Settings.OutputPath, wrappersFile);
|
|
|
|
|
|
|
|
if (File.Exists(output_enums)) File.Delete(output_enums);
|
|
|
|
if (File.Exists(output_delegates)) File.Delete(output_delegates);
|
|
|
|
if (File.Exists(output_core)) File.Delete(output_core);
|
|
|
|
if (File.Exists(output_wrappers)) File.Delete(output_wrappers);
|
|
|
|
|
|
|
|
File.Move(temp_enums_file, output_enums);
|
|
|
|
File.Move(temp_delegates_file, output_delegates);
|
|
|
|
File.Move(temp_core_file, output_core);
|
|
|
|
File.Move(temp_wrappers_file, output_wrappers);
|
2009-02-22 10:43:35 +00:00
|
|
|
}
|
2009-02-28 19:29:34 +00:00
|
|
|
|
2009-02-22 10:43:35 +00:00
|
|
|
#endregion
|
2009-02-28 19:29:34 +00:00
|
|
|
|
2009-02-22 10:43:35 +00:00
|
|
|
#region void WriteDelegates
|
2009-02-28 19:29:34 +00:00
|
|
|
|
2009-02-22 10:43:35 +00:00
|
|
|
public virtual void WriteDelegates(BindStreamWriter sw, DelegateCollection delegates)
|
|
|
|
{
|
|
|
|
Trace.WriteLine(String.Format("Writing delegates to:\t{0}.{1}.{2}", Settings.OutputNamespace, Settings.OutputClass, Settings.DelegatesClass));
|
|
|
|
|
|
|
|
sw.WriteLine("#pragma warning disable 3019"); // CLSCompliant attribute
|
|
|
|
sw.WriteLine("#pragma warning disable 1591"); // Missing doc comments
|
|
|
|
|
|
|
|
sw.WriteLine();
|
|
|
|
sw.WriteLine("partial class {0}", Settings.OutputClass);
|
|
|
|
sw.WriteLine("{");
|
|
|
|
sw.Indent();
|
|
|
|
|
|
|
|
sw.WriteLine("internal static partial class {0}", Settings.DelegatesClass);
|
|
|
|
sw.WriteLine("{");
|
|
|
|
sw.Indent();
|
2009-02-28 19:29:34 +00:00
|
|
|
|
2009-08-21 20:28:14 +00:00
|
|
|
foreach (Delegate d in delegates.Values)
|
2009-02-22 10:43:35 +00:00
|
|
|
{
|
|
|
|
sw.WriteLine("[System.Security.SuppressUnmanagedCodeSecurity()]");
|
|
|
|
sw.WriteLine("internal {0};", d.ToString());
|
|
|
|
sw.WriteLine("internal {0}static {1} {2}{1};", // = null
|
|
|
|
d.Unsafe ? "unsafe " : "",
|
|
|
|
d.Name,
|
|
|
|
Settings.FunctionPrefix);
|
|
|
|
}
|
2009-02-28 19:29:34 +00:00
|
|
|
|
2009-02-22 10:43:35 +00:00
|
|
|
sw.Unindent();
|
|
|
|
sw.WriteLine("}");
|
|
|
|
|
|
|
|
sw.Unindent();
|
|
|
|
sw.WriteLine("}");
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region void WriteImports
|
|
|
|
|
|
|
|
public virtual void WriteImports(BindStreamWriter sw, DelegateCollection delegates)
|
|
|
|
{
|
|
|
|
Trace.WriteLine(String.Format("Writing imports to:\t{0}.{1}.{2}", Settings.OutputNamespace, Settings.OutputClass, Settings.ImportsClass));
|
|
|
|
|
|
|
|
sw.WriteLine("#pragma warning disable 3019"); // CLSCompliant attribute
|
|
|
|
sw.WriteLine("#pragma warning disable 1591"); // Missing doc comments
|
|
|
|
|
|
|
|
sw.WriteLine();
|
|
|
|
sw.WriteLine("partial class {0}", Settings.OutputClass);
|
|
|
|
sw.WriteLine("{");
|
|
|
|
sw.Indent();
|
|
|
|
sw.WriteLine();
|
|
|
|
sw.WriteLine("internal static partial class {0}", Settings.ImportsClass);
|
|
|
|
sw.WriteLine("{");
|
|
|
|
sw.Indent();
|
|
|
|
//sw.WriteLine("static {0}() {1} {2}", Settings.ImportsClass, "{", "}"); // Disable BeforeFieldInit
|
|
|
|
sw.WriteLine();
|
2009-08-21 20:28:14 +00:00
|
|
|
foreach (Delegate d in delegates.Values)
|
2009-02-22 10:43:35 +00:00
|
|
|
{
|
2009-08-03 23:06:05 +00:00
|
|
|
sw.WriteLine("[System.Security.SuppressUnmanagedCodeSecurity()]");
|
|
|
|
sw.WriteLine(
|
|
|
|
"[System.Runtime.InteropServices.DllImport({0}.Library, EntryPoint = \"{1}{2}\"{3})]",
|
|
|
|
Settings.OutputClass,
|
|
|
|
Settings.FunctionPrefix,
|
|
|
|
d.Name,
|
|
|
|
d.Name.EndsWith("W") || d.Name.EndsWith("A") ? ", CharSet = CharSet.Auto" : ", ExactSpelling = true"
|
|
|
|
);
|
|
|
|
sw.WriteLine("internal extern static {0};", d.DeclarationString());
|
2009-02-22 10:43:35 +00:00
|
|
|
}
|
|
|
|
sw.Unindent();
|
|
|
|
sw.WriteLine("}");
|
|
|
|
sw.Unindent();
|
|
|
|
sw.WriteLine("}");
|
|
|
|
}
|
2009-02-28 19:29:34 +00:00
|
|
|
|
2009-02-22 10:43:35 +00:00
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region void WriteWrappers
|
|
|
|
|
|
|
|
public void WriteWrappers(BindStreamWriter sw, FunctionCollection wrappers, Dictionary<string, string> CSTypes)
|
|
|
|
{
|
|
|
|
Trace.WriteLine(String.Format("Writing wrappers to:\t{0}.{1}", Settings.OutputNamespace, Settings.OutputClass));
|
|
|
|
|
|
|
|
sw.WriteLine("#pragma warning disable 3019"); // CLSCompliant attribute
|
|
|
|
sw.WriteLine("#pragma warning disable 1591"); // Missing doc comments
|
2009-03-25 21:48:14 +00:00
|
|
|
sw.WriteLine("#pragma warning disable 1572"); // Wrong param comments
|
|
|
|
sw.WriteLine("#pragma warning disable 1573"); // Missing param comments
|
2009-02-22 10:43:35 +00:00
|
|
|
|
|
|
|
sw.WriteLine();
|
2009-08-15 17:35:20 +00:00
|
|
|
sw.WriteLine("partial class {0}", Settings.OutputClass);
|
2009-02-22 10:43:35 +00:00
|
|
|
sw.WriteLine("{");
|
|
|
|
|
|
|
|
sw.Indent();
|
|
|
|
//sw.WriteLine("static {0}() {1} {2}", className, "{", "}"); // Static init in GLHelper.cs
|
|
|
|
sw.WriteLine();
|
2009-03-08 00:46:58 +00:00
|
|
|
|
|
|
|
int current = 0;
|
2009-02-22 10:43:35 +00:00
|
|
|
foreach (string key in wrappers.Keys)
|
|
|
|
{
|
|
|
|
if (((Settings.Compatibility & Settings.Legacy.NoSeparateFunctionNamespaces) == Settings.Legacy.None) && key != "Core")
|
|
|
|
{
|
2009-02-28 19:29:34 +00:00
|
|
|
if (!Char.IsDigit(key[0]))
|
|
|
|
{
|
|
|
|
sw.WriteLine("public static partial class {0}", key);
|
|
|
|
}
|
2009-02-22 10:43:35 +00:00
|
|
|
else
|
|
|
|
{
|
2009-02-28 19:29:34 +00:00
|
|
|
// Identifiers cannot start with a number:
|
2009-02-22 10:43:35 +00:00
|
|
|
sw.WriteLine("public static partial class {0}{1}", Settings.ConstantPrefix, key);
|
|
|
|
}
|
|
|
|
sw.WriteLine("{");
|
|
|
|
sw.Indent();
|
|
|
|
}
|
|
|
|
|
2009-05-30 15:28:52 +00:00
|
|
|
wrappers[key].Sort();
|
2009-02-22 10:43:35 +00:00
|
|
|
foreach (Function f in wrappers[key])
|
|
|
|
{
|
2009-10-27 22:37:05 +00:00
|
|
|
current = WriteWrapper(sw, current, f);
|
2009-02-22 10:43:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (((Settings.Compatibility & Settings.Legacy.NoSeparateFunctionNamespaces) == Settings.Legacy.None) && key != "Core")
|
|
|
|
{
|
|
|
|
sw.Unindent();
|
|
|
|
sw.WriteLine("}");
|
|
|
|
sw.WriteLine();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sw.Unindent();
|
|
|
|
sw.WriteLine("}");
|
|
|
|
}
|
|
|
|
|
2009-10-27 22:37:05 +00:00
|
|
|
private static int WriteWrapper(BindStreamWriter sw, int current, Function f)
|
|
|
|
{
|
|
|
|
if ((Settings.Compatibility & Settings.Legacy.NoDocumentation) == 0)
|
|
|
|
{
|
|
|
|
Console.WriteLine("Creating docs for #{0} ({1})", current++, f.Name);
|
|
|
|
WriteDocumentation(sw, f);
|
|
|
|
}
|
|
|
|
WriteMethod(sw, f);
|
|
|
|
return current;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void WriteMethod(BindStreamWriter sw, Function f)
|
|
|
|
{
|
2010-10-10 12:28:27 +00:00
|
|
|
if (f.Deprecated && Settings.IsEnabled(Settings.Legacy.AddDeprecationWarnings))
|
|
|
|
{
|
|
|
|
sw.WriteLine("[Obsolete(\"Deprecated in OpenGL {0}\")]", f.DeprecatedVersion);
|
|
|
|
}
|
|
|
|
|
2009-10-27 22:37:05 +00:00
|
|
|
if (!f.CLSCompliant)
|
|
|
|
{
|
|
|
|
sw.WriteLine("[System.CLSCompliant(false)]");
|
|
|
|
}
|
2010-10-10 12:28:27 +00:00
|
|
|
|
2009-10-27 22:37:05 +00:00
|
|
|
sw.WriteLine("[AutoGenerated(Category = \"{0}\", Version = \"{1}\", EntryPoint = \"{2}\")]",
|
|
|
|
f.Category, f.Version, Settings.FunctionPrefix + f.WrappedDelegate.Name);
|
|
|
|
sw.WriteLine("public static ");
|
|
|
|
sw.Write(f);
|
|
|
|
sw.WriteLine();
|
|
|
|
}
|
|
|
|
|
2010-10-12 11:01:25 +00:00
|
|
|
static DocProcessor processor = new DocProcessor(Path.Combine(Settings.DocPath, Settings.DocFile));
|
|
|
|
static Dictionary<string, string> docfiles;
|
2009-10-27 22:37:05 +00:00
|
|
|
private static void WriteDocumentation(BindStreamWriter sw, Function f)
|
|
|
|
{
|
2010-10-12 11:01:25 +00:00
|
|
|
if (docfiles == null)
|
2009-10-27 22:37:05 +00:00
|
|
|
{
|
2010-10-12 11:01:25 +00:00
|
|
|
docfiles = new Dictionary<string, string>();
|
|
|
|
foreach (string file in Directory.GetFiles(Settings.DocPath))
|
2009-10-27 22:37:05 +00:00
|
|
|
{
|
2010-10-12 11:01:25 +00:00
|
|
|
docfiles.Add(Path.GetFileName(file), file);
|
2009-10-27 22:37:05 +00:00
|
|
|
}
|
|
|
|
}
|
2010-10-12 11:01:25 +00:00
|
|
|
try
|
|
|
|
{
|
|
|
|
string file = Settings.FunctionPrefix + f.WrappedDelegate.Name + ".xml";
|
|
|
|
if (!docfiles.ContainsKey(file))
|
|
|
|
file = Settings.FunctionPrefix + f.TrimmedName + ".xml";
|
|
|
|
if (!docfiles.ContainsKey(file))
|
|
|
|
file = Settings.FunctionPrefix + f.TrimmedName.TrimEnd(numbers) + ".xml";
|
|
|
|
|
|
|
|
if (docfiles.ContainsKey(file))
|
|
|
|
sw.WriteLine(processor.ProcessFile(docfiles[file]));
|
|
|
|
}
|
|
|
|
catch
|
2009-10-27 22:37:05 +00:00
|
|
|
{ }
|
|
|
|
}
|
|
|
|
|
2009-02-22 10:43:35 +00:00
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region void WriteTypes
|
|
|
|
|
|
|
|
public void WriteTypes(BindStreamWriter sw, Dictionary<string, string> CSTypes)
|
|
|
|
{
|
|
|
|
sw.WriteLine();
|
|
|
|
foreach (string s in CSTypes.Keys)
|
|
|
|
{
|
|
|
|
sw.WriteLine("using {0} = System.{1};", s, CSTypes[s]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
2009-02-28 19:29:34 +00:00
|
|
|
#region void WriteEnums
|
2009-02-22 10:43:35 +00:00
|
|
|
|
|
|
|
public void WriteEnums(BindStreamWriter sw, EnumCollection enums)
|
|
|
|
{
|
|
|
|
//sw.WriteLine("#pragma warning disable 3019"); // CLSCompliant attribute
|
|
|
|
sw.WriteLine("#pragma warning disable 1591"); // Missing doc comments
|
|
|
|
sw.WriteLine();
|
|
|
|
|
|
|
|
if ((Settings.Compatibility & Settings.Legacy.NestedEnums) != Settings.Legacy.None)
|
|
|
|
Trace.WriteLine(String.Format("Writing enums to:\t{0}.{1}.{2}", Settings.OutputNamespace, Settings.OutputClass, Settings.NestedEnumsClass));
|
|
|
|
else
|
|
|
|
Trace.WriteLine(String.Format("Writing enums to:\t{0}", Settings.EnumsOutput));
|
|
|
|
|
|
|
|
if ((Settings.Compatibility & Settings.Legacy.ConstIntEnums) == Settings.Legacy.None)
|
|
|
|
{
|
|
|
|
if ((Settings.Compatibility & Settings.Legacy.NestedEnums) != Settings.Legacy.None &&
|
|
|
|
!String.IsNullOrEmpty(Settings.NestedEnumsClass))
|
|
|
|
{
|
|
|
|
sw.WriteLine("public class Enums");
|
|
|
|
sw.WriteLine("{");
|
|
|
|
sw.Indent();
|
|
|
|
}
|
|
|
|
|
2009-08-21 20:28:14 +00:00
|
|
|
foreach (Enum @enum in enums.Values)
|
2009-02-22 10:43:35 +00:00
|
|
|
{
|
|
|
|
sw.Write(@enum);
|
|
|
|
sw.WriteLine();
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((Settings.Compatibility & Settings.Legacy.NestedEnums) != Settings.Legacy.None &&
|
|
|
|
!String.IsNullOrEmpty(Settings.NestedEnumsClass))
|
|
|
|
{
|
|
|
|
sw.Unindent();
|
|
|
|
sw.WriteLine("}");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Tao legacy mode: dump all enums as constants in GLClass.
|
2009-08-21 20:28:14 +00:00
|
|
|
foreach (Constant c in enums[Settings.CompleteEnumName].ConstantCollection.Values)
|
2009-02-22 10:43:35 +00:00
|
|
|
{
|
|
|
|
// Print constants avoiding circular definitions
|
|
|
|
if (c.Name != c.Value)
|
|
|
|
{
|
|
|
|
sw.WriteLine(String.Format(
|
|
|
|
"public const int {0} = {2}((int){1});",
|
|
|
|
c.Name.StartsWith(Settings.ConstantPrefix) ? c.Name : Settings.ConstantPrefix + c.Name,
|
|
|
|
Char.IsDigit(c.Value[0]) ? c.Value : c.Value.StartsWith(Settings.ConstantPrefix) ? c.Value : Settings.ConstantPrefix + c.Value,
|
|
|
|
c.Unchecked ? "unchecked" : ""));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
2009-02-28 19:29:34 +00:00
|
|
|
#region void WriteLicense
|
|
|
|
|
2009-03-08 18:08:35 +00:00
|
|
|
public void WriteLicense(BindStreamWriter sw)
|
2009-02-28 19:29:34 +00:00
|
|
|
{
|
2009-03-08 18:08:35 +00:00
|
|
|
sw.WriteLine(File.ReadAllText(Path.Combine(Settings.InputPath, Settings.LicenseFile)));
|
2009-02-28 19:29:34 +00:00
|
|
|
sw.WriteLine();
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
2009-02-22 10:43:35 +00:00
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
}
|