27fb7a5b96
Added test for header::getAllByName/Type
146 lines
2.8 KiB
C++
146 lines
2.8 KiB
C++
// Copyright (C) 2001 Claus Dræby
|
|
// Terms of use are in the file COPYING
|
|
#include <iostream>
|
|
#include <cstdlib>
|
|
#include "optmap.h"
|
|
|
|
using namespace std;
|
|
using namespace options_utils;
|
|
|
|
optmap::optmap(const char* usage)
|
|
: i(1), prog("program"), tail(usage)
|
|
{
|
|
}
|
|
|
|
optmap::~optmap()
|
|
{
|
|
for (group_t::iterator p = group.begin(); p != group.end(); ++p)
|
|
delete p->first;
|
|
}
|
|
optmap& optmap::add(const char* c, cmd* h)
|
|
{
|
|
if (cmds.find(c) != cmds.end())
|
|
throw invalid_argument(string("duplicated option: ")+c);
|
|
cmds[c] = h;
|
|
if (group[h].size() == 0)
|
|
gvec.push_back(h);
|
|
group[h].push_back(c);
|
|
return *this;
|
|
}
|
|
|
|
optmap& optmap::alias(const char* new_opt, const char* old_opt)
|
|
{
|
|
cmd* h = cmds[old_opt];
|
|
if (!h)
|
|
throw invalid_argument(string("no alias: ")+old_opt);
|
|
return add(new_opt, h);
|
|
}
|
|
bool optmap::parse(int c, const char** v)
|
|
{
|
|
argc = c;
|
|
argv = v;
|
|
prog = argv[0];
|
|
for (; i < argc; ++i) {
|
|
multichar = false;
|
|
const char* s = argv[i];
|
|
size_t l = strlen(s);
|
|
if (*s != '-' || l == 1)
|
|
return true;
|
|
if (s[1] == '-') {
|
|
if (l == 2) { // end of options marker `--'
|
|
++i;
|
|
return true;
|
|
}
|
|
if (!do_cmd(s+2))
|
|
return false;
|
|
} else {
|
|
char cmd[2];
|
|
cmd[1] = '\0';
|
|
multichar = l > 2;
|
|
first_multi = true;
|
|
for (const char* p = s+1; *p; ++p) {
|
|
cmd[0] = *p;
|
|
if (!do_cmd(cmd))
|
|
return false;;
|
|
first_multi = false;
|
|
if (!multichar) // get_arg used it
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
const char* optmap::get_arg()
|
|
{
|
|
if (multichar) {
|
|
if (!first_multi) {
|
|
cerr << "internal option requires argument " << argv[i] << endl;
|
|
return 0;
|
|
}
|
|
multichar = false;
|
|
return argv[i]+2;
|
|
}
|
|
return i < argc - 1 ? argv[++i] : 0;
|
|
}
|
|
|
|
void optmap::usage(bool abort)
|
|
{
|
|
cerr << "usage: " << prog;
|
|
for (gvec_t::iterator p = gvec.begin(); p != gvec.end(); ++p) {
|
|
cmd* h = *p;
|
|
vector<string>& v(group[h]);
|
|
string arg = h->arg();
|
|
bool need_par = arg.size() > 0 && v.size() > 1;
|
|
bool first = true;
|
|
cerr << " [";
|
|
if (need_par)
|
|
cerr << "(";
|
|
for (vector<string>::iterator s = v.begin(); s != v.end(); ++s) {
|
|
cerr << (first ? " " : " | ") << (s->size() != 1 ? "--":"-") << *s;
|
|
first = false;
|
|
}
|
|
if (need_par)
|
|
cerr << ")";
|
|
if (arg.size())
|
|
cerr << ' ' << arg;
|
|
cerr << " ]";
|
|
}
|
|
cerr << (tail.size() ? " " : "") << tail << endl;
|
|
if (abort)
|
|
exit(1);
|
|
}
|
|
|
|
bool optmap::do_cmd(const string& opt)
|
|
{
|
|
cmd* c = cmds[opt];
|
|
if (!c) {
|
|
cerr << "unknown option: " << opt << endl;
|
|
return false;
|
|
}
|
|
return c->do_cmd(this);
|
|
}
|
|
|
|
bool opt_int::do_cmd(optmap* om)
|
|
{
|
|
const char* arg = om->get_arg();
|
|
if (!arg)
|
|
return false;
|
|
char* end;
|
|
int v = strtol(arg, &end, 10);
|
|
if (*end) {
|
|
cerr << "failed to parse int argument: " << arg << endl;
|
|
return false;
|
|
}
|
|
val = v;
|
|
return true;
|
|
}
|
|
bool opt_string::do_cmd(optmap* om)
|
|
{
|
|
const char* arg = om->get_arg();
|
|
if (!arg)
|
|
return false;
|
|
val = arg;
|
|
return true;
|
|
}
|