if (eq) {
// everything after = is option argument
arg = eq + 1;
} else if ((option->options & ARG_OPTIONAL) == 0) {
} else if ((option->flags & ARG_OPTIONAL) == 0) {
// next argv is option argument
if (i == argc) goto missing;
arg = argv[++i];
}
}
argp->parser(key, arg, this);
argp->parse(key, arg, this);
}
}
// parse rest argv as normal arguments
for (i = i + 1; i < argc; i++) {
argp->parser(Key::ARG, argv[i], this);
argp->parse(Key::ARG, argv[i], this);
args++;
}
if (!args) argp->parser(Key::NO_ARGS, 0, this);
if (!args) argp->parse(Key::NO_ARGS, 0, this);
argp->parser(Key::END, 0, this);
argp->parser(Key::SUCCESS, 0, this);
argp->parse(Key::END, 0, this);
argp->parse(Key::SUCCESS, 0, this);
return 0;
unknown:
std::cerr << std::format("unknown option {}\n", argv[i]);
argp->parser(Key::ERROR, 0, this);
argp->parse(Key::ERROR, 0, this);
return 1;
missing:
std::cerr << std::format("option {} missing a value\n", argv[i]);
argp->parser(Key::ERROR, 0, this);
argp->parse(Key::ERROR, 0, this);
return 2;
excess:
std::cerr << std::format("option {} don't require a value\n", argv[i]);
argp->parser(Key::ERROR, 0, this);
argp->parse(Key::ERROR, 0, this);
return 3;
}
class trie_t {
public:
~trie_t() noexcept {
for (uint8_t i = 0; i < 26; i++) {
delete children[i];
}
}
void insert(const std::string &option, int key) {
trie_t *crnt = this;
for (const char c : option) {
if (!crnt->terminal) crnt->key = key;
crnt->count++;
const uint8_t idx = c - 'a';
if (!crnt->children[idx]) crnt->children[idx] = new trie_t();
crnt = crnt->children[idx];
}
crnt->terminal = true;
crnt->key = key;
}
int get(const std::string &option) const {
const trie_t *crnt = this;
for (const char c : option) {
const uint8_t idx = c - 'a';
if (!crnt->children[idx]) return 0;
crnt = crnt->children[idx];
}
if (!crnt->terminal && crnt->count > 1) return 0;
return crnt->key;
}
private:
trie_t *children[26] = {0};
uint8_t count = 0;
int key = 0;
bool terminal = false;
};
struct help_entry_t {
std::vector<const char *> opt_long;
std::vector<char> opt_short;