Merge() static private method

Places a new constant in the specified enum, if it doesn't already exist. The existing constant is replaced iff the new has a numeric value and the old has a reference value (eg 0x5 is preferred over AttribMask.Foo)
static private Merge ( Bind.Structures.Enum s, Constant t ) : Bind.Structures.Enum
s Bind.Structures.Enum
t Bind.Structures.Constant
return Bind.Structures.Enum
Example #1
0
        public void ReadDelegates(string file, DelegateCollection delegates)
        {
            var specs = new XPathDocument(file);

            foreach (XPathNavigator nav in specs.CreateNavigator().Select("/signatures/delete"))
            {
                foreach (XPathNavigator node in nav.SelectChildren("function", String.Empty))
                {
                    delegates.Remove(node.GetAttribute("name", String.Empty));
                }
            }
            foreach (XPathNavigator nav in specs.CreateNavigator().Select("/signatures/add"))
            {
                Utilities.Merge(delegates, ReadDelegates(nav));
            }
        }
Example #2
0
        public void ReadEnums(string file, EnumCollection enums)
        {
            // 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("/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("/signatures/add"))
            {
                Utilities.Merge(enums, ReadEnums(nav));
            }
        }
Example #3
0
        public void ReadEnums(string file, EnumCollection enums, string apiname, string apiversions)
        {
            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 (var apiversion in apiversions.Split('|'))
            {
                string xpath_add, xpath_delete;
                GetSignaturePaths(apiname, apiversion, out xpath_add, out xpath_delete);

                // 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(xpath_delete))
                {
                    foreach (XPathNavigator node in nav.SelectChildren("enum", String.Empty))
                    {
                        enums.Remove(node.GetAttribute("name", String.Empty));
                    }
                }
                foreach (XPathNavigator nav in specs.CreateNavigator().Select(xpath_add))
                {
                    Utilities.Merge(enums, ReadEnums(nav));
                }
            }
        }
Example #4
0
        private EnumCollection ReadEnums(XPathNavigator nav)
        {
            EnumCollection enums = new EnumCollection();
            Enum           all   = new Enum()
            {
                Name = Settings.CompleteEnumName
            };

            if (nav != null)
            {
                var reuse_list = new List <KeyValuePair <Enum, string> >();

                // First pass: collect all available tokens and enums
                foreach (XPathNavigator node in nav.SelectChildren("enum", String.Empty))
                {
                    Enum e = new Enum()
                    {
                        Name = node.GetAttribute("name", String.Empty).Trim(),
                        Type = node.GetAttribute("type", String.Empty).Trim()
                    };

                    e.Obsolete = node.GetAttribute("obsolete", String.Empty).Trim();

                    if (String.IsNullOrEmpty(e.Name))
                    {
                        throw new InvalidOperationException(String.Format("Empty name for enum element {0}", node.ToString()));
                    }

                    // It seems that all flag collections contain "Mask" in their names.
                    // This looks like a heuristic, but it holds 100% in practice
                    // (checked all enums to make sure).
                    e.IsFlagCollection = e.Name.ToLower().Contains("mask");

                    foreach (XPathNavigator param in node.SelectChildren(XPathNodeType.Element))
                    {
                        Constant c = null;
                        switch (param.Name)
                        {
                        case "token":
                            c = new Constant
                            {
                                Name  = param.GetAttribute("name", String.Empty).Trim(),
                                Value = param.GetAttribute("value", String.Empty).Trim()
                            };
                            break;

                        case "use":
                            c = new Constant
                            {
                                Name      = param.GetAttribute("token", String.Empty).Trim(),
                                Reference = param.GetAttribute("enum", String.Empty).Trim(),
                                Value     = param.GetAttribute("token", String.Empty).Trim(),
                            };
                            break;

                        case "reuse":
                            var reuse_enum = param.GetAttribute("enum", String.Empty).Trim();
                            reuse_list.Add(new KeyValuePair <Enum, string>(e, reuse_enum));
                            break;

                        default:
                            throw new NotSupportedException();
                        }

                        if (c != null)
                        {
                            Utilities.Merge(all, c);
                            try
                            {
                                if (!e.ConstantCollection.ContainsKey(c.Name))
                                {
                                    e.ConstantCollection.Add(c.Name, c);
                                }
                                else if (e.ConstantCollection[c.Name].Value != c.Value)
                                {
                                    var existing = e.ConstantCollection[c.Name];
                                    if (existing.Reference != null && c.Reference == null)
                                    {
                                        e.ConstantCollection[c.Name] = c;
                                    }
                                    else if (existing.Reference == null && c.Reference != null)
                                    {
                                        // Keep existing
                                    }
                                    else
                                    {
                                        Console.WriteLine("[Warning] Conflicting token {0}.{1} with value {2} != {3}",
                                                          e.Name, c.Name, e.ConstantCollection[c.Name].Value, c.Value);
                                    }
                                }
                            }
                            catch (ArgumentException ex)
                            {
                                Console.WriteLine("[Warning] Failed to add constant {0} to enum {1}: {2}", c.Name, e.Name, ex.Message);
                            }
                        }
                    }

                    Utilities.Merge(enums, e);
                }

                // Second pass: resolve "reuse" directives
restart:
                foreach (var pair in reuse_list)
                {
                    var e     = pair.Key;
                    var reuse = pair.Value;
                    var count = e.ConstantCollection.Count;

                    if (enums.ContainsKey(reuse))
                    {
                        var reuse_enum = enums[reuse];
                        foreach (var token in reuse_enum.ConstantCollection.Values)
                        {
                            Utilities.Merge(e, token);
                        }
                    }
                    else
                    {
                        Console.WriteLine("[Warning] Reuse token not found: {0}", reuse);
                    }

                    if (count != e.ConstantCollection.Count)
                    {
                        // Restart resolution of reuse directives whenever
                        // we modify an enum. This is the simplest (brute) way
                        // to resolve chains of reuse directives:
                        // e.g. enum A reuses B which reuses C
                        goto restart;
                    }
                }
            }

            Utilities.Merge(enums, all);
            return(enums);
        }
Example #5
0
        private EnumCollection ReadEnums(XPathNavigator nav)
        {
            EnumCollection enums = new EnumCollection();
            Enum           all   = new Enum()
            {
                Name = Settings.CompleteEnumName
            };

            if (nav != null)
            {
                foreach (XPathNavigator node in nav.SelectChildren("enum", String.Empty))
                {
                    Enum e = new Enum()
                    {
                        Name = node.GetAttribute("name", String.Empty),
                        Type = node.GetAttribute("type", String.Empty)
                    };
                    if (String.IsNullOrEmpty(e.Name))
                    {
                        throw new InvalidOperationException(String.Format("Empty name for enum element {0}", node.ToString()));
                    }

                    foreach (XPathNavigator param in node.SelectChildren(XPathNodeType.Element))
                    {
                        Constant c = null;
                        switch (param.Name)
                        {
                        case "token":
                            c = new Constant
                            {
                                Name  = param.GetAttribute("name", String.Empty),
                                Value = param.GetAttribute("value", String.Empty)
                            };
                            break;

                        case "use":
                            c = new Constant
                            {
                                Name      = param.GetAttribute("token", String.Empty),
                                Reference = param.GetAttribute("enum", String.Empty),
                                Value     = param.GetAttribute("token", String.Empty),
                            };
                            break;

                        default:
                            throw new NotSupportedException();
                        }
                        Utilities.Merge(all, c);
                        try
                        {
                            if (!e.ConstantCollection.ContainsKey(c.Name))
                            {
                                e.ConstantCollection.Add(c.Name, c);
                            }
                            else if (e.ConstantCollection[c.Name].Value != c.Value)
                            {
                                var existing = e.ConstantCollection[c.Name];
                                if (existing.Reference != null && c.Reference == null)
                                {
                                    e.ConstantCollection[c.Name] = c;
                                }
                                else if (existing.Reference == null && c.Reference != null)
                                {
                                }   // Keep existing
                                else
                                {
                                    Console.WriteLine("[Warning] Conflicting token {0}.{1} with value {2} != {3}",
                                                      e.Name, c.Name, e.ConstantCollection[c.Name].Value, c.Value);
                                }
                            }
                        }
                        catch (ArgumentException ex)
                        {
                            Console.WriteLine("[Warning] Failed to add constant {0} to enum {1}: {2}", c.Name, e.Name, ex.Message);
                        }
                    }

                    Utilities.Merge(enums, e);
                }
            }

            Utilities.Merge(enums, all);
            return(enums);
        }