public Documentation Process(Function f, EnumProcessor processor) { Documentation docs = null; if (DocumentationCache.ContainsKey(f.WrappedDelegate.Name)) { return(DocumentationCache[f.WrappedDelegate.Name]); } else { var file = Settings.FunctionPrefix + f.WrappedDelegate.Name + ".xml"; if (!DocumentationFiles.ContainsKey(file)) { file = Settings.FunctionPrefix + f.TrimmedName + ".xml"; } if (!DocumentationFiles.ContainsKey(file)) { file = Settings.FunctionPrefix + f.TrimmedName.TrimEnd(numbers) + ".xml"; } docs = (DocumentationFiles.ContainsKey(file) ? ProcessFile(DocumentationFiles[file], processor) : null) ?? new Documentation { Summary = String.Empty, Parameters = f.Parameters.Select(p => new DocumentationParameter(p.Name, String.Empty)).ToList() }; DocumentationCache.Add(f.WrappedDelegate.Name, docs); } return(docs); }
public Documentation Process(Function f, EnumProcessor processor) { Documentation docs = null; if (DocumentationCache.ContainsKey(f.WrappedDelegate.Name)) { return DocumentationCache[f.WrappedDelegate.Name]; } else { var file = Settings.FunctionPrefix + f.WrappedDelegate.Name + ".xml"; if (!DocumentationFiles.ContainsKey(file)) file = Settings.FunctionPrefix + f.TrimmedName + ".xml"; if (!DocumentationFiles.ContainsKey(file)) file = Settings.FunctionPrefix + f.TrimmedName.TrimEnd(numbers) + ".xml"; docs = (DocumentationFiles.ContainsKey(file) ? ProcessFile(DocumentationFiles[file], processor) : null) ?? new Documentation { Summary = String.Empty, Parameters = f.Parameters.Select(p => new DocumentationParameter(p.Name, String.Empty)).ToList() }; DocumentationCache.Add(f.WrappedDelegate.Name, docs); } return docs; }
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) { TranslateExtension(d); TranslateReturnType(enum_processor, nav, d, enums, apiname, version); TranslateParameters(enum_processor, nav, d, enums, apiname, version); TranslateAttributes(nav, d, enums, 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_element = GetFuncOverload(nav, d, apiname, apiversion); if (overload_element != null) { var overload = new Delegate(d); ApplyParameterReplacement(overload, overload_element); ApplyReturnTypeReplacement(overload, overload_element); 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; }
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; } } }
Documentation ToInlineDocs(XDocument doc, EnumProcessor enum_processor) { if (doc == null || enum_processor == null) { throw new ArgumentNullException(); } var no_const_processing = Settings.Legacy.NoAdvancedEnumProcessing | Settings.Legacy.ConstIntEnums; if (!Generator.Settings.IsEnabled(no_const_processing)) { // Translate all GL_FOO_BAR constants according to EnumProcessor foreach (var e in doc.XPathSelectElements("//constant")) { var c = e.Value; if (c.StartsWith(Settings.ConstantPrefix)) { // Remove "GL_" from the beginning of the string c = c.Replace(Settings.ConstantPrefix, String.Empty); } e.Value = enum_processor.TranslateConstantName(c, false); } } // Create inline documentation var inline = new Documentation { Summary = Cleanup( ((IEnumerable)doc.XPathEvaluate("/refentry/refnamediv/refpurpose")) .Cast <XElement>().First().Value), Parameters = ((IEnumerable)doc.XPathEvaluate("/refentry/refsect1[@id='parameters']/variablelist/varlistentry/term/parameter")) .Cast <XElement>() .Select(p => new DocumentationParameter( p.Value.Trim(), Cleanup(p.XPathSelectElement("../../listitem").Value))) .ToList() }; inline.Summary = Char.ToUpper(inline.Summary[0]) + inline.Summary.Substring(1); return(inline); }
// 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); }
void TranslateParameter(Parameter p, XPathNavigator function_override, XPathNavigator overrides, EnumProcessor enum_processor, EnumCollection enums, string category, string apiname) { TranslateType(p, function_override, overrides, enum_processor, enums, category, apiname); // Translate char* -> string. This simplifies the rest of the logic below if (p.CurrentType.ToLower().Contains("char") && p.Pointer > 0) { p.CurrentType = "string"; p.Pointer--; } // Find out the necessary wrapper types. if (p.CurrentType.ToLower() == "string" && p.Pointer == 0) { // char* -> IntPtr // Due to a bug in the Mono runtime, we need // to marshal [out] string parameters ourselves. // StringBuilder crashes at runtime. // For symmetry, and to avoid potential runtime bugs, // we will also marshal [in] string types manually. p.QualifiedType = "IntPtr"; p.WrapperType |= WrapperTypes.StringParameter; } if (p.CurrentType.ToLower() == "string" && p.Pointer >= 1) { // string* -> [In] String[] // [Out] StringBuilder[] parameter is not currently supported // Higher indirection levels are also not supported if (p.Flow == FlowDirection.Out) { throw new NotSupportedException("[Out] String* parameters are not currently supported."); } if (p.Pointer >= 2) { throw new NotSupportedException("String arrays with arity >= 2 are not currently supported."); } p.QualifiedType = "IntPtr"; p.Pointer = 0; p.Array = 0; p.WrapperType |= WrapperTypes.StringArrayParameter; } if (p.Pointer > 0 && p.WrapperType == 0) { if (p.QualifiedType.ToLower().StartsWith("void")) { p.QualifiedType = "IntPtr"; p.Pointer = 0; // Generic parameters cannot have pointers p.WrapperType |= WrapperTypes.GenericParameter; p.WrapperType |= WrapperTypes.ArrayParameter; p.WrapperType |= WrapperTypes.ReferenceParameter; } else { p.WrapperType |= WrapperTypes.ArrayParameter; p.WrapperType |= WrapperTypes.ReferenceParameter; p.WrapperType |= WrapperTypes.PointerParameter; } } if (Utilities.Keywords(Settings.Language).Contains(p.Name)) p.Name = Settings.KeywordEscapeCharacter + p.Name; // This causes problems with bool arrays //if (CurrentType.ToLower().Contains("bool")) // WrapperType = WrapperTypes.BoolParameter; }
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() == "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); }
void TranslateType(Bind.Structures.Type type, XPathNavigator function_override, XPathNavigator overrides, EnumProcessor enum_processor, EnumCollection enums, string category, string apiname) { Bind.Structures.Enum @enum; string s; category = enum_processor.TranslateEnumName(category); // Try to find out if it is an enum. If the type exists in the normal GLEnums list, use this. // Special case for Boolean which is there simply because C89 does not support bool types. // We don't really need that in C# bool normal = enums.TryGetValue(type.CurrentType, out @enum) || enums.TryGetValue(enum_processor.TranslateEnumName(type.CurrentType), out @enum); // Translate enum types type.IsEnum = false; if (normal && @enum.Name != "GLenum" && @enum.Name != "Boolean") { type.IsEnum = true; if ((Settings.Compatibility & Settings.Legacy.ConstIntEnums) != Settings.Legacy.None) { type.QualifiedType = "int"; } else { // Some functions and enums have the same names. // Make sure we reference the enums rather than the functions. if (normal) { type.QualifiedType = String.Format("{0}.{1}", Settings.EnumsOutput, @enum.Name); } } } else if (Generator.GLTypes.TryGetValue(type.CurrentType, out s)) { // Check if the parameter is a generic GLenum. If it is, search for a better match, // otherwise fallback to Settings.CompleteEnumName (named 'All' by default). if (s.Contains("GLenum") /*&& !String.IsNullOrEmpty(category)*/) { type.IsEnum = true; if ((Settings.Compatibility & Settings.Legacy.ConstIntEnums) != Settings.Legacy.None) { type.QualifiedType = "int"; } else { // Better match: enum.Name == function.Category (e.g. GL_VERSION_1_1 etc) // Note: for backwards compatibility we use "category" only for the gl api. // glcore, gles1 and gles2 use the All enum instead. if (apiname == "gl" && enums.ContainsKey(category)) { type.QualifiedType = String.Format("{0}{1}{2}", Settings.EnumsOutput, Settings.NamespaceSeparator, enum_processor.TranslateEnumName(category)); } else { type.QualifiedType = String.Format("{0}{1}{2}", Settings.EnumsOutput, Settings.NamespaceSeparator, Settings.CompleteEnumName); } } } else { // Todo: what is the point of this here? It is overwritten below. // A few translations for consistency switch (type.CurrentType.ToLower()) { case "string": type.QualifiedType = "String"; break; } type.QualifiedType = s; } } type.CurrentType = Generator.CSTypes.ContainsKey(type.CurrentType) ? Generator.CSTypes[type.CurrentType] : type.CurrentType; // Make sure that enum parameters follow enum overrides, i.e. // if enum ErrorCodes is overriden to ErrorCode, then parameters // of type ErrorCodes should also be overriden to ErrorCode. XPathNavigator enum_override = overrides.SelectSingleNode( EnumProcessor.GetOverridesPath(apiname, type.CurrentType)); if (enum_override != null) { // For consistency - many overrides use string instead of String. if (enum_override.Value == "string") type.QualifiedType = "String"; else if (enum_override.Value == "StringBuilder") type.QualifiedType = "StringBuilder"; else type.CurrentType = enum_override.Value; } if (type.CurrentType == "IntPtr" && String.IsNullOrEmpty(type.PreviousType)) type.Pointer = 0; if (type.Pointer >= 3) { System.Diagnostics.Trace.WriteLine(String.Format( "[Error] Type '{0}' has a high pointer level. Bindings will be incorrect.", type)); } if (!type.IsEnum) { // Remove qualifier if type is not an enum // Resolves issues when replacing / overriding // an enum parameter with a non-enum type type.QualifiedType = type.CurrentType; } }
void GenerateDocumentation(FunctionCollection wrappers, EnumProcessor enum_processor, DocProcessor doc_processor) { foreach (var list in wrappers) { foreach (var f in list.Value) { f.Documentation = doc_processor.Process(f, enum_processor); } } }
Documentation ToInlineDocs(XDocument doc, EnumProcessor enum_processor) { if (doc == null || enum_processor == null) throw new ArgumentNullException(); var no_const_processing = Settings.Legacy.NoAdvancedEnumProcessing | Settings.Legacy.ConstIntEnums; if (!Generator.Settings.IsEnabled(no_const_processing)) { // Translate all GL_FOO_BAR constants according to EnumProcessor foreach (var e in doc.XPathSelectElements("//constant")) { var c = e.Value; if (c.StartsWith(Settings.ConstantPrefix)) { // Remove "GL_" from the beginning of the string c = c.Replace(Settings.ConstantPrefix, String.Empty); } e.Value = enum_processor.TranslateConstantName(c, false); } } // Create inline documentation var inline = new Documentation { Summary = Cleanup( ((IEnumerable)doc.XPathEvaluate("/refentry/refnamediv/refpurpose")) .Cast<XElement>().First().Value), Parameters = ((IEnumerable)doc.XPathEvaluate("/refentry/refsect1[@id='parameters']/variablelist/varlistentry/term/parameter")) .Cast<XElement>() .Select(p => new DocumentationParameter( p.Value.Trim(), Cleanup(p.XPathSelectElement("../../listitem").Value))) .ToList() }; inline.Summary = Char.ToUpper(inline.Summary[0]) + inline.Summary.Substring(1); return inline; }
void TranslateParameter(Parameter p, EnumProcessor enum_processor, XPathNavigator overrides, EnumCollection enums, string category, string apiname) { TranslateType(p, enum_processor, overrides, enums, category, apiname); // Find out the necessary wrapper types. if (p.Pointer != 0)/* || CurrentType == "IntPtr")*/ { if (p.CurrentType.ToLower().Contains("string") || p.CurrentType.ToLower().Contains("char") && p.Pointer > 1) { // string* -> [In] String[] or [Out] StringBuilder[] p.QualifiedType = p.Flow == FlowDirection.Out ? "StringBuilder[]" : "String[]"; p.Pointer = 0; p.WrapperType = WrapperTypes.None; } else if (p.CurrentType.ToLower().Contains("char")) { // char* -> [In] String or [Out] StringBuilder p.QualifiedType = p.Flow == FlowDirection.Out ? "StringBuilder" : "String"; p.Pointer = 0; p.WrapperType = WrapperTypes.None; } else if (p.CurrentType.ToLower().Contains("void") || (!String.IsNullOrEmpty(p.PreviousType) && p.PreviousType.ToLower().Contains("void"))) //|| CurrentType.Contains("IntPtr")) { p.CurrentType = "IntPtr"; p.Pointer = 0; p.WrapperType = WrapperTypes.GenericParameter; } else { p.WrapperType = WrapperTypes.ArrayParameter; } } if (p.Reference) p.WrapperType |= WrapperTypes.ReferenceParameter; if (Utilities.Keywords(Settings.Language).Contains(p.Name)) p.Name = Settings.KeywordEscapeCharacter + p.Name; // This causes problems with bool arrays //if (CurrentType.ToLower().Contains("bool")) // WrapperType = WrapperTypes.BoolParameter; }
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); }
void TranslateParameter(Parameter p, XPathNavigator function_override, XPathNavigator overrides, EnumProcessor enum_processor, EnumCollection enums, string category, string apiname) { TranslateType(p, function_override, overrides, enum_processor, enums, category, apiname); // Find out the necessary wrapper types. if (p.Pointer != 0)/* || CurrentType == "IntPtr")*/ { if (p.CurrentType.ToLower().Contains("string") || p.CurrentType.ToLower().Contains("char") && p.Pointer > 1) { // string* -> [In] String[] or [Out] StringBuilder[] p.QualifiedType = p.Flow == FlowDirection.Out ? "StringBuilder[]" : "String[]"; p.Pointer = 0; p.WrapperType = WrapperTypes.None; } else if (p.CurrentType.ToLower().Contains("char")) { // char* -> [In] String or [Out] StringBuilder p.QualifiedType = p.Flow == FlowDirection.Out ? "StringBuilder" : "String"; p.Pointer = 0; p.WrapperType = WrapperTypes.None; } else if (p.CurrentType.ToLower().Contains("void") || (!String.IsNullOrEmpty(p.PreviousType) && p.PreviousType.ToLower().Contains("void"))) //|| CurrentType.Contains("IntPtr")) { p.CurrentType = "IntPtr"; p.Pointer = 0; p.WrapperType = WrapperTypes.GenericParameter; } else { p.WrapperType = WrapperTypes.ArrayParameter; } } if (p.Reference) { p.WrapperType |= WrapperTypes.ReferenceParameter; } if (Utilities.Keywords(Settings.Language).Contains(p.Name)) { p.Name = Settings.KeywordEscapeCharacter + p.Name; } // This causes problems with bool arrays //if (CurrentType.ToLower().Contains("bool")) // WrapperType = WrapperTypes.BoolParameter; }
// Strips MathML tags from the source and replaces the equations with the content // found in the <!-- eqn: :--> comments in the docs. // Todo: Some simple MathML tags do not include comments, find a solution. // Todo: Some files include more than 1 function - find a way to map these extra functions. Documentation ProcessFile(string file, EnumProcessor processor) { string text; if (LastFile == file) return Cached; LastFile = file; text = File.ReadAllText(file); text = text .Replace("ε", "epsilon") // Fix unrecognized ε entities .Replace("xml:", String.Empty); // Remove namespaces text = remove_doctype.Replace(text, String.Empty); text = remove_xmlns.Replace(text, string.Empty); Match m = remove_mathml.Match(text); while (m.Length > 0) { string removed = text.Substring(m.Index, m.Length); text = text.Remove(m.Index, m.Length); int equation = removed.IndexOf("eqn"); if (equation > 0) { // Find the start and end of the equation string int eqn_start = equation + 4; int eqn_end = removed.IndexOf(":-->") - equation - 4; if (eqn_end < 0) { // Note: a few docs from man4 delimit eqn end with ": -->" eqn_end = removed.IndexOf(": -->") - equation - 4; } if (eqn_end < 0) { Console.WriteLine("[Warning] Failed to find equation for mml."); goto next; } string eqn_substring = removed.Substring(eqn_start, eqn_end); text = text.Insert(m.Index, "<![CDATA[" + eqn_substring + "]]>"); } next: m = remove_mathml.Match(text); } XDocument doc = null; try { doc = XDocument.Parse(text); Cached = ToInlineDocs(doc, processor); return Cached; } catch (Exception e) { Console.WriteLine(e.ToString()); Console.WriteLine(doc.ToString()); return null; } }
// Strips MathML tags from the source and replaces the equations with the content // found in the <!-- eqn: :--> comments in the docs. // Todo: Some simple MathML tags do not include comments, find a solution. // Todo: Some files include more than 1 function - find a way to map these extra functions. Documentation ProcessFile(string file, EnumProcessor processor) { string text; if (LastFile == file) { return(Cached); } LastFile = file; text = File.ReadAllText(file); text = text .Replace("ε", "epsilon") // Fix unrecognized ε entities .Replace("xml:", String.Empty); // Remove namespaces text = remove_doctype.Replace(text, String.Empty); text = remove_xmlns.Replace(text, string.Empty); Match m = remove_mathml.Match(text); while (m.Length > 0) { string removed = text.Substring(m.Index, m.Length); text = text.Remove(m.Index, m.Length); int equation = removed.IndexOf("eqn"); if (equation > 0) { // Find the start and end of the equation string int eqn_start = equation + 4; int eqn_end = removed.IndexOf(":-->") - equation - 4; if (eqn_end < 0) { // Note: a few docs from man4 delimit eqn end with ": -->" eqn_end = removed.IndexOf(": -->") - equation - 4; } if (eqn_end < 0) { Console.WriteLine("[Warning] Failed to find equation for mml."); goto next; } string eqn_substring = removed.Substring(eqn_start, eqn_end); text = text.Insert(m.Index, "<![CDATA[" + eqn_substring + "]]>"); } next: m = remove_mathml.Match(text); } XDocument doc = null; try { doc = XDocument.Parse(text); Cached = ToInlineDocs(doc, processor); return(Cached); } catch (Exception e) { Console.WriteLine(e.ToString()); Console.WriteLine(doc.ToString()); return(null); } }
void TranslateType(Bind.Structures.Type type, XPathNavigator function_override, XPathNavigator overrides, EnumProcessor enum_processor, EnumCollection enums, string category, string apiname) { Bind.Structures.Enum @enum; string s; category = enum_processor.TranslateEnumName(category); // Try to find out if it is an enum. If the type exists in the normal GLEnums list, use this. // Special case for Boolean - it is an enum, but it is dumb to use that instead of the 'bool' type. bool normal = enums.TryGetValue(type.CurrentType, out @enum); // Translate enum types type.IsEnum = false; if (normal && @enum.Name != "GLenum" && @enum.Name != "Boolean") { type.IsEnum = true; if ((Settings.Compatibility & Settings.Legacy.ConstIntEnums) != Settings.Legacy.None) { type.QualifiedType = "int"; } else { // Some functions and enums have the same names. // Make sure we reference the enums rather than the functions. if (normal) { type.QualifiedType = type.CurrentType.Insert(0, String.Format("{0}.", Settings.EnumsOutput)); } } } else if (Generator.GLTypes.TryGetValue(type.CurrentType, out s)) { // Check if the parameter is a generic GLenum. If it is, search for a better match, // otherwise fallback to Settings.CompleteEnumName (named 'All' by default). if (s.Contains("GLenum") /*&& !String.IsNullOrEmpty(category)*/) { type.IsEnum = true; if ((Settings.Compatibility & Settings.Legacy.ConstIntEnums) != Settings.Legacy.None) { type.QualifiedType = "int"; } else { // Better match: enum.Name == function.Category (e.g. GL_VERSION_1_1 etc) // Note: for backwards compatibility we use "category" only for the gl api. // glcore, gles1 and gles2 use the All enum instead. if (apiname == "gl" && enums.ContainsKey(category)) { type.QualifiedType = String.Format("{0}{1}{2}", Settings.EnumsOutput, Settings.NamespaceSeparator, enum_processor.TranslateEnumName(category)); } else { type.QualifiedType = String.Format("{0}{1}{2}", Settings.EnumsOutput, Settings.NamespaceSeparator, Settings.CompleteEnumName); } } } else { // Todo: what is the point of this here? It is overwritten below. // A few translations for consistency switch (type.CurrentType.ToLower()) { case "string": type.QualifiedType = "String"; break; } type.QualifiedType = s; } } type.CurrentType = Generator.CSTypes.ContainsKey(type.CurrentType) ? Generator.CSTypes[type.CurrentType] : type.CurrentType; // Make sure that enum parameters follow enum overrides, i.e. // if enum ErrorCodes is overriden to ErrorCode, then parameters // of type ErrorCodes should also be overriden to ErrorCode. XPathNavigator enum_override = overrides.SelectSingleNode( EnumProcessor.GetOverridesPath(apiname, type.CurrentType)); if (enum_override != null) { // For consistency - many overrides use string instead of String. if (enum_override.Value == "string") { type.QualifiedType = "String"; } else if (enum_override.Value == "StringBuilder") { type.QualifiedType = "StringBuilder"; } else { type.CurrentType = enum_override.Value; } } if (type.CurrentType == "IntPtr" && String.IsNullOrEmpty(type.PreviousType)) { type.Pointer = 0; } if (type.Pointer >= 3) { System.Diagnostics.Trace.WriteLine(String.Format( "[Error] Type '{0}' has a high pointer level. Bindings will be incorrect.", type)); } if (!type.IsEnum) { // Remove qualifier if type is not an enum // Resolves issues when replacing / overriding // an enum parameter with a non-enum type type.QualifiedType = type.CurrentType; } }