예제 #1
0
 public void Write(Enum e)
 {
     foreach (string s in splitLines.Split(e.ToString()))
     {
         WriteLine(s.TrimEnd('\r', '\n'));
     }
 }
예제 #2
0
        // Resolve 'use' tokens by searching and replacing the correct
        // value from the enum collection.
        // Tokens that can't be resolved are removed.
        static void ResolveAliases(Enum e, EnumCollection enums)
        {
            // Note that we have the removal must be a separate step, since
            // we cannot modify a collection while iterating with foreach.
            var broken_references = e.ConstantCollection.Values
                                    .Where(c => !Constant.TranslateConstantWithReference(c, enums))
                                    .Select(c => c).ToList();

            foreach (var c in broken_references)
            {
                Console.WriteLine("[Warning] Reference {0} not found for token {1}.", c.Reference, c);
                e.ConstantCollection.Remove(c.Name);
            }
        }
        public override EnumCollection ReadEnums(StreamReader specFile)
        {
            // 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

            EnumCollection enums = new EnumCollection();
            Enum           all   = new Enum()
            {
                Name = Settings.CompleteEnumName
            };
            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("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 = new Constant(param.GetAttribute("name", String.Empty), param.GetAttribute("value", String.Empty));
                            Utilities.Merge(all, c);
                            try { e.ConstantCollection.Add(c.Name, c); }
                            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);
            enums.Translate(overrides);
            return(enums);
        }
예제 #4
0
 /// <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(EnumCollection enums, Enum t)
 {
     if (!enums.ContainsKey(t.Name))
     {
         enums.Add(t.Name, t);
     }
     else
     {
         Enum e = enums[t.Name];
         foreach (Constant c in t.ConstantCollection.Values)
         {
             Merge(e, c);
         }
     }
 }
예제 #5
0
        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);
        }
예제 #6
0
파일: Utilities.cs 프로젝트: noggs/opentk
        /// <summary>
        /// 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)
        /// </summary>
        /// <param name="s"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        internal static Enum Merge(Enum s, Constant t)
        {
            if (!s.ConstantCollection.ContainsKey(t.Name))
            {
                s.ConstantCollection.Add(t.Name, t);
            }
            else
            {
                // Tried to add a constant that already exists. If one constant
                // is like: 'Foo = 0x5' and the other like: 'Foo = Bar.Foo', then
                // keep the first one.
                if (!String.IsNullOrEmpty(s.ConstantCollection[t.Name].Reference))
                {
                    s.ConstantCollection[t.Name] = t;
                }
            }

            return(s);
        }
예제 #7
0
        /// <summary>
        /// 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)
        /// </summary>
        /// <param name="s"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        internal static Enum Merge(Enum s, Constant t)
        {
            if (!s.ConstantCollection.ContainsKey(t.Name))
            {
                s.ConstantCollection.Add(t.Name, t);
            }
            else
            {
                // Tried to add a constant that already exists. If one constant
                // is like: 'Foo = 0x5' and the other like: 'Foo = Bar.Foo', then
                // keep the first one.
                if (!Char.IsDigit(((Constant)s.ConstantCollection[t.Name]).Value[0]))
                {
                    s.ConstantCollection.Remove(t.Name);
                    s.ConstantCollection.Add(t.Name, t);
                }
            }

            return(s);
        }
        /// <summary>
        /// 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)
        /// </summary>
        /// <param name="s"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        internal static Enum Merge(Enum s, Constant t)
        {
            if (!s.ConstantCollection.ContainsKey(t.Name))
            {
                s.ConstantCollection.Add(t.Name, t);
            }
            else
            {
                // Tried to add a constant that already exists. If one constant
                // is like: 'Foo = 0x5' and the other like: 'Foo = Bar.Foo', then 
                // keep the first one.
                if (!Char.IsDigit(((Constant)s.ConstantCollection[t.Name]).Value[0]))
                {
                    s.ConstantCollection.Remove(t.Name);
                    s.ConstantCollection.Add(t.Name, t);
                }
            }

            return s;
        }
예제 #9
0
 // Resolve 'use' tokens by searching and replacing the correct
 // value from the enum collection.
 // Tokens that can't be resolved are removed.
 static void ResolveAliases(Enum e, EnumCollection enums)
 {
     // Note that we have the removal must be a separate step, since
     // we cannot modify a collection while iterating with foreach.
     var broken_references = e.ConstantCollection.Values
         .Where(c => !Constant.TranslateConstantWithReference(c, enums, null))
         .Select(c => c).ToList();
     foreach (var c in broken_references)
     {
         Console.WriteLine("[Warning] Reference {0} not found for token {1}.", c.Reference, c);
         e.ConstantCollection.Remove(c.Name);
     }
 }
예제 #10
0
파일: Generator.cs 프로젝트: jwatte/gears
        public virtual EnumCollection ReadEnums(StreamReader specFile)
        {
            Trace.WriteLine("Reading opengl enumerant specs.");
            Trace.Indent();

            EnumCollection enums = new EnumCollection();

            // complete_enum contains all opengl enumerants.
            Enum complete_enum = new Enum();
            complete_enum.Name = Settings.CompleteEnumName;

            do
            {
                string line = NextValidLine(specFile);
                if (String.IsNullOrEmpty(line))
                    break;

                line = line.Replace('\t', ' ');

                // We just encountered the start of a new enumerant:
                while (!String.IsNullOrEmpty(line) && line.Contains("enum"))
                {
                    string[] words = line.Split(Utilities.Separators, StringSplitOptions.RemoveEmptyEntries);
                    if (words.Length == 0)
                        continue;

                    // Declare a new enumerant
                    Enum e = new Enum();
                    e.Name = Char.IsDigit(words[0][0]) ? Settings.ConstantPrefix + words[0] : words[0];

                    // And fill in the values for this enumerant
                    do
                    {
                        line = NextValidLine(specFile);

                        if (String.IsNullOrEmpty(line) || line.StartsWith("#"))
                            continue;

                        if (line.Contains("enum:") || specFile.EndOfStream)
                            break;

                        line = line.Replace('\t', ' ');
                        words = line.Split(Utilities.Separators, StringSplitOptions.RemoveEmptyEntries);

                        if (words.Length == 0)
                            continue;

                        // If we reach this point, we have found a new value for the current enumerant
                        Constant c = new Constant();
                        if (line.Contains("="))
                        {
                            // Trim the name's prefix, but only if not in Tao compat mode.
                            if (Settings.Compatibility == Settings.Legacy.Tao)
                            {
                            }
                            else
                            {
                                if (words[0].StartsWith(Settings.ConstantPrefix))
                                    words[0] = words[0].Substring(Settings.ConstantPrefix.Length);

                                if (Char.IsDigit(words[0][0]))
                                    words[0] = Settings.ConstantPrefix + words[0];
                            }

                            c.Name = words[0];
                            c.Value = words[2];
                        }
                        else if (words[0] == "use")
                        {
                            // Trim the prefix.
                            if (words[2].StartsWith(Settings.ConstantPrefix))
                                words[2] = words[2].Substring(Settings.ConstantPrefix.Length);

                            // If the remaining string starts with a digit, we were wrong above.
                            // Re-add the "GL_"
                            if (Char.IsDigit(words[2][0]))
                                words[2] = Settings.ConstantPrefix + words[2];

                            c.Name = words[2];
                            c.Reference = words[1];
                            c.Value = words[2];
                        }
                        else
                        {
                            // Typical cause is hand-editing the specs and forgetting to add an '=' sign.
                            throw new InvalidOperationException(String.Format(
                                "[Error] Invalid constant definition: \"{0}\"", line));
                        }

                        //if (!String.IsNullOrEmpty(c.Name) && !e.Members.Contains.Contains(c))
                        //SpecTranslator.Merge(e.Members, c);
                        if (!e.ConstantCollection.ContainsKey(c.Name))
                            e.ConstantCollection.Add(c.Name, c);
                        else
                            Trace.WriteLine(String.Format(
                                "Spec error: Constant {0} defined twice in enum {1}, discarding last definition.",
                                c.Name, e.Name));

                        // Insert the current constant in the list of all constants.
                        //SpecTranslator.Merge(complete_enum.Members, c);
                        complete_enum = Utilities.Merge(complete_enum, c);
                    }
                    while (!specFile.EndOfStream);

                    // At this point, the complete value list for the current enumerant has been read, so add this
                    // enumerant to the list.
                    //e.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "public enum " + e.Name));
                    //e.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, "public enum " + e.Name));

                    // (disabled) Hack - discard Boolean enum, it fsucks up the fragile translation code ahead.
                    //if (!e.Name.Contains("Bool"))
                    //Utilities.Merge(enums, e);

                    //e.Translate();

                    if (!enums.ContainsKey(e.Name))
                        enums.Add(e.Name, e);
                    else
                    {
                        // The enum already exists, merge constants.
                        foreach (Constant t in e.ConstantCollection.Values)
                            Utilities.Merge(enums[e.Name], t);
                    }
                }
            }
            while (!specFile.EndOfStream);

            enums.Add(complete_enum.Name, complete_enum);

            Trace.Unindent();

            return enums;
        }
예제 #11
0
        public virtual EnumCollection ReadEnums(StreamReader specFile)
        {
            Trace.WriteLine("Reading opengl enumerant specs.");
            Trace.Indent();

            EnumCollection enums = new EnumCollection();

            // complete_enum contains all opengl enumerants.
            Bind.Structures.Enum complete_enum = new Bind.Structures.Enum();
            complete_enum.Name = Settings.CompleteEnumName;

            do
            {
                string line = NextValidLine(specFile);
                if (String.IsNullOrEmpty(line))
                    break;

                line = line.Replace('\t', ' ');

                // We just encountered the start of a new enumerant:
                while (!String.IsNullOrEmpty(line) && line.Contains("enum"))
                {
                    string[] words = line.Split(Utilities.Separators, StringSplitOptions.RemoveEmptyEntries);
                    if (words.Length == 0)
                        continue;

                    // Declare a new enumerant
                    Bind.Structures.Enum e = new Bind.Structures.Enum();
                    e.Name = Char.IsDigit(words[0][0]) ? Settings.ConstantPrefix + words[0] : words[0];

                    // And fill in the values for this enumerant
                    do
                    {
                        line = NextValidLine(specFile);

                        if (String.IsNullOrEmpty(line) || line.StartsWith("#"))
                            continue;

                        if (line.Contains("enum:") || specFile.EndOfStream)
                            break;

                        line = line.Replace('\t', ' ');
                        words = line.Split(Utilities.Separators, StringSplitOptions.RemoveEmptyEntries);

                        if (words.Length == 0)
                            continue;

                        // If we reach this point, we have found a new value for the current enumerant
                        Constant c = new Constant();
                        if (line.Contains("="))
                        {
                            // Trim the name's prefix, but only if not in Tao compat mode.
                            if (Settings.Compatibility == Settings.Legacy.Tao)
                            {
                            }
                            else
                            {
                                if (words[0].StartsWith(Settings.ConstantPrefix))
                                    words[0] = words[0].Substring(Settings.ConstantPrefix.Length);

                                if (Char.IsDigit(words[0][0]))
                                    words[0] = Settings.ConstantPrefix + words[0];
                            }

                            c.Name = words[0];

                            uint number;
                            if (UInt32.TryParse(words[2].Replace("0x", String.Empty), System.Globalization.NumberStyles.AllowHexSpecifier, null, out number))
                            {
                                // The value is a number, check if it should be unchecked.
                                if (number > 0x7FFFFFFF)
                                {
                                    c.Unchecked = true;
                                }
                            }
                            else
                            {
                                // The value is not a number. Strip the prefix.
                                if (words[2].StartsWith(Settings.ConstantPrefix))
                                    words[2] = words[2].Substring(Settings.ConstantPrefix.Length);

                                // If the name now starts with a digit (doesn't matter whether we
                                // stripped "GL_" above), add a "GL_" prefix.
                                // (e.g. GL_4_BYTES).
                                if (Char.IsDigit(words[2][0]))
                                    words[2] = Settings.ConstantPrefix + words[2];
                            }

                            c.Value = words[2];
                        }
                        else if (words[0] == "use")
                        {
                            // Trim the prefix.
                            if (words[2].StartsWith(Settings.ConstantPrefix))
                                words[2] = words[2].Substring(Settings.ConstantPrefix.Length);

                            // If the remaining string starts with a digit, we were wrong above.
                            // Re-add the "GL_"
                            if (Char.IsDigit(words[2][0]))
                                words[2] = Settings.ConstantPrefix + words[2];

                            c.Name = words[2];
                            c.Reference = words[1];
                            c.Value = words[2];
                        }

                        //if (!String.IsNullOrEmpty(c.Name) && !e.Members.Contains.Contains(c))
                        //SpecTranslator.Merge(e.Members, c);
                        if (!e.ConstantCollection.ContainsKey(c.Name))
                            e.ConstantCollection.Add(c.Name, c);
                        else
                            Trace.WriteLine(String.Format(
                                "Spec error: Constant {0} defined twice in enum {1}, discarding last definition.",
                                c.Name, e.Name));

                        // Insert the current constant in the list of all constants.
                        //SpecTranslator.Merge(complete_enum.Members, c);
                        complete_enum = Utilities.Merge(complete_enum, c);
                    }
                    while (!specFile.EndOfStream);

                    // At this point, the complete value list for the current enumerant has been read, so add this
                    // enumerant to the list.
                    //e.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "public enum " + e.Name));
                    //e.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, "public enum " + e.Name));

                    // (disabled) Hack - discard Boolean enum, it fsucks up the fragile translation code ahead.
                    //if (!e.Name.Contains("Bool"))
                    //Utilities.Merge(enums, e);

                    //e.Translate();

                    if (!enums.ContainsKey(e.Name))
                    {
                        enums.Add(e.Name, e);
                    }
                    else
                    {
                        // The enum already exists, merge constants.
                        Trace.WriteLine(String.Format("Conflict: Enum {0} already exists, merging constants.", e.Name));
                        foreach (Constant t in e.ConstantCollection.Values)
                        {
                            Utilities.Merge(enums[e.Name], t);
                        }
                    }

                    //enums.Add(e);
                }
                //SpecTranslator.Merge(enums, complete_enum);
            }
            while (!specFile.EndOfStream);

            enums.Add(complete_enum.Name, complete_enum);

            Trace.Unindent();

            return enums;
        }
예제 #12
0
        public override EnumCollection ReadEnums(StreamReader specFile)
        {
            // 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

            EnumCollection enums = new EnumCollection();
            Enum all = new Enum() { Name = Settings.CompleteEnumName }; 
            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("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 = new Constant(param.GetAttribute("name", String.Empty), param.GetAttribute("value", String.Empty));
                            Utilities.Merge(all, c);
                            try { e.ConstantCollection.Add(c.Name, c); }
                            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);
            enums.Translate(overrides);
            return enums;
        }
예제 #13
0
        public virtual EnumCollection ReadEnums(StreamReader specFile)
        {
            Trace.WriteLine("Reading opengl enumerant specs.");
            Trace.Indent();

            EnumCollection enums = new EnumCollection();

            // complete_enum contains all opengl enumerants.
            Enum complete_enum = new Enum();

            complete_enum.Name = Settings.CompleteEnumName;

            do
            {
                string line = NextValidLine(specFile);
                if (String.IsNullOrEmpty(line))
                {
                    break;
                }

                line = line.Replace('\t', ' ');

                // We just encountered the start of a new enumerant:
                while (!String.IsNullOrEmpty(line) && line.Contains("enum"))
                {
                    string[] words = line.Split(Utilities.Separators, StringSplitOptions.RemoveEmptyEntries);
                    if (words.Length == 0)
                    {
                        continue;
                    }

                    // Declare a new enumerant
                    Enum e = new Enum();
                    e.Name = Char.IsDigit(words[0][0]) ? Settings.ConstantPrefix + words[0] : words[0];

                    // And fill in the values for this enumerant
                    do
                    {
                        line = NextValidLine(specFile);

                        if (String.IsNullOrEmpty(line) || line.StartsWith("#"))
                        {
                            continue;
                        }

                        if (line.Contains("enum:") || specFile.EndOfStream)
                        {
                            break;
                        }

                        line  = line.Replace('\t', ' ');
                        words = line.Split(Utilities.Separators, StringSplitOptions.RemoveEmptyEntries);

                        if (words.Length == 0)
                        {
                            continue;
                        }

                        // If we reach this point, we have found a new value for the current enumerant
                        Constant c = new Constant();
                        if (line.Contains("="))
                        {
                            // Trim the name's prefix, but only if not in Tao compat mode.
                            if (Settings.Compatibility == Settings.Legacy.Tao)
                            {
                            }
                            else
                            {
                                if (words[0].StartsWith(Settings.ConstantPrefix))
                                {
                                    words[0] = words[0].Substring(Settings.ConstantPrefix.Length);
                                }

                                if (Char.IsDigit(words[0][0]))
                                {
                                    words[0] = Settings.ConstantPrefix + words[0];
                                }
                            }

                            c.Name  = words[0];
                            c.Value = words[2];
                        }
                        else if (words[0] == "use")
                        {
                            // Trim the prefix.
                            if (words[2].StartsWith(Settings.ConstantPrefix))
                            {
                                words[2] = words[2].Substring(Settings.ConstantPrefix.Length);
                            }

                            // If the remaining string starts with a digit, we were wrong above.
                            // Re-add the "GL_"
                            if (Char.IsDigit(words[2][0]))
                            {
                                words[2] = Settings.ConstantPrefix + words[2];
                            }

                            c.Name      = words[2];
                            c.Reference = words[1];
                            c.Value     = words[2];
                        }
                        else
                        {
                            // Typical cause is hand-editing the specs and forgetting to add an '=' sign.
                            throw new InvalidOperationException(String.Format(
                                                                    "[Error] Invalid constant definition: \"{0}\"", line));
                        }

                        //if (!String.IsNullOrEmpty(c.Name) && !e.Members.Contains.Contains(c))
                        //SpecTranslator.Merge(e.Members, c);
                        if (!e.ConstantCollection.ContainsKey(c.Name))
                        {
                            e.ConstantCollection.Add(c.Name, c);
                        }
                        else
                        {
                            Trace.WriteLine(String.Format(
                                                "Spec error: Constant {0} defined twice in enum {1}, discarding last definition.",
                                                c.Name, e.Name));
                        }

                        // Insert the current constant in the list of all constants.
                        //SpecTranslator.Merge(complete_enum.Members, c);
                        complete_enum = Utilities.Merge(complete_enum, c);
                    }while (!specFile.EndOfStream);

                    // At this point, the complete value list for the current enumerant has been read, so add this
                    // enumerant to the list.
                    //e.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "public enum " + e.Name));
                    //e.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, "public enum " + e.Name));

                    // (disabled) Hack - discard Boolean enum, it breaks up the fragile translation code ahead.
                    //if (!e.Name.Contains("Bool"))
                    //Utilities.Merge(enums, e);

                    //e.Translate();

                    if (!enums.ContainsKey(e.Name))
                    {
                        enums.Add(e.Name, e);
                    }
                    else
                    {
                        // The enum already exists, merge constants.
                        foreach (Constant t in e.ConstantCollection.Values)
                        {
                            Utilities.Merge(enums[e.Name], t);
                        }
                    }
                }
            }while (!specFile.EndOfStream);

            enums.Add(complete_enum.Name, complete_enum);

            Trace.Unindent();

            return(enums);
        }
예제 #14
0
 public void Write(Enum e)
 {
     foreach (string s in splitLines.Split(e.ToString()))
         WriteLine(s.TrimEnd('\r', '\n'));
 }
예제 #15
0
 /// <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(EnumCollection enums, Enum t)
 {
     if (!enums.ContainsKey(t.Name))
     {
         enums.Add(t.Name, t);
     }
     else
     {
         Enum e = enums[t.Name];
         foreach (Constant c in t.ConstantCollection.Values)
         {
             Merge(e, c);
         }
     }
 }
예제 #16
0
        /// <summary>
        /// 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)
        /// </summary>
        /// <param name="s"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        internal static Enum Merge(Enum s, Constant t)
        {
            if (!s.ConstantCollection.ContainsKey(t.Name))
            {
                s.ConstantCollection.Add(t.Name, t);
            }
            else
            {
                // Tried to add a constant that already exists. If one constant
                // is like: 'Foo = 0x5' and the other like: 'Foo = Bar.Foo', then 
                // keep the first one.
                if (!String.IsNullOrEmpty(s.ConstantCollection[t.Name].Reference))
                {
                    s.ConstantCollection[t.Name] = t;
                }
            }

            return s;
        }
예제 #17
0
        public virtual EnumCollection ReadEnums(StreamReader specFile)
        {
            Trace.WriteLine("Reading opengl enumerant specs.");
            Trace.Indent();

            EnumCollection enums = new EnumCollection();

            // complete_enum contains all opengl enumerants.
            Bind.Structures.Enum complete_enum = new Bind.Structures.Enum();
            complete_enum.Name = Settings.CompleteEnumName;

            do
            {
                string line = NextValidLine(specFile);
                if (String.IsNullOrEmpty(line))
                {
                    break;
                }

                line = line.Replace('\t', ' ');

                // We just encountered the start of a new enumerant:
                while (!String.IsNullOrEmpty(line) && line.Contains("enum"))
                {
                    string[] words = line.Split(Utilities.Separators, StringSplitOptions.RemoveEmptyEntries);
                    if (words.Length == 0)
                    {
                        continue;
                    }

                    // Declare a new enumerant
                    Bind.Structures.Enum e = new Bind.Structures.Enum();
                    e.Name = Char.IsDigit(words[0][0]) ? Settings.ConstantPrefix + words[0] : words[0];

                    // And fill in the values for this enumerant
                    do
                    {
                        line = NextValidLine(specFile);

                        if (String.IsNullOrEmpty(line) || line.StartsWith("#"))
                        {
                            continue;
                        }

                        if (line.Contains("enum:") || specFile.EndOfStream)
                        {
                            break;
                        }

                        line  = line.Replace('\t', ' ');
                        words = line.Split(Utilities.Separators, StringSplitOptions.RemoveEmptyEntries);

                        if (words.Length == 0)
                        {
                            continue;
                        }

                        // If we reach this point, we have found a new value for the current enumerant
                        Constant c = new Constant();
                        if (line.Contains("="))
                        {
                            // Trim the name's prefix, but only if not in Tao compat mode.
                            if (Settings.Compatibility == Settings.Legacy.Tao)
                            {
                            }
                            else
                            {
                                if (words[0].StartsWith(Settings.ConstantPrefix))
                                {
                                    words[0] = words[0].Substring(Settings.ConstantPrefix.Length);
                                }

                                if (Char.IsDigit(words[0][0]))
                                {
                                    words[0] = Settings.ConstantPrefix + words[0];
                                }
                            }

                            c.Name = words[0];

                            uint number;
                            if (UInt32.TryParse(words[2].Replace("0x", String.Empty), System.Globalization.NumberStyles.AllowHexSpecifier, null, out number))
                            {
                                // The value is a number, check if it should be unchecked.
                                if (number > 0x7FFFFFFF)
                                {
                                    c.Unchecked = true;
                                }
                            }
                            else
                            {
                                // The value is not a number. Strip the prefix.
                                if (words[2].StartsWith(Settings.ConstantPrefix))
                                {
                                    words[2] = words[2].Substring(Settings.ConstantPrefix.Length);
                                }

                                // If the name now starts with a digit (doesn't matter whether we
                                // stripped "GL_" above), add a "GL_" prefix.
                                // (e.g. GL_4_BYTES).
                                if (Char.IsDigit(words[2][0]))
                                {
                                    words[2] = Settings.ConstantPrefix + words[2];
                                }
                            }

                            c.Value = words[2];
                        }
                        else if (words[0] == "use")
                        {
                            // Trim the prefix.
                            if (words[2].StartsWith(Settings.ConstantPrefix))
                            {
                                words[2] = words[2].Substring(Settings.ConstantPrefix.Length);
                            }

                            // If the remaining string starts with a digit, we were wrong above.
                            // Re-add the "GL_"
                            if (Char.IsDigit(words[2][0]))
                            {
                                words[2] = Settings.ConstantPrefix + words[2];
                            }

                            c.Name      = words[2];
                            c.Reference = words[1];
                            c.Value     = words[2];
                        }

                        //if (!String.IsNullOrEmpty(c.Name) && !e.Members.Contains.Contains(c))
                        //SpecTranslator.Merge(e.Members, c);
                        if (!e.ConstantCollection.ContainsKey(c.Name))
                        {
                            e.ConstantCollection.Add(c.Name, c);
                        }
                        else
                        {
                            Trace.WriteLine(String.Format(
                                                "Spec error: Constant {0} defined twice in enum {1}, discarding last definition.",
                                                c.Name, e.Name));
                        }

                        // Insert the current constant in the list of all constants.
                        //SpecTranslator.Merge(complete_enum.Members, c);
                        complete_enum = Utilities.Merge(complete_enum, c);
                    }while (!specFile.EndOfStream);

                    // At this point, the complete value list for the current enumerant has been read, so add this
                    // enumerant to the list.
                    //e.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "public enum " + e.Name));
                    //e.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, "public enum " + e.Name));

                    // (disabled) Hack - discard Boolean enum, it fsucks up the fragile translation code ahead.
                    //if (!e.Name.Contains("Bool"))
                    //Utilities.Merge(enums, e);

                    //e.Translate();

                    if (!enums.ContainsKey(e.Name))
                    {
                        enums.Add(e.Name, e);
                    }
                    else
                    {
                        // The enum already exists, merge constants.
                        Trace.WriteLine(String.Format("Conflict: Enum {0} already exists, merging constants.", e.Name));
                        foreach (Constant t in e.ConstantCollection.Values)
                        {
                            Utilities.Merge(enums[e.Name], t);
                        }
                    }

                    //enums.Add(e);
                }
                //SpecTranslator.Merge(enums, complete_enum);
            }while (!specFile.EndOfStream);

            enums.Add(complete_enum.Name, complete_enum);

            Trace.Unindent();

            return(enums);
        }