void TranslateAttributes(Delegate d, XPathNavigator function_override, XPathNavigator nav, string apiname, string apiversion) { if (function_override != null) { var version_override = function_override.SelectSingleNode("version"); if (version_override != null) { d.Version = version_override.Value; } var profile_override = function_override.SelectSingleNode("profile"); if (profile_override != null) { Debug.Print("Profile override not yet implemented"); } var name_override = function_override.SelectSingleNode("name"); if (name_override != null) { d.Name = name_override.Value; } var obsolete = function_override.GetAttribute("obsolete", String.Empty); if (!String.IsNullOrEmpty(obsolete)) { d.Obsolete = obsolete; } } }
/// <summary> /// Merges the given enum into the enum list. If an enum of the same name exists, /// it merges their respective constants. /// </summary> /// <param name="enums"></param> /// <param name="t"></param> internal static void Merge(DelegateCollection delegates, Delegate t) { if (!delegates.ContainsKey(t.Name)) { delegates.Add(t.Name, t); } }
static XPathNodeIterator GetFuncOverload(XPathNavigator nav, Delegate d, string apiname, string apiversion) { // Try a few different extension variations that appear in the overrides xml file string[] extensions = { d.Extension, TranslateExtension(d.Extension), d.Extension.ToUpper() }; string trimmed_name = GetTrimmedName(d); XPathNodeIterator function_overload = null; foreach (var ext in extensions) { string extensionless_name = GetTrimmedExtension(d.Name, ext); function_overload = nav.Select(GetOverloadsPath(apiname, apiversion, d.Name, ext)); if (function_overload.Count != 0) { break; } function_overload = nav.Select(GetOverloadsPath(apiname, apiversion, extensionless_name, ext)); if (function_overload.Count != 0) { break; } function_overload = nav.Select(GetOverloadsPath(apiname, apiversion, trimmed_name, ext)); if (function_overload.Count != 0) { break; } } return(function_overload); }
static IEnumerable <Function> CreateNormalWrappers(Delegate d, EnumCollection enums) { Function f = new Function(d); WrapReturnType(f); foreach (var wrapper in WrapParameters(f, enums)) { yield return(wrapper); } }
static Delegate CreateArrayReturnTypeConvencienceWrapper(Delegate d) { var f = new Delegate(d); var p_array = f.Parameters.Last(); var p_size = f.Parameters[f.Parameters.Count - 2]; f.Parameters.RemoveAt(f.Parameters.Count - 2); p_array.WrapperType = WrapperTypes.ConvenienceArrayType; p_array.Pointer = 0; return(f); }
static void ApplyReturnTypeReplacement(Delegate d, XPathNavigator function_override) { if (function_override != null) { XPathNavigator return_override = function_override.SelectSingleNode("returns"); if (return_override != null) { d.ReturnType.CurrentType = return_override.Value; } } }
static XPathNavigator GetFuncOverride(XPathNavigator nav, Delegate d) { string name = TrimName(d.Name, false); string ext = d.Extension; var function_override = nav.SelectSingleNode(String.Format(Path, d.Name, ext)) ?? nav.SelectSingleNode(String.Format(Path, name, ext)) ?? nav.SelectSingleNode(String.Format(Path, Utilities.StripGL2Extension(d.Name), ext)); return(function_override); }
public override DelegateCollection ReadDelegates(StreamReader specFile) { DelegateCollection delegates = new DelegateCollection(); XPathDocument specs = new XPathDocument(specFile); XPathDocument overrides = new XPathDocument(new StreamReader(Path.Combine(Settings.InputPath, functionOverridesFile))); foreach (XPathNavigator nav in new XPathNavigator[] { specs.CreateNavigator().SelectSingleNode("/signatures"), overrides.CreateNavigator().SelectSingleNode("/overrides/add") }) { if (nav != null) { foreach (XPathNavigator node in nav.SelectChildren("function", String.Empty)) { Delegate d = new Delegate(); d.Name = node.GetAttribute("name", String.Empty); //d.Extension = node.GetAttribute("extension"); d.Version = node.GetAttribute("version", String.Empty); d.Category = node.GetAttribute("category", String.Empty); foreach (XPathNavigator param in node.SelectChildren(XPathNodeType.Element)) { switch (param.Name) { case "returns": d.ReturnType.CurrentType = param.GetAttribute("type", String.Empty); break; case "param": Parameter p = new Parameter(); p.CurrentType = param.GetAttribute("type", String.Empty); p.Name = param.GetAttribute("name", String.Empty); string element_count = param.GetAttribute("elementcount", String.Empty); if (!String.IsNullOrEmpty(element_count)) { p.ElementCount = Int32.Parse(element_count); } p.Flow = Parameter.GetFlowDirection(param.GetAttribute("flow", String.Empty)); d.Parameters.Add(p); break; } } d.Translate(overrides); delegates.Add(d); } } } return(delegates); }
Delegate GetCLSCompliantDelegate(Delegate d) { Delegate f = new Delegate(d); for (int i = 0; i < f.Parameters.Count; i++) { f.Parameters[i].CurrentType = GetCLSCompliantType(f.Parameters[i]); } f.ReturnType.CurrentType = GetCLSCompliantType(f.ReturnType); return(f); }
public static bool RequiresSlot(this Delegate d, Settings settings) { double version; Double.TryParse( d.Version, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out version); return (!settings.IsEnabled(Settings.Legacy.UseDllImports) || (settings.IsEnabled(Settings.Legacy.UseWindowsCompatibleGL) && version > 1.1) || d.Extension != "Core"); }
public override DelegateCollection ReadDelegates(StreamReader specFile) { DelegateCollection delegates = new DelegateCollection(); XPathDocument specs = new XPathDocument(specFile); XPathDocument overrides = new XPathDocument(new StreamReader(Path.Combine(Settings.InputPath, functionOverridesFile))); foreach (XPathNavigator nav in new XPathNavigator[] { specs.CreateNavigator().SelectSingleNode("/signatures"), overrides.CreateNavigator().SelectSingleNode("/overrides/add") }) { if (nav != null) { foreach (XPathNavigator node in nav.SelectChildren("function", String.Empty)) { Delegate d = new Delegate(); d.Name = node.GetAttribute("name", String.Empty); //d.Extension = node.GetAttribute("extension"); d.Version = node.GetAttribute("version", String.Empty); d.Category = node.GetAttribute("category", String.Empty); foreach (XPathNavigator param in node.SelectChildren(XPathNodeType.Element)) { switch (param.Name) { case "returns": d.ReturnType.CurrentType = param.GetAttribute("type", String.Empty); break; case "param": Parameter p = new Parameter(); p.CurrentType = param.GetAttribute("type", String.Empty); p.Name = param.GetAttribute("name", String.Empty); string element_count = param.GetAttribute("elementcount", String.Empty); if (!String.IsNullOrEmpty(element_count)) p.ElementCount = Int32.Parse(element_count); p.Flow = Parameter.GetFlowDirection(param.GetAttribute("flow", String.Empty)); d.Parameters.Add(p); break; } } d.Translate(overrides); delegates.Add(d); } } } return delegates; }
// Trims unecessary suffices from the specified OpenGL function name. static string GetTrimmedName(Delegate d) { string name = d.Name; string extension = d.Extension; string trimmed_name = GetTrimmedExtension(name, extension); // Note: some endings should not be trimmed, for example: 'b' from Attrib. // Check the endingsNotToTrim regex for details. Match m = EndingsNotToTrim.Match(trimmed_name); if ((m.Index + m.Length) != trimmed_name.Length) { m = Endings.Match(trimmed_name); if (m.Length > 0 && m.Index + m.Length == trimmed_name.Length) { // Only trim endings, not internal matches. if (m.Value[m.Length - 1] == 'v' && EndingsAddV.IsMatch(name) && !name.StartsWith("Get") && !name.StartsWith("MatrixIndex")) { // Only trim ending 'v' when there is a number trimmed_name = trimmed_name.Substring(0, m.Index) + "v"; } else { if (!trimmed_name.EndsWith("xedv")) { trimmed_name = trimmed_name.Substring(0, m.Index); } else { trimmed_name = trimmed_name.Substring(0, m.Index + 1); } } } } // If we have a convenience overload, we should turn the name from // plural into singular if (d.ReturnType.WrapperType == WrapperTypes.ConvenienceReturnType || d.ReturnType.WrapperType == WrapperTypes.ConvenienceArrayReturnType || d.Parameters.Any(p => p.WrapperType == WrapperTypes.ConvenienceArrayType)) { trimmed_name = trimmed_name.Replace("Queries", "Query"); trimmed_name = trimmed_name.TrimEnd('s'); } return(trimmed_name); }
// Translates the opengl return type to the equivalent C# type. // // First, we use the official typemap (gl.tm) to get the correct type. // Then we override this, when it is: // 1) A string (we have to use Marshal.PtrToStringAnsi, to avoid heap corruption) // 2) An array (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). // Return types must always be CLS-compliant, because .Net does not support overloading on return types. static void TranslateReturnType(XPathNavigator nav, Delegate d, EnumCollection enums) { var function_override = GetFuncOverride(nav, d); if (function_override != null) { XPathNavigator return_override = function_override.SelectSingleNode("returns"); if (return_override != null) { d.ReturnType.CurrentType = return_override.Value; } } d.ReturnType.Translate(nav, d.Category, enums); if (d.ReturnType.CurrentType.ToLower().Contains("void") && d.ReturnType.Pointer != 0) { d.ReturnType.QualifiedType = "IntPtr"; d.ReturnType.WrapperType = WrapperTypes.GenericReturnType; } if (d.ReturnType.CurrentType.ToLower().Contains("string")) { d.ReturnType.QualifiedType = "IntPtr"; d.ReturnType.WrapperType = WrapperTypes.StringReturnType; } if (d.ReturnType.CurrentType.ToLower() == "object") { d.ReturnType.QualifiedType = "IntPtr"; d.ReturnType.WrapperType |= WrapperTypes.GenericReturnType; } if (d.ReturnType.CurrentType.Contains("GLenum")) { if ((Settings.Compatibility & Settings.Legacy.ConstIntEnums) == Settings.Legacy.None) { d.ReturnType.QualifiedType = String.Format("{0}{1}{2}", Settings.EnumsOutput, Settings.NamespaceSeparator, Settings.CompleteEnumName); } else { d.ReturnType.QualifiedType = "int"; } } d.ReturnType.CurrentType = d.ReturnType.GetCLSCompliantType(); }
void TranslateParameters(Delegate d, XPathNavigator function_override, XPathNavigator nav, EnumProcessor enum_processor, EnumCollection enums, string apiname, string apiversion) { ApplyParameterReplacement(d, function_override); for (int i = 0; i < d.Parameters.Count; i++) { TranslateParameter(d.Parameters[i], function_override, nav, enum_processor, enums, d.Category, apiname); if (d.Parameters[i].CurrentType == "UInt16" && d.Name.Contains("LineStipple")) { d.Parameters[i].WrapperType = WrapperTypes.UncheckedParameter; } } }
// Translates the opengl return type to the equivalent C# type. // // First, we use the official typemap (gl.tm) to get the correct type. // Then we override this, when it is: // 1) A string (we have to use Marshal.PtrToStringAnsi, to avoid heap corruption) // 2) An array (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). // Return types must always be CLS-compliant, because .Net does not support overloading on return types. void TranslateReturnType(Delegate d, XPathNavigator function_override, XPathNavigator nav, EnumProcessor enum_processor, EnumCollection enums, string apiname, string apiversion) { ApplyReturnTypeReplacement(d, function_override); TranslateType(d.ReturnType, function_override, nav, enum_processor, enums, d.Category, apiname); if (d.ReturnType.CurrentType.ToLower().Contains("void") && d.ReturnType.Pointer != 0) { d.ReturnType.QualifiedType = "IntPtr"; d.ReturnType.Pointer--; d.ReturnType.WrapperType = WrapperTypes.GenericReturnType; } if (d.ReturnType.CurrentType.ToLower().Contains("string")) { d.ReturnType.QualifiedType = "IntPtr"; d.ReturnType.WrapperType = WrapperTypes.StringReturnType; } if (d.ReturnType.CurrentType.ToLower() == "object") { d.ReturnType.QualifiedType = "IntPtr"; d.ReturnType.WrapperType |= WrapperTypes.GenericReturnType; } if (d.ReturnType.CurrentType.Contains("GLenum")) { if ((Settings.Compatibility & Settings.Legacy.ConstIntEnums) == Settings.Legacy.None) { d.ReturnType.QualifiedType = String.Format("{0}{1}{2}", Settings.EnumsOutput, Settings.NamespaceSeparator, Settings.CompleteEnumName); } else { d.ReturnType.QualifiedType = "int"; } } d.ReturnType.CurrentType = GetCLSCompliantType(d.ReturnType); }
public virtual void Process() { // Matches functions that cannot have their trailing 'v' trimmed for CLS-Compliance reasons. // Built through trial and error :) //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?|TextureParameter.v)", // RegexOptions.Compiled); Type.Initialize(glTypemap, csTypemap); Enum.Initialize(enumSpec, enumSpecExt); Enum.GLEnums.Translate(new XPathDocument(Path.Combine(Settings.InputPath, functionOverridesFile))); Function.Initialize(); Delegate.Initialize(glSpec, glSpecExt); WriteBindings( Delegate.Delegates, Function.Wrappers, Enum.GLEnums); }
static Delegate CreateReturnTypeConvenienceWrapper(Delegate d) { var f = new Delegate(d); f.ReturnType = new Type(f.Parameters.Last()); f.ReturnType.Pointer = 0; f.Parameters.RemoveAt(f.Parameters.Count - 1); f.ReturnType.WrapperType = WrapperTypes.ConvenienceReturnType; if (f.Parameters.Count > 0) { var p_size = f.Parameters.Last(); if (p_size.CurrentType.ToLower().StartsWith("int") && p_size.Pointer == 0) { f.Parameters.RemoveAt(f.Parameters.Count - 1); f.ReturnType.WrapperType = WrapperTypes.ConvenienceArrayReturnType; } } return(f); }
static void ApplyParameterReplacement(Delegate d, XPathNavigator function_override) { if (function_override != null) { for (int i = 0; i < d.Parameters.Count; i++) { XPathNavigator param_override = function_override.SelectSingleNode(String.Format( "param[@name='{0}' or @index='{1}']", d.Parameters[i].RawName, i)); if (param_override != null) { foreach (XPathNavigator node in param_override.SelectChildren(XPathNodeType.Element)) { switch (node.Name) { case "type": d.Parameters[i].CurrentType = (string)node.TypedValue; break; case "name": d.Parameters[i].Name = (string)node.TypedValue; break; case "flow": d.Parameters[i].Flow = Parameter.GetFlowDirection((string)node.TypedValue); break; case "count": int count; if (Int32.TryParse(node.Value, out count)) { d.Parameters[i].ElementCount = count; } break; } } } } } }
static void TranslateParameters(XPathNavigator nav, Delegate d, EnumCollection enums) { var function_override = GetFuncOverride(nav, d); for (int i = 0; i < d.Parameters.Count; i++) { if (function_override != null) { XPathNavigator param_override = function_override.SelectSingleNode( String.Format("param[@name='{0}']", d.Parameters[i].RawName)); if (param_override != null) { foreach (XPathNavigator node in param_override.SelectChildren(XPathNodeType.Element)) { switch (node.Name) { case "type": d.Parameters[i].CurrentType = (string)node.TypedValue; break; case "name": d.Parameters[i].Name = (string)node.TypedValue; break; case "flow": d.Parameters[i].Flow = Parameter.GetFlowDirection((string)node.TypedValue); break; } } } } d.Parameters[i].Translate(nav, d.Category, enums); if (d.Parameters[i].CurrentType == "UInt16" && d.Name.Contains("LineStipple")) { d.Parameters[i].WrapperType = WrapperTypes.UncheckedParameter; } } }
static Delegate CreateReturnTypeConvenienceWrapper(Delegate d) { var f = new Delegate(d); f.ReturnType = new Type(f.Parameters.Last()); f.ReturnType.Pointer = 0; f.Parameters.RemoveAt(f.Parameters.Count - 1); f.ReturnType.WrapperType = WrapperTypes.ConvenienceReturnType; if (f.Parameters.Count > 0) { var p_size = f.Parameters.Last(); if (p_size.CurrentType.ToLower().StartsWith("int") && p_size.Pointer == 0) { f.Parameters.RemoveAt(f.Parameters.Count - 1); f.ReturnType.WrapperType = WrapperTypes.ConvenienceArrayReturnType; } } return f; }
public FunctionCollection Process(EnumProcessor enum_processor, DocProcessor doc_processor, DelegateCollection delegates, EnumCollection enums, string apiname, string apiversion) { Console.WriteLine("Processing delegates."); var nav = new XPathDocument(Overrides).CreateNavigator(); foreach (var version in apiversion.Split('|')) { // Translate each delegate: // 1st using the <replace> elements in overrides.xml // 2nd using the hardcoded rules in FuncProcessor (e.g. char* -> string) foreach (var signatures in delegates.Values) { foreach (var d in signatures) { var replace = GetFuncOverride(nav, d, apiname, apiversion); TranslateExtension(d); TranslateReturnType(d, replace, nav, enum_processor, enums, apiname, version); TranslateParameters(d, replace, nav, enum_processor, enums, apiname, version); TranslateAttributes(d, replace, nav, apiname, version); } } // Create overloads for backwards compatibility, // by resolving <overload> elements var overload_list = new List<Delegate>(); foreach (var d in delegates.Values.Select(v => v.First())) { var overload_elements = GetFuncOverload(nav, d, apiname, apiversion); foreach (XPathNavigator overload_element in overload_elements) { var overload = new Delegate(d); TranslateReturnType(overload, overload_element, nav, enum_processor, enums, apiname, version); TranslateParameters(overload, overload_element, nav, enum_processor, enums, apiname, version); TranslateAttributes(overload, overload_element, nav, apiname, version); overload_list.Add(overload); } } foreach (var overload in overload_list) { delegates.Add(overload); } } Console.WriteLine("Generating wrappers."); var wrappers = CreateWrappers(delegates, enums); Console.WriteLine("Generating convenience overloads."); wrappers.AddRange(CreateConvenienceOverloads(wrappers)); Console.WriteLine("Generating CLS compliant overloads."); wrappers = CreateCLSCompliantWrappers(wrappers, enums); Console.WriteLine("Removing non-CLS compliant duplicates."); wrappers = MarkCLSCompliance(wrappers); Console.WriteLine("Removing overloaded delegates."); RemoveOverloadedDelegates(delegates, wrappers); Console.WriteLine("Generating address table."); GenerateAddressTable(delegates); Console.WriteLine("Generating documentation."); GenerateDocumentation(wrappers, enum_processor, doc_processor); return wrappers; }
Delegate GetCLSCompliantDelegate(Delegate d) { Delegate f = new Delegate(d); for (int i = 0; i < f.Parameters.Count; i++) { f.Parameters[i].CurrentType = GetCLSCompliantType(f.Parameters[i]); } f.ReturnType.CurrentType = GetCLSCompliantType(f.ReturnType); return f; }
void TranslateParameters(Delegate d, XPathNavigator function_override, XPathNavigator nav, EnumProcessor enum_processor, EnumCollection enums, string apiname, string apiversion) { ApplyParameterReplacement(d, function_override); for (int i = 0; i < d.Parameters.Count; i++) { TranslateParameter(d.Parameters[i], function_override, nav, enum_processor, enums, d.Category, apiname); if (d.Parameters[i].CurrentType == "UInt16" && d.Name.Contains("LineStipple")) d.Parameters[i].WrapperType |= WrapperTypes.UncheckedParameter; } }
void TranslateExtension(Delegate d) { var extension = d.Extension.ToUpper(); if (extension.Length > 2) { extension = extension[0] + extension.Substring(1).ToLower(); } d.Extension = extension; }
static XPathNavigator GetFuncOverride(XPathNavigator nav, Delegate d, string apiname, string apiversion) { string ext = d.Extension; string trimmed_name = GetTrimmedName(d); string extensionless_name = GetTrimmedExtension(d.Name, ext); var function_override = nav.SelectSingleNode(GetOverridesPath(apiname, apiversion, d.Name, ext)) ?? nav.SelectSingleNode(GetOverridesPath(apiname, apiversion, extensionless_name, ext)) ?? nav.SelectSingleNode(GetOverridesPath(apiname, apiversion, trimmed_name, ext)); return function_override; }
public FunctionCollection Process(EnumProcessor enum_processor, DelegateCollection delegates, EnumCollection enums, string apiname, string apiversion) { Console.WriteLine("Processing delegates."); var nav = new XPathDocument(Overrides).CreateNavigator(); foreach (var version in apiversion.Split('|')) { // Translate each delegate: // 1st using the <replace> elements in overrides.xml // 2nd using the hardcoded rules in FuncProcessor (e.g. char* -> string) foreach (var signatures in delegates.Values) { foreach (var d in signatures) { var replace = GetFuncOverride(nav, d, apiname, apiversion); TranslateExtension(d); TranslateReturnType(d, replace, nav, enum_processor, enums, apiname, version); TranslateParameters(d, replace, nav, enum_processor, enums, apiname, version); TranslateAttributes(d, replace, nav, apiname, version); } } // Create overloads for backwards compatibility, // by resolving <overload> elements var overload_list = new List <Delegate>(); foreach (var d in delegates.Values.Select(v => v.First())) { var overload_elements = GetFuncOverload(nav, d, apiname, apiversion); foreach (XPathNavigator overload_element in overload_elements) { var overload = new Delegate(d); TranslateReturnType(overload, overload_element, nav, enum_processor, enums, apiname, version); TranslateParameters(overload, overload_element, nav, enum_processor, enums, apiname, version); TranslateAttributes(overload, overload_element, nav, apiname, version); overload_list.Add(overload); } } foreach (var overload in overload_list) { delegates.Add(overload); } } Console.WriteLine("Generating convenience overloads."); delegates.AddRange(CreateConvenienceOverloads(delegates)); Console.WriteLine("Generating wrappers."); var wrappers = CreateWrappers(delegates, enums); Console.WriteLine("Generating CLS compliant overloads."); wrappers = CreateCLSCompliantWrappers(wrappers, enums); Console.WriteLine("Removing non-CLS compliant duplicates."); wrappers = MarkCLSCompliance(wrappers); Console.WriteLine("Removing overloaded delegates."); RemoveOverloadedDelegates(delegates, wrappers); return(wrappers); }
public virtual DelegateCollection ReadDelegates(StreamReader specFile) { Console.WriteLine("Reading function specs."); //List<Bind.Structures.Delegate> delegates = new List<Bind.Structures.Delegate>(); DelegateCollection delegates = new DelegateCollection(); do { string line = NextValidLine(specFile); if (String.IsNullOrEmpty(line)) break; while (line.Contains("(") && !specFile.EndOfStream) { // Get next OpenGL function Bind.Structures.Delegate d = new Bind.Structures.Delegate(); // Get function name: d.Name = line.Split(Utilities.Separators, StringSplitOptions.RemoveEmptyEntries)[0]; //if (d.Name.Contains("QueryHyperpipeBestAttribSGIX")) //{ //} 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]; p.Pointer = words[4].Contains("array") ? true : words[4].Contains("reference") ? true : false; p.Flow = words[3] == "in" ? Parameter.FlowDirection.In : Parameter.FlowDirection.Out; d.Parameters.Add(p); break; // Version directive is not used. GetTexParameterIivEXT and GetTexParameterIuivEXT define two(!) versions (why?) //case "version": // Line denotes function version (i.e. 1.0, 1.2, 1.5) // d.UserData.Add("version", words[1]); // break; case "category": d.Category = words[1]; break; } } while (!specFile.EndOfStream); d.Translate(); delegates.Add(d); } } while (!specFile.EndOfStream); return delegates; }
void TranslateExtension(Delegate d) { d.Extension = TranslateExtension(d.Extension); }
// Trims unecessary suffices from the specified OpenGL function name. static string GetTrimmedName(Delegate d) { string name = d.Name; string extension = d.Extension; string trimmed_name = GetTrimmedExtension(name, extension); // Note: some endings should not be trimmed, for example: 'b' from Attrib. // Check the endingsNotToTrim regex for details. Match m = EndingsNotToTrim.Match(trimmed_name); if ((m.Index + m.Length) != trimmed_name.Length) { m = Endings.Match(trimmed_name); if (m.Length > 0 && m.Index + m.Length == trimmed_name.Length) { // Only trim endings, not internal matches. if (m.Value[m.Length - 1] == 'v' && EndingsAddV.IsMatch(name) && !name.StartsWith("Get") && !name.StartsWith("MatrixIndex")) { // Only trim ending 'v' when there is a number trimmed_name = trimmed_name.Substring(0, m.Index) + "v"; } else { if (!trimmed_name.EndsWith("xedv")) { trimmed_name = trimmed_name.Substring(0, m.Index); } else { trimmed_name = trimmed_name.Substring(0, m.Index + 1); } } } } return trimmed_name; }
static Delegate CreateArrayReturnTypeConvencienceWrapper(Delegate d) { var f = new Delegate(d); var p_array = f.Parameters.Last(); var p_size = f.Parameters[f.Parameters.Count - 2]; f.Parameters.RemoveAt(f.Parameters.Count - 2); p_array.WrapperType = WrapperTypes.ConvenienceArrayType; p_array.Pointer = 0; return f; }
static void TranslateParameters(XPathNavigator nav, Delegate d, EnumCollection enums) { var function_override = GetFuncOverride(nav, d); for (int i = 0; i < d.Parameters.Count; i++) { if (function_override != null) { XPathNavigator param_override = function_override.SelectSingleNode( String.Format("param[@name='{0}']", d.Parameters[i].RawName)); if (param_override != null) { foreach (XPathNavigator node in param_override.SelectChildren(XPathNodeType.Element)) { switch (node.Name) { case "type": d.Parameters[i].CurrentType = (string)node.TypedValue; break; case "name": d.Parameters[i].Name = (string)node.TypedValue; break; case "flow": d.Parameters[i].Flow = Parameter.GetFlowDirection((string)node.TypedValue); break; } } } } d.Parameters[i].Translate(nav, d.Category, enums); if (d.Parameters[i].CurrentType == "UInt16" && d.Name.Contains("LineStipple")) d.Parameters[i].WrapperType = WrapperTypes.UncheckedParameter; } }
static XPathNavigator GetFuncOverride(XPathNavigator nav, Delegate d) { string name = TrimName(d.Name, false); string ext = d.Extension; var function_override = nav.SelectSingleNode(String.Format(Path, name, ext)) ?? nav.SelectSingleNode(String.Format(Path, d.Name, ext)) ?? nav.SelectSingleNode(String.Format(Path, Utilities.StripGL2Extension(d.Name), ext)); return function_override; }
void TranslateAttributes(XPathNavigator nav, Delegate d, EnumCollection enums, string apiname, string apiversion) { var function_override = GetFuncOverride(nav, d, apiname, apiversion); if (function_override != null) { var version_override = function_override.SelectSingleNode("version"); if (version_override != null) { d.Version = version_override.Value; } var profile_override = function_override.SelectSingleNode("profile"); if (profile_override != null) { Debug.Print("Profile override not yet implemented"); } } }
static XPathNavigator GetFuncOverride(XPathNavigator nav, Delegate d, string apiname, string apiversion) { // Try a few different extension variations that appear in the overrides xml file string[] extensions = { d.Extension, TranslateExtension(d.Extension), d.Extension.ToUpper() }; string trimmed_name = GetTrimmedName(d); XPathNavigator function_override = null; foreach (var ext in extensions) { string extensionless_name = GetTrimmedExtension(d.Name, ext); function_override = nav.SelectSingleNode(GetOverridesPath(apiname, apiversion, d.Name, ext)) ?? nav.SelectSingleNode(GetOverridesPath(apiname, apiversion, extensionless_name, ext)) ?? nav.SelectSingleNode(GetOverridesPath(apiname, apiversion, trimmed_name, ext)); if (function_override != null) { break; } } return function_override; }
IEnumerable<Delegate> CreateConvenienceOverloads(DelegateCollection delegates) { foreach (var list in delegates.Values) { var d = list.First(); if (d.Parameters.Count > 0 && d.Parameters.Count <= 2) { var p = d.Parameters.Last(); var r = d.ReturnType; bool is_candidate = true; is_candidate &= d.Name.StartsWith("Get") || d.Name.StartsWith("Gen") || d.Name.StartsWith("Delete") || d.Name.StartsWith("New"); is_candidate &= d.Name.EndsWith("v") || d.Name.EndsWith("s"); is_candidate &= p.Pointer > 0; is_candidate &= r.CurrentType == "void" && r.Pointer == 0; if (is_candidate && p.Flow == FlowDirection.Out) { var f = new Delegate(d); f.ReturnType = new Type(f.Parameters.Last()); f.ReturnType.Pointer = 0; f.Parameters.RemoveAt(f.Parameters.Count - 1); f.ReturnType.WrapperType = WrapperTypes.ConvenienceReturnType; if (f.Parameters.Count > 0) { var p_size = f.Parameters.Last(); if (p_size.CurrentType.ToLower().Contains("int") && p_size.Pointer == 0) { f.Parameters.RemoveAt(f.Parameters.Count - 1); f.ReturnType.WrapperType = WrapperTypes.ConvenienceArrayReturnType; } } yield return f; } else if (is_candidate && p.Flow != FlowDirection.Out) { if (d.Parameters.Count == 2) { var f = new Delegate(d); var p_array = f.Parameters.Last(); var p_size = f.Parameters[f.Parameters.Count - 2]; f.Parameters.RemoveAt(f.Parameters.Count - 2); p_array.WrapperType = WrapperTypes.ConvenienceArrayType; p_array.Pointer = 0; yield return f; } } } } }
static void ApplyParameterReplacement(Delegate d, XPathNavigator function_override) { if (function_override != null) { for (int i = 0; i < d.Parameters.Count; i++) { XPathNavigator param_override = function_override.SelectSingleNode(String.Format( "param[@name='{0}' or @index='{1}']", d.Parameters[i].RawName, i)); if (param_override != null) { foreach (XPathNavigator node in param_override.SelectChildren(XPathNodeType.Element)) { switch (node.Name) { case "type": d.Parameters[i].CurrentType = (string)node.TypedValue; break; case "name": d.Parameters[i].Name = (string)node.TypedValue; break; case "flow": d.Parameters[i].Flow = Parameter.GetFlowDirection((string)node.TypedValue); break; case "count": int count; if (Int32.TryParse(node.Value, out count)) d.Parameters[i].ElementCount = count; break; } } } } } }
public virtual DelegateCollection ReadDelegates(StreamReader specFile) { Console.WriteLine("Reading function specs."); DelegateCollection delegates = new DelegateCollection(); XPathDocument function_overrides = new XPathDocument(Path.Combine(Settings.InputPath, functionOverridesFile)); do { string line = NextValidLine(specFile); if (String.IsNullOrEmpty(line)) break; while (line.Contains("(") && !specFile.EndOfStream) { // Get next OpenGL function Delegate d = new Delegate(); // 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]; 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]")) p.ElementCount = 1; p.Flow = words[3] == "in" ? FlowDirection.In : FlowDirection.Out; d.Parameters.Add(p); break; // 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; case "category": d.Category = words[1]; break; } } while (!specFile.EndOfStream); d.Translate(function_overrides); delegates.Add(d); } } while (!specFile.EndOfStream); return delegates; }
// Translates the opengl return type to the equivalent C# type. // // First, we use the official typemap (gl.tm) to get the correct type. // Then we override this, when it is: // 1) A string (we have to use Marshal.PtrToStringAnsi, to avoid heap corruption) // 2) An array (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). // Return types must always be CLS-compliant, because .Net does not support overloading on return types. void TranslateReturnType(Delegate d, XPathNavigator function_override, XPathNavigator nav, EnumProcessor enum_processor, EnumCollection enums, string apiname, string apiversion) { ApplyReturnTypeReplacement(d, function_override); TranslateType(d.ReturnType, function_override, nav, enum_processor, enums, d.Category, apiname); if (d.ReturnType.CurrentType.ToLower() == "void" && d.ReturnType.Pointer != 0) { d.ReturnType.QualifiedType = "IntPtr"; d.ReturnType.Pointer--; d.ReturnType.WrapperType |= WrapperTypes.GenericReturnType; } if (d.ReturnType.CurrentType.ToLower() == "string") { d.ReturnType.QualifiedType = "IntPtr"; d.ReturnType.WrapperType |= WrapperTypes.StringReturnType; } if (d.ReturnType.CurrentType.ToLower() == "object") { d.ReturnType.QualifiedType = "IntPtr"; d.ReturnType.WrapperType |= WrapperTypes.GenericReturnType; } if (d.ReturnType.CurrentType.Contains("GLenum")) { if ((Settings.Compatibility & Settings.Legacy.ConstIntEnums) == Settings.Legacy.None) d.ReturnType.QualifiedType = String.Format("{0}{1}{2}", Settings.EnumsOutput, Settings.NamespaceSeparator, Settings.CompleteEnumName); else d.ReturnType.QualifiedType = "int"; } if (d.ReturnType.CurrentType.ToLower().Contains("bool")) { d.ReturnType.QualifiedType = "byte"; d.ReturnType.WrapperType |= WrapperTypes.BoolParameter; } d.ReturnType.CurrentType = GetCLSCompliantType(d.ReturnType); }
// Merges the given delegate into the delegate list. internal static void Merge(DelegateCollection delegates, Delegate t) { delegates.Add(t.Name, t); }
// Trims unecessary suffices from the specified OpenGL function name. static string GetTrimmedName(Delegate d) { string name = d.Name; string extension = d.Extension; string trimmed_name = GetTrimmedExtension(name, extension); // Note: some endings should not be trimmed, for example: 'b' from Attrib. // Check the endingsNotToTrim regex for details. Match m = EndingsNotToTrim.Match(trimmed_name); if ((m.Index + m.Length) != trimmed_name.Length) { m = Endings.Match(trimmed_name); if (m.Length > 0 && m.Index + m.Length == trimmed_name.Length) { // Only trim endings, not internal matches. if (m.Value[m.Length - 1] == 'v' && EndingsAddV.IsMatch(name) && !name.StartsWith("Get") && !name.StartsWith("MatrixIndex")) { // Only trim ending 'v' when there is a number trimmed_name = trimmed_name.Substring(0, m.Index) + "v"; } else { if (!trimmed_name.EndsWith("xedv")) { trimmed_name = trimmed_name.Substring(0, m.Index); } else { trimmed_name = trimmed_name.Substring(0, m.Index + 1); } } } } // If we have a convenience overload, we should turn the name from // plural into singular if (d.ReturnType.WrapperType == WrapperTypes.ConvenienceReturnType || d.ReturnType.WrapperType == WrapperTypes.ConvenienceArrayReturnType || d.Parameters.Any(p => p.WrapperType == WrapperTypes.ConvenienceArrayType)) { trimmed_name = trimmed_name.Replace("Queries", "Query"); trimmed_name = trimmed_name.TrimEnd('s'); } return trimmed_name; }
// Translates the opengl return type to the equivalent C# type. // // First, we use the official typemap (gl.tm) to get the correct type. // Then we override this, when it is: // 1) A string (we have to use Marshal.PtrToStringAnsi, to avoid heap corruption) // 2) An array (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). // Return types must always be CLS-compliant, because .Net does not support overloading on return types. static void TranslateReturnType(XPathNavigator nav, Delegate d, EnumCollection enums) { var function_override = GetFuncOverride(nav, d); if (function_override != null) { XPathNavigator return_override = function_override.SelectSingleNode("returns"); if (return_override != null) { d.ReturnType.CurrentType = return_override.Value; } } d.ReturnType.Translate(nav, d.Category, enums); if (d.ReturnType.CurrentType.ToLower().Contains("void") && d.ReturnType.Pointer != 0) { d.ReturnType.QualifiedType = "IntPtr"; d.ReturnType.WrapperType = WrapperTypes.GenericReturnType; } if (d.ReturnType.CurrentType.ToLower().Contains("string")) { d.ReturnType.QualifiedType = "IntPtr"; d.ReturnType.WrapperType = WrapperTypes.StringReturnType; } if (d.ReturnType.CurrentType.ToLower() == "object") { d.ReturnType.QualifiedType = "IntPtr"; d.ReturnType.WrapperType |= WrapperTypes.GenericReturnType; } if (d.ReturnType.CurrentType.Contains("GLenum")) { if ((Settings.Compatibility & Settings.Legacy.ConstIntEnums) == Settings.Legacy.None) d.ReturnType.QualifiedType = String.Format("{0}{1}{2}", Settings.EnumsOutput, Settings.NamespaceSeparator, Settings.CompleteEnumName); else d.ReturnType.QualifiedType = "int"; } d.ReturnType.CurrentType = d.ReturnType.GetCLSCompliantType(); }
public virtual DelegateCollection ReadDelegates(StreamReader specFile) { Console.WriteLine("Reading function specs."); DelegateCollection delegates = new DelegateCollection(); XPathDocument function_overrides = new XPathDocument(Path.Combine(Settings.InputPath, functionOverridesFile)); do { string line = NextValidLine(specFile); if (String.IsNullOrEmpty(line)) { break; } while (line.Contains("(") && !specFile.EndOfStream) { // Get next OpenGL function Delegate d = new Delegate(); // 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]; 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]")) { p.ElementCount = 1; } p.Flow = words[3] == "in" ? FlowDirection.In : FlowDirection.Out; d.Parameters.Add(p); break; // 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; case "category": d.Category = words[1]; break; } }while (!specFile.EndOfStream); d.Translate(function_overrides); delegates.Add(d); } }while (!specFile.EndOfStream); return(delegates); }
static IEnumerable<Function> CreateNormalWrappers(Delegate d, EnumCollection enums) { Function f = new Function(d); WrapReturnType(f); foreach (var wrapper in WrapParameters(f, enums)) { yield return wrapper; } }
public virtual DelegateCollection ReadDelegates(StreamReader specFile) { Console.WriteLine("Reading function specs."); //List<Bind.Structures.Delegate> delegates = new List<Bind.Structures.Delegate>(); DelegateCollection delegates = new DelegateCollection(); do { string line = NextValidLine(specFile); if (String.IsNullOrEmpty(line)) { break; } while (line.Contains("(") && !specFile.EndOfStream) { // Get next OpenGL function Bind.Structures.Delegate d = new Bind.Structures.Delegate(); // Get function name: d.Name = line.Split(Utilities.Separators, StringSplitOptions.RemoveEmptyEntries)[0]; //if (d.Name.Contains("QueryHyperpipeBestAttribSGIX")) //{ //} 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]; p.Pointer = words[4].Contains("array") ? true : words[4].Contains("reference") ? true : false; p.Flow = words[3] == "in" ? Parameter.FlowDirection.In : Parameter.FlowDirection.Out; d.Parameters.Add(p); break; // Version directive is not used. GetTexParameterIivEXT and GetTexParameterIuivEXT define two(!) versions (why?) //case "version": // Line denotes function version (i.e. 1.0, 1.2, 1.5) // d.UserData.Add("version", words[1]); // break; case "category": d.Category = words[1]; break; } }while (!specFile.EndOfStream); d.Translate(); delegates.Add(d); } }while (!specFile.EndOfStream); return(delegates); }