1 // Copyright © 2017-2021 Rémi Thebault
2 /++
3  +  Wayland scanner for D.
4  +  Scan wayland XML protocol and generates client or server code for that protocol.
5  +/
6 module wayland.scanner;
7 
8 import wayland.scanner.common;
9 import wayland.scanner.client;
10 import wayland.scanner.server;
11 
12 import arsd.dom;
13 
14 import std.array;
15 import std.getopt;
16 import std.stdio;
17 
18 enum scannerVersion = "v0.3.1";
19 enum usageIntro = "wayland:scanner-"~scannerVersion~"\n"~
20                   "  A Wayland protocol scanner and D code generator.\n\n";
21 enum bindingsCopyright = "Copyright © 2017-2019 Rémi Thebault";
22 
23 
24 int main(string[] args)
25 {
26     auto opt = new Options;
27     opt.cmdLine = args.join(" ");
28     auto optHandler = getopt (
29         args,
30         "code|c",   "generated code: client|server [client]", &opt.code,
31         "input|i",  "input file [stdin]", &opt.inFile,
32         "output|o", "output file [stdout]", &opt.outFile,
33         "module|m", "D module name (required)", &opt.moduleName,
34     );
35 
36     if (optHandler.helpWanted)
37     {
38         defaultGetoptFormatter (
39             stdout.lockingTextWriter,
40             usageIntro ~ "Options:",
41             optHandler.options
42         );
43         return 0;
44     }
45 
46     if (opt.moduleName.empty)
47     {
48         defaultGetoptFormatter (
49             stderr.lockingTextWriter,
50             usageIntro ~
51             "Error: D module name must be supplied with '--module' or '-m'\n\n" ~
52             "Options:",
53             optHandler.options
54         );
55         return 1;
56     }
57 
58     try
59     {
60         File input = (opt.inFile.empty) ? stdin : File(opt.inFile, "r");
61         File output = (opt.outFile.empty) ? stdout : File(opt.outFile, "w");
62 
63         string xmlStr;
64         foreach (string l; lines(input))
65         {
66             xmlStr ~= l;
67         }
68         auto xmlDoc = new Document;
69         xmlDoc.parse(xmlStr, true, true);
70 
71         if (opt.code == GenCode.client)
72             fact = new ClientFactory;
73         else
74             fact = new ServerFactory;
75 
76         auto p = fact.makeProtocol(xmlDoc.root);
77         p.writeCode(new SourceFile(output), opt);
78     }
79     catch(Exception ex)
80     {
81         stderr.writeln("Error: "~ex.msg);
82         return 1;
83     }
84 
85     return 0;
86 }
87 
88 enum GenCode
89 {
90     client,
91     server,
92 }
93 
94 class Options
95 {
96     string cmdLine;
97 
98     string inFile;
99     string outFile;
100     string moduleName;
101 
102     GenCode code;
103 }