Avoid singleton Settings. Allow v1 signatures
authorStefanos A. <stapostol@gmail.com>
Fri, 1 Nov 2013 08:01:35 +0000 (09:01 +0100)
committerStefanos A. <stapostol@gmail.com>
Fri, 1 Nov 2013 08:01:35 +0000 (09:01 +0100)
A Settings object is now passed directly as a parameter, in order to
support different configurations in the same process. The XmlSpecReader
can now distinguish between, and support both, pre-GL4.4 and post-GL4.4
specs.

Source/Bind/XmlSpecReader.cs

index 3df76f574543423e2938223787fe635be161b391..ec6d793a97cdb51dbd461b948e9f5b037e0ae2e3 100644 (file)
@@ -2,7 +2,7 @@
 //
 // The Open Toolkit Library License
 //
-// Copyright (c) 2006 - 2010 the Open Toolkit library.
+// Copyright (c) 2006 - 2013 Stefanos Apostolopoulos for the Open Toolkit library.
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to deal
@@ -41,11 +41,36 @@ namespace Bind
 
     class XmlSpecReader : ISpecReader
     {
+        Settings Settings { get; set; }
+
+        #region Constructors
+
+        public XmlSpecReader(Settings settings)
+        {
+            if (settings == null)
+                throw new ArgumentNullException("settings");
+            Settings = settings;
+        }
+
+        #endregion
+
         #region ISpecReader Members
 
         public void ReadDelegates(string file, DelegateCollection delegates, string apiname)
         {
             var specs = new XPathDocument(file);
+
+            // The pre-GL4.4 spec format does not distinguish between
+            // different apinames (it is assumed that different APIs
+            // are stored in distinct signature.xml files).
+            // To maintain compatibility, we detect the version of the
+            // signatures.xml file and ignore apiname if it is version 1.
+            var specversion = GetSpecVersion(specs);
+            if (specversion == "1")
+            {
+                apiname = null;
+            }
+
             foreach (XPathNavigator nav in specs.CreateNavigator().Select(
                 !String.IsNullOrEmpty(apiname) ?
                 String.Format("/signatures/delete[@name='{0}']", apiname) :
@@ -63,7 +88,149 @@ namespace Bind
             }
         }
 
-        private DelegateCollection ReadDelegates(XPathNavigator specs)
+        public void ReadEnums(string file, EnumCollection enums, string apiname)
+        {
+            var specs = new XPathDocument(file);
+
+            // The pre-GL4.4 spec format does not distinguish between
+            // different apinames (it is assumed that different APIs
+            // are stored in distinct signature.xml files).
+            // To maintain compatibility, we detect the version of the
+            // signatures.xml file and ignore apiname if it is version 1.
+            var specversion = GetSpecVersion(specs);
+            if (specversion == "1")
+            {
+                apiname = null;
+            }
+
+            // First, read all enum definitions from spec and override file.
+            // Afterwards, read all token/enum overrides from overrides file.
+            foreach (XPathNavigator nav in specs.CreateNavigator().Select(
+                !String.IsNullOrEmpty(apiname) ?
+                String.Format("/signatures/delete[@name='{0}']", apiname) :
+                String.Format("/signatures/delete")))
+            {
+                foreach (XPathNavigator node in nav.SelectChildren("enum", String.Empty))
+                    enums.Remove(node.GetAttribute("name", String.Empty));
+            }
+            foreach (XPathNavigator nav in specs.CreateNavigator().Select(
+                !String.IsNullOrEmpty(apiname) ?
+                String.Format("/signatures/add[@name='{0}']", apiname) :
+                String.Format("/signatures/add")))
+            {
+                Utilities.Merge(enums, ReadEnums(nav));
+            }
+        }
+
+        public Dictionary<string, string> ReadTypeMap(string file)
+        {
+            using (var sr = new StreamReader(file))
+            {
+                Console.WriteLine("Reading opengl types.");
+                Dictionary<string, string> GLTypes = new Dictionary<string, string>();
+
+                if (sr == null)
+                    return GLTypes;
+
+                do
+                {
+                    string line = sr.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*");
+                    }
+                    else if (words[0] == "CharPointer" || words[0] == "charPointerARB" ||
+                             words[0] == "ConstCharPointer")
+                    {
+                        // 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
+                        // String[] or StringBuilder[].
+                        GLTypes.Add(words[0], "String");
+                    }
+                    /*else if (words[0].Contains("Pointer"))
+                    {
+                        GLTypes.Add(words[0], words[1].Replace("Pointer", "*"));
+                    }*/
+                    else if (words[1].Contains("GLvoid"))
+                    {
+                        GLTypes.Add(words[0], "void");
+                    }
+                    else if (words[1] == "const" && words[2] == "GLubyte")
+                    {
+                        GLTypes.Add(words[0], "String");
+                    }
+                    else if (words[1] == "struct")
+                    {
+                        GLTypes.Add(words[0], words[2]);
+                    }
+                    else
+                    {
+                        GLTypes.Add(words[0], words[1]);
+                    }
+                }
+                while (!sr.EndOfStream);
+
+                return GLTypes;
+            }
+        }
+
+        public Dictionary<string, string> ReadCSTypeMap(string file)
+        {
+            using (var sr = new StreamReader(file))
+            {
+                Dictionary<string, string> CSTypes = new Dictionary<string, string>();
+                Console.WriteLine("Reading C# types.");
+
+                while (!sr.EndOfStream)
+                {
+                    string line = sr.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 Members
+
+        string GetSpecVersion(XPathDocument specs)
+        {
+            var version =
+                specs.CreateNavigator().SelectSingleNode("/signatures")
+                .GetAttribute("version", String.Empty);
+            if (String.IsNullOrEmpty(version))
+            {
+                version = "1";
+            }
+            return version;
+        }
+
+        DelegateCollection ReadDelegates(XPathNavigator specs)
         {
             DelegateCollection delegates = new DelegateCollection();
             var extensions = new List<string>();
@@ -132,31 +299,7 @@ namespace Bind
             return delegates;
         }
 
-        public void ReadEnums(string file, EnumCollection enums, string apiname)
-        {
-            // First, read all enum definitions from spec and override file.
-            // Afterwards, read all token/enum overrides from overrides file.
-            // Every single enum is merged into
-
-            var specs = new XPathDocument(file);
-            foreach (XPathNavigator nav in specs.CreateNavigator().Select(
-                !String.IsNullOrEmpty(apiname) ?
-                String.Format("/signatures/delete[@name='{0}']", apiname) :
-                String.Format("/signatures/delete")))
-            {
-                foreach (XPathNavigator node in nav.SelectChildren("enum", String.Empty))
-                    enums.Remove(node.GetAttribute("name", String.Empty));
-            }
-            foreach (XPathNavigator nav in specs.CreateNavigator().Select(
-                !String.IsNullOrEmpty(apiname) ?
-                String.Format("/signatures/add[@name='{0}']", apiname) :
-                String.Format("/signatures/add")))
-            {
-                Utilities.Merge(enums, ReadEnums(nav));
-            }
-        }
-
-        private EnumCollection ReadEnums(XPathNavigator nav)
+        EnumCollection ReadEnums(XPathNavigator nav)
         {
             EnumCollection enums = new EnumCollection();
             Enum all = new Enum() { Name = Settings.CompleteEnumName };
@@ -242,98 +385,6 @@ namespace Bind
             return enums;
         }
 
-        public Dictionary<string, string> ReadTypeMap(string file)
-        {
-            using (var sr = new StreamReader(file))
-            {
-                Console.WriteLine("Reading opengl types.");
-                Dictionary<string, string> GLTypes = new Dictionary<string, string>();
-
-                if (sr == null)
-                    return GLTypes;
-
-                do
-                {
-                    string line = sr.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*");
-                    }
-                    else if (words[0] == "CharPointer" || words[0] == "charPointerARB" ||
-                             words[0] == "ConstCharPointer")
-                    {
-                        // 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
-                        // String[] or StringBuilder[].
-                        GLTypes.Add(words[0], "String");
-                    }
-                    /*else if (words[0].Contains("Pointer"))
-                    {
-                        GLTypes.Add(words[0], words[1].Replace("Pointer", "*"));
-                    }*/
-                    else if (words[1].Contains("GLvoid"))
-                    {
-                        GLTypes.Add(words[0], "void");
-                    }
-                    else if (words[1] == "const" && words[2] == "GLubyte")
-                    {
-                        GLTypes.Add(words[0], "String");
-                    }
-                    else if (words[1] == "struct")
-                    {
-                        GLTypes.Add(words[0], words[2]);
-                    }
-                    else
-                    {
-                        GLTypes.Add(words[0], words[1]);
-                    }
-                }
-                while (!sr.EndOfStream);
-
-                return GLTypes;
-            }
-        }
-
-        public Dictionary<string, string> ReadCSTypeMap(string file)
-        {
-            using (var sr = new StreamReader(file))
-            {
-                Dictionary<string, string> CSTypes = new Dictionary<string, string>();
-                Console.WriteLine("Reading C# types.");
-
-                while (!sr.EndOfStream)
-                {
-                    string line = sr.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
     }
 }