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