aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/salticidae/util.h45
-rw-r--r--src/util.cpp22
2 files changed, 55 insertions, 12 deletions
diff --git a/include/salticidae/util.h b/include/salticidae/util.h
index de63146..ab052de 100644
--- a/include/salticidae/util.h
+++ b/include/salticidae/util.h
@@ -34,6 +34,8 @@
#include <getopt.h>
#include <event2/event.h>
+#include "salticidae/ref.h"
+
namespace salticidae {
void sec2tv(double t, struct timeval &tv);
@@ -144,12 +146,19 @@ class Config {
virtual void append(const std::string &) {
throw SalticidaeError("undefined OptVal behavior: append");
}
+
virtual ~OptVal() = default;
};
+ using optval_t = RcObj<OptVal>;
+
class OptValFlag: public OptVal {
bool val;
public:
+ template<typename... Args>
+ static RcObj<OptValFlag> create(Args... args) {
+ return new OptValFlag(args...);
+ }
OptValFlag() = default;
OptValFlag(bool val): val(val) {}
void switch_on() override { val = true; }
@@ -159,6 +168,10 @@ class Config {
class OptValStr: public OptVal {
std::string val;
public:
+ template<typename... Args>
+ static RcObj<OptValStr> create(Args... args) {
+ return new OptValStr(args...);
+ }
OptValStr() = default;
OptValStr(const std::string &val): val(val) {}
void set_val(const std::string &strval) override {
@@ -170,6 +183,10 @@ class Config {
class OptValInt: public OptVal {
int val;
public:
+ template<typename... Args>
+ static RcObj<OptValInt> create(Args... args) {
+ return new OptValInt(args...);
+ }
OptValInt() = default;
OptValInt(int val): val(val) {}
void set_val(const std::string &strval) override {
@@ -186,6 +203,10 @@ class Config {
class OptValDouble: public OptVal {
double val;
public:
+ template<typename... Args>
+ static RcObj<OptValDouble> create(Args... args) {
+ return new OptValDouble(args...);
+ }
OptValDouble() = default;
OptValDouble(double val): val(val) {}
void set_val(const std::string &strval) override {
@@ -203,6 +224,10 @@ class Config {
using strvec_t = std::vector<std::string>;
strvec_t val;
public:
+ template<typename... Args>
+ static RcObj<OptValStrVec> create(Args... args) {
+ return new OptValStrVec(args...);
+ }
OptValStrVec() = default;
OptValStrVec(const strvec_t &val): val(val) {}
void append(const std::string &strval) override {
@@ -214,13 +239,16 @@ class Config {
private:
struct Opt {
std::string optname;
- OptVal *optval;
+ std::string optdoc;
+ optval_t optval;
Action action;
struct option opt;
- Opt(const std::string &optname, OptVal *optval, Action action, int idx);
+ Opt(const std::string &optname, const std::string &optdoc,
+ const optval_t &optval, Action action, int idx);
Opt(Opt &&other):
optname(std::move(other.optname)),
- optval(other.optval),
+ optdoc(std::move(other.optdoc)),
+ optval(std::move(other.optval)),
action(other.action),
opt(other.opt) { opt.name = this->optname.c_str(); }
};
@@ -228,24 +256,27 @@ class Config {
std::unordered_map<std::string, Opt> conf;
std::vector<Opt *> getopt_order;
std::string conf_fname;
- OptValStr opt_val_conf;
+ RcObj<OptValStr> opt_val_conf;
int conf_idx;
+
void update(const std::string &optname, const char *optval);
void update(Opt &opt, const char *optval);
public:
Config(const std::string &conf_fname):
conf_fname(conf_fname),
- opt_val_conf(this->conf_fname) {
+ opt_val_conf(new OptValStr(this->conf_fname)) {
conf_idx = getopt_order.size();
- add_opt("conf", opt_val_conf, SET_VAL);
+ add_opt("conf", opt_val_conf, SET_VAL, "load options from a file");
}
~Config() {}
- void add_opt(const std::string &optname, OptVal &optval, Action action);
+ void add_opt(const std::string &optname, const optval_t &optval, Action action,
+ const std::string &optdoc = "");
bool load(const std::string &fname);
size_t parse(int argc, char **argv);
+ void print_help(FILE *output = stderr);
};
class Event {
diff --git a/src/util.cpp b/src/util.cpp
index a1086f8..580306c 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -134,20 +134,23 @@ void ElapsedTime::stop(bool show_info) {
elapsed_sec, cpu_elapsed_sec);
}
-Config::Opt::Opt(const std::string &optname, OptVal *optval, Action action, int idx): \
- optname(optname), optval(optval), action(action) {
+Config::Opt::Opt(const std::string &optname, const std::string &optdoc,
+ const optval_t &optval, Action action, int idx):
+ optname(optname), optdoc(optdoc), optval(optval), action(action) {
opt.name = this->optname.c_str();
opt.has_arg = action == SWITCH_ON ? no_argument : required_argument;
opt.flag = nullptr;
opt.val = idx;
}
-void Config::add_opt(const std::string &optname, OptVal &optval, Action action) {
+void Config::add_opt(const std::string &optname, const optval_t &optval, Action action,
+ const std::string &optdoc) {
if (conf.count(optname))
throw SalticidaeError("option name already exists");
auto it = conf.insert(
std::make_pair(optname,
- Opt(optname, &optval, action, getopt_order.size()))).first;
+ Opt(optname, optdoc,
+ optval, action, getopt_order.size()))).first;
getopt_order.push_back(&it->second);
}
@@ -219,7 +222,7 @@ size_t Config::parse(int argc, char **argv) {
update(*getopt_order[id], optarg);
if (id == conf_idx)
{
- auto &fname = opt_val_conf.get();
+ auto &fname = opt_val_conf->get();
if (load(fname))
SALTICIDAE_LOG_INFO("loading extra configuration from %s", fname.c_str());
else
@@ -229,6 +232,15 @@ size_t Config::parse(int argc, char **argv) {
return optind;
}
+void Config::print_help(FILE *output) {
+ for (auto opt: getopt_order)
+ {
+ fprintf(output, "--%s\t\t%s\n",
+ opt->optname.c_str(),
+ opt->optdoc.c_str());
+ }
+}
+
std::vector<std::string> split(const std::string &s, const std::string &delim) {
std::vector<std::string> res;
size_t lastpos = 0;