1 //Argument parsing and other mess
2 module util.argparse;
3 import util.inform;
4 import util.config;
5 import util.statman;
6 import std.stdio;
7 import std.getopt;
8 import std.file;
9 import std.algorithm;
10 
11 ///Ugly argument parsing, no attempt at abstraction
12 int argParse(string[] args)
13 {
14 	StatManager* result;
15 	//Skip exe location
16 	size_t stat = 1;
17 	string curTok(size_t tmp = stat)
18 	in(stat <= args.length, "Index out of bounds, no more arguments")
19 	{
20 		return args[tmp];
21 	}
22 
23 	bool accept(string tmp)
24 	{
25 
26 		if (stat == args.length)
27 			return false;
28 		if (args[stat] == tmp)
29 		{
30 			++stat;
31 			return true;
32 		}
33 		else
34 		{
35 			return false;
36 		}
37 	}
38 	//Config to use
39 	string configName = "";
40 	string spitItOut;
41 	bool useJson;
42 
43 	auto optResult = getopt(args, config.passThrough, "j|json", &useJson,
44 			"c|config", &configName, "o|output", &spitItOut);
45 
46 	//This pattern can be made into a uda at some point but the interface isn't fixed yet
47 
48 	//Counter doesn't need a config file
49 	if (accept("counter"))
50 	{
51 		import commands.featurecount : command;
52 
53 		try
54 		{
55 			result = command(args);
56 
57 		}
58 		catch (Exception e)
59 		{
60 			inform(e.msg);
61 		}
62 
63 	}
64 
65 	//Everything needing config file goes past here
66 	if (!exists("bq.json"))
67 		alert("No config file found");
68 
69 	const config = loadConfig("bq.json");
70 	while (configName == "")
71 	{
72 		import std..string : strip;
73 
74 		writeln("Specify a configuration name");
75 		configName = readln().strip;
76 
77 	}
78 
79 	//Print some information about the loaded configurations
80 	{
81 		writef!"%d Configurations loaded\n"(config.rawBuilds.length);
82 		config.rawBuilds
83 			.map!(x => x.name)
84 			.each!(x => writef!"* %s\n"(x));
85 
86 	}
87 	const build = config.getBuildByString(configName);
88 
89 	if (accept("outwatch"))
90 	{
91 		import commands.outwatch : command;
92 
93 		try
94 		{
95 			return command(build);
96 		}
97 		catch (Exception e)
98 		{
99 			("outwatch exception thrown: " ~ e.msg).alert;
100 		}
101 	}
102 
103 	if (accept("build"))
104 	{
105 		import commands.justbuild : command;
106 
107 		result = command(build, args);
108 
109 	}
110 
111 	if (accept("memory"))
112 	{
113 		import commands.memory : command;
114 
115 		result = command(build, args);
116 	}
117 	if (result)
118 	{
119 		if (useJson)
120 		{
121 			result.getJSON.toPrettyString.writeln;
122 			return 0;
123 		}
124 		else
125 		{
126 			result.prettyString.writeln;
127 			return 0;
128 		}
129 
130 		if (spitItOut != "")
131 		{
132 			if (exists(spitItOut))
133 			{
134 				alert("Output file already exists");
135 			}
136 			else
137 			{
138 				import util.colour;
139 
140 				auto g = File(spitItOut, "w");
141 				toggleColour;
142 				scope (exit)
143 					toggleColour;
144 				g.write(result.prettyString);
145 			}
146 		}
147 	}
148 	alert("No valid command given!");
149 	return 1;
150 }