aboutsummaryrefslogtreecommitdiffstats
path: root/tests/lib/unit++/optmap.cc
diff options
context:
space:
mode:
Diffstat (limited to 'tests/lib/unit++/optmap.cc')
-rw-r--r--tests/lib/unit++/optmap.cc145
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;
+}