8 #include "wvscatterhash.h"
12 #undef __error_t_defined
33 : short_option(_short_option), long_option(_long_option), desc(_desc)
43 return WvString::null;
63 void remove(
char short_option,
WvStringParm long_option);
66 void add_required_arg();
67 void subtract_required_arg();
80 bool argp_add(
const char *name,
int key,
const char *arg,
int flags,
81 const char *doc,
int group);
83 void argp_init(
size_t size = 0);
96 WvArgsOptionList options_list;
97 WvArgsOptionDict options_dict;
100 size_t required_args;
107 void WvArgsOption::add_to_argp(
WvArgsData &data)
109 data.argp_add(long_option, short_option, 0, 0, desc, 0);
148 return WvString::null;
174 return WvString::null;
200 return WvString::null;
223 return WvString::null;
251 return WvString::null;
253 return WvString(
"invalid option `%s'", arg);
277 data.argp_add(long_option, short_option, arg_desc, 0, desc, 0);
302 char *tailptr = NULL;
304 long int tmp = strtol(arg, &tailptr, 10);
305 if (errno == ERANGE || tmp > INT_MAX || tmp < INT_MIN )
308 return WvString(
"`%s': invalid number.", arg);
313 return WvString(
"`%s': invalid number.", arg);
318 return WvString::null;
344 char *tailptr = NULL;
346 long int tmp = strtol(arg, &tailptr, 10);
350 return WvString(
"`%s': invalid number.", arg);
355 return WvString(
"`%s': invalid number.", arg);
360 return WvString::null;
386 char *tailptr = NULL;
388 float tmp = strtof(arg, &tailptr);
392 return WvString(
"`%s': invalid number.", arg);
397 return WvString(
"`%s': invalid number.", arg);
402 return WvString::null;
428 char *tailptr = NULL;
430 double tmp = strtod(arg, &tailptr);
434 return WvString(
"`%s': invalid number.", arg);
439 return WvString(
"`%s': invalid number.", arg);
444 return WvString::null;
471 return WvString::null;
497 return WvString::null;
525 return WvString::null;
527 return WvString(
"invalid option: `%s'", arg);
532 WvArgsData::WvArgsData()
533 : flags(0), argp_(NULL), argp_index(0), argp_size(0),
534 required_args(0), maximum_args(0), last_no_key(-1)
539 WvArgsData::~WvArgsData()
552 void *WvArgsData::self()
const
563 if (!option->short_option)
564 option->short_option = last_no_key--;
566 options_list.append(option,
true);
567 options_dict.add(option,
false);
573 void WvArgsData::remove(
char short_option,
WvStringParm long_option)
577 WvArgsOptionList::Iter i(options_list);
578 for (i.rewind(); i.next(); )
580 bool matches_short =
false;
581 bool matches_long =
false;
583 if (short_option !=
'\0' && i->short_option == short_option)
584 matches_short =
true;
585 if (!long_option.
isnull() && i->long_option == long_option)
588 if ((matches_short && matches_long)
589 || (matches_short && i->long_option.isnull())
590 || (matches_long && i->short_option ==
'\0'))
593 options_dict.remove(i.ptr());
601 else if (matches_short)
605 i->short_option =
'\0';
606 options_dict.remove(i.ptr());
607 options_dict.add(i.ptr(),
false);
609 else if (matches_long)
612 i->long_option = WvString::null;
618 void WvArgsData::zap()
631 void WvArgsData::argp_init(
size_t size)
644 void WvArgsData::argp_build()
647 argp_init(options_list.count() + 2);
649 WvArgsOptionList::Iter i(options_list);
650 for (i.rewind(); i.next(); )
651 i->add_to_argp(*
this);
655 bool WvArgsData::argp_add(
const argp_option &option)
657 if (argp_index >= (argp_size - 1))
664 memcpy(argp_ + argp_index, &option,
sizeof(
argp_option));
667 memset(argp_ + argp_index, 0,
sizeof(
argp_option));
672 bool WvArgsData::argp_add(
const char *name,
int key,
const char *arg,
673 int flags,
const char *doc,
int group)
675 if (argp_index >= (argp_size - 1))
686 option->flags = flags;
688 option->group = group;
691 memset(argp_ + argp_index, 0,
sizeof(
argp_option));
696 bool WvArgsData::argp_double()
699 void *tmp = realloc(argp_, 2 * argp_size *
sizeof(
argp_option));
709 void WvArgsData::add_required_arg()
715 void WvArgsData::subtract_required_arg()
727 error_t WvArgsData::parser(
int key,
char *arg,
struct argp_state *state)
734 if (state->arg_num >= data->maximum_args)
739 data->args_.append(arg);
742 case ARGP_KEY_NO_ARGS:
744 if (state->arg_num < data->required_args)
755 WvString error = option->process(arg);
758 argp_failure(state, argp_err_exit_status, 0,
764 return ARGP_ERR_UNKNOWN;
791 if (header && footer)
792 prog_doc =
WvString(
"%s\v%s", header, footer);
796 prog_doc =
WvString(
" \v%s", footer);
799 argp_program_version = version;
800 argp_program_bug_address = email;
802 struct argp argp = { data->argp(), &WvArgsData::parser, args_doc, prog_doc,
805 bool error = argp_parse(&argp, argc, argv, data->flags, 0, data->self());
809 remaining_args->zap();
810 WvStringList::Iter i(data->args());
811 for (i.rewind(); i.next(); )
812 remaining_args->add(
new WvString(*i),
true);
821 this->version = version;
833 this->header = header;
839 this->footer = footer;
845 struct argp argp = { data->argp(), 0, 0, 0, 0, 0, 0 };
846 argp_help(&argp, stdout, ARGP_HELP_STD_USAGE, argv[0]);
852 struct argp argp = { data->argp(), 0, 0, 0, 0, 0, 0 };
853 argp_help(&argp, stdout, ARGP_HELP_STD_HELP, argv[0]);
859 data->remove(short_option, long_option);
867 data->remove(short_option, long_option);
875 data->remove(short_option, long_option);
883 data->remove(short_option, long_option);
891 data->remove(short_option, long_option);
892 data->add(
new WvArgsIntOption(short_option, long_option, desc, arg_desc,
899 data->remove(short_option, long_option);
907 data->remove(short_option, long_option);
915 data->remove(short_option, long_option);
924 data->remove(short_option, long_option);
933 data->remove(short_option, long_option);
935 desc, arg_desc, val));
942 data->remove(short_option, long_option);
950 data->remove(short_option, WvString::null);
956 data->remove(0, long_option);
968 data->add_required_arg();
970 args_doc.append(
" ");
971 args_doc.append(desc);
974 args_doc.append(
"...");
975 data->maximum_args = LONG_MAX;
977 else if (data->maximum_args < LONG_MAX)
978 ++(data->maximum_args);
986 data->subtract_required_arg();
994 case NO_EXIT_ON_ERRORS:
995 return data->flags & ARGP_NO_EXIT;
1002 void WvArgs::set_flag(
const flags_t flag,
const bool value)
1004 printf(
"set_flag(%d, %d)\n", flag, value);
1008 case NO_EXIT_ON_ERRORS:
1009 mask = ARGP_NO_EXIT;
1016 data->flags |= mask;
1018 data->flags &= ~mask;
1020 printf(
"set_flag(%d, %d) = %d\n", flag, value, data->flags);
A WvFastString acts exactly like a WvString, but can take (const char *) strings without needing to a...
void set_email(WvStringParm email)
Set the e-mail address for bug reports.
void remove_option(char short_option)
Remove an option by specifying its short form.
bool isnull() const
returns true if this string is null
flags_t
These flags control the behaviour of WvArgs.
void print_help(int argc, char **argv)
Output the long usage message based on the provided options.
wv::function< bool(void *)> NoArgCallback
The callback type used for switches that do not take a parameter.
const char * cstr() const
return a (const char *) for this string.
bool process(int argc, char **argv, WvStringList *remaining_args=NULL)
Process the command line arguments passed to main() using the options provided through calls to add_o...
WvArgs - Sane command-line argument processing for WvStreams.
void add_optional_arg(WvStringParm desc, bool multiple=false)
Add an optional argument to the list of parameters.
void set_help_header(WvStringParm header)
Set the introductory help message, printed at the beginning of –help.
void add_required_arg(WvStringParm desc, bool multiple=false)
Add a required argument to the list of parameters.
bool get_flag(const flags_t flag) const
Get and set flags.
void add_flip_bool_option(char short_option, WvStringParm long_option, WvStringParm desc, bool &val)
Add a boolean option, which, when spefied, changes the value of the boolean variable from false to tr...
void print_usage(int argc, char **argv)
Output the short usage message based on the provided options.
void add_option(char short_option, WvStringParm long_option, WvStringParm desc, WvStringParm arg_desc, int &val)
Add a switch that takes an integer argument.
This is a WvList of WvStrings, and is a really handy way to parse strings.
void add_set_bool_option(char short_option, WvStringParm long_option, WvStringParm desc, bool &val)
Add a boolean option, which, when specified, sets the specified boolean variable to true...
void remove_all_options()
Remove all options.
wv::function< bool(WvStringParm, void *)> ArgCallback
The callback type used for switches that take a parameter It returns true if the switch was parsed co...
void set_version(WvStringParm version)
Set the –version string.
WvString is an implementation of a simple and efficient printable-string class.
void set_help_footer(WvStringParm footer)
Set the descriptive help message, printed at the end of –help.
void add_reset_bool_option(char short_option, WvStringParm long_option, WvStringParm desc, bool &val)
Add a boolean option, which, when spefied, sets the specified boolean variable to false...