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 }