#include <argv_parser.h>
Inheritance diagram for s11n::argv_parser:
Public Member Functions | |
argv_parser (int argc, char *argv[], int startAt=0) | |
Creates a new parser using the given arguments array and arg count. | |
virtual void | set_help (const std::string &key, const std::string &text) |
get/set_help() text for a given key. | |
virtual const std::string | getHelp (const std::string &key) const |
Returns the help text associated with key. | |
virtual bool | is_set (const std::string &key) const |
Re-implemented to check keys -FOO and --FOO if key FOO is not found. | |
virtual std::string | get_string (const std::string &key, const std::string &defaultVal=std::string()) const |
get_string() is overridden to add a special case to all get() calls made via the property_store API: if a get() function is called with a key which does not start with a dash (-) character and they key cannot be found in our list then -key and --key will be tried. | |
virtual int | args (int argc, char *argv[], int startAt, const char *argpre="-") |
Makes a half-hearted attempt to parse out any args (begining with "-"). | |
virtual int | args (std::string args, std::string separators=" ") |
Similar to parse( int... | |
virtual const std::string | dump_help (bool showcurrentvals=true) const |
Creates a "usage"-like string for this object containing all keys for which set_help() has been called. | |
virtual bool | is_help_set () |
Returns true if -help --help, -? or --? is set. | |
Static Public Member Functions | |
argv_parser & | args (int argc, char *argv[]) |
args( int, char * ) should be called once from your main() if you want clients to be able to use args() to get at them. | |
argv_parser & | args () |
Returns the object containing the arguments supplied to args(int,char**). |
It exists in the s11n source tree only to ease development of test apps, and should not be considered to be part of the core library.
Use it like this:
#include <iostream> #include "argv_parser.h"
#define VERBOSE if( opts.get( "verbose", false ) ) cerr
int main( int argc, char **argv ) { argv_parser & opts = argv_parser::args( argc, argv ); opts.set( "dosomething", ! opts.get_bool( "donothing", false ) ); if( ! opts.get( "dosomething", true ) ) { exit( 0 )); } int myint = opts.get( "width", 20 ); double myangle = opts.get( "angle", 0.0 );
VERBOSE << "This is a verbose message." << endl; return opts.get( "errorcode", 0 ); }(that code's just off the top of my head - it may not compile as-is.)
Note that client code outside of main can then get access to the args via the static function args():
argv_parser & opts = argv_parser::args();
See the property_store object's API for a full list of accessor functions.
Supported command-line formats:
-foo bar [that is, -foo == "bar"] is the same as: [--foo bar] [-foo=bar] [--foo=bar]
-foo -bar false [-foo == true, -bar == false] -foo -bar=false [same] --double-dashed "some string value" --double-dashed="some string value" [same as previous line]
Whether you use single or double dashes is irrelevant, but you must call get() with the same key as was actually passed on the command-line, like so:
int width = opts.getInt( "-width", opts.getInt( "--width", 42 ) ); will check for -width first, then --width, defaulting to 42.
Alternately, if you use this form: opts.get_string( "foo" ); // WITHOUT a dash the following options are searched:
so the above call may actually result in getting the value from -foo or --foo. This is a potential logic problem if your application uses two semantically-different, like-named arguments like -force and --force. In this case a call to get( "force" ) would find -force and not --force. Use get( "-force" ) or get("--force") to avoid this ambiguity. The dashed versions of an argument are only sought after if get() is called without a dash before the key.
These sample dash-searching rules apply to is_set().
A note to Qt users: call args() on this object before calling QApplication a(argc, argv ), or QApplication will steal any argument called -name (and possibly others), removing it from argv. i.e., if you do not call args() on this object first, QApplication may steal arguments so you'll never see them. Been there, done that.
Known Bugs and/or gotchyas:
Negative numbers:
--boolflag -123=something
will be parsed as:
[--boolflag == true] [-123=something]
Search the .cpp file for 'negative' and you'll find where this bug lives. Since numeric arguments are so rare this is not such a big deal, i think. i can think of only a few real-world examples which use args like -1: ssh, [GNU] xargs, head, tail, lpr, ... okay, maybe they aren't so uncommon :/
Along those same lines:
--bool -234 --foobarwill be parsed as:
[--bool == -234] [--foobar == true]
Which i consider to be correct for most cases. If you want to set --bool to a negative number use: --bool=-123 If you want to force a boolean value in this case:
--bool=true -234 546
parses as:
--bool=true -234=456
i hate the inconsistency this adds, though. :/
Definition at line 139 of file argv_parser.h.
|
Similar to parse( int... ) except that this one reads a whole line of options, parses that into an array, then passes it to parse(...). Note that this _may_ (but should not, ideally) behave slightly differently from arguments passed to the other form, which typically come in as command-line args (parsed by your shell). This functions uses a stdstring_tokenizer to do it's parsing, so any differences in behaviour should be resolved there. i am not aware of any differences. |
|
Makes a half-hearted attempt to parse out any args (begining with "-"). Any args without values passed after them are assigned the value true. Sample valid command lines:
foo --a --b foo --c bar --f (--a and --f == true, --b == "foo" and --c == "bar") foo --a eat --b this --c "you lazy bum" (--a==eat, --b==this, --c=="you lazy bum") foo --a=b --c d (--a == b, --c == d) These are identical for purposes of get( "c" ): [... -c=-1.0 ...] [... -c -1.0 ...] [... --c 1.0 ...] [... --c=1.0 ...] To get the values, call the property_store API functions like: int foo = parser.getInt( "--i" ); // getInt("i") now works for -i or --i :) bool bar = parser.get_bool( "--b" ); // or get_bool( "b") for -b or --b'startat' says which element in argv[] to start with. If argpre = 0 then it uses the default argument prefix (defaults to "-"). If it is >0 then that is used as a char * prefix for all arguments. This function also stores all processed values in a way familiar to bash and perl users: $0 = the first argument, $1 = the second arg etc. Thus given: ./foo --arg1 val1 --arg2=fooWe have: myargs["$1"] == "--arg1" myargs["$3"] == "--arg2=foo" (it is arguably useful to split these, but then usage would be inconsistent with bash/perl. However, as it is now it is inconsistent with the results of "--arg2 foo" :/)Note that the values are added to this object (or overwrite existing entries), and the list is not cleared by this function. |
|
Creates a "usage"-like string for this object containing all keys for which set_help() has been called. If showcurrentvals is true then the current values are also added to th string, otherwise they are left out. Note that the order of the dumped help text/keys is alphabetic (because that's how the container object stores them). TODO: maintain the order of args, using the order from set_help(). Sample:
in main() do: argv_parser & args = argv_parser::args( argc, argv ); if( args.is_hel_set() ) { // triggers on --help, -help, -? or --? cerr << args.dump_help(); exit( 0 ); // some apps exit with a non-zero for help, some don't. } |
|
get_string() is overridden to add a special case to all get() calls made via the property_store API: if a get() function is called with a key which does not start with a dash (-) character and they key cannot be found in our list then -key and --key will be tried. This means that, assuming the above sample code is in place, the following would work:
~/ > myapp --foo=17.34 ... double d = opts.getDouble( "foo", 0.0 ); // d == 17.34 As will this: opts.set( "--mykey", "myvalue" ); ... cerr << "mykey="<< opts.get_string( "mykey" ) << endl; Note, however, that command-line arguments passed without a leading dash are not treated as arguments, and will not be inside this object if the command-line arguments are passed in via args(). Additionally, it is important to note that if key is passed in with a leading "-" then the additional "dash checking" is NOT done. That is, if you call:
opts.get_string( "-d", 0.0 ); then ONLY the entry -d will match, and not --d. Reimplemented from s11n::property_store. |