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