Changeset 99

Show
Ignore:
Timestamp:
02/08/07 01:01:54 (2 years ago)
Author:
KirkMcDonald
Message:

This update breaks existing code.
* Merged Phobos and Tango versions of optparse into a single module.
* Changed naming conventions to that used in the Tango version.
* Updated docs to reflect these changes.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • misc/optparse.d

    r93 r99  
    2222/** 
    2323 * Command-line option parsing, in the style of Python's optparse. 
     24 * 
     25 * Refer to the complete docs for more information. 
    2426 */ 
    2527module optparse; 
    2628 
    27 import std.stdio : writefln, writef; 
    28 import std.string : find, toupper, toString; 
    29 import std.c.stdlib : exit, EXIT_FAILURE, EXIT_SUCCESS; 
    30 import std.conv : toInt, ConvError; 
    31 import std.path : getBaseName; 
    32 import std.utf : toUTF8, toUTF32; 
     29version (Tango) { 
     30    import tango.io.Stdout : Stdout; 
     31    import tango.text.Util : find = locate, locatePrior; 
     32    import tango.text.Ascii : toupper = toUpper; 
     33    import tango.stdc.stdlib : exit, EXIT_FAILURE, EXIT_SUCCESS; 
     34    import tango.text.convert.Integer : parse, toInt, toString = toUtf8; 
     35    import tango.text.convert.Utf : toUTF8 = toUtf8, toUTF32 = toUtf32; 
     36    int getNotFound(char[] s) { 
     37        return s.length; 
     38    } 
     39} else { 
     40    import std.stdio : writefln, writef; 
     41    import std.string : find, toupper, toString; 
     42    import std.c.stdlib : exit, EXIT_FAILURE, EXIT_SUCCESS; 
     43    import std.conv : toInt, ConvError; 
     44    import std.path : getBaseName; 
     45    import std.utf : toUTF8, toUTF32; 
     46    int getNotFound(char[] s) { 
     47        return -1; 
     48    } 
     49
    3350 
    3451/* 
     
    7491} 
    7592 
    76 // Thrown if client code tries to set up an improper option. 
     93/// Thrown if client code tries to set up an improper option. 
    7794class OptionError : Exception { 
    7895    this(char[] msg) { super(msg); } 
     
    83100} 
    84101 
     102/++ 
     103This class represents the results after parsing the command-line. 
     104+/ 
    85105class Options { 
    86106    char[][][char[]] opts; 
    87107    int[char[]] counted_opts; 
     108    /// By default, leftover arguments are placed in this array. 
    88109    char[][] args; 
    89110 
     111    /// Retrieves the results of the Store and StoreConst actions. 
    90112    char[] opIndex(char[] opt) { 
    91113        char[][]* o = opt in opts; 
     
    96118        } 
    97119    } 
     120    /// Retrieves the results of the Store action, when the type is Integer. 
    98121    int value(char[] opt) { 
    99122        char[][]* o = opt in opts; 
     
    104127        } 
    105128    } 
     129    /// Retrieves the results of the Append and AppendConst actions. 
    106130    char[][] list(char[] opt) { 
    107131        char[][]* o = opt in opts; 
     
    112136        } 
    113137    } 
    114     int[] value_list(char[] opt) { 
     138    /// Retrieves the results of the Append action, when the type is Integer. 
     139    int[] valueList(char[] opt) { 
    115140        char[][]* o = opt in opts; 
    116141        int[] l; 
     
    123148        return l; 
    124149    } 
     150    /// Retrieves the results of the Count action. 
    125151    int count(char[] opt) { 
    126152        int* c = opt in counted_opts; 
     
    131157        } 
    132158    } 
     159    /// Retrieves the results of the SetTrue and SetFalse actions. 
    133160    bool flag(char[] opt) { 
    134161        char[][]* o = opt in opts; 
     
    142169 
    143170// Options, args, this opt's index in args, name[, arg] 
     171/// 
    144172alias void delegate(Options, inout char[][], inout int, char[], char[]) OptionCallbackFancyArg; 
     173/// 
    145174alias void delegate(Options, inout char[][], inout int, char[], int)    OptionCallbackFancyInt; 
     175/// 
    146176alias void delegate(Options, inout char[][], inout int, char[])         OptionCallbackFancy; 
    147177 
     178/// 
    148179alias void delegate(char[]) OptionCallbackArg; 
     180/// 
    149181alias void delegate(int)    OptionCallbackInt; 
     182/// 
    150183alias void delegate()       OptionCallback; 
    151184 
     
    160193 * CallbackVoid: dg 
    161194*/ 
    162 enum Action { Store, StoreConst, Append, AppendConst, Count, SetTrue, SetFalse, Callback, CallbackFancy, Help } 
    163 enum ArgType { None, String, Integer } 
     195/// 
     196enum Action { /+++/Store, /+++/StoreConst, /+++/Append, /+++/AppendConst, /+++/Count, /+++/SetTrue, /+++/SetFalse, /+++/Callback, /+++/CallbackFancy, /+++/Help /+++/} 
     197/// 
     198enum ArgType { /+++/None, /+++/String, /+++/Integer /+++/} 
    164199 
    165200ArgType defaultType(Action action) { 
     
    174209} 
    175210 
     211/++ 
     212This class represents a single command-line option. 
     213+/ 
    176214class Option { 
    177215    char[][] shortopts, longopts; 
     
    207245        this.type = type; 
    208246        this.name = name; 
    209         this.argname = toupper(name); 
     247        this.argname = toupper(name.dup); 
    210248        this.default_string = ""; 
    211249        this.default_value = 0; 
     
    268306                result ~= ", "; 
    269307            } else if (this.hasArg()) { 
    270                 result ~= "=" ~ toupper(this.argname); 
     308                result ~= "=" ~ toupper(this.argname.dup); 
    271309            } 
    272310        } 
     
    303341    } 
    304342    // Does whatever this option is supposed to do. 
    305     void perform_action(OptionParser parser, Options results, inout char[][] args, inout int idx, char[] arg) { 
     343    void performAction(OptionParser parser, Options results, inout char[][] args, inout int idx, char[] arg) { 
    306344        int i; 
    307345        if (this.type == ArgType.Integer) { 
     
    361399                break; 
    362400            case Action.Help: 
    363                 parser.help_text(); 
     401                parser.helpText(); 
    364402                exit(EXIT_SUCCESS); 
    365403                break; 
    366404        } 
    367405    } 
     406    /// Returns whether this option accepts an argument. 
    368407    bool hasArg() { 
    369408        return this.type != ArgType.None; 
    370409    } 
     410    /// Sets the help text for this option. 
    371411    Option help(char[] help) { 
    372412        this.helptext = help; 
    373413        return this; 
    374414    } 
     415    /// Sets the name of this option's argument, if it has one. 
    375416    Option argName(char[] argname) { 
    376417        this.argname = argname; 
     
    428469} 
    429470 
     471/++ 
     472This class is used to define a set of options, and parse the command-line 
     473arguments. 
     474+/ 
    430475class OptionParser { 
    431476    OptionCallbackArg leftover_cb; 
     477    /// An array of all of the options known by this parser. 
    432478    Option[] options; 
    433     char[] name, desc, argdesc; 
     479    char[] name, desc; 
     480    /// The description of the programs arguments, as used in the Help action. 
     481    char[] argdesc; 
    434482    private void delegate(char[]) error_callback; 
    435483 
     
    440488    } 
    441489 
    442     void set_error_callback(void delegate(char[]) dg) { 
     490    /// Sets a callback, to override the default error behavior. 
     491    void setErrorCallback(void delegate(char[]) dg) { 
    443492        error_callback = dg; 
    444493    } 
    445     void unknown_opt_error(char[] opt) { 
     494    void unknownOptError(char[] opt) { 
    446495        error("Unknown argument '"~opt~"'"); 
    447496    } 
    448     void expected_arg_error(char[] opt) { 
     497    void expectedArgError(char[] opt) { 
    449498        error("'"~opt~"' option expects an argument."); 
    450499    } 
     500    /// Displays an error message and terminates the program. 
    451501    void error(char[] err) { 
    452502        if (error_callback !is null) { 
    453503            error_callback(err); 
    454504        } else { 
    455             this.help_text(); 
    456             writefln(err); 
     505            this.helpText(); 
     506            version (Tango) { 
     507                Stdout.formatln(err); 
     508            } else { 
     509                writefln(err); 
     510            } 
    457511        } 
    458512        exit(EXIT_FAILURE); 
    459513    } 
    460     int toOptInt(char[] s) { 
    461         int i; 
    462         try { 
    463             i = toInt(s); 
    464         } catch (ConvError e) { 
    465             error("Could not convert '"~s~"' to an integer."); 
    466         } 
    467         return i; 
    468     } 
    469  
    470     void help_text() { 
     514    version (Tango) { 
     515        int toOptInt(char[] s) { 
     516            int i; 
     517            uint ate; 
     518            i = .parse(s, 10u, &ate); 
     519            if (ate != s.length) 
     520                error("Could not convert '"~s~"' to an integer."); 
     521            return i; 
     522        } 
     523    } else { 
     524        int toOptInt(char[] s) { 
     525            int i; 
     526            try { 
     527                i = toInt(s); 
     528            } catch (ConvError e) { 
     529                error("Could not convert '"~s~"' to an integer."); 
     530            } 
     531            return i; 
     532        } 
     533    } 
     534 
     535    /// Displays useful "help" information about the program's options. 
     536    void helpText() { 
    471537        int optWidth; 
    472538        char[][] optStrs; 
     
    478544            } 
    479545        } 
    480         writefln("Usage: %s %s", this.name, this.argdesc); 
    481         if (this.desc !is null && this.desc != "") writefln(this.desc); 
    482         writefln("\nOptions:"); 
    483         foreach(i, opt; options) { 
    484             // The commented-out code is a great idea I'll do properly later. 
    485             //if (opt.helptext.length + optWidth + 3 > 80) { 
    486             //    writefln("  %s\n\t%s", optStrs[i], opt.helptext); 
    487             //} else { 
    488             writefln("  %-*s %s", optWidth, optStrs[i], opt.helptext); 
    489             //} 
     546        version (Tango) { 
     547            typedef char spacechar = ' '; 
     548            spacechar[] padding; 
     549            Stdout.formatln("Usage: {0} {1}", this.name, this.argdesc); 
     550            if (this.desc !is null && this.desc != "") Stdout.println(this.desc); 
     551            Stdout.println("\nOptions:"); 
     552            foreach(i, opt; options) { 
     553                padding.length = optWidth - optStrs[i].length; 
     554                Stdout.formatln("  {0}{1} {2}", optStrs[i], cast(char[])padding, opt.helptext); 
     555            } 
     556        } else { 
     557            writefln("Usage: %s %s", this.name, this.argdesc); 
     558            if (this.desc !is null && this.desc != "") writefln(this.desc); 
     559            writefln("\nOptions:"); 
     560            foreach(i, opt; options) { 
     561                // The commented-out code is a great idea I'll do properly later. 
     562                //if (opt.helptext.length + optWidth + 3 > 80) { 
     563                //    writefln("  %s\n\t%s", optStrs[i], opt.helptext); 
     564                //} else { 
     565                writefln("  %-*s %s", optWidth, optStrs[i], opt.helptext); 
     566                //} 
     567            } 
    490568        } 
    491569    } 
     
    501579        return null; 
    502580    } 
    503     char[] get_program_name(char[] path) { 
    504         version(Windows) { 
    505             // (Unicode note: ".exe" only contains 4 code units, so this slice 
    506             // should Just Work.) (Although it remains to be seen how robust 
    507             // this code actually is.) 
    508             assert(path[$-4 .. $] == ".exe"); 
    509             path = path[0 .. $-4]; 
    510         } 
    511         return getBaseName(path); 
    512     } 
    513     Options parse_args(char[][] args) { 
    514         this.name = get_program_name(args[0]); 
     581    version (Tango) { 
     582        char[] getProgramName(char[] path) { 
     583            version(Windows) { 
     584                char delimiter = '\\'; 
     585            } else { 
     586                char delimiter = '/'; 
     587            } 
     588            uint idx = locatePrior(path, delimiter); 
     589            if (idx == path.length) return path; 
     590            return path[idx+1 .. $]; 
     591        } 
     592    } else { 
     593        char[] getProgramName(char[] path) { 
     594            version(Windows) { 
     595                // (Unicode note: ".exe" only contains 4 code units, so this slice 
     596                // should Just Work.) (Although it remains to be seen how robust 
     597                // this code actually is.) 
     598                assert(path[$-4 .. $] == ".exe"); 
     599                path = path[0 .. $-4]; 
     600            } 
     601            return getBaseName(path); 
     602        } 
     603    } 
     604    /// Parses the passed command-line arguments and returns the results. 
     605    Options parse(char[][] args) { 
     606        this.name = getProgramName(args[0]); 
    515607        args = args[1 .. $]; 
    516608        Options options = new Options; 
     
    554646            } else if (opt.startswith("--")) { 
    555647                idx = find(opt, '='); 
    556                 if (idx != -1) { 
     648                if (idx != getNotFound(opt)) { 
    557649                    newopt = opt[0 .. idx]; 
    558650                    // Stitch out the old arg, stitch in the newopt, arg pair. 
     
    565657                match = matches(newopt); 
    566658                if (match is null) { 
    567                     unknown_opt_error(newopt); 
     659                    unknownOptError(newopt); 
    568660                } 
    569661                if (match.hasArg) { 
    570                     if (i == args.length-1) expected_arg_error(match.name); 
     662                    if (i == args.length-1) expectedArgError(match.name); 
    571663                    arg = args[i+1]; 
    572664                    ++i; 
     
    574666                    arg = null; 
    575667                } 
    576                 match.perform_action(this, options, args, i, arg); 
     668                match.performAction(this, options, args, i, arg); 
    577669            } else if (opt.startswith("-")) { 
    578670                if (opt.length >= 2) { 
     
    582674                        match = matches(newopt); 
    583675                        if (match is null) { 
    584                             unknown_opt_error(newopt); 
     676                            unknownOptError(newopt); 
    585677                        } 
    586678                        if (match.hasArg) { 
     
    588680                            // next element of args for the arg. 
    589681                            if (j == opt32.length-1) { 
    590                                 if (i == args.length-1) expected_arg_error(match.name); 
     682                                if (i == args.length-1) expectedArgError(match.name); 
    591683                                arg = args[i+1]; 
    592684                                ++i; 
     
    595687                            } else { 
    596688                                arg = toUTF8(opt32[j+1 .. $]); 
    597                                 match.perform_action(this, options, args, i, arg); 
     689                                match.performAction(this, options, args, i, arg); 
    598690                                break; 
    599691                            } 
     
    601693                            arg = null; 
    602694                        } 
    603                         match.perform_action(this, options, args, i, arg); 
     695                        match.performAction(this, options, args, i, arg); 
    604696                    } 
    605697                } else { 
    606                     unknown_opt_error(opt); 
     698                    unknownOptError(opt); 
    607699                } 
    608700            } else { 
     
    620712    } 
    621713 
    622     void leftover_callback(OptionCallbackArg dg) { 
     714    /++ 
     715    Overrides the default behavior of leftover arguments, calling this callback 
     716    with them instead of adding them an array. 
     717    +/ 
     718    void leftoverCallback(OptionCallbackArg dg) { 
    623719        this.leftover_cb = dg; 
    624720    } 
    625     Option add_option(Option option) { 
     721    /// 
     722    Option addOption(Option option) { 
    626723        this.options ~= option; 
    627724        return option; 
    628725    } 
    629726    //                    options  action             name  type                       const_value  dga   dgv   dgi   fdga  fdgi  fdg 
    630     Option add_option(char[][] options ...) { 
    631         return add_option(options, Action.Store,      null, defaultType(Action.Store), null,        null, null, null, null, null, null); 
    632     } 
    633     Option add_option(char[][] options, char[] name) { 
    634         return add_option(options, Action.Store,      name, defaultType(Action.Store), null,        null, null, null, null, null, null); 
    635     } 
    636     Option add_option(char[][] options, Action action) { 
    637         return add_option(options, action,            null, defaultType(action),       null,        null, null, null, null, null, null); 
    638     } 
    639     Option add_option(char[][] options, ArgType type) { 
    640         return add_option(options, Action.Store,      null, type,                      null,        null, null, null, null, null, null); 
    641     } 
    642     Option add_option(char[][] options, Action action, ArgType type) { 
    643         return add_option(options, action,            null, type,                      null,        null, null, null, null, null, null); 
    644     } 
    645     Option add_option(char[][] options, char[] name, Action action) { 
    646         return add_option(options, action,            name, defaultType(action),       null,        null, null, null, null, null, null); 
    647     } 
    648     Option add_option(char[][] options, char[] name, Action action, ArgType type) { 
    649         return add_option(options, action,            name, type,                      null,        null, null, null, null, null, null); 
    650     } 
    651     Option add_option(char[][] options, Action action, char[] const_value) { 
    652         return add_option(options, action,            null, defaultType(action),       const_value, null, null, null, null, null, null); 
    653     } 
    654     Option add_option(char[][] options, char[] name, char[] const_value) { 
    655         return add_option(options, Action.StoreConst, name, defaultType(Action.Store), const_value, null, null, null, null, null, null); 
    656     } 
    657     Option add_option(char[][] options, char[] name, Action action, char[] const_value) { 
    658         return add_option(options, action,            name, defaultType(action),       const_value, null, null, null, null, null, null); 
    659     } 
    660     Option add_option(char[][] options, OptionCallbackArg dg) { 
    661         return add_option(options, Action.Callback,   null, ArgType.String,            null,        dg,   null, null, null, null, null); 
    662     } 
    663     Option add_option(char[][] options, OptionCallback dg) { 
    664         return add_option(options, Action.Callback,   null, ArgType.None,              null,        null, dg,   null, null, null, null); 
    665     } 
    666     Option add_option(char[][] options, OptionCallbackInt dg) { 
    667         return add_option(options, Action.Callback,   null, ArgType.Integer,           null,        null, null, dg,   null, null, null); 
    668     } 
    669     Option add_option(char[][] options, OptionCallbackFancyArg dg) { 
    670         return add_option(options, Action.CallbackFancy, null, ArgType.String,         null,        null, null, null, dg,   null, null); 
    671     } 
    672     Option add_option(char[][] options, OptionCallbackFancy dg) { 
    673         return add_option(options, Action.CallbackFancy, null, ArgType.None,           null,        null, null, null, null, null, dg); 
    674     } 
    675     Option add_option(char[][] options, OptionCallbackFancyInt dg) { 
    676         return add_option(options, Action.CallbackFancy, null, ArgType.Integer,        null,        null, null, null, null, dg,   null); 
    677     } 
    678     Option add_option(char[][] options, char[] name, OptionCallbackFancyArg dg) { 
    679         return add_option(options, Action.CallbackFancy, name, ArgType.String,         null,        null, null, null, dg,   null, null); 
    680     } 
    681     Option add_option(char[][] options, char[] name, OptionCallbackFancy dg) { 
    682         return add_option(options, Action.CallbackFancy, name, ArgType.None,           null,        null, null, null, null, null, dg); 
    683     } 
    684     Option add_option(char[][] options, char[] name, OptionCallbackFancyInt dg) { 
    685         return add_option(options, Action.CallbackFancy, name, ArgType.Integer,        null,        null, null, null, null, dg,   null); 
     727    /// 
     728    Option addOption(char[][] options ...) { 
     729        return addOption(options, Action.Store,      null, defaultType(Action.Store), null,        null, null, null, null, null, null); 
     730    } 
     731    /// 
     732    Option addOption(char[][] options, char[] name) { 
     733        return addOption(options, Action.Store,      name, defaultType(Action.Store), null,        null, null, null, null, null, null); 
     734    } 
     735    /// 
     736    Option addOption(char[][] options, Action action) { 
     737        return addOption(options, action,            null, defaultType(action),       null,        null, null, null, null, null, null); 
     738    } 
     739    /// 
     740    Option addOption(char[][] options, ArgType type) { 
     741        return addOption(options, Action.Store,      null, type,                      null,        null, null, null, null, null, null); 
     742    } 
     743    /// 
     744    Option addOption(char[][] options, Action action, ArgType type) { 
     745        return addOption(options, action,            null, type,                      null,        null, null, null, null, null, null); 
     746    } 
     747    /// 
     748    Option addOption(char[][] options, char[] name, Action action) { 
     749        return addOption(options, action,            name, defaultType(action),       null,        null, null, null, null, null, null); 
     750    } 
     751    /// 
     752    Option addOption(char[][] options, char[] name, Action action, ArgType type) { 
     753        return addOption(options, action,            name, type,                      null,        null, null, null, null, null, null); 
     754    } 
     755    /// 
     756    Option addOption(char[][] options, Action action, char[] const_value) { 
     757        return addOption(options, action,            null, defaultType(action),       const_value, null, null, null, null, null, null); 
     758    } 
     759    /// 
     760    Option addOption(char[][] options, char[] name, char[] const_value) { 
     761        return addOption(options, Action.StoreConst, name, defaultType(Action.Store), const_value, null, null, null, null, null, null); 
     762    } 
     763    /// 
     764    Option addOption(char[][] options, char[] name, Action action, char[] const_value) { 
     765        return addOption(options, action,            name, defaultType(action),       const_value, null, null, null, null, null, null); 
     766    } 
     767    /// 
     768    Option addOption(char[][] options, OptionCallbackArg dg) { 
     769        return addOption(options, Action.Callback,   null, ArgType.String,            null,        dg,   null, null, null, null, null); 
     770    } 
     771    /// 
     772    Option addOption(char[][] options, OptionCallback dg) { 
     773        return addOption(options, Action.Callback,   null, ArgType.None,              null,        null, dg,   null, null, null, null); 
     774    } 
     775    /// 
     776    Option addOption(char[][] options, OptionCallbackInt dg) { 
     777        return addOption(options, Action.Callback,   null, ArgType.Integer,           null,        null, null, dg,   null, null, null); 
     778    } 
     779    /// 
     780    Option addOption(char[][] options, OptionCallbackFancyArg dg) { 
     781        return addOption(options, Action.CallbackFancy, null, ArgType.String,         null,        null, null, null, dg,   null, null); 
     782    } 
     783    /// 
     784    Option addOption(char[][] options, OptionCallbackFancy dg) { 
     785        return addOption(options, Action.CallbackFancy, null, ArgType.None,           null,        null, null, null, null, null, dg); 
     786    } 
     787    /// 
     788    Option addOption(char[][] options, OptionCallbackFancyInt dg) { 
     789        return addOption(options, Action.CallbackFancy, null, ArgType.Integer,        null,        null, null, null, null, dg,   null); 
     790    } 
     791    /// 
     792    Option addOption(char[][] options, char[] name, OptionCallbackFancyArg dg) { 
     793        return addOption(options, Action.CallbackFancy, name, ArgType.String,         null,        null, null, null, dg,   null, null); 
     794    } 
     795    /// 
     796    Option addOption(char[][] options, char[] name, OptionCallbackFancy dg) { 
     797        return addOption(options, Action.CallbackFancy, name, ArgType.None,           null,        null, null, null, null, null, dg); 
     798    } 
     799    /// 
     800    Option addOption(char[][] options, char[] name, OptionCallbackFancyInt dg) { 
     801        return addOption(options, Action.CallbackFancy, name, ArgType.Integer,        null,        null, null, null, null, dg,   null); 
    686802    } 
    687803    // Although users certainly /can/ call this, all those overloads are there 
    688804    // for a reason. 
    689     Option add_option( 
     805    Option addOption( 
    690806        char[][] options,  
    691807        Action action, char[] name, ArgType type, char[] const_value, 
     
    731847            else 
    732848                throw new OptionError( 
    733                     "No options provided to add_option!" 
     849                    "No options provided to addOption!" 
    734850                ); 
    735851        } 
  • misc/optparse.html

    r93 r99  
    4444<blockquote><tt>OptionParser(char[] desc="")</tt></blockquote> 
    4545 
    46 <p>The <i>desc</i> parameter should be a short description of your program. It is used by the built-in help features, described later. <tt>OptionParser</tt> has a number of methods, the most important of which is <tt>add_option</tt>. The <tt>add_option</tt> method has a large number of overloads, representing the large number of kinds of options that <tt>optparse</tt> supports. Before going over these overloads, it is necessary to go over some of <tt>optparse</tt>'s concepts.</p> 
     46<p>The <i>desc</i> parameter should be a short description of your program. It is used by the built-in help features, described later. <tt>OptionParser</tt> has a number of methods, the most important of which is <tt>addOption</tt>. The <tt>addOption</tt> method has a large number of overloads, representing the large number of kinds of options that <tt>optparse</tt> supports. Before going over these overloads, it is necessary to go over some of <tt>optparse</tt>'s concepts.</p> 
    4747 
    4848<p>First, this documentation makes the distinction between an <i>option</i> and an <i>argument</i>. An <i>option</i> is a literal string supplied by client code, such as "<tt>-f</tt>" or "<tt>--file</tt>". An <i>argument</i> is supplied by the end-user on the command-line. Some options accept arguments. If the user supplies "<tt>myapp --file=somefile.txt</tt>" to your program, then "<tt>--file</tt>" is an option, and "<tt>somefile.txt</tt>" is an argument to it. Arguments not associated with any particular option are called <i>leftover arguments</i>.</p> 
     
    6969<p>Options also have a <i>name</i>, which is used in a number of contexts. The name defaults to the first long option specified, without the dashes. If no long options are specified, it uses the first short option. An option's name is mainly used when retrieving its results, after parsing the arguments. Occasionally, it is useful to give multiple options the same name. Examples of this are given later.</p> 
    7070 
    71 <p>For completeness' sake, here are all of the overloads of <tt>add_option</tt>:</p> 
    72  
    73 <ul> 
    74 <li><tt>Option add_option(char[][] options ...)</tt></li> 
    75 <li><tt>Option add_option(char[][] options, char[] name)</tt></li> 
    76 <li><tt>Option add_option(char[][] options, Action action)</tt></li> 
    77 <li><tt>Option add_option(char[][] options, ArgType type)</tt></li> 
    78 <li><tt>Option add_option(char[][] options, Action action, ArgType type)</tt></li> 
    79 <li><tt>Option add_option(char[][] options, char[] name, Action action)</tt></li> 
    80 <li><tt>Option add_option(char[][] options, char[] name, Action action, ArgType type)</tt></li> 
    81 <li><tt>Option add_option(char[][] options, Action action, char[] const_value)</tt></li> 
    82 <li><tt>Option add_option(char[][] options, char[] name, char[] const_value)</tt></li> 
    83 <li><tt>Option add_option(char[][] options, char[] name, Action action, char[] const_value)</tt></li> 
    84 <li><tt>Option add_option(char[][] options, void delegate() dg)</tt></li> 
    85 <li><tt>Option add_option(char[][] options, void delegate(char[]) dg)</tt></li> 
    86 <li><tt>Option add_option(char[][] options, void delegate(int) dg)</tt></li> 
    87 <li><tt>Option add_option(char[][] options, void delegate(Options, inout char[][], inout int, char[]) dg)</tt></li> 
    88 <li><tt>Option add_option(char[][] options, void delegate(Options, inout char[][], inout int, char[], char[]) dg)</tt></li> 
    89 <li><tt>Option add_option(char[][] options, void delegate(Options, inout char[][], inout int, char[], int) dg)</tt></li> 
    90 <li><tt>Option add_option(char[][] options, char[] name, void delegate(Options, inout char[][], inout int, char[]) dg)</tt></li> 
    91 <li><tt>Option add_option(char[][] options, char[] name, void delegate(Options, inout char[][], inout int, char[], char[]) dg)</tt></li> 
    92 <li><tt>Option add_option(char[][] options, char[] name, void delegate(Options, inout char[][], inout int, char[], int) dg)</tt></li> 
    93 </ul> 
    94  
    95 <p>As I describe each action, I will also list the relevant <tt>add_option</tt> overloads to that action. Not all of these apply to all of the actions.</p> 
     71<p>For completeness' sake, here are all of the overloads of <tt>addOption</tt>:</p> 
     72 
     73<ul> 
     74<li><tt>Option addOption(char[][] options ...)</tt></li> 
     75<li><tt>Option addOption(char[][] options, char[] name)</tt></li> 
     76<li><tt>Option addOption(char[][] options, Action action)</tt></li> 
     77<li><tt>Option addOption(char[][] options, ArgType type)</tt></li> 
     78<li><tt>Option addOption(char[][] options, Action action, ArgType type)</tt></li> 
     79<li><tt>Option addOption(char[][] options, char[] name, Action action)</tt></li> 
     80<li><tt>Option addOption(char[][] options, char[] name, Action action, ArgType type)</tt></li> 
     81<li><tt>Option addOption(char[][] options, Action action, char[] const_value)</tt></li> 
     82<li><tt>Option addOption(char[][] options, char[] name, char[] const_value)</tt></li> 
     83<li><tt>Option addOption(char[][] options, char[] name, Action action, char[] const_value)</tt></li> 
     84<li><tt>Option addOption(char[][] options, void delegate() dg)</tt></li> 
     85<li><tt>Option addOption(char[][] options, void delegate(char[]) dg)</tt></li> 
     86<li><tt>Option addOption(char[][] options, void delegate(int) dg)</tt></li> 
     87<li><tt>Option addOption(char[][] options, void delegate(Options, inout char[][], inout int, char[]) dg)</tt></li> 
     88<li><tt>Option addOption(char[][] options, void delegate(Options, inout char[][], inout int, char[], char[]) dg)</tt></li> 
     89<li><tt>Option addOption(char[][] options, void delegate(Options, inout char[][], inout int, char[], int) dg)</tt></li> 
     90<li><tt>Option addOption(char[][] options, char[] name, void delegate(Options, inout char[][], inout int, char[]) dg)</tt></li> 
     91<li><tt>Option addOption(char[][] options, char[] name, void delegate(Options, inout char[][], inout int, char[], char[]) dg)</tt></li> 
     92<li><tt>Option addOption(char[][] options, char[] name, void delegate(Options, inout char[][], inout int, char[], int) dg)</tt></li> 
     93</ul> 
     94 
     95<p>As I describe each action, I will also list the relevant <tt>addOption</tt> overloads to that action. Not all of these apply to all of the actions.</p> 
    9696 
    9797<p>A very simple use of optparse looks like this:</p> 
     
    9999<blockquote><pre>void main(char[][] args) { 
    100100    auto parser = new OptionParser(); 
    101     parser.add_option("-o", "--option"); 
    102     auto options = parser.parse_args(args); 
     101    parser.addOption("-o", "--option"); 
     102    auto options = parser.parse(args); 
    103103}</pre></blockquote> 
    104104 
     
    115115<h4>Methods</h4> 
    116116<ul> 
    117 <li><tt>Option add_option(char[][] options ...)</tt></li> 
    118 <li><tt>Option add_option(char[][] options, char[] name)</tt></li> 
    119 <li><tt>Option add_option(char[][] options, Action action)</tt></li> 
    120 <li><tt>Option add_option(char[][] options, ArgType type)</tt></li> 
    121 <li><tt>Option add_option(char[][] options, Action action, ArgType type)</tt></li> 
    122 <li><tt>Option add_option(char[][] options, char[] name, Action action)</tt></li> 
    123 <li><tt>Option add_option(char[][] options, char[] name, Action action, ArgType type)</tt></li> 
     117<li><tt>Option addOption(char[][] options ...)</tt></li> 
     118<li><tt>Option addOption(char[][] options, char[] name)</tt></li> 
     119<li><tt>Option addOption(char[][] options, Action action)</tt></li> 
     120<li><tt>Option addOption(char[][] options, ArgType type)</tt></li> 
     121<li><tt>Option addOption(char[][] options, Action action, ArgType type)</tt></li> 
     122<li><tt>Option addOption(char[][] options, char[] name, Action action)</tt></li> 
     123<li><tt>Option addOption(char[][] options, char[] name, Action action, ArgType type)</tt></li> 
    124124</ul> 
    125125 
     
    140140<blockquote><pre>void main(char[][] args) { 
    141141    auto parser = new OptionParser(); 
    142     parser.add_option("-f", "--file"); 
    143     parser.add_option(["-n", "--number"], ArgType.Integer); 
    144     auto options = parser.parse_args(args); 
     142    parser.addOption("-f", "--file"); 
     143    parser.addOption(["-n", "--number"], ArgType.Integer); 
     144    auto options = parser.parse(args); 
    145145    writefln("file: %s", options["file"]); 
    146146    writefln("number: %s", options.value("number")); 
     
    161161<h4>Methods</h4> 
    162162<ul> 
    163 <li><tt>Option add_option(char[][] options, Action action)</tt></li> 
    164 <li><tt>Option add_option(char[][] options, Action action, ArgType type)</tt></li> 
    165 <li><tt>Option add_option(char[][] options, char[] name, Action action)</tt></li> 
    166 <li><tt>Option add_option(char[][] options, char[] name, Action action, ArgType type)</tt></li> 
     163<li><tt>Option addOption(char[][] options, Action action)</tt></li> 
     164<li><tt>Option addOption(char[][] options, Action action, ArgType type)</tt></li> 
     165<li><tt>Option addOption(char[][] options, char[] name, Action action)</tt></li> 
     166<li><tt>Option addOption(char[][] options, char[] name, Action action, ArgType type)</tt></li> 
    167167</ul> 
    168168 
     
    172172<blockquote><tt>char[][] imports = options.list("import");</tt></blockquote> 
    173173 
    174 <p>If the type is <tt>Integer</tt>, use the <tt>value_list</tt> method:</p> 
    175  
    176 <blockquote><tt>int[] values = options.value_list("value");</tt></blockquote> 
     174<p>If the type is <tt>Integer</tt>, use the <tt>valueList</tt> method:</p> 
     175 
     176<blockquote><tt>int[] values = options.valueList("value");</tt></blockquote> 
    177177 
    178178<p>If the option is not provided on the command line, and no default was provided with <tt>def</tt>, these will both return an empty array.</p> 
     
    181181<blockquote><pre>void main(char[][] args) { 
    182182    auto parser = new OptionParser(); 
    183     parser.add_option(["-I", "--import"], Action.Append); 
    184     parser.add_option(["-V", "--value"], Action.Append, ArgType.Integer); 
    185     auto options = parser.parse_args(args); 
     183    parser.addOption(["-I", "--import"], Action.Append); 
     184    parser.addOption(["-V", "--value"], Action.Append, ArgType.Integer); 
     185    auto options = parser.parse(args); 
    186186    writefln("imports: %s", options.list("import")); 
    187     writefln("values: %s", options.value_list("value")); 
     187    writefln("values: %s", options.valueList("value")); 
    188188}</pre></blockquote> 
    189189 
     
    204204<h4>Methods</h4> 
    205205<ul> 
    206 <li><tt>Option add_option(char[][] options, Action action, char[] const_value)</tt></li> 
    207 <li><tt>Option add_option(char[][] options, char[] name, char[] const_value)</tt></li> 
    208 <li><tt>Option add_option(char[][] options, char[] name, Action action, char[] const_value)</tt></li> 
     206<li><tt>Option addOption(char[][] options, Action action, char[] const_value)</tt></li> 
     207<li><tt>Option addOption(char[][] options, char[] name, char[] const_value)</tt></li> 
     208<li><tt>Option addOption(char[][] options, char[] name, Action action, char[] const_value)</tt></li> 
    209209</ul> 
    210210 
     
    217217<blockquote><pre>void main(char[][] args) { 
    218218    auto parser = new OptionParser(); 
    219     parser.add_option(["--enable"], "flag", Action.StoreConst, "on"); 
    220     parser.add_option(["--disable"], "flag", Action.StoreConst, "off"); 
    221     auto options = parser.parse_args(args); 
     219    parser.addOption(["--enable"], "flag", Action.StoreConst, "on"); 
     220    parser.addOption(["--disable"], "flag", Action.StoreConst, "off"); 
     221    auto options = parser.parse(args); 
    222222    writefln("flag: %s", options["flag"]); 
    223223}</pre></blockquote> 
     
    237237<h4>Methods</h4> 
    238238<ul> 
    239 <li><tt>Option add_option(char[][] options, Action action, char[] const_value)</tt></li> 
    240 <li><tt>Option add_option(char[][] options, char[] name, Action action, char[] const_value)</tt></li> 
     239<li><tt>Option addOption(char[][] options, Action action, char[] const_value)</tt></li> 
     240<li><tt>Option addOption(char[][] options, char[] name, Action action, char[] const_value)</tt></li> 
    241241</ul> 
    242242 
     
    247247<blockquote><pre>void main(char[][] args) { 
    248248    auto parser = new OptionParser(); 
    249     parser.add_option(["--blue"], "color", Action.AppendConst, "blue"); 
    250     parser.add_option(["--green"], "color", Action.AppendConst, "green"); 
    251     auto options = parser.parse_args(args); 
     249    parser.addOption(["--blue"], "color", Action.AppendConst, "blue"); 
     250    parser.addOption(["--green"], "color", Action.AppendConst, "green"); 
     251    auto options = parser.parse(args); 
    252252    writefln("colors: %s", options.list("color")); 
    253253}</pre></blockquote> 
     
    265265<h4>Methods</h4> 
    266266<ul> 
    267 <li><tt>Option add_option(char[][] options, Action action)</tt></li> 
    268 <li><tt>Option add_option(char[][] options, char[] name, Action action)</tt></li> 
     267<li><tt>Option addOption(char[][] options, Action action)</tt></li> 
     268<li><tt>Option addOption(char[][] options, char[] name, Action action)</tt></li> 
    269269</ul> 
    270270 
     
    279279<blockquote><pre>void main(char[][] args) { 
    280280    auto parser = new OptionParser(); 
    281     parser.add_option(["--enable"], "flag", Action.SetTrue); 
    282     parser.add_option(["--disable"], "flag", Action.SetFalse); 
    283     auto options = parser.parse_args(args); 
     281    parser.addOption(["--enable"], "flag", Action.SetTrue); 
     282    parser.addOption(["--disable"], "flag", Action.SetFalse); 
     283    auto options = parser.parse(args); 
    284284    writefln("flag: %s", options.flag("flag")); 
    285285}</pre></blockquote> 
     
    299299<h4>Methods</h4> 
    300300<ul> 
    301 <li><tt>Option add_option(char[][] options, Action action)</tt></li> 
    302 <li><tt>Option add_option(char[][] options, char[] name, Action action)</tt></li> 
     301<li><tt>Option addOption(char[][] options, Action action)</tt></li> 
     302<li><tt>Option addOption(char[][] options, char[] name, Action action)</tt></li> 
    303303</ul> 
    304304 
     
    311311<blockquote><pre>void main(char[][] args) { 
    312312    auto parser = new OptionParser(); 
    313     parser.add_option(["-v", "--verbose"], "verbosity", Action.Count); 
    314     auto options = parser.parse_args(args); 
     313    parser.addOption(["-v", "--verbose"], "verbosity", Action.Count); 
     314    auto options = parser.parse(args); 
    315315    writefln("verbosity: %s", options.count("verbosity")); 
    316316}</pre></blockquote> 
     
    332332<h4>Methods</h4> 
    333333<ul> 
    334 <li><tt>Option add_option(char[][] options, void delegate() dg)</tt></li> 
    335 <li><tt>Option add_option(char[][] options, void delegate(char[]) dg)</tt></li> 
    336 <li><tt>Option add_option(char[][] options, void delegate(int) dg)</tt></li> 
     334<li><tt>Option addOption(char[][] options, void delegate() dg)</tt></li> 
     335<li><tt>Option addOption(char[][] options, void delegate(char[]) dg)</tt></li> 
     336<li><tt>Option addOption(char[][] options, void delegate(int) dg)</tt></li> 
    337337</ul> 
    338338<h4>Results</h4> 
     
    342342<blockquote><pre>void main(char[][] args) { 
    343343    auto parser = new OptionParser(); 
    344     parser.add_option(["--callback"], { 
     344    parser.addOption(["--callback"], { 
    345345        writefln("Callback encountered!"); 
    346346    }); 
    347     auto options = parser.parse_args(args); 
     347    auto options = parser.parse(args); 
    348348    writefln("Done."); 
    349349}</pre></blockquote> 
     
    365365<dt><tt>Options</tt></dt> <dd>The current results of parsing the command-line, up to when the callback was encountered.</dd> 
    366366 
    367 <dt><tt>inout char[][]</tt></dt> <dd>The args array. This is mostly identical to the array originally passed to <tt>parse_args</tt>, with the following differences: 
     367<dt><tt>inout char[][]</tt></dt> <dd>The args array. This is mostly identical to the array originally passed to <tt>parse</tt>, with the following differences: 
    368368    <ol> 
    369369    <li>The first element, with the executable name, has been removed.</li> 
     
    381381<h4>Methods</h4> 
    382382<ul> 
    383 <li><tt>Option add_option(char[][] options, void delegate(Options, inout char[][], inout int, char[]) dg)</tt></li> 
    384 <li><tt>Option add_option(char[][] options, void delegate(Options, inout char[][], inout int, char[], char[]) dg)</tt></li> 
    385 <li><tt>Option add_option(char[][] options, void delegate(Options, inout char[][], inout int, char[], int) dg)</tt></li> 
    386 <li><tt>Option add_option(char[][] options, char[] name, void delegate(Options, inout char[][], inout int, char[]) dg)</tt></li> 
    387 <li><tt>Option add_option(char[][] options, char[] name, void delegate(Options, inout char[][], inout int, char[], char[]) dg)</tt></li> 
    388 <li><tt>Option add_option(char[][] options, char[] name, void delegate(Options, inout char[][], inout int, char[], int) dg)</tt></li> 
     383<li><tt>Option addOption(char[][] options, void delegate(Options, inout char[][], inout int, char[]) dg)</tt></li> 
     384<li><tt>Option addOption(char[][] options, void delegate(Options, inout char[][], inout int, char[], char[]) dg)</tt></li> 
     385<li><tt>Option addOption(char[][] options, void delegate(Options, inout char[][], inout int, char[], int) dg)</tt></li> 
     386<li><tt>Option addOption(char[][] options, char[] name, void delegate(Options, inout char[][], inout int, char[]) dg)</tt></li> 
     387<li><tt>Option addOption(char[][] options, char[] name, void delegate(Options, inout char[][], inout int, char[], char[]) dg)</tt></li> 
     388<li><tt>Option addOption(char[][] options, char[] name, void delegate(Options, inout char[][], inout int, char[], int) dg)</tt></li> 
    389389</ul> 
    390390<h4>Results</h4> 
     
    394394<blockquote><pre>void main(char[][] args) { 
    395395    auto parser = new OptionParser(); 
    396     parser.add_option( 
     396    parser.addOption( 
    397397        ["--adv-callback"], 
    398398        (Options o, inout char[][] a, inout int i, char[] name) { 
     
    401401        } 
    402402    ); 
    403     parser.add_option(["-c"], Action.Count); 
    404     auto options = parser.parse_args(args); 
     403    parser.addOption(["-c"], Action.Count); 
     404    auto options = parser.parse(args); 
    405405    writefln("count: %s", options.count("c")); 
    406406}</pre></blockquote> 
     
    431431<p>Options are printed in the following form. Given these options:</p> 
    432432 
    433 <blockquote><pre>parser.add_option("-f", "--file").help("The file to operate on.") 
    434 parser.add_option(["--enable"], Action.SetTrue).help("Enables the option.")</pre></blockquote> 
     433<blockquote><pre>parser.addOption("-f", "--file").help("The file to operate on.") 
     434parser.addOption(["--enable"], Action.SetTrue).help("Enables the option.")</pre></blockquote> 
    435435 
    436436<p><tt>Help</tt> produces the following:</p> 
     
    441441<p>The <tt>help</tt> method of the <tt>Option</tt> class provides the description used in the listing. Notice also the "<tt>=FILE</tt>" in the first option above. This indicates that the option accepts an argument. If you wanted to have this say "<tt>=FILENAME</tt>" instead, you would instead define the <tt>--file</tt> option as:</p> 
    442442 
    443 <blockquote<tt>parser.add_option("-f", "--file").help("The file to operate on.").argName("filename");</tt></blockquote> 
     443<blockquote<tt>parser.addOption("-f", "--file").help("The file to operate on.").argName("filename");</tt></blockquote> 
    444444 
    445445<p>The <tt>argName</tt> method of <tt>Option</tt> class defines this string, which otherwise defaults to the option's name. Note that it always converts the argument's name to all-caps.</p> 
     
    447447<h4>Methods</h4> 
    448448<ul>