diff --git a/Source/Bind/CSharpSpecWriter.cs b/Source/Bind/CSharpSpecWriter.cs index 2ef841fa..6a7eb936 100644 --- a/Source/Bind/CSharpSpecWriter.cs +++ b/Source/Bind/CSharpSpecWriter.cs @@ -299,29 +299,29 @@ namespace Bind if (!docfiles.ContainsKey(docfile)) docfile = Settings.FunctionPrefix + f.TrimmedName.TrimEnd(numbers) + ".xml"; - var docs = new List(); - if (docfiles.ContainsKey(docfile)) - { - docs.AddRange(Processor.ProcessFile(docfiles[docfile])); - } - if (docs.Count == 0) - { - docs.Add("/// "); - } + Documentation docs = + (docfiles.ContainsKey(docfile) ? + Processor.ProcessFile(docfiles[docfile]) : + null) ?? + new Documentation + { + Summary = String.Empty, + Parameters = f.Parameters.Select(p => + new KeyValuePair(p.Name, String.Empty)).ToList() + }; - int summary_start = docs[0].IndexOf("") + "".Length; string warning = "[deprecated: v{0}]"; string category = "[requires: {0}]"; if (f.Deprecated) { warning = String.Format(warning, f.DeprecatedVersion); - docs[0] = docs[0].Insert(summary_start, warning); + docs.Summary = docs.Summary.Insert(0, warning); } if (f.Extension != "Core" && !String.IsNullOrEmpty(f.Category)) { category = String.Format(category, f.Category); - docs[0] = docs[0].Insert(summary_start, category); + docs.Summary = docs.Summary.Insert(0, category); } else if (!String.IsNullOrEmpty(f.Version)) { @@ -329,22 +329,23 @@ namespace Bind category = String.Format(category, "v" + f.Version); else category = String.Format(category, "v" + f.Version + " and " + f.Category); - docs[0] = docs[0].Insert(summary_start, category); + docs.Summary = docs.Summary.Insert(0, category); } - foreach (var param in f.WrappedDelegate.Parameters) + for (int i = 0; i < f.Parameters.Count; i++) { - var index = docs.IndexOf("/// "); - if (index != -1 && param.ComputeSize != "") + var param = f.Parameters[i]; + if (!String.IsNullOrEmpty(param.ComputeSize)) { - var compute_size = string.Format("[length: {0}]", param.ComputeSize); - docs[index] = docs[index] + compute_size; + docs.Parameters[i].Value.Insert(0, + String.Format("[length: {0}]", param.ComputeSize)); } } - foreach (var doc in docs) + sw.WriteLine("/// {0}", docs.Summary); + foreach (var p in docs.Parameters) { - sw.WriteLine(doc); + sw.WriteLine("/// {1}", p.Key, p.Value); } } catch (Exception e) diff --git a/Source/Bind/CppSpecWriter.cs b/Source/Bind/CppSpecWriter.cs index b9f8e6ab..e53ffa42 100644 --- a/Source/Bind/CppSpecWriter.cs +++ b/Source/Bind/CppSpecWriter.cs @@ -696,29 +696,28 @@ typedef const char* GLstring; if (!docfiles.ContainsKey(docfile)) docfile = Settings.FunctionPrefix + f.TrimmedName.TrimEnd(numbers) + ".xml"; - var docs = new List(); - if (docfiles.ContainsKey(docfile)) - { - docs.AddRange(Processor.ProcessFile(docfiles[docfile])); - } - if (docs.Count == 0) - { - docs.Add("/// "); - } + Documentation docs = + (docfiles.ContainsKey(docfile) ? + Processor.ProcessFile(docfiles[docfile]) : null) ?? + new Documentation + { + Summary = String.Empty, + Parameters = f.Parameters.Select(p => + new KeyValuePair(p.Name, String.Empty)).ToList() + }; - int summary_start = docs[0].IndexOf("") + "".Length; string warning = "[deprecated: v{0}]"; string category = "[requires: {0}]"; if (f.Deprecated) { warning = String.Format(warning, f.DeprecatedVersion); - docs[0] = docs[0].Insert(summary_start, warning); + docs.Summary = docs.Summary.Insert(0, warning); } if (f.Extension != "Core" && !String.IsNullOrEmpty(f.Category)) { category = String.Format(category, f.Category); - docs[0] = docs[0].Insert(summary_start, category); + docs.Summary = docs.Summary.Insert(0, category); } else if (!String.IsNullOrEmpty(f.Version)) { @@ -726,12 +725,26 @@ typedef const char* GLstring; category = String.Format(category, "v" + f.Version); else category = String.Format(category, "v" + f.Version + " and " + f.Category); - docs[0] = docs[0].Insert(summary_start, category); + docs.Summary = docs.Summary.Insert(0, category); } - foreach (var doc in docs) + for (int i = 0; i < f.WrappedDelegate.Parameters.Count; i++) { - sw.WriteLine(doc); + var param = f.WrappedDelegate.Parameters[i]; + if (param.ComputeSize != String.Empty) + { + docs.Parameters[i].Value.Insert(0, + String.Format("[length: {0}]", param.ComputeSize)); + } + } + + sw.Write("/// \brief "); + sw.WriteLine(docs.Summary); + foreach (var p in docs.Parameters) + { + sw.Write(@"/// \param "); + sw.Write(p.Key); + sw.WriteLine(p.Value); } } catch (Exception e) diff --git a/Source/Bind/DocProcessor.cs b/Source/Bind/DocProcessor.cs index d8141672..9acfb961 100644 --- a/Source/Bind/DocProcessor.cs +++ b/Source/Bind/DocProcessor.cs @@ -1,9 +1,17 @@ using System; +using System.Collections; +using System.Collections.Generic; using System.IO; +using System.Linq; +using System.Text; using System.Text.RegularExpressions; using System.Xml; +using System.Xml.Linq; +using System.Xml.XPath; using System.Xml.Xsl; +using Bind.Structures; + namespace Bind { class DocProcessor @@ -15,11 +23,20 @@ namespace Bind static readonly XslCompiledTransform xslt = new XslCompiledTransform(); static readonly XmlReaderSettings settings = new XmlReaderSettings(); - string[] Text; + Documentation Cached; string LastFile; public DocProcessor(string transform_file) { + if (!File.Exists(transform_file)) + { + // If no specific transform file exists + // get the generic transform file from + // the parent directory + var dir = Directory.GetParent(Path.GetDirectoryName(transform_file)).FullName; + var file = Path.GetFileName(transform_file); + transform_file = Path.Combine(dir, file); + } xslt.Load(transform_file); settings.ProhibitDtd = false; settings.XmlResolver = null; @@ -29,16 +46,22 @@ namespace Bind // found in the 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. - public string[] ProcessFile(string file) + public Documentation ProcessFile(string file) { string text; if (LastFile == file) - return Text; + return Cached; LastFile = file; text = File.ReadAllText(file); + text = text + .Replace("xml:", String.Empty) // Remove namespaces + .Replace("ε", "epsilon") // Fix unrecognized ε entities + .Replace("", "") // Improve output + .Replace("", ""); + Match m = remove_mathml.Match(text); while (m.Length > 0) { @@ -69,34 +92,42 @@ namespace Bind m = remove_mathml.Match(text); } - XmlReader doc = null; + //XmlReader doc = null; + XDocument doc = null; try { // The pure XmlReader is ~20x faster than the XmlTextReader. - doc = XmlReader.Create(new StringReader(text), settings); - //doc = new XmlTextReader(new StringReader(text)); - - using (StringWriter sw = new StringWriter()) - { - xslt.Transform(doc, null, sw); - Text = sw.ToString().Split(new char[] { '\r', '\n' }, - StringSplitOptions.RemoveEmptyEntries); - - // Remove unecessary whitespace - // Indentation is handled by BindStreamWriter - for (int i = 0; i < Text.Length; i++) - { - Text[i] = Text[i].Trim(); - } - return Text; - } + //doc = XmlReader.Create(new StringReader(text), settings); + doc = XDocument.Parse(text); + Cached = ToInlineDocs(doc); + return Cached; } catch (XmlException e) { Console.WriteLine(e.ToString()); Console.WriteLine(doc.ToString()); - return new string[0]; + return null; } } + + Documentation ToInlineDocs(XDocument doc) + { + var inline = new Documentation + { + Summary = + ((IEnumerable)doc.XPathEvaluate("//*[name()='refentry']/*[name()='refnamediv']/*[name()='refpurpose']")) + .Cast().First().Value.Trim(), + Parameters = + ((IEnumerable)doc.XPathEvaluate("*[name()='refentry']/*[name()='refsect1'][@id='parameters']/*[name()='variablelist']/*[name()='varlistentry']")) + .Cast() + .Select(p => new KeyValuePair( + p.XPathSelectElement("*[name()='term']/*[name()='parameter']").Value.Trim(), + p.XPathSelectElement("*[name()='listitem']").Value.Trim())) + .ToList() + }; + + inline.Summary = Char.ToUpper(inline.Summary[0]) + inline.Summary.Substring(1); + return inline; + } } } diff --git a/Source/Bind/ES/ES2Generator.cs b/Source/Bind/ES/ES2Generator.cs index 39122e37..a44ddae0 100644 --- a/Source/Bind/ES/ES2Generator.cs +++ b/Source/Bind/ES/ES2Generator.cs @@ -10,7 +10,7 @@ using Enum=Bind.Structures.Enum; namespace Bind.ES { // Generation implementation for OpenGL ES 2.0 and 3.0 - class ES2Generator : ESGenerator + class ES2Generator : Generator { public ES2Generator(Settings settings, string dirName) : base(settings, dirName) @@ -22,9 +22,17 @@ namespace Bind.ES Settings.DefaultDelegatesFile = "ES20Delegates.cs"; Settings.DefaultEnumsFile = "ES20Enums.cs"; Settings.DefaultWrappersFile = "ES20.cs"; + Settings.DefaultDocPath = Path.Combine( + Settings.DefaultDocPath, "ES20"); Profile = "gles2"; Version = "2.0"; + + // For compatibility with OpenTK 1.0 and Xamarin, generate + // overloads using the "All" enum in addition to strongly-typed enums. + // This can be disabled by passing "-o:-keep_untyped_enums" as a cmdline parameter. + Settings.DefaultCompatibility |= Settings.Legacy.KeepUntypedEnums; + Settings.DefaultCompatibility |= Settings.Legacy.UseDllImports; } } } diff --git a/Source/Bind/ES/ES3Generator.cs b/Source/Bind/ES/ES3Generator.cs index 8ac5d13c..2b3c664e 100644 --- a/Source/Bind/ES/ES3Generator.cs +++ b/Source/Bind/ES/ES3Generator.cs @@ -10,7 +10,7 @@ using Enum=Bind.Structures.Enum; namespace Bind.ES { // Generation implementation for OpenGL ES 3.0 - class ES3Generator : ESGenerator + class ES3Generator : Generator { public ES3Generator(Settings settings, string dirName) : base(settings, dirName) @@ -22,9 +22,17 @@ namespace Bind.ES Settings.DefaultDelegatesFile = "ES30Delegates.cs"; Settings.DefaultEnumsFile = "ES30Enums.cs"; Settings.DefaultWrappersFile = "ES30.cs"; + Settings.DefaultDocPath = Path.Combine( + Settings.DefaultDocPath, "ES30"); Profile = "gles2"; // The 3.0 spec reuses the gles2 apiname Version = "2.0|3.0"; + + // For compatibility with OpenTK 1.0 and Xamarin, generate + // overloads using the "All" enum in addition to strongly-typed enums. + // This can be disabled by passing "-o:-keep_untyped_enums" as a cmdline parameter. + Settings.DefaultCompatibility |= Settings.Legacy.KeepUntypedEnums; + Settings.DefaultCompatibility |= Settings.Legacy.UseDllImports; } } } diff --git a/Source/Bind/ES/ESGenerator.cs b/Source/Bind/ES/ESGenerator.cs index 712b5da9..0a0a0f15 100644 --- a/Source/Bind/ES/ESGenerator.cs +++ b/Source/Bind/ES/ESGenerator.cs @@ -22,6 +22,8 @@ namespace Bind.ES Settings.DefaultDelegatesFile = "ES11Delegates.cs"; Settings.DefaultEnumsFile = "ES11Enums.cs"; Settings.DefaultWrappersFile = "ES11.cs"; + Settings.DefaultDocPath = Path.Combine( + Settings.DefaultDocPath, "ES20"); // no ES11 docbook sources available // Khronos releases a combined 1.0+1.1 specification, // so we cannot distinguish between the two. diff --git a/Source/Bind/GL2/GL4Generator.cs b/Source/Bind/GL2/GL4Generator.cs index 360f835b..173bd0c1 100644 --- a/Source/Bind/GL2/GL4Generator.cs +++ b/Source/Bind/GL2/GL4Generator.cs @@ -45,6 +45,8 @@ namespace Bind.GL2 Settings.DefaultDelegatesFile = "GL4Delegates.cs"; Settings.DefaultEnumsFile = "GL4Enums.cs"; Settings.DefaultWrappersFile = "GL4.cs"; + Settings.DefaultDocPath = Path.Combine( + Settings.DefaultDocPath, "GL4"); Profile = "glcore"; } diff --git a/Source/Bind/GL2/Generator.cs b/Source/Bind/GL2/Generator.cs index f9218e70..7a5ea1c2 100644 --- a/Source/Bind/GL2/Generator.cs +++ b/Source/Bind/GL2/Generator.cs @@ -18,7 +18,7 @@ using Type=Bind.Structures.Type; namespace Bind.GL2 { - class Generator : IBind + abstract class Generator : IBind { #region Fields @@ -82,22 +82,6 @@ namespace Bind.GL2 Settings.DelegatesClass = "Delegates"; Settings.OutputClass = "GL"; - if (Settings.Compatibility == Settings.Legacy.Tao) - { - Settings.OutputNamespace = "Tao.OpenGl"; - Settings.OutputClass = "Gl"; - } - else - { - // Defaults - } - - Settings.DefaultOutputNamespace = "OpenTK.Graphics.OpenGL"; - Settings.DefaultImportsFile = "GLCore.cs"; - Settings.DefaultDelegatesFile = "GLDelegates.cs"; - Settings.DefaultEnumsFile = "GLEnums.cs"; - Settings.DefaultWrappersFile = "GL.cs"; - Delegates = new DelegateCollection(); Enums = new EnumCollection(); Wrappers = new FunctionCollection(); diff --git a/Source/Bind/Generator.Bind.csproj b/Source/Bind/Generator.Bind.csproj index 4eb98e16..f6e517ca 100644 --- a/Source/Bind/Generator.Bind.csproj +++ b/Source/Bind/Generator.Bind.csproj @@ -55,6 +55,7 @@ 4 AllRules.ruleset full + -mode:es30 285212672 @@ -227,680 +228,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -914,124 +241,10 @@ Code + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Designer @@ -1057,4 +270,7 @@ + + + \ No newline at end of file diff --git a/Source/Bind/JavaSpecWriter.cs b/Source/Bind/JavaSpecWriter.cs index 755174fd..c7d34aa5 100644 --- a/Source/Bind/JavaSpecWriter.cs +++ b/Source/Bind/JavaSpecWriter.cs @@ -347,29 +347,28 @@ namespace Bind if (!docfiles.ContainsKey(docfile)) docfile = Settings.FunctionPrefix + f.TrimmedName.TrimEnd(numbers) + ".xml"; - var docs = new List(); - if (docfiles.ContainsKey(docfile)) + Documentation docs = + (docfiles.ContainsKey(docfile) ? + Processor.ProcessFile(docfiles[docfile]) : null) ?? + new Documentation { - docs.AddRange(Processor.ProcessFile(docfiles[docfile])); - } - if (docs.Count == 0) - { - docs.Add("/// "); - } + Summary = String.Empty, + Parameters = f.Parameters.Select(p => + new KeyValuePair(p.Name, String.Empty)).ToList() + }; - int summary_start = docs[0].IndexOf("") + "".Length; string warning = "[deprecated: v{0}]"; string category = "[requires: {0}]"; if (f.Deprecated) { warning = String.Format(warning, f.DeprecatedVersion); - docs[0] = docs[0].Insert(summary_start, warning); + docs.Summary = docs.Summary.Insert(0, warning); } if (f.Extension != "Core" && !String.IsNullOrEmpty(f.Category)) { category = String.Format(category, f.Category); - docs[0] = docs[0].Insert(summary_start, category); + docs.Summary = docs.Summary.Insert(0, category); } else if (!String.IsNullOrEmpty(f.Version)) { @@ -377,12 +376,23 @@ namespace Bind category = String.Format(category, "v" + f.Version); else category = String.Format(category, "v" + f.Version + " and " + f.Category); - docs[0] = docs[0].Insert(summary_start, category); + docs.Summary = docs.Summary.Insert(0, category); } - foreach (var doc in docs) + for (int i = 0; i < f.WrappedDelegate.Parameters.Count; i++) { - sw.WriteLine(doc); + var param = f.WrappedDelegate.Parameters[i]; + if (param.ComputeSize != String.Empty) + { + docs.Parameters[i].Value.Insert(0, + String.Format("[length: {0}]", param.ComputeSize)); + } + } + + sw.WriteLine("/// {0}", docs.Summary); + foreach (var p in docs.Parameters) + { + sw.WriteLine("/// {1}", p.Key, p.Value); } } catch (Exception e) diff --git a/Source/Bind/Main.cs b/Source/Bind/Main.cs index 4374f042..8078220f 100644 --- a/Source/Bind/Main.cs +++ b/Source/Bind/Main.cs @@ -187,7 +187,7 @@ namespace Bind case GeneratorMode.All: Console.WriteLine("Using 'all' generator mode."); Console.WriteLine("Use '-mode:all/gl2/gl4/es10/es11/es20/es30' to select a specific mode."); - Generators.Add(new Generator(Settings, dirName)); + Generators.Add(new GL2Generator(Settings, dirName)); Generators.Add(new GL4Generator(Settings, dirName)); Generators.Add(new ESGenerator(Settings, dirName)); Generators.Add(new ES2Generator(Settings, dirName)); @@ -195,7 +195,7 @@ namespace Bind break; case GeneratorMode.GL2: - Generators.Add(new Generator(Settings, dirName)); + Generators.Add(new GL2Generator(Settings, dirName)); break; case GeneratorMode.GL3: diff --git a/Source/Bind/Specifications/Docs/ToInlineDocs.xslt b/Source/Bind/Specifications/Docs/ToInlineDocs.xslt deleted file mode 100644 index fe39f5a6..00000000 --- a/Source/Bind/Specifications/Docs/ToInlineDocs.xslt +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - /// - /// - /// - - - - - /// - - /// - /// - /// - - /// - - - - - - - \ No newline at end of file diff --git a/Source/Bind/Structures/Documentation.cs b/Source/Bind/Structures/Documentation.cs new file mode 100644 index 00000000..99d37388 --- /dev/null +++ b/Source/Bind/Structures/Documentation.cs @@ -0,0 +1,41 @@ +#region License +// +// Documentation.cs +// +// Author: +// Stefanos A. +// +// Copyright (c) 2006-2014 Stefanos Apostolopoulos +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +#endregion + +using System; +using System.Collections.Generic; + +namespace Bind.Structures +{ + public class Documentation + { + public string Summary { get; set; } + public List> Parameters { get; set; } + } +} +