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