diff options
Diffstat (limited to 'tests/lib/unit++/optmap.cc')
-rw-r--r-- | tests/lib/unit++/optmap.cc | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/tests/lib/unit++/optmap.cc b/tests/lib/unit++/optmap.cc new file mode 100644 index 00000000..9e65d849 --- /dev/null +++ b/tests/lib/unit++/optmap.cc @@ -0,0 +1,145 @@ +// 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; +} |