00001
00002
00003
00004
00005
00006
00007 #include "wvargs.h"
00008 #include "wvscatterhash.h"
00009
00010
00011 #undef error_t
00012 #undef argc
00013 #undef argv
00014 #undef __argc
00015 #undef __argv
00016
00017 #include <argp.h>
00018
00019
00020 class WvArgsOption
00021 {
00022 public:
00023
00024 int short_option;
00025 WvString long_option;
00026 WvString desc;
00027
00028 WvArgsOption(int _short_option,
00029 WvStringParm _long_option,
00030 WvStringParm _desc)
00031 : short_option(_short_option), long_option(_long_option), desc(_desc)
00032 {
00033 }
00034
00035 virtual ~WvArgsOption()
00036 {
00037 }
00038
00039 virtual WvString process(WvStringParm arg)
00040 {
00041 return WvString::null;
00042 }
00043
00044 virtual void add_to_argp(WvArgsData &data);
00045 };
00046
00047
00048 DeclareWvList(WvArgsOption);
00049 DeclareWvScatterDict(WvArgsOption, int, short_option);
00050
00051 class WvArgsData
00052 {
00053 public:
00054 WvArgsData();
00055 ~WvArgsData();
00056
00057 argp_option *argp() const;
00058 void *self() const;
00059
00060 void add(WvArgsOption *option);
00061 void remove(char short_option, WvStringParm long_option);
00062 void zap();
00063
00064 void add_required_arg();
00065 void subtract_required_arg();
00066 const WvStringList &args() const;
00067
00068 static error_t parser(int key, char *arg, argp_state *state);
00069
00070 unsigned int flags;
00071
00072 protected:
00073 friend class WvArgsOption;
00074 friend class WvArgsArgOption;
00075 friend class WvArgs;
00076
00077 void argp_build();
00078 bool argp_add(const char *name, int key, const char *arg, int flags,
00079 const char *doc, int group);
00080 private:
00081 void argp_init(size_t size = 0);
00082
00083 bool argp_add(const argp_option &option);
00084 bool argp_double();
00085
00086 argp_option *argp_;
00087 size_t argp_index;
00088 size_t argp_size;
00089
00090
00091
00092
00093
00094 WvArgsOptionList options_list;
00095 WvArgsOptionDict options_dict;
00096
00097 WvStringList args_;
00098 size_t required_args;
00099 size_t maximum_args;
00100
00101 int last_no_key;
00102 };
00103
00104
00105 void WvArgsOption::add_to_argp(WvArgsData &data)
00106 {
00107 data.argp_add(long_option, short_option, 0, 0, desc, 0);
00108 }
00109
00110
00111 class WvArgsNoArgOption : public WvArgsOption
00112 {
00113
00114 public:
00115
00116 WvArgsNoArgOption(int _short_option,
00117 WvStringParm _long_option,
00118 WvStringParm _desc)
00119 : WvArgsOption(_short_option, _long_option, _desc)
00120 {
00121 }
00122 };
00123
00124
00125 class WvArgsSetBoolOption : public WvArgsNoArgOption
00126 {
00127
00128 private:
00129
00130 bool &flag;
00131
00132 public:
00133
00134 WvArgsSetBoolOption(int _short_option,
00135 WvStringParm _long_option,
00136 WvStringParm _desc,
00137 bool &_flag)
00138 : WvArgsNoArgOption(_short_option, _long_option, _desc),
00139 flag(_flag)
00140 {
00141 }
00142
00143 virtual WvString process(WvStringParm arg)
00144 {
00145 flag = true;
00146 return WvString::null;
00147 }
00148 };
00149
00150
00151 class WvArgsResetBoolOption : public WvArgsNoArgOption
00152 {
00153
00154 private:
00155
00156 bool &flag;
00157
00158 public:
00159
00160 WvArgsResetBoolOption(int _short_option,
00161 WvStringParm _long_option,
00162 WvStringParm _desc,
00163 bool &_flag)
00164 : WvArgsNoArgOption(_short_option, _long_option, _desc),
00165 flag(_flag)
00166 {
00167 }
00168
00169 virtual WvString process(WvStringParm arg)
00170 {
00171 flag = false;
00172 return WvString::null;
00173 }
00174 };
00175
00176
00177 class WvArgsFlipBoolOption : public WvArgsNoArgOption
00178 {
00179
00180 private:
00181
00182 bool &flag;
00183
00184 public:
00185
00186 WvArgsFlipBoolOption(int _short_option,
00187 WvStringParm _long_option,
00188 WvStringParm _desc,
00189 bool &_flag)
00190 : WvArgsNoArgOption(_short_option, _long_option, _desc),
00191 flag(_flag)
00192 {
00193 }
00194
00195 virtual WvString process(WvStringParm arg)
00196 {
00197 flag = !flag;
00198 return WvString::null;
00199 }
00200 };
00201
00202
00203 class WvArgsIncIntOption : public WvArgsNoArgOption
00204 {
00205 private:
00206 int &val;
00207
00208 public:
00209 WvArgsIncIntOption(int _short_option,
00210 WvStringParm _long_option,
00211 WvStringParm _desc,
00212 int &_val)
00213 : WvArgsNoArgOption(_short_option, _long_option, _desc),
00214 val(_val)
00215 {
00216 }
00217
00218 virtual WvString process(WvStringParm arg)
00219 {
00220 val++;
00221 return WvString::null;
00222 }
00223 };
00224
00225
00226 class WvArgsNoArgCallbackOption : public WvArgsNoArgOption
00227 {
00228
00229 private:
00230
00231 WvArgs::NoArgCallback cb;
00232 void *ud;
00233
00234 public:
00235
00236 WvArgsNoArgCallbackOption(int _short_option,
00237 WvStringParm _long_option,
00238 WvStringParm _desc,
00239 WvArgs::NoArgCallback _cb,
00240 void *_ud)
00241 : WvArgsNoArgOption(_short_option, _long_option, _desc),
00242 cb(_cb), ud(_ud)
00243 {
00244 }
00245
00246 virtual WvString process(WvStringParm arg)
00247 {
00248 if (cb(ud))
00249 return WvString::null;
00250 else
00251 return WvString("invalid option `%s'", arg);
00252 }
00253 };
00254
00255
00256 class WvArgsArgOption : public WvArgsOption
00257 {
00258 private:
00259
00260 WvString arg_desc;
00261
00262 public:
00263
00264 WvArgsArgOption(int _short_option,
00265 WvStringParm _long_option,
00266 WvStringParm _desc,
00267 WvStringParm _arg_desc)
00268 : WvArgsOption(_short_option, _long_option, _desc),
00269 arg_desc(_arg_desc)
00270 {
00271 }
00272
00273 virtual void add_to_argp(WvArgsData &data)
00274 {
00275 data.argp_add(long_option, short_option, arg_desc, 0, desc, 0);
00276 }
00277 };
00278
00279
00280 class WvArgsIntOption : public WvArgsArgOption
00281 {
00282 private:
00283
00284 int &val;
00285
00286 public:
00287
00288 WvArgsIntOption(int _short_option,
00289 WvStringParm _long_option,
00290 WvStringParm _desc,
00291 WvStringParm _arg_desc,
00292 int &_val)
00293 : WvArgsArgOption(_short_option, _long_option, _desc, _arg_desc),
00294 val(_val)
00295 {
00296 }
00297
00298 virtual WvString process(WvStringParm arg)
00299 {
00300 char *tailptr = NULL;
00301 errno = 0;
00302 long int tmp = strtol(arg, &tailptr, 10);
00303 if (errno == ERANGE || tmp > INT_MAX || tmp < INT_MIN )
00304 {
00305
00306 return WvString("`%s': invalid number.", arg);
00307 }
00308 else if (*tailptr)
00309 {
00310
00311 return WvString("`%s': invalid number.", arg);
00312 }
00313 else
00314 {
00315 val = tmp;
00316 return WvString::null;
00317 }
00318 }
00319 };
00320
00321
00322 class WvArgsLongOption : public WvArgsArgOption
00323 {
00324 private:
00325
00326 long &val;
00327
00328 public:
00329
00330 WvArgsLongOption(int _short_option,
00331 WvStringParm _long_option,
00332 WvStringParm _desc,
00333 WvStringParm _arg_desc,
00334 long &_val)
00335 : WvArgsArgOption(_short_option, _long_option, _desc, _arg_desc),
00336 val(_val)
00337 {
00338 }
00339
00340 virtual WvString process(WvStringParm arg)
00341 {
00342 char *tailptr = NULL;
00343 errno = 0;
00344 long int tmp = strtol(arg, &tailptr, 10);
00345 if (errno == ERANGE)
00346 {
00347
00348 return WvString("`%s': invalid number.", arg);
00349 }
00350 else if (*tailptr)
00351 {
00352
00353 return WvString("`%s': invalid number.", arg);
00354 }
00355 else
00356 {
00357 val = tmp;
00358 return WvString::null;
00359 }
00360 }
00361 };
00362
00363
00364 class WvArgsFloatOption : public WvArgsArgOption
00365 {
00366 private:
00367
00368 float &val;
00369
00370 public:
00371
00372 WvArgsFloatOption(int _short_option,
00373 WvStringParm _long_option,
00374 WvStringParm _desc,
00375 WvStringParm _arg_desc,
00376 float &_val)
00377 : WvArgsArgOption(_short_option, _long_option, _desc, _arg_desc),
00378 val(_val)
00379 {
00380 }
00381
00382 virtual WvString process(WvStringParm arg)
00383 {
00384 char *tailptr = NULL;
00385 errno = 0;
00386 float tmp = strtof(arg, &tailptr);
00387 if (errno == ERANGE)
00388 {
00389
00390 return WvString("`%s': invalid number.", arg);
00391 }
00392 else if (*tailptr)
00393 {
00394
00395 return WvString("`%s': invalid number.", arg);
00396 }
00397 else
00398 {
00399 val = tmp;
00400 return WvString::null;
00401 }
00402 }
00403 };
00404
00405
00406 class WvArgsDoubleOption : public WvArgsArgOption
00407 {
00408 private:
00409
00410 double &val;
00411
00412 public:
00413
00414 WvArgsDoubleOption(int _short_option,
00415 WvStringParm _long_option,
00416 WvStringParm _desc,
00417 WvStringParm _arg_desc,
00418 double &_val)
00419 : WvArgsArgOption(_short_option, _long_option, _desc, _arg_desc),
00420 val(_val)
00421 {
00422 }
00423
00424 virtual WvString process(WvStringParm arg)
00425 {
00426 char *tailptr = NULL;
00427 errno = 0;
00428 double tmp = strtod(arg, &tailptr);
00429 if (errno == ERANGE)
00430 {
00431
00432 return WvString("`%s': invalid number.", arg);
00433 }
00434 else if (*tailptr)
00435 {
00436
00437 return WvString("`%s': invalid number.", arg);
00438 }
00439 else
00440 {
00441 val = tmp;
00442 return WvString::null;
00443 }
00444 }
00445 };
00446
00447
00448 class WvArgsStringOption : public WvArgsArgOption
00449 {
00450 private:
00451
00452 WvString &val;
00453
00454 public:
00455
00456 WvArgsStringOption(int _short_option,
00457 WvStringParm _long_option,
00458 WvStringParm _desc,
00459 WvStringParm _arg_desc,
00460 WvString &_val)
00461 : WvArgsArgOption(_short_option, _long_option, _desc, _arg_desc),
00462 val(_val)
00463 {
00464 }
00465
00466 virtual WvString process(WvStringParm arg)
00467 {
00468 val = arg;
00469 return WvString::null;
00470 }
00471 };
00472
00473
00474 class WvArgsStringListAppendOption : public WvArgsArgOption
00475 {
00476 private:
00477
00478 WvStringList &val;
00479
00480 public:
00481
00482 WvArgsStringListAppendOption(int _short_option,
00483 WvStringParm _long_option,
00484 WvStringParm _desc,
00485 WvStringParm _arg_desc,
00486 WvStringList &_val)
00487 : WvArgsArgOption(_short_option, _long_option, _desc, _arg_desc),
00488 val(_val)
00489 {
00490 }
00491
00492 virtual WvString process(WvStringParm arg)
00493 {
00494 val.append(arg);
00495 return WvString::null;
00496 }
00497 };
00498
00499
00500 class WvArgsArgCallbackOption : public WvArgsArgOption
00501 {
00502 private:
00503
00504 WvArgs::ArgCallback cb;
00505 void *ud;
00506
00507 public:
00508
00509 WvArgsArgCallbackOption(int _short_option,
00510 WvStringParm _long_option,
00511 WvStringParm _desc,
00512 WvStringParm _arg_desc,
00513 WvArgs::ArgCallback _cb,
00514 void *_ud)
00515 : WvArgsArgOption(_short_option, _long_option, _desc, _arg_desc),
00516 cb(_cb), ud(_ud)
00517 {
00518 }
00519
00520 virtual WvString process(WvStringParm arg)
00521 {
00522 if (cb(arg, ud))
00523 return WvString::null;
00524 else
00525 return WvString("invalid option: `%s'", arg);
00526 }
00527 };
00528
00529
00530 WvArgsData::WvArgsData()
00531 : flags(0), argp_(NULL), argp_index(0), argp_size(0),
00532 required_args(0), maximum_args(0), last_no_key(-1)
00533 {
00534 }
00535
00536
00537 WvArgsData::~WvArgsData()
00538 {
00539 if (argp_)
00540 free(argp_);
00541 }
00542
00543
00544 argp_option *WvArgsData::argp() const
00545 {
00546 return argp_;
00547 }
00548
00549
00550 void *WvArgsData::self() const
00551 {
00552 return (void *)this;
00553 }
00554
00555
00556 void WvArgsData::add(WvArgsOption *option)
00557 {
00558 if (!option)
00559 return;
00560
00561 if (!option->short_option)
00562 option->short_option = last_no_key--;
00563
00564 options_list.append(option, true);
00565 options_dict.add(option, false);
00566 }
00567
00568
00569
00570
00571 void WvArgsData::remove(char short_option, WvStringParm long_option)
00572 {
00573
00574
00575 WvArgsOptionList::Iter i(options_list);
00576 for (i.rewind(); i.next(); )
00577 {
00578 bool matches_short = false;
00579 bool matches_long = false;
00580
00581 if (short_option != '\0' && i->short_option == short_option)
00582 matches_short = true;
00583 if (!long_option.isnull() && i->long_option == long_option)
00584 matches_long = true;
00585
00586 if (matches_short && matches_long
00587 || matches_short && i->long_option.isnull()
00588 || matches_long && i->short_option == '\0')
00589 {
00590
00591 options_dict.remove(i.ptr());
00592 i.xunlink();
00593 if (argp_)
00594 {
00595 free(argp_);
00596 argp_ = NULL;
00597 }
00598 }
00599 else if (matches_short)
00600 {
00601
00602
00603 i->short_option = '\0';
00604 options_dict.remove(i.ptr());
00605 options_dict.add(i.ptr(), false);
00606 }
00607 else if (matches_long)
00608 {
00609
00610 i->long_option = WvString::null;
00611 }
00612 }
00613 }
00614
00615
00616 void WvArgsData::zap()
00617 {
00618 options_dict.zap();
00619 options_list.zap();
00620
00621 if (argp_)
00622 {
00623 free(argp_);
00624 argp_ = NULL;
00625 }
00626 }
00627
00628
00629 void WvArgsData::argp_init(size_t size)
00630 {
00631 argp_size = size;
00632 if (argp_size < 1)
00633 argp_size = 1;
00634
00635
00636 argp_ = (argp_option *)malloc(argp_size * sizeof(argp_option));
00637
00638 memset(argp_, 0, sizeof(argp_option));
00639 }
00640
00641
00642 void WvArgsData::argp_build()
00643 {
00644 if (!argp_)
00645 argp_init(options_list.count() + 2);
00646
00647 WvArgsOptionList::Iter i(options_list);
00648 for (i.rewind(); i.next(); )
00649 i->add_to_argp(*this);
00650 }
00651
00652
00653 bool WvArgsData::argp_add(const argp_option &option)
00654 {
00655 if (argp_index >= (argp_size - 1))
00656 {
00657 if (!argp_double())
00658 return false;
00659 }
00660
00661
00662 memcpy(argp_ + argp_index, &option, sizeof(argp_option));
00663
00664 ++argp_index;
00665 memset(argp_ + argp_index, 0, sizeof(argp_option));
00666 return true;
00667 }
00668
00669
00670 bool WvArgsData::argp_add(const char *name, int key, const char *arg,
00671 int flags, const char *doc, int group)
00672 {
00673 if (argp_index >= (argp_size - 1))
00674 {
00675 if (!argp_double())
00676 return false;
00677 }
00678
00679
00680 argp_option *option = argp_ + argp_index;
00681 option->name = name;
00682 option->key = key;
00683 option->arg = arg;
00684 option->flags = flags;
00685 option->doc = doc;
00686 option->group = group;
00687
00688 ++argp_index;
00689 memset(argp_ + argp_index, 0, sizeof(argp_option));
00690 return true;
00691 }
00692
00693
00694 bool WvArgsData::argp_double()
00695 {
00696
00697 void *tmp = realloc(argp_, 2 * argp_size * sizeof(argp_option));
00698 if (!tmp)
00699 return false;
00700
00701 argp_ = (argp_option *)tmp;
00702 argp_size *= 2;
00703 return true;
00704 }
00705
00706
00707 void WvArgsData::add_required_arg()
00708 {
00709 ++required_args;
00710 }
00711
00712
00713 void WvArgsData::subtract_required_arg()
00714 {
00715 --required_args;
00716 }
00717
00718
00719 const WvStringList &WvArgsData::args() const
00720 {
00721 return args_;
00722 }
00723
00724
00725 error_t WvArgsData::parser(int key, char *arg, struct argp_state *state)
00726 {
00727 WvArgsData *data = (WvArgsData *)state->input;
00728
00729 switch (key)
00730 {
00731 case ARGP_KEY_ARG:
00732 if (state->arg_num >= data->maximum_args)
00733 {
00734
00735 argp_usage(state);
00736 }
00737 data->args_.append(arg);
00738 break;
00739
00740 case ARGP_KEY_NO_ARGS:
00741 case ARGP_KEY_END:
00742 if (state->arg_num < data->required_args)
00743 {
00744
00745 argp_usage(state);
00746 }
00747 break;
00748
00749 default:
00750 WvArgsOption *option = data->options_dict[key];
00751 if (option)
00752 {
00753 WvString error = option->process(arg);
00754 if (!error.isnull())
00755 {
00756 argp_failure(state, argp_err_exit_status, 0,
00757 "%s", error.cstr());
00758 return EINVAL;
00759 }
00760 }
00761 else
00762 return ARGP_ERR_UNKNOWN;
00763 }
00764
00765 return 0;
00766 }
00767
00768
00769 WvArgs::WvArgs()
00770 : data(new WvArgsData())
00771 {
00772 }
00773
00774
00775 WvArgs::~WvArgs()
00776 {
00777 if (data)
00778 delete data;
00779 }
00780
00781
00782 bool WvArgs::process(int argc, char **argv, WvStringList *remaining_args)
00783 {
00784 if (!data->argp())
00785 data->argp_build();
00786
00787
00788 WvString prog_doc;
00789 if (header && footer)
00790 prog_doc = WvString("%s\v%s", header, footer);
00791 else if (header)
00792 prog_doc = WvString("%s", header);
00793 else if (footer)
00794 prog_doc = WvString(" \v%s", footer);
00795
00796
00797 argp_program_version = version;
00798 argp_program_bug_address = email;
00799
00800 struct argp argp = { data->argp(), &WvArgsData::parser, args_doc, prog_doc,
00801 0, 0, 0 };
00802
00803 bool error = argp_parse(&argp, argc, argv, data->flags, 0, data->self());
00804
00805 if (remaining_args)
00806 {
00807 remaining_args->zap();
00808 WvStringList::Iter i(data->args());
00809 for (i.rewind(); i.next(); )
00810 remaining_args->add(new WvString(*i), true);
00811 }
00812
00813 return !error;
00814 }
00815
00816
00817 void WvArgs::set_version(WvStringParm version)
00818 {
00819 this->version = version;
00820 }
00821
00822
00823 void WvArgs::set_email(WvStringParm email)
00824 {
00825 this->email = email;
00826 }
00827
00828
00829 void WvArgs::set_help_header(WvStringParm header)
00830 {
00831 this->header = header;
00832 }
00833
00834
00835 void WvArgs::set_help_footer(WvStringParm footer)
00836 {
00837 this->footer = footer;
00838 }
00839
00840
00841 void WvArgs::print_usage(int argc, char **argv)
00842 {
00843 struct argp argp = { data->argp(), 0, 0, 0, 0, 0, 0 };
00844 argp_help(&argp, stdout, ARGP_HELP_STD_USAGE, argv[0]);
00845 }
00846
00847
00848 void WvArgs::print_help(int argc, char **argv)
00849 {
00850 struct argp argp = { data->argp(), 0, 0, 0, 0, 0, 0 };
00851 argp_help(&argp, stdout, ARGP_HELP_STD_HELP, argv[0]);
00852 }
00853
00854 void WvArgs::add_set_bool_option(char short_option, WvStringParm long_option,
00855 WvStringParm desc, bool &val)
00856 {
00857 data->remove(short_option, long_option);
00858 data->add(new WvArgsSetBoolOption(short_option, long_option, desc, val));
00859 }
00860
00861
00862 void WvArgs::add_reset_bool_option(char short_option, WvStringParm long_option,
00863 WvStringParm desc, bool &val)
00864 {
00865 data->remove(short_option, long_option);
00866 data->add(new WvArgsResetBoolOption(short_option, long_option, desc, val));
00867 }
00868
00869
00870 void WvArgs::add_flip_bool_option(char short_option, WvStringParm long_option,
00871 WvStringParm desc, bool &val)
00872 {
00873 data->remove(short_option, long_option);
00874 data->add(new WvArgsFlipBoolOption(short_option, long_option, desc, val));
00875 }
00876
00877
00878 void WvArgs::add_option(char short_option, WvStringParm long_option,
00879 WvStringParm desc, NoArgCallback cb, void *ud)
00880 {
00881 data->remove(short_option, long_option);
00882 data->add(new WvArgsNoArgCallbackOption(short_option, long_option, desc,
00883 cb, ud));
00884 }
00885
00886 void WvArgs::add_option(char short_option, WvStringParm long_option,
00887 WvStringParm desc, WvStringParm arg_desc, int &val)
00888 {
00889 data->remove(short_option, long_option);
00890 data->add(new WvArgsIntOption(short_option, long_option, desc, arg_desc,
00891 val));
00892 }
00893
00894 void WvArgs::add_option(char short_option, WvStringParm long_option,
00895 WvStringParm desc, WvStringParm arg_desc, long &val)
00896 {
00897 data->remove(short_option, long_option);
00898 data->add(new WvArgsLongOption(short_option, long_option, desc, arg_desc,
00899 val));
00900 }
00901
00902 void WvArgs::add_option(char short_option, WvStringParm long_option,
00903 WvStringParm desc, WvStringParm arg_desc, float &val)
00904 {
00905 data->remove(short_option, long_option);
00906 data->add(new WvArgsFloatOption(short_option, long_option, desc, arg_desc,
00907 val));
00908 }
00909
00910 void WvArgs::add_option(char short_option, WvStringParm long_option,
00911 WvStringParm desc, WvStringParm arg_desc, double &val)
00912 {
00913 data->remove(short_option, long_option);
00914 data->add(new WvArgsDoubleOption(short_option, long_option, desc,
00915 arg_desc, val));
00916 }
00917
00918 void WvArgs::add_option(char short_option, WvStringParm long_option,
00919 WvStringParm desc, WvStringParm arg_desc,
00920 WvString &val)
00921 {
00922 data->remove(short_option, long_option);
00923 data->add(new WvArgsStringOption(short_option, long_option, desc,
00924 arg_desc, val));
00925 }
00926
00927 void WvArgs::add_option(char short_option, WvStringParm long_option,
00928 WvStringParm desc, WvStringParm arg_desc,
00929 WvStringList &val)
00930 {
00931 data->remove(short_option, long_option);
00932 data->add(new WvArgsStringListAppendOption(short_option, long_option,
00933 desc, arg_desc, val));
00934 }
00935
00936 void WvArgs::add_option(char short_option, WvStringParm long_option,
00937 WvStringParm desc, WvStringParm arg_desc,
00938 ArgCallback cb, void *ud)
00939 {
00940 data->remove(short_option, long_option);
00941 data->add(new WvArgsArgCallbackOption(short_option, long_option, desc,
00942 arg_desc, cb, ud));
00943 }
00944
00945
00946 void WvArgs::remove_option(char short_option)
00947 {
00948 data->remove(short_option, WvString::null);
00949 }
00950
00951
00952 void WvArgs::remove_option(WvStringParm long_option)
00953 {
00954 data->remove(0, long_option);
00955 }
00956
00957
00958 void WvArgs::remove_all_options()
00959 {
00960 data->zap();
00961 }
00962
00963
00964 void WvArgs::add_required_arg(WvStringParm desc, bool multiple)
00965 {
00966 data->add_required_arg();
00967 if (!!args_doc)
00968 args_doc.append(" ", multiple);
00969 args_doc.append(desc, multiple);
00970 if (data->maximum_args < LONG_MAX)
00971 ++(data->maximum_args);
00972 }
00973
00974
00975 void WvArgs::add_optional_arg(WvStringParm desc, bool multiple)
00976 {
00977
00978 add_required_arg(WvString("[%s]", desc));
00979 data->subtract_required_arg();
00980 if (multiple)
00981 {
00982 args_doc.append("...");
00983 data->maximum_args = LONG_MAX;
00984 }
00985 }
00986
00987
00988 bool WvArgs::get_flag(const flags_t flag) const
00989 {
00990 switch (flag)
00991 {
00992 case NO_EXIT_ON_ERRORS:
00993 return data->flags & ARGP_NO_EXIT;
00994 default:
00995 return false;
00996 }
00997 }
00998
00999
01000 void WvArgs::set_flag(const flags_t flag, const bool value)
01001 {
01002 printf("set_flag(%d, %d)\n", flag, value);
01003 unsigned int mask;
01004 switch (flag)
01005 {
01006 case NO_EXIT_ON_ERRORS:
01007 mask = ARGP_NO_EXIT;
01008 break;
01009 default:
01010 return;
01011 }
01012
01013 if (value)
01014 data->flags |= mask;
01015 else
01016 data->flags &= ~mask;
01017
01018 printf("set_flag(%d, %d) = %d\n", flag, value, data->flags);
01019 }