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 }