| Thread overview | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 30, 2005 optparse.d -- good enough to be std.optparse? | ||||
|---|---|---|---|---|
| ||||
Attachments: | I've made a command-line option helper similar to Python's optparse. It allows you to specify what D-type you want the option as, short name, long name, help, and more. It automatically creates a formatted help message and prints it on errors. It checks that clients' usage of the module is proper; and it checks that the command-line arguments meet what was specified. It has a compehensive unittest that demonstrates more. The source is attached.
: /**
: * Example usage:
: */
: int main (char[][] args)
: {
: int verbosity;
: char[] outfile;
: char[][] files;
:
: // Constructor parameters are used in printing help.
: // -h / --help is always added by default
: // and uses program-name and usage.
: // --version (no short name) is added by
: // default if version is given.
: // program-name
: OptionParser op = new OptionParser(__FILE__[0..$-2],
: // usage version
: "[options] --files=f1,fN [outfile]", "0.2");
:
: // int, short and long, help, metavar,
: // no default, not mandatory
: op.addOption!(int)("v", "verbose",
: "Be more and more and more and more and more "
: "and more and more verbose.", "LEVEL");
: // comma-separated string list, short and long, help,
: // metavar, no default, mandatory
: op.addOption!(char[][])("fs", "files",
: "Files to process, and make this a really long help "
: "string as well to test aligning.", "FILE,FILE,...",
: null, true);
: // float, long-only, help, metavar, default, not mandatory
: op.addOption!(float)(null, "thing", "Do it with this.",
: "FLOAT", -4.297e21f);
: // no-value, short-only, with help, no metavar,
: // no default, not mandatory
: op.addOption!()("a", null, "Use alternate method.");
:
: // Parse command-line arguments, including args[0]
: // program-name (it's skipped).
: // args will be reset to the remaining non-option
: // command-line arguments in the order they appeared.
: Options options = op.parse(args);
:
: // Check if option was given on the command-line
: // by using (char[] in Options).
: // If the option has both short and long names,
: // either can be used.
: if ("verbose" in options)
: // If option was given and it has a value,
: // retrieve it by indexing Options with short
: // or long name (or only one if only one)
: // and do getValue!(T)
: verbosity = options["verbose"].getValue!(int);
:
: if (verbosity > 0)
: writefln("I'll say a little.");
: if (verbosity > 1)
: writefln("I'll say a lot more.");
:
: // args was reset by parse to the remaining
: // non-option command-line arguments
: if (args.length == 1)
: // use the first non-option argument
: outfile = args[0];
: else if (args.length > 1)
: // OptionError.errorExit("message") can be used to
: // print help and exit process;
: // useful when checking non-option arguments
: op.errorExit("more than one output file specified");
:
: // mandatory options can be assumed to be
: // there after successful parse
: assert ("files" in options);
: files = options["files"].getValue!(char[][]);
: if (files.length == 0)
: op.errorExit("need to specifiy at least one input file");
:
: if (verbosity > 0)
: {
: if ("thing" in options)
: writefln("my thing is: ",
: options["thing"].getValue!(float));
:
: // no-value options are simply tested for being in Options
: if ("a" in options)
: writefln("I would process files using alternate method:");
: else
: writefln("I would process files using normal method:");
: foreach (char[] f; files)
: writefln("\t",f);
: writefln("and output to ",
: outfile.length ? outfile : "<stdout>");
: }
:
: return 0;
: }
Example command-line output of above program:
---------------------------------------------------------------
$ ./example -h
usage: optparse [options] --files=f1,fN [outfile]
options:
-h, --help Show this help message and exit.
--version Show program's version number and exit.
-vLEVEL, --verbose=LEVEL
Be more and more and more and more and more and more
and more verbose.
-fsFILE,FILE,..., --files=FILE,FILE,...
Files to process, and make this a really long help
string as well to test aligning.
--thing=FLOAT Do it with this.
-a Use alternate method.
---------------------------------------------------------------
$ ./example -v2 --files=somefile,anotherfile,nextfile --thing -4.23e-6 -a
outputfile
I'll say a little.
I'll say a lot more.
my thing is: -4.23e-06
I would process files using alternate method:
somefile
anotherfile
nextfile
and output to outputfile
---------------------------------------------------------------
$ ./example --asdf
optparse: error: no such option: --asdf
[help]
---------------------------------------------------------------
$ ./example
optparse: error: -fs / --files option is mandatory
[help]
| |||
May 30, 2005 Re: optparse.d -- good enough to be std.optparse? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to derick_eddington | In article <d7g5nd$3i3$1@digitaldaemon.com>, derick_eddington@nospam.yashmoo.com says... > >Example command-line output of above program: > >--------------------------------------------------------------- > >$ ./example -h >usage: optparse [options] --files=f1,fN [outfile] > >options: >-h, --help Show this help message and exit. >--version Show program's version number and exit. >-vLEVEL, --verbose=LEVEL >Be more and more and more and more and more and more >and more verbose. >-fsFILE,FILE,..., --files=FILE,FILE,... >Files to process, and make this a really long help >string as well to test aligning. >--thing=FLOAT Do it with this. >-a Use alternate method. > Arg, forgot to : these. The help print is nicely formatted... | |||
May 31, 2005 Re: optparse.d -- good enough to be std.optparse? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to derick_eddington | Very useful. I'd like to add this to Mango, if that would be OK? - Kris <derick_eddington@nospam.yashmoo.com> wrote in message news:d7g5nd$3i3$1@digitaldaemon.com... > I've made a command-line option helper similar to Python's optparse. It allows > you to specify what D-type you want the option as, short name, long name, help, > and more. It automatically creates a formatted help message and prints it on > errors. It checks that clients' usage of the module is proper; and it checks > that the command-line arguments meet what was specified. It has a compehensive > unittest that demonstrates more. The source is attached. > > : /** > : * Example usage: > : */ > : int main (char[][] args) > : { > : int verbosity; > : char[] outfile; > : char[][] files; > : > : // Constructor parameters are used in printing help. > : // -h / --help is always added by default > : // and uses program-name and usage. > : // --version (no short name) is added by > : // default if version is given. > : // program-name > : OptionParser op = new OptionParser(__FILE__[0..$-2], > : // usage version > : "[options] --files=f1,fN [outfile]", "0.2"); > : > : // int, short and long, help, metavar, > : // no default, not mandatory > : op.addOption!(int)("v", "verbose", > : "Be more and more and more and more and more " > : "and more and more verbose.", "LEVEL"); > : // comma-separated string list, short and long, help, > : // metavar, no default, mandatory > : op.addOption!(char[][])("fs", "files", > : "Files to process, and make this a really long help " > : "string as well to test aligning.", "FILE,FILE,...", > : null, true); > : // float, long-only, help, metavar, default, not mandatory > : op.addOption!(float)(null, "thing", "Do it with this.", > : "FLOAT", -4.297e21f); > : // no-value, short-only, with help, no metavar, > : // no default, not mandatory > : op.addOption!()("a", null, "Use alternate method."); > : > : // Parse command-line arguments, including args[0] > : // program-name (it's skipped). > : // args will be reset to the remaining non-option > : // command-line arguments in the order they appeared. > : Options options = op.parse(args); > : > : // Check if option was given on the command-line > : // by using (char[] in Options). > : // If the option has both short and long names, > : // either can be used. > : if ("verbose" in options) > : // If option was given and it has a value, > : // retrieve it by indexing Options with short > : // or long name (or only one if only one) > : // and do getValue!(T) > : verbosity = options["verbose"].getValue!(int); > : > : if (verbosity > 0) > : writefln("I'll say a little."); > : if (verbosity > 1) > : writefln("I'll say a lot more."); > : > : // args was reset by parse to the remaining > : // non-option command-line arguments > : if (args.length == 1) > : // use the first non-option argument > : outfile = args[0]; > : else if (args.length > 1) > : // OptionError.errorExit("message") can be used to > : // print help and exit process; > : // useful when checking non-option arguments > : op.errorExit("more than one output file specified"); > : > : // mandatory options can be assumed to be > : // there after successful parse > : assert ("files" in options); > : files = options["files"].getValue!(char[][]); > : if (files.length == 0) > : op.errorExit("need to specifiy at least one input file"); > : > : if (verbosity > 0) > : { > : if ("thing" in options) > : writefln("my thing is: ", > : options["thing"].getValue!(float)); > : > : // no-value options are simply tested for being in Options > : if ("a" in options) > : writefln("I would process files using alternate method:"); > : else > : writefln("I would process files using normal method:"); > : foreach (char[] f; files) > : writefln("\t",f); > : writefln("and output to ", > : outfile.length ? outfile : "<stdout>"); > : } > : > : return 0; > : } > > Example command-line output of above program: > > --------------------------------------------------------------- > > $ ./example -h > usage: optparse [options] --files=f1,fN [outfile] > > options: > -h, --help Show this help message and exit. > --version Show program's version number and exit. > -vLEVEL, --verbose=LEVEL > Be more and more and more and more and more and more > and more verbose. > -fsFILE,FILE,..., --files=FILE,FILE,... > Files to process, and make this a really long help > string as well to test aligning. > --thing=FLOAT Do it with this. > -a Use alternate method. > > --------------------------------------------------------------- > > $ ./example -v2 --files=somefile,anotherfile,nextfile --thing -4.23e-6 -a > outputfile > I'll say a little. > I'll say a lot more. > my thing is: -4.23e-06 > I would process files using alternate method: > somefile > anotherfile > nextfile > and output to outputfile > > --------------------------------------------------------------- > > $ ./example --asdf > optparse: error: no such option: --asdf > > [help] > > --------------------------------------------------------------- > > $ ./example > optparse: error: -fs / --files option is mandatory > > [help] > > > > | |||
May 31, 2005 Re: optparse.d -- good enough to be std.optparse? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Kris | Certainly. I'll keep you updated as I enhance and fix bugs. In article <d7g9q7$7b3$1@digitaldaemon.com>, Kris says... > >Very useful. I'd like to add this to Mango, if that would be OK? > >- Kris > ><derick_eddington@nospam.yashmoo.com> wrote in message news:d7g5nd$3i3$1@digitaldaemon.com... >> I've made a command-line option helper similar to Python's optparse. It >allows >> you to specify what D-type you want the option as, short name, long name, >help, >> and more. It automatically creates a formatted help message and prints it >on >> errors. It checks that clients' usage of the module is proper; and it >checks >> that the command-line arguments meet what was specified. It has a >compehensive >> unittest that demonstrates more. The source is attached. | |||
May 31, 2005 Re: optparse.d -- good enough to be std.optparse? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to derick_eddington | derick_eddington@nospam.yashmoo.com wrote: > Certainly. I'll keep you updated as I enhance and fix bugs. Excellent ~ thx! | |||
May 31, 2005 Re: optparse.d -- good enough to be std.optparse? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to kris | In article <d7gqjo$nth$2@digitaldaemon.com>, kris says... > >derick_eddington@nospam.yashmoo.com wrote: >> Certainly. I'll keep you updated as I enhance and fix bugs. Who doesn't love to enhance bugs? =P > >Excellent ~ thx! Regards, James Dunne | |||
May 31, 2005 Re: optparse.d -- good enough to be std.optparse? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to derick_eddington | Cool, Derick! What about using box values there? Having them and use TypeList instead of optionParser = new OptionParser(__FILE__[0..$-2], "[option [value]]", "0.0"); optionParser.addOption!()("v","verbose"); optionParser.addOption!(float)("f","foo",null,null,null,true); optionParser.addOption!(int)("x","xeno","does this and that","THING",123); will allow to build such declarations in compile time - statically. Just hypothesis.... Andrew. <derick_eddington@nospam.yashmoo.com> wrote in message news:d7g5nd$3i3$1@digitaldaemon.com... > I've made a command-line option helper similar to Python's optparse. It > allows > you to specify what D-type you want the option as, short name, long name, > help, > and more. It automatically creates a formatted help message and prints it > on > errors. It checks that clients' usage of the module is proper; and it > checks > that the command-line arguments meet what was specified. It has a > compehensive > unittest that demonstrates more. The source is attached. > > : /** > : * Example usage: > : */ > : int main (char[][] args) > : { > : int verbosity; > : char[] outfile; > : char[][] files; > : > : // Constructor parameters are used in printing help. > : // -h / --help is always added by default > : // and uses program-name and usage. > : // --version (no short name) is added by > : // default if version is given. > : // program-name > : OptionParser op = new OptionParser(__FILE__[0..$-2], > : // usage version > : "[options] --files=f1,fN [outfile]", "0.2"); > : > : // int, short and long, help, metavar, > : // no default, not mandatory > : op.addOption!(int)("v", "verbose", > : "Be more and more and more and more and more " > : "and more and more verbose.", "LEVEL"); > : // comma-separated string list, short and long, help, > : // metavar, no default, mandatory > : op.addOption!(char[][])("fs", "files", > : "Files to process, and make this a really long help " > : "string as well to test aligning.", "FILE,FILE,...", > : null, true); > : // float, long-only, help, metavar, default, not mandatory > : op.addOption!(float)(null, "thing", "Do it with this.", > : "FLOAT", -4.297e21f); > : // no-value, short-only, with help, no metavar, > : // no default, not mandatory > : op.addOption!()("a", null, "Use alternate method."); > : > : // Parse command-line arguments, including args[0] > : // program-name (it's skipped). > : // args will be reset to the remaining non-option > : // command-line arguments in the order they appeared. > : Options options = op.parse(args); > : > : // Check if option was given on the command-line > : // by using (char[] in Options). > : // If the option has both short and long names, > : // either can be used. > : if ("verbose" in options) > : // If option was given and it has a value, > : // retrieve it by indexing Options with short > : // or long name (or only one if only one) > : // and do getValue!(T) > : verbosity = options["verbose"].getValue!(int); > : > : if (verbosity > 0) > : writefln("I'll say a little."); > : if (verbosity > 1) > : writefln("I'll say a lot more."); > : > : // args was reset by parse to the remaining > : // non-option command-line arguments > : if (args.length == 1) > : // use the first non-option argument > : outfile = args[0]; > : else if (args.length > 1) > : // OptionError.errorExit("message") can be used to > : // print help and exit process; > : // useful when checking non-option arguments > : op.errorExit("more than one output file specified"); > : > : // mandatory options can be assumed to be > : // there after successful parse > : assert ("files" in options); > : files = options["files"].getValue!(char[][]); > : if (files.length == 0) > : op.errorExit("need to specifiy at least one input file"); > : > : if (verbosity > 0) > : { > : if ("thing" in options) > : writefln("my thing is: ", > : options["thing"].getValue!(float)); > : > : // no-value options are simply tested for being in Options > : if ("a" in options) > : writefln("I would process files using alternate method:"); > : else > : writefln("I would process files using normal method:"); > : foreach (char[] f; files) > : writefln("\t",f); > : writefln("and output to ", > : outfile.length ? outfile : "<stdout>"); > : } > : > : return 0; > : } > > Example command-line output of above program: > > --------------------------------------------------------------- > > $ ./example -h > usage: optparse [options] --files=f1,fN [outfile] > > options: > -h, --help Show this help message and exit. > --version Show program's version number and exit. > -vLEVEL, --verbose=LEVEL > Be more and more and more and more and more and more > and more verbose. > -fsFILE,FILE,..., --files=FILE,FILE,... > Files to process, and make this a really long help > string as well to test aligning. > --thing=FLOAT Do it with this. > -a Use alternate method. > > --------------------------------------------------------------- > > $ ./example -v2 --files=somefile,anotherfile,nextfile --thing -4.23e-6 -a > outputfile > I'll say a little. > I'll say a lot more. > my thing is: -4.23e-06 > I would process files using alternate method: > somefile > anotherfile > nextfile > and output to outputfile > > --------------------------------------------------------------- > > $ ./example --asdf > optparse: error: no such option: --asdf > > [help] > > --------------------------------------------------------------- > > $ ./example > optparse: error: -fs / --files option is mandatory > > [help] > > > > | |||
June 01, 2005 Re: optparse.d -- updated | ||||
|---|---|---|---|---|
| ||||
Posted in reply to kris Attachments: | I've updated optparse.d:
Option groups for help printout.
Example:
: optionParser = new OptionParser("myapp", "[option [value]]");
: optionParser.addOption!()("v", "verbose");
: optionParser.addOption!(float)("f", "foo", null, null, null, true);
: optionParser.addOption!(int)("x", "xeno", "does this and that", "THING");
: optionParser.addOption!(int[])("a", "apple", "make applesauce", null);
: optionParser.addOption!(long)("l", "long", "be longer", "LONG");
: optionParser.addOption!(double)("d", "double", null, "DOUBLE");
: optionParser.addOption!(uint[])("ui", "uint", null, "UINT,...");
: // make a group, options must have previously been added
: optionParser.makeGroup("number options", "f", "x", "a", "l", "d", "ui");
: optionParser.addOption!(char[])(null, "bar", "make it happen", "BLOB");
: optionParser.addOption!(char[][])("sb", "shabang", "blow up", "IT");
: // make a group, options must have previously been added
: optionParser.makeGroup("string options", "bar", "sb");
Will make help:
: usage: myapp [option [value]]
:
: options:
: -h, --help Show this help message and exit.
: --version Show program's version number and exit.
: -v, --verbose
:
: number options:
: -f, --foo
: -x THING, --xeno=THING
: does this and that
: -a, --apple make applesauce
: -l LONG, --long=LONG
: be longer
: -d DOUBLE, --double=DOUBLE
: -ui UINT,..., --uint=UINT,...
:
: string options:
: --bar=BLOB make it happen
: -sb IT, --shabang=IT
: blow up
Help string formatting separates short-name from METAVAR by a space for easier reading.
Smarter use of templates to support more types.
Bug *un-enhanced* :) where "--option= --next-opt" would consume --next-opt as --option's value instead of causing error because --option has no value.
A few more unittest cases.
Question for potential users of optparse.d:
Would you rather have anal checking of all usage of the module or reduce the
object-file size from 55k to 35k? I tried to use "version" but it's too buggy (I
just wanted version'd else-if...)
--Derick
| |||
June 01, 2005 Re: optparse.d -- static | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrew Fedoniouk | If it could be setup statically at compile-time and have the same conciseness, flexibility, and ease of checking for options and retrieving their values, that would be awesome, but I don't follow what you mean about box values and TypeList. Could you elaborate? The only way to parameterize something at compile-time is with templates, right? But they can only take integral values, not char[] for option names or arbitrary types for default values. Statically-initialized structs could be used but then they still have to be given to an OptionParser and variables for them would also need to be declared. I don't think it can be done and retain the same degree of simpleness of use. In article <d7iifp$2jhh$1@digitaldaemon.com>, Andrew Fedoniouk says... > >Cool, Derick! > >What about using box values there? > >Having them and use TypeList instead of > > optionParser = new OptionParser(__FILE__[0..$-2], "[option [value]]", >"0.0"); > optionParser.addOption!()("v","verbose"); > optionParser.addOption!(float)("f","foo",null,null,null,true); > optionParser.addOption!(int)("x","xeno","does this and that","THING",123); > >will allow to build such declarations in compile time - statically. > >Just hypothesis.... > >Andrew. | |||
June 01, 2005 Re: optparse.d -- static | ||||
|---|---|---|---|---|
| ||||
Posted in reply to derick_eddington | <derick_eddington@nospam.yashmoo.com> wrote in message news:d7jvl1$1420$1@digitaldaemon.com... > If it could be setup statically at compile-time and have the same > conciseness, > flexibility, and ease of checking for options and retrieving their values, > that > would be awesome, but I don't follow what you mean about box values and > TypeList. Could you elaborate? > > The only way to parameterize something at compile-time is with templates, > right? > But they can only take integral values, not char[] for option names or > arbitrary > types for default values. Statically-initialized structs could be used > but then > they still have to be given to an OptionParser and variables for them > would also > need to be declared. I don't think it can be done and retain the same > degree of > simpleness of use. Yep. You are right. I was thinking about simple implementation of something close to boost::spirit http://spirit.sourceforge.net/ but it seems like even simple implementation is an overkill for such task. Andrew. > > > In article <d7iifp$2jhh$1@digitaldaemon.com>, Andrew Fedoniouk says... >> >>Cool, Derick! >> >>What about using box values there? >> >>Having them and use TypeList instead of >> >> optionParser = new OptionParser(__FILE__[0..$-2], "[option [value]]", >>"0.0"); >> optionParser.addOption!()("v","verbose"); >> optionParser.addOption!(float)("f","foo",null,null,null,true); >> optionParser.addOption!(int)("x","xeno","does this and >> that","THING",123); >> >>will allow to build such declarations in compile time - statically. >> >>Just hypothesis.... >> >>Andrew. > > | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply