Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1452 chris 1
//
2
// Copyright (C) 2009 the Open Toolkit (http://www.opentk.com)
3
//
4
// Permission is hereby granted, free of charge, to any person obtaining
5
// a copy of this software and associated documentation files (the
6
// "Software"), to deal in the Software without restriction, including
7
// without limitation the rights to use, copy, modify, merge, publish,
8
// distribute, sublicense, and/or sell copies of the Software, and to
9
// permit persons to whom the Software is furnished to do so, subject to
10
// the following conditions:
11
// 
12
// The above copyright notice and this permission notice shall be
13
// included in all copies or substantial portions of the Software.
14
// 
15
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
//
23
 
24
using System;
25
using System.Collections.Generic;
26
using System.Diagnostics;
27
using System.IO;
28
using System.Linq;
29
using System.Xml;
30
using System.Xml.Linq;
31
using Mono.Options;
32
 
33
namespace CHeaderToXML
34
{
35
    class EnumTokenComparer : IEqualityComparer<XNode>
36
    {
37
        public bool Equals (XNode a, XNode b)
38
        {
39
            return ((XElement) a).Attribute("name").Equals(((XElement) b).Attribute("name"));
40
        }
41
 
42
        public int GetHashCode (XNode a)
43
        {
44
            return ((XElement) a).Attribute("name").GetHashCode();
45
        }
46
    }
47
 
48
    class EntryPoint
49
    {
50
        static void Main(string[] args)
51
        {
52
            try
53
            {
54
                bool showHelp = false;
55
                string prefix = "gl";
56
                string version = null;
57
                OptionSet opts = new OptionSet {
58
                { "p=", "The {PREFIX} to remove from parsed functions and constants.  " +
59
                    "Defaults to \"" + prefix + "\".",
60
                    v => prefix = v },
61
                { "v=", "The {VERSION} of the headers being parsed.",
62
                    v => version = v },
63
                { "?|h|help", "Show this message and exit.",
64
                    v => showHelp = v != null },
65
            };
66
                var headers = opts.Parse(args);
67
                var app = Path.GetFileName(Environment.GetCommandLineArgs()[0]);
68
                if (showHelp)
69
                {
70
                    Console.WriteLine("usage: {0} -p:PREFIX -v:VERSION HEADERS", app);
71
                    Console.WriteLine();
72
                    Console.WriteLine("Options:");
73
                    opts.WriteOptionDescriptions(Console.Out);
74
                    Console.WriteLine();
75
                    Console.WriteLine("HEADERS are the header files to parse into XML.");
76
                    return;
77
                }
78
                if (version == null)
79
                {
80
                    Console.WriteLine("{0}: missing required parameter -p.", app);
81
                    Console.WriteLine("Use '{0} --help' for usage.", app);
82
                    return;
83
                }
84
                var sigs = headers.Select(h => new ESCLParser
85
                {
86
                    Prefix = prefix,
87
                    Version = version
88
                }.Parse(h));
89
 
90
                // Merge any duplicate enum entries (in case an enum is declared
91
                // in multiple files with different entries in each file).
92
                var entries = new Dictionary<string, XElement>();
93
                foreach (var e in sigs.SelectMany(s => s).Where(s => s.Name.LocalName == "enum"))
94
                {
95
                    var name = (string)e.Attribute("name");
96
                    if (entries.ContainsKey(name) && e.Name.LocalName == "enum")
97
                    {
98
                        var p = entries[name];
99
                        var curTokens = p.Nodes().ToList();
100
                        p.RemoveNodes();
101
                        p.Add(curTokens.Concat(e.Nodes()).Distinct(new EnumTokenComparer()));
102
                    }
103
                    else
104
                        entries.Add(name, e);
105
                }
106
 
107
                // sort enum tokens
108
                foreach (var e in entries)
109
                {
110
                    if (e.Value.Name.LocalName != "enum")
111
                        continue;
112
                    var tokens = e.Value.Elements()
113
                        .OrderBy(t => (string)t.Attribute("name"))
114
                        .ToList();
115
                    e.Value.RemoveNodes();
116
                    e.Value.Add(tokens);
117
                }
118
 
119
                var settings = new XmlWriterSettings();
120
                settings.Indent = true;
121
 
122
                using (var writer = XmlWriter.Create(Console.Out, settings))
123
                {
124
                    new XElement("signatures",
125
                        entries.Values.OrderBy(s => s.Attribute("name").Value),  // only enums
126
                        sigs.SelectMany(s => s).Where(s => s.Name.LocalName == "function")    // only functions
127
                             .OrderBy(s => s.Attribute("extension").Value)
128
                             .ThenBy(s => s.Attribute("name").Value)
129
                    ).WriteTo(writer);
130
                    writer.Flush();
131
                    writer.Close();
132
                }
133
            }
134
            finally
135
            {
136
                Console.WriteLine();
137
                if (Debugger.IsAttached)
138
                {
139
                    Console.WriteLine("Press any key to continue...");
140
                    Console.ReadKey(true);
141
                }
142
            }
143
        }
144
    }
145
}