#include <cstdint>
#include <climits>
#include <functional>
-#include <getopt.h>
#include <iostream>
#include <string>
#include <vector>
#include "libmemcached/common.h"
+#ifdef HAVE_GETOPT_H
+# include <getopt.h>
+#elif defined _MSC_VER
+# include "win32/getopt.h"
+#endif
+
class client_options {
public:
std::string help;
std::function<bool(client_options &, extended_option &)> parse;
std::function<bool(const client_options &, const extended_option &, memcached_st *)> apply;
- const char *arg;
+ char *arg;
bool set;
};
def("username", 'u', required_argument, "SASL username.")
.apply = [](const client_options &opt, const extended_option &ext, memcached_st *memc) {
if (auto username = ext.arg) {
- if (!LIBMEMCACHED_WITH_SASL_SUPPORT) {
- if (!opt.isset("quiet")) {
- std::cerr << "SASL username was supplied, but binary was not built with SASL support.\n";
- return false;
- }
- }
- if (MEMCACHED_SUCCESS != memcached_set_sasl_auth_data(memc, username, opt.argof("password"))) {
+#if !LIBMEMCACHED_WITH_SASL_SUPPORT
if (!opt.isset("quiet")) {
- std::cerr << memcached_last_error_message(memc);
+ std::cerr
+ << "SASL username was supplied, but binary was not built with SASL support.\n";
}
return false;
+#else
+ if (memc) {
+ if (MEMCACHED_SUCCESS
+ != memcached_set_sasl_auth_data(memc, username, opt.argof("password"))) {
+ if (!opt.isset("quiet")) {
+ std::cerr << memcached_last_error_message(memc);
+ }
+ return false;
+ }
}
+#endif
}
return true;
};
extended_option &get(const std::string &name) {
// UB if not found
- return *std::find_if(options.begin(), options.end(), [&name](extended_option &ext) {
- return ext.opt.name && ext.opt.name == name;
- });
+ return *find(name);
}
extended_option &get(int c) {
// UB if not found
- return *std::find_if(options.begin(), options.end(), [c](extended_option &ext) {
- return ext.opt.val == c || (c == 1 && ext.opt.val == '-');
- });
+ return *find(c);
}
const extended_option &get(const std::string &name) const {
- for (const auto &ext_opt : options) {
- if (ext_opt.opt.name && ext_opt.opt.name == name) {
- return ext_opt;
- }
- }
- return null_ext_opt;
+ // UB if not found
+ return *find(name);
}
const extended_option &get(int c) const {
- for (const auto &ext_opt : options) {
- if (ext_opt.opt.val == c) {
- return ext_opt;
- } else if (c == 1 && ext_opt.opt.val == '-') {
- // GNU argv extension
- return ext_opt;
- }
- }
- return null_ext_opt;
+ // UB if not found
+ return *find(c);
+ }
+
+ bool has(const std::string &name) const {
+ auto found = find(name);
+ return found != options.cend();
+ }
+ bool has(int c) const {
+ auto found = find(c);
+ return found != options.cend();
}
bool isset(const std::string &name) const {
- return get(name).set;
+ return has(name) && get(name).set;
}
bool isset(int c) const {
- return get(c).set;
+ return has(c) && get(c).set;
}
void unset(const std::string &name) {
- auto &opt = get(name);
- opt.set = false;
- opt.arg = nullptr;
+ set(name, false);
}
void unset(int c) {
- auto &opt = get(c);
- opt.set = false;
- opt.arg = nullptr;
+ set(c, false);
}
- void set(const std::string &name, bool set_ = true, const char *optarg_ = nullptr) {
- auto &opt = get(name);
- opt.set = set_;
- opt.arg = optarg_;
+ void set(const std::string &name, bool set_ = true, char *optarg_ = nullptr) {
+ if (has(name)) {
+ auto &opt = get(name);
+ opt.set = set_;
+ opt.arg = optarg_;
+ }
}
- void set(int c, bool set_ = true, const char *optarg_ = nullptr) {
- auto &opt = get(c);
- opt.set = set_;
- opt.arg = optarg_;
+ void set(int c, bool set_ = true, char *optarg_ = nullptr) {
+ if (has(c)) {
+ auto &opt = get(c);
+ opt.set = set_;
+ opt.arg = optarg_;
+ }
}
- const char *argof(const std::string &name) const {
- return get(name).arg;
+ char *argof(const std::string &name) const {
+ if (has(name)) {
+ return get(name).arg;
+ }
+ return nullptr;
}
- const char *argof(int c) const {
- return get(c).arg;
+ char *argof(int c) const {
+ if (has(c)) {
+ return get(c).arg;
+ }
+ return nullptr;
}
const extended_option &operator[](const std::string &name) const {
bool apply(memcached_st *memc);
private:
- static option null_opt;
- static const extended_option null_ext_opt;
+ using iterator = std::vector<extended_option>::iterator;
+ using const_iterator = std::vector<extended_option>::const_iterator;
+ using predicate = std::function<bool(const extended_option &ext)>;
+
+ const_iterator find(const predicate &pred) const {
+ return std::find_if(options.cbegin(), options.cend(), pred);
+ }
+ const_iterator find(const std::string &name) const {
+ return find([&name](const extended_option &ext) {
+ return ext.opt.name && ext.opt.name == name;
+ });
+ }
+ const_iterator find(int c) const {
+ return find([c](const extended_option &ext) {
+ return ext.opt.val == c || (c == 1 && ext.opt.val == '-');
+ });
+ }
+
+ iterator find(const predicate &pred) {
+ return std::find_if(options.begin(), options.end(), pred);
+ }
+ iterator find(const std::string &name) {
+ return find([&name](const extended_option &ext) {
+ return ext.opt.name && ext.opt.name == name;
+ });
+ }
+ iterator find(int c) {
+ return find([c](const extended_option &ext) {
+ return ext.opt.val == c || (c == 1 && ext.opt.val == '-');
+ });
+ }
};