fix includes
[awesomized/libmemcached] / src / bin / common / options.hpp
index 28ade9733c8d1b233561b22969157b5202420754..980ca38dc39ab8865a498002e98d6f334d4c2814 100644 (file)
 #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:
 
@@ -34,7 +39,7 @@ 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;
   };
 
@@ -94,13 +99,13 @@ public:
     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 !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;
           }
-        }
+          return false;
+#else
         if (memc) {
           if (MEMCACHED_SUCCESS
               != memcached_set_sasl_auth_data(memc, username, opt.argof("password"))) {
@@ -110,6 +115,7 @@ public:
             return false;
           }
         }
+#endif
       }
       return true;
     };
@@ -256,71 +262,71 @@ public:
 
   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 {
@@ -337,6 +343,35 @@ public:
   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 == '-');
+    });
+  }
 };