8 #include "wvscatterhash.h"
12 #undef __error_t_defined
31 WvStringParm _long_option,
33 : short_option(_short_option), long_option(_long_option), desc(_desc)
41 virtual WvString process(WvStringParm arg)
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);
119 WvStringParm _long_option,
137 WvStringParm _long_option,
145 virtual WvString process(WvStringParm arg)
148 return WvString::null;
163 WvStringParm _long_option,
171 virtual WvString process(WvStringParm arg)
174 return WvString::null;
189 WvStringParm _long_option,
197 virtual WvString process(WvStringParm arg)
200 return WvString::null;
212 WvStringParm _long_option,
220 virtual WvString process(WvStringParm arg)
223 return WvString::null;
239 WvStringParm _long_option,
248 virtual WvString process(WvStringParm arg)
251 return WvString::null;
253 return WvString(
"invalid option `%s'", arg);
267 WvStringParm _long_option,
269 WvStringParm _arg_desc)
277 data.argp_add(long_option, short_option, arg_desc, 0, desc, 0);
291 WvStringParm _long_option,
293 WvStringParm _arg_desc,
300 virtual WvString process(WvStringParm arg)
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;
333 WvStringParm _long_option,
335 WvStringParm _arg_desc,
342 virtual WvString process(WvStringParm arg)
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;
375 WvStringParm _long_option,
377 WvStringParm _arg_desc,
384 virtual WvString process(WvStringParm arg)
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;
417 WvStringParm _long_option,
419 WvStringParm _arg_desc,
426 virtual WvString process(WvStringParm arg)
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;
459 WvStringParm _long_option,
461 WvStringParm _arg_desc,
468 virtual WvString process(WvStringParm arg)
471 return WvString::null;
485 WvStringParm _long_option,
487 WvStringParm _arg_desc,
494 virtual WvString process(WvStringParm arg)
497 return WvString::null;
512 WvStringParm _long_option,
514 WvStringParm _arg_desc,
522 virtual WvString process(WvStringParm arg)
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]);
857 WvStringParm desc,
bool &val)
859 data->remove(short_option, long_option);
865 WvStringParm desc,
bool &val)
867 data->remove(short_option, long_option);
873 WvStringParm desc,
bool &val)
875 data->remove(short_option, long_option);
883 data->remove(short_option, long_option);
889 WvStringParm desc, WvStringParm arg_desc,
int &val)
891 data->remove(short_option, long_option);
892 data->add(
new WvArgsIntOption(short_option, long_option, desc, arg_desc,
897 WvStringParm desc, WvStringParm arg_desc,
long &val)
899 data->remove(short_option, long_option);
905 WvStringParm desc, WvStringParm arg_desc,
float &val)
907 data->remove(short_option, long_option);
913 WvStringParm desc, WvStringParm arg_desc,
double &val)
915 data->remove(short_option, long_option);
921 WvStringParm desc, WvStringParm arg_desc,
924 data->remove(short_option, long_option);
930 WvStringParm desc, WvStringParm arg_desc,
933 data->remove(short_option, long_option);
935 desc, arg_desc, val));
939 WvStringParm desc, WvStringParm arg_desc,
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);