1 /** Extensions to getopt
2 	License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
3 	TODO: Merge with getoptx.d
4 */
5 module nxt.getopt_ex;
6 
7 import std.stdio;
8 public import std.getopt;
9 
10 // private import std.contracts;
11 private import std.meta : AliasSeq;
12 private import std.conv;
13 
14 bool getoptEx(T...)(string helphdr, ref string[] args, T opts)
15 {
16 	assert(args.length,
17 			"Invalid arguments string passed: program name missing");
18 
19 	string helpMsg = getoptHelp(opts); // extract all help strings
20 	bool helpPrinted = false; // state tells if called with "--help"
21 	void printHelp()
22 	{
23 		writeln("\n", helphdr, "\n", helpMsg,
24 				"--help", "\n\tproduce help message");
25 		helpPrinted = true;
26 	}
27 
28 	getopt(args, GetoptEx!(opts), "help", &printHelp);
29 
30 	return helpPrinted;
31 }
32 
33 private template GetoptEx(TList...)
34 {
35 	static if (TList.length)
36 	{
37 		static if (is(typeof(TList[0]) : config))
38 			// it's a configuration flag, lets move on
39 			alias AliasSeq!(TList[0],
40 							GetoptEx!(TList[1 .. $])) GetoptEx;
41 		else
42 			// it's an option string, eat help string
43 			alias AliasSeq!(TList[0],
44 							TList[2],
45 							GetoptEx!(TList[3 .. $])) GetoptEx;
46 	}
47 	else
48 		alias TList GetoptEx;
49 }
50 
51 private string getoptHelp(T...)(T opts)
52 {
53 	static if (opts.length)
54 	{
55 		static if (is(typeof(opts[0]) : config))
56 			// it's a configuration flag, skip it
57 			return getoptHelp(opts[1 .. $]);
58 		else
59 		{
60 			// it's an option string
61 			string option  = to!(string)(opts[0]);
62 			string help	= to!(string)(opts[1]);
63 			return("--" ~ option ~ "\n" ~ help ~ "\n" ~ getoptHelp(opts[3 .. $]));
64 		}
65 	}
66 	else
67 		return to!(string)("\n");
68 }