memcat: make file argutent to --file optional and default to <key>
[awesomized/libmemcached] / src / bin / memcat.cc
index 00519b520bd9f1193d86a49c7c4b6bdfe1a6c78c..ab8fc6db5ed959649128a35082841f872cda4ac7 100644 (file)
 #define PROGRAM_DESCRIPTION "Cat a set of key values to stdout."
 #define PROGRAM_VERSION     "1.1"
 
-#include "libmemcached/common.h"
 #include "common/options.hpp"
+#include "common/checks.hpp"
 
 #include <iostream>
 #include <fstream>
 
-memcached_return_t memcat(const client_options &opt, memcached_st *memc, const char *key, std::ostream &ref) {
+memcached_return_t memcat(const client_options &opt, memcached_st *memc, const char *key, std::ostream *ref) {
   memcached_return_t rc;
   uint32_t flags;
   size_t len;
   auto val = memcached_get(memc, key, strlen(key), &len, &flags, &rc);
+  auto verbose = opt.isset("verbose");
 
   if (MEMCACHED_SUCCESS == rc) {
-    if (opt.flags.verbose) {
-      ref << "key: " << key << "\n";
+    if (verbose) {
+      *ref << "key: " << key << "\n";
     }
-    if (opt.flags.flags) {
-      ref << "flags: " << flags << "\n";
+    if (opt.isset("flags")) {
+      if (verbose) {
+      *ref << "flags: ";
+      }
+      *ref << flags << "\n";
     }
-    if (opt.flags.verbose) {
-      ref << "value: ";
+    if (verbose) {
+      *ref << "value: ";
     }
-    ref.write(val, len);
-    ref << std::endl;
+
+    ref->write(val, len);
+
+    if (verbose || !opt.isset("file")) {
+      *ref << std::endl;
+    }
+
+    ref->flush();
   }
 
   if (val) {
@@ -52,43 +62,27 @@ memcached_return_t memcat(const client_options &opt, memcached_st *memc, const c
 }
 
 int main(int argc, char *argv[]) {
-  memcached_st memc;
-  client_options opt{PROGRAM_NAME, PROGRAM_VERSION, PROGRAM_DESCRIPTION, {
-      client_options::flag::help,
-      client_options::flag::version,
-      client_options::flag::verbose,
-      client_options::flag::debug,
-      client_options::flag::quiet,
-      client_options::flag::servers,
-      client_options::flag::binary,
-      client_options::flag::username,
-      client_options::flag::password,
-      client_options::flag::hash,
-      client_options::flag::flags,
-      client_options::flag::file,
-  }};
-
-  if (!opt.parse(argc, argv)) {
-    exit(EXIT_FAILURE);
-  }
-  if (opt.flags.help) {
-    opt.printHelp("key [ key ... ]");
-    exit(EXIT_SUCCESS);
+  client_options opt{PROGRAM_NAME, PROGRAM_VERSION, PROGRAM_DESCRIPTION, "key [key ...]"};
+
+  for (const auto &def : opt.defaults) {
+    opt.add(def);
   }
-  if (opt.flags.version) {
-    opt.printVersion();
-    exit(EXIT_SUCCESS);
+  opt.add("flags", 'F', no_argument, "Display key flags, too.");
+  opt.add("file", 'f', optional_argument, "Output to file instead of standard output."
+                                          "\n\t\t# NOTE: defaults to <key> if no argument was provided.");
+
+  char **argp = nullptr;
+  if (!opt.parse(argc, argv, &argp)) {
+    exit(EXIT_FAILURE);
   }
 
-  if (opt.flags.quiet && !opt.args.file) {
+  if (opt.isset("quiet") && !opt.isset("file")) {
     std::cerr << "--quiet operation was requested, but --file was not set.\n";
     exit(EXIT_FAILURE);
   }
 
-  if (!memcached_create(&memc)) {
-    if (!opt.flags.quiet) {
-      std::cerr << "Failed to initialize memcached client.\n";
-    }
+  memcached_st memc;
+  if (!check_memcached(opt, memc)) {
     exit(EXIT_FAILURE);
   }
 
@@ -97,39 +91,21 @@ int main(int argc, char *argv[]) {
     exit(EXIT_FAILURE);
   }
 
-  if (!*opt.args.positional) {
-    if (!opt.flags.quiet) {
-      std::cerr << "No key(s) provided.\n";
-      memcached_free(&memc);
-      exit(EXIT_FAILURE);
-    }
+  if (!check_argp(opt, argp, "No key(s) provided.")) {
+    memcached_free(&memc);
+    exit(EXIT_FAILURE);
   }
 
   auto exit_code = EXIT_SUCCESS;
-  for (auto arg = opt.args.positional; *arg; ++arg) {
+  for (auto arg = argp; *arg; ++arg) {
     auto key = *arg;
     if (*key) {
-      memcached_return_t rc;
-      if (opt.args.file && *opt.args.file) {
-        std::ofstream file{opt.args.file, std::ios::binary};
-        rc = memcat(opt, &memc, key, file);
-      } else {
-        rc = memcat(opt, &memc, key, std::cout);
-      }
-      if (MEMCACHED_SUCCESS != rc) {
-        exit_code = EXIT_FAILURE;
+      char *file = opt.isset("file") ? (opt.argof("file") ?: key) : nullptr;
+      std::ofstream fstream{};
+      std::ostream *ostream = check_ostream(opt, file, fstream);
 
-        if (MEMCACHED_NOTFOUND == rc) {
-          if (opt.flags.verbose) {
-            std::cerr << "not found: " << key << "\n";
-          }
-          // continue;
-        } else {
-          if (!opt.flags.quiet) {
-            std::cerr << memcached_last_error_message(&memc) << "\n";
-          }
-          break;
-        }
+      if (!check_return(opt, memc, key, memcat(opt, &memc, key, ostream))) {
+        exit_code = EXIT_FAILURE;
       }
     }
   }