-
Notifications
You must be signed in to change notification settings - Fork 0
/
Program.cs
162 lines (145 loc) · 6.21 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
using System;
using System.Threading.Tasks;
using CommandLine;
using System.IO;
using System.Net.Http;
namespace GLThreadGen
{
public class CommandLineOptions
{
public const string KhronosXMLURL = "https://raw.githubusercontent.com/KhronosGroup/OpenGL-Registry/master/xml/gl.xml";
[Option("noxml", HelpText = "Indicates that XML should not be used. If this is set, no enums will be generated and the command buffer API will use standard GLenums.")]
public bool NoXML { get; set; }
[Option("inputxml", HelpText = "Input XML file to read. Used to generate type-safe bindings for command buffers. If this is not provided and the --noxml flag is not set, the XML will be downloaded from GitHub.")]
public string XMLInputFile { get; set; }
[Option('i', "input", Required = true, HelpText = "Input file to read. Must be either a header file generated by GLAD.")]
public string InputFile { get; set; }
[Option('o', "outdir", Default = "generated", HelpText = "Root directory for generated code")]
public string OutDir { get; set; }
}
class Program
{
static void Main(string[] args)
{
CommandLineOptions options = null;
var res = Parser.Default.ParseArguments<CommandLineOptions>(args).WithParsed<CommandLineOptions>(
opts =>
{
options = opts;
}
).WithNotParsed(
errors =>
{
foreach (var v in errors)
{
if (v.Tag == ErrorType.HelpRequestedError)
{
return;
}
}
Console.Error.WriteLine("Failed to parse command line");
foreach (var v in errors)
{
Console.Error.WriteLine(v);
}
}
);
if (options == null) { return; }
if (!File.Exists(options.InputFile))
{
Console.Error.WriteLine($"Input file \"{options.InputFile}\" does not exist.");
return;
}
if (!Directory.Exists(options.OutDir))
{
try
{
Directory.CreateDirectory(options.OutDir);
Console.WriteLine("Created output directory");
}
catch(Exception ex)
{
Console.Error.WriteLine($"Failed to create output directory: {ex.Message}");
}
}
OpenGL_XML_Specification.Registry xmlRegistry = null;
GLDataRegistry registry = new GLDataRegistry();
var tracker = new CodegenOverrideTracker(registry);
// Read step
{
if (options.InputFile.EndsWith(".h"))
{
Console.WriteLine("Parsing GLAD header from disk...");
using (var inStream = new FileStream(options.InputFile, FileMode.Open, FileAccess.Read))
{
var parser = new GLADHeaderParser(inStream, registry);
parser.Parse();
}
}
else
{
Console.Error.WriteLine($"Input file must be either a Khronos XML document or a header generated by GLAD");
return;
}
if (!options.NoXML)
{
if (options.XMLInputFile != null)
{
if (File.Exists(options.XMLInputFile))
{
Console.WriteLine("Reading Khronos XML from disk...");
using (var inStream = new FileStream(options.XMLInputFile, FileMode.Open, FileAccess.Read))
{
Console.WriteLine($"Parsing XML...");
var parser = new KhronosXMLParser(inStream, registry);
parser.Parse();
xmlRegistry = parser.XMLRegistry;
}
}
else
{
Console.Error.WriteLine("Input XML file does not exist. Remove the --inputxml flag to fetch from GitHub or add --noxml to remove type safety.");
return;
}
}
using (var client = new HttpClient())
{
Console.WriteLine($"Downloading {CommandLineOptions.KhronosXMLURL}...");
Stream stream = null;
Task.Run(async ()=>
{
stream = await client.GetStreamAsync(CommandLineOptions.KhronosXMLURL);
}).Wait();
using (stream)
{
Console.WriteLine($"Parsing XML...");
var parser = new KhronosXMLParser(stream, registry);
parser.Parse();
xmlRegistry = parser.XMLRegistry;
}
}
}
}
// Post process
Console.WriteLine($"Read {registry.Functions.Count} functions, post processing...");
tracker.Initialize(xmlRegistry);
foreach (var func in registry.Functions.Values)
{
var list = tracker.GetOverrideList(func.Name);
if (list != null)
{
foreach (var ovr in list)
{
ovr.ModifyFunctionEntry?.Invoke(func);
}
}
}
// Write step
Console.WriteLine("Generating code...");
var generator = new CodeGenerator(options.OutDir, registry, tracker);
generator.Generate();
//generator.OpenDirectory();
Console.WriteLine("Done");
}
}
}