Occurs if there's a duplicate argument
Occurs when an argument does not validate
Occurs when an argument is incorrectly formatted
Occurs when a program argument is missing
Thrown when an error occurs in parsing
The duplication policy can be passed to a ProgramOptions Option.duplicatePolicy
You can configure a ProgramOptions object with a number of Options and then use it to parse and array of command line arguments.
Represents one program options. One of more of these can be given to a ProgramOptions object as template arguments.
1 import std.file: thisExePath; 2 import std.process: environment; 3 4 environment["OPT_4"] = "22"; 5 6 auto args = [ 7 thisExePath, // Program name should be ignored 8 "program_name", // Unknown argument, there's a handler for stray arguments 9 "--opt1", "value1", // "--arg value" format 10 "-b", "1", // "-a 1" format, case sensitive short name by default 11 "--Opt3=2", // "--arg=value" format, case insesitive long name by default 12 // "--opt4", // Set by an envaronment variable 13 "--OPT5", "4", // first value of an int array 14 "--opt5", "5", // second value of an int array 15 // "--opt6", // Not set, will be give default value of int array 16 "--opt7", "9", // Also an array 17 "--unknown", "ha", // Unknown option and value 18 "--opt8=two", // An enum vaue 19 "-i", "-j", "--incremental", "--opt9", // Option aliasing 20 "--opt10", "11", // A validated, must be greater than 10 21 "--opt11", "3,4,5", // Array format "--arg=v0,v1,v2" 22 "--opt12", "1=2::3=4::5=6", // Associative array with custom seperator (Default is ",") 23 "--opt13", "verbose", // A custom parsed value - opt13 is an int 24 "-xyz=-7", // Setting multiple, bundleable options at once 25 "--opt1", "value2", // Uses duplication policy to be ignored 26 "--opt14", "1,2", // Parses to a Custom type 27 "--opt15", // Boolean, no value 28 "--", // Args after this are ignored 29 "extra", 30 ]; 31 32 enum Enum { one, two, } 33 static struct Custom { 34 int x; 35 int y; 36 this(int a, int b) { 37 x = a; 38 y = b; 39 } 40 this(string str) { 41 import std.string: split; 42 import std.conv: to; 43 auto parts = str.split(","); 44 x = parts[0].to!int; 45 y = parts[1].to!int; 46 } 47 } 48 49 auto options = ProgramOptions!( 50 Option!("opt1", string) 51 .shortName!"a" 52 .description!"This is the description for option 1" 53 .duplicatePolicy!(OptionDuplicatePolicy.firstOneWins), 54 Option!("opt2", int) 55 .shortName!"b" 56 .description!"This is the description for option 2", 57 Option!("opt3", int) 58 .shortName!"B" 59 .description!( 60 `There are three kinds of comments: 61 1. Something rather sinister 62 2. And something else that's not so sinister` 63 ), 64 Option!("opt4", int) 65 .defaultValue!3 66 .environmentVar!"OPT_4" 67 .description!"THis is one that takes an env var", 68 Option!("opt5", int[]) 69 .environmentVar!"OPT_5" 70 .description!"THis is one that takes an env var as well", 71 Option!("opt6", int[]) 72 .defaultValue!([6, 7, 8]), 73 Option!("opt7", float[]) 74 .defaultValue!([1, 2]), 75 Option!("opt8", Enum), 76 Option!("opt9", int) 77 .shortName!"i|j" 78 .longName!"incremental|opt9" 79 .incremental!true 80 .description!"sets some level incremental thingy", 81 Option!("opt10", int) 82 .validator!(a => a > 10), 83 Option!("opt11", int[]), 84 Option!("opt12", int[int]) 85 .separator!"::", 86 Option!("opt13", int) 87 .parser!((value) { 88 if (value == "verbose") return 7; 89 return -1; 90 }), 91 Option!("b0", int) 92 .shortName!"x", 93 Option!("b1", int) 94 .shortName!"y", 95 Option!("b2", int) 96 .shortName!"z", 97 Option!("opt14", Custom), 98 Option!("opt15", bool), 99 Option!("opt16", bool) 100 .longName!"" 101 .environmentVar!"OPT_16" 102 .description!"THis one only takes and envornment variable and cant be set with any flags", 103 )(); 104 105 string[] unknownArgs; 106 options.unknownArgHandler = (string name) { 107 unknownArgs ~= name; 108 return false; 109 }; 110 111 assert(options.parse(args) == ["extra"]); 112 assert(unknownArgs == ["program_name", "--unknown", "ha"]); 113 114 assert(options.opt1 == "value1"); 115 assert(options.opt2 == 1); 116 assert(options.opt3 == 2); 117 assert(options.opt4 == 22); 118 assert(options.opt5 == [4, 5]); 119 assert(options.opt6 == [6, 7, 8]); 120 assert(options.opt7 == [9]); 121 assert(options.opt8 == Enum.two); 122 assert(options.opt9 == 4); 123 assert(options.opt10 > 10); 124 assert(options.opt11 == [3, 4, 5]); 125 assert(options.opt12 == [1: 2, 3: 4, 5: 6]); 126 assert(options.opt13 == 7); 127 assert(options.b0 == -7); 128 assert(options.b1 == -7); 129 assert(options.b2 == -7); 130 assert(options.opt14 == Custom(1, 2)); 131 assert(options.opt15 == true); 132 133 assert(options.helpText == 134 `Options: 135 -a --opt1 This is the description for option 1 136 -b --opt2 This is the description for option 2 137 -B --opt3 There are three kinds of comments: 138 1. Something rather sinister 139 2. And something else that's not so sinister 140 --opt4 THis is one that takes an env var 141 --opt5 THis is one that takes an env var as well 142 --opt6 143 --opt7 144 --opt8 145 -i --incremental sets some level incremental thingy 146 --opt10 147 --opt11 148 --opt12 149 --opt13 150 -x --b0 151 -y --b1 152 -z --b2 153 --opt14 154 --opt15 155 156 Environment Vars: 157 OPT_4 See: --opt4 158 OPT_5 See: --opt5 159 OPT_16 THis one only takes and envornment variable and cant be set with any flags` 160 );
Handles program options which are arguments passed with a leading - or -- and followed by a value
Features:
<li> Input validation <li> Customize seperators for associative array args <li> Supports environment variables <li> Supports default values <li> Supports custom types that have a constructor that is called with a string <li> You can supply custom types and they will be called with a string that you can parse
Enhancements_over_std.getopt:
<li> getopt(args) is destructive on args. <li> You cannot create your getopts and the parse later, which in combination with try/catch leads to awkward code <li> getopt doesn't accept $ ./program -p 3. For short opts, you have to do $ ./program -p3. <li> getopt doesn't allow case-sensitive short name and a case-insensitive long name <li> getopt will initialize an array type with the default values AND what the program arg was. <li> You cannot assign values to bundled short args, they are only incrementable <li> There is no way to handle what happens with duplicate arguments