108 char y_str[2] = { y.
swShort ,
'\0' };
109 return (strcmp(x.
swLong, y_str) < 0);
112 char x_str[2] = { x.
swShort ,
'\0' };
113 return (strcmp(x_str, y.
swLong) < 0);
128 return (strcmp(str,
"--") == 0);
138 return (strncmp(str,
"--", 2) == 0);
144 return (*str ==
'-');
179 int argc,
const char*
const argv[])
182 parse(optArgDescs, argc, argv);
201 int argc,
const char*
const argv[])
206 checkForErrors(optArgDescsOrig);
207 const OptArgDesc* optArgDescs = createSortedCopy(optArgDescsOrig);
209 bool endOfOpts =
false;
211 for (
int i = 1; i < argc; ++i) {
212 const char* str = argv[i];
217 if (str ==
NULL || *str ==
'\0') {
235 SwDesc swdesc = makeSwitchDesc(str);
236 if (swdesc.
sw.empty()) {
241 const OptArgDesc* d = findOptDesc(optArgDescs, swdesc);
247 if (d->
kind == ARG_NONE) {
248 if (!swdesc.
arg.empty()) {
249 string msg =
"Invalid argument `" + swdesc.
arg +
"' to switch `" 254 else if (d->
kind == ARG_REQ || d->
kind == ARG_OPT) {
255 if (swdesc.
arg.empty()) {
257 if (nexti < argc && argv[nexti]) {
258 const char* nxt = argv[nexti];
267 if (swdesc.
arg.empty() && d->
kind == ARG_REQ) {
273 addOption(*d, swdesc);
279 arguments.push_back(
string(str));
283 delete[] optArgDescs;
300 string sw(1, swShort);
314 SwitchToArgMap::const_iterator it = switchToArgMap.find(sw);
315 return (it != switchToArgMap.end());
323 string sw(1, swShort);
337 SwitchToArgMap::const_iterator it = switchToArgMap.find(sw);
338 if ((it != switchToArgMap.end()) && ((*it).second !=
NULL)) {
349 string sw(1, swShort);
350 return getOptArg(sw);
357 return getOptArg(sw);
363 SwitchToArgMap::const_iterator it = switchToArgMap.find(sw);
364 if (it == switchToArgMap.end()) {
367 string* arg = (*it).second;
378 return arguments.size();
457 const string& x = value;
458 if (x ==
"true" || x ==
"1" || x ==
"yes" || x ==
"on") {
461 else if (x ==
"false" || x ==
"0" || x ==
"no" || x ==
"off") {
465 string msg =
"Expected boolean value but received: '" + x +
"'";
467 msg = string(errTag) +
": " + msg;
479 os <<
"Command: `" << getCmd() <<
"'" << std::endl;
481 os <<
"Switch to Argument map:" << std::endl;
482 for (SwitchToArgMap::const_iterator it = switchToArgMap.begin();
483 it != switchToArgMap.end(); ++it) {
484 const string& sw = (*it).first;
485 const string* arg = (*it).second;
486 os <<
" " << sw <<
" --> " << ((arg) ? *arg :
"<>") << std::endl;
489 os <<
"Regular arguments:" << std::endl;
490 for (
unsigned int i = 0; i < arguments.size(); ++i) {
491 os <<
" " << arguments[i] << std::endl;
509 for (SwitchToArgMap::iterator it = switchToArgMap.begin();
510 it != switchToArgMap.end(); ++it) {
511 string* arg = (*it).second;
514 switchToArgMap.clear();
526 for (
const OptArgDesc* p = optArgDescs; *p != OptArgDesc_NULL; ++p) {
533 for (
const OptArgDesc* p = optArgDescs; *p != OptArgDesc_NULL; ++p, ++i) {
536 copy[sz] = OptArgDesc_NULL;
558 for (
const OptArgDesc* p = optArgDescs; *p != OptArgDesc_NULL; ++p) {
560 if (p->swShort == 0 && !p->swLong) {
572 if (p->kind == ARG_NULL) {
573 msg =
"OptArgDesc.kind is invalid for: " + sw;
578 if (p->dupKind == DUPOPT_NULL) {
579 msg =
"OptArgDesc.dupKind is invalid for: " + sw;
584 if (p->dupKind == DUPOPT_CAT && !p->dupArgSep) {
585 msg =
"OptArgDesc.dupArgSep is invalid for: " + sw;
599 unsigned int len = strlen(str);
600 const char* strEnd = str + len;
601 const char* begSw =
NULL, *endSw =
NULL;
602 const char* begArg =
NULL, *endArg =
NULL;
606 begArg = strchr(str,
'=');
612 endSw = (begArg) ? (begArg - 2) : (strEnd - 1);
617 begArg = (len > 2) ? (str + 2) :
NULL;
618 endArg = (begArg) ? (strEnd - 1) :
NULL;
619 begSw = (len > 1) ? (str + 1) :
NULL;
629 for (
const char* p = begSw; p && p <= endSw; ++p) {
632 for (
const char* p = begArg; p && p <= endArg; ++p) {
647 bool errOnMultipleMatches)
658 unsigned int swLen = swdesc.
sw.length();
660 for (
const OptArgDesc* p = optArgDescs; *p != OptArgDesc_NULL; ++p) {
662 if (p->swLong && strncmp(p->swLong, swdesc.
sw.c_str(), swLen) == 0) {
668 if (p->swShort != 0 && p->swShort == swdesc.
sw[0]) {
680 if (errOnMultipleMatches
681 && (m = findOptDesc((odesc + 1), swdesc,
false))) {
686 bool isOk = (swdesc.
isLong 687 && (strcmp(odesc->
swLong, swdesc.
sw.c_str()) == 0)
690 string msg =
"Switch `";
691 msg += swdesc.
sw; msg +=
"' matches two different options: ";
714 string swShort(1, odesc.
swShort);
715 addOption(odesc, swShort, swdesc.
arg);
718 string swLong(odesc.
swLong);
719 addOption(odesc, swLong, swdesc.
arg);
731 const string& sw,
const string& arg)
733 SwitchToArgMap::iterator it = switchToArgMap.find(sw);
734 if (it == switchToArgMap.end()) {
736 string* theArg = (arg.empty()) ?
NULL :
new string(arg);
737 switchToArgMap.insert(SwitchToArgMap::value_type(sw, theArg));
741 string* theArg = (*it).second;
743 if (odesc.
dupKind == DUPOPT_ERR) {
749 theArg =
new string(arg);
752 if (odesc.
dupKind == DUPOPT_CLOB) {
755 else if (odesc.
dupKind == DUPOPT_CAT) {
bool isOpt(const char swShort) const
static OptArgDesc OptArgDesc_NULL
const OptArgDesc * createSortedCopy(const OptArgDesc *optArgDescs)
const std::string & getOptArg(const char swShort) const
double toDbl(const char *str, unsigned *endidx)
const std::string & getCmd() const
static uint64_t toUInt64(const std::string &str)
static string MISSING_ARG
uint64_t toUInt64(const char *str, unsigned *endidx)
virtual const std::string & what() const
static double toDbl(const std::string &str)
void copy(const char *dst,...)
bool isOptArg(const char swShort) const
void parse(const OptArgDesc *optArgDescs, int argc, const char *const argv[])
long toLong(const char *str, unsigned *endidx)
static bool isSwitch(const char *str)
unsigned int getNumArgs() const
bool operator()(const CmdLineParser::OptArgDesc &x, const CmdLineParser::OptArgDesc &y) const
static bool isShortSwitch(const char *str)
static bool isOptArg_long(const char *option)
void dump(std::ostream &os=std::cerr) const
void checkForErrors(const OptArgDesc *optArgDescs)
static bool isDashDash(const char *str)
static string UNKNOWN_SWITCH
static string MISSING_SWITCH
#define CmdLineParser_OptArgDesc_NULL_MACRO
const OptArgDesc * findOptDesc(const OptArgDesc *optArgDescs, const SwDesc &swdesc, bool errOnMultipleMatches=true)
SwDesc makeSwitchDesc(const char *str)
static bool isLongSwitch(const char *str)
const std::string & getArg(unsigned int i) const
static bool parseArg_bool(const std::string &value, const char *errTag)
static bool isArg(const char *str)
static long toLong(const std::string &str)
void addOption(const OptArgDesc &odesc, const SwDesc &swdesc)