]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph_argparse: add ceph_argparse_withint
authorColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Fri, 2 Sep 2011 20:37:31 +0000 (13:37 -0700)
committerColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Tue, 6 Sep 2011 22:28:44 +0000 (15:28 -0700)
Add an easy way of parsing an int argument. Always match va_start with
va_end.

Signed-off-by: Colin McCabe <colin.mccabe@dreamhost.com>
src/common/ceph_argparse.cc
src/common/ceph_argparse.h
src/test/ceph_argparse.cc

index a7e8313e8b1b319e5602efd0e6aae5e13141b323..8b39c6698ff30d26bf551d38ed8026e25e5b08c2 100644 (file)
  */
 
 #include "auth/Auth.h"
+#include "common/ConfUtils.h"
 #include "common/ceph_argparse.h"
 #include "common/common_init.h"
-#include "global/global_init.h"
-#include "common/ConfUtils.h"
-#include "common/version.h"
 #include "common/config.h"
+#include "common/strtol.h"
+#include "common/version.h"
 #include "include/intarith.h"
 #include "include/str_list.h"
 #include "msg/msg_types.h"
@@ -279,31 +279,32 @@ bool ceph_argparse_flag(std::vector<const char*> &args,
   va_start(ap, i);
   while (1) {
     a = va_arg(ap, char*);
-    if (a == NULL)
+    if (a == NULL) {
+      va_end(ap);
       return false;
+    }
     char a2[strlen(a)+1];
     dashes_to_underscores(a, a2);
     if (strcmp(a2, first) == 0) {
       i = args.erase(i);
+      va_end(ap);
       return true;
     }
   }
 }
 
-bool ceph_argparse_binary_flag(std::vector<const char*> &args,
+static bool va_ceph_argparse_binary_flag(std::vector<const char*> &args,
        std::vector<const char*>::iterator &i, int *ret,
-       std::ostringstream *oss, ...)
+       std::ostringstream *oss, va_list ap)
 {
   const char *first = *i;
   char tmp[strlen(first)+1];
   dashes_to_underscores(first, tmp);
   first = tmp;
   const char *a;
-  va_list ap;
   int strlen_a;
 
   // does this argument match any of the possibilities?
-  va_start(ap, oss);
   while (1) {
     a = va_arg(ap, char*);
     if (a == NULL)
@@ -339,19 +340,29 @@ bool ceph_argparse_binary_flag(std::vector<const char*> &args,
   }
 }
 
-bool ceph_argparse_witharg(std::vector<const char*> &args,
-       std::vector<const char*>::iterator &i, std::string *ret, ...)
+bool ceph_argparse_binary_flag(std::vector<const char*> &args,
+       std::vector<const char*>::iterator &i, int *ret,
+       std::ostringstream *oss, ...)
+{
+  bool r;
+  va_list ap;
+  va_start(ap, oss);
+  r = va_ceph_argparse_binary_flag(args, i, ret, oss, ap);
+  va_end(ap);
+  return r;
+}
+
+static bool va_ceph_argparse_witharg(std::vector<const char*> &args,
+       std::vector<const char*>::iterator &i, std::string *ret, va_list ap)
 {
   const char *first = *i;
   char tmp[strlen(first)+1];
   dashes_to_underscores(first, tmp);
   first = tmp;
   const char *a;
-  va_list ap;
   int strlen_a;
 
   // does this argument match any of the possibilities?
-  va_start(ap, ret);
   while (1) {
     a = va_arg(ap, char*);
     if (a == NULL)
@@ -380,6 +391,40 @@ bool ceph_argparse_witharg(std::vector<const char*> &args,
   }
 }
 
+bool ceph_argparse_witharg(std::vector<const char*> &args,
+       std::vector<const char*>::iterator &i, std::string *ret, ...)
+{
+  bool r;
+  va_list ap;
+  va_start(ap, ret);
+  r = va_ceph_argparse_witharg(args, i, ret, ap);
+  va_end(ap);
+  return r;
+}
+
+bool ceph_argparse_withint(std::vector<const char*> &args,
+       std::vector<const char*>::iterator &i, int *ret,
+       std::ostringstream *oss, ...)
+{
+  bool r;
+  va_list ap;
+  std::string str;
+  va_start(ap, oss);
+  r = va_ceph_argparse_witharg(args, i, &str, ap);
+  va_end(ap);
+  if (!r) {
+    return false;
+  }
+
+  std::string err;
+  int myret = strict_strtol(str.c_str(), 10, &err);
+  *ret = myret;
+  if (!err.empty()) {
+    *oss << err;
+  }
+  return true;
+}
+
 CephInitParameters ceph_argparse_early_args
          (std::vector<const char*>& args, uint32_t module_type, int flags,
           std::string *conf_file_list)
@@ -387,8 +432,9 @@ CephInitParameters ceph_argparse_early_args
   CephInitParameters iparams(module_type);
   std::string val;
   for (std::vector<const char*>::iterator i = args.begin(); i != args.end(); ) {
-    if (strcmp(*i, "--") == 0)
+    if (ceph_argparse_double_dash(args, i)) {
       break;
+    }
     else if (ceph_argparse_flag(args, i, "--version", "-v", (char*)NULL)) {
       cout << pretty_version_to_str() << std::endl;
       _exit(0);
index b2f4a3c651d5f08442a103110833f3323e553a6d..ece8b8ae169c7df70df1c297089d6df55bd9ea8b 100644 (file)
@@ -104,6 +104,9 @@ bool ceph_argparse_binary_flag(std::vector<const char*> &args,
 extern CephInitParameters ceph_argparse_early_args
            (std::vector<const char*>& args, uint32_t module_type, int flags,
             std::string *conf_file_list);
+extern bool ceph_argparse_withint(std::vector<const char*> &args,
+       std::vector<const char*>::iterator &i, int *ret,
+       std::ostringstream *oss, ...);
 extern void generic_server_usage();
 extern void generic_client_usage();
 
index d0f1625b48dfafd19f77b98a7d04ac4bf2db149d..c8e996765f07ed09bf1ce89b75e05691632f7f42 100644 (file)
@@ -270,3 +270,70 @@ TEST(CephArgParse, WithDashesAndUnderscores) {
   }
   ASSERT_EQ(found_baz, "");
 }
+
+extern bool ceph_argparse_withint(std::vector<const char*> &args,
+       std::vector<const char*>::iterator &i, int *ret,
+       std::ostringstream *oss, ...);
+
+TEST(CephArgParse, WithInt) {
+  const char *BAZSTUFF1[] = { "./myprog", "--foo", "50", "--bar", "52", NULL };
+  const char *BAZSTUFF2[] = { "./myprog", "--foo", "--bar", "52", NULL };
+  const char *BAZSTUFF3[] = { "./myprog", "--foo", "40", "--", "--bar", "42", NULL };
+
+  // normal test
+  VectorContainer bazstuff1(BAZSTUFF1);
+  ostringstream err;
+  int foo = -1, bar = -1;
+  for (std::vector<const char*>::iterator i = bazstuff1.arr.begin();
+       i != bazstuff1.arr.end(); )
+  {
+    if (ceph_argparse_double_dash(bazstuff1.arr, i)) {
+      break;
+    } else if (ceph_argparse_withint(bazstuff1.arr, i, &foo, &err, "--foo", (char*)NULL)) {
+      ASSERT_EQ(string(""), err.str());
+    } else if (ceph_argparse_withint(bazstuff1.arr, i, &bar, &err, "--bar", (char*)NULL)) {
+      ASSERT_EQ(string(""), err.str());
+    }
+    else {
+      ++i;
+    }
+  }
+  ASSERT_EQ(foo, 50);
+  ASSERT_EQ(bar, 52);
+
+  // parse error test
+  VectorContainer bazstuff2(BAZSTUFF2);
+  ostringstream err2;
+  for (std::vector<const char*>::iterator i = bazstuff2.arr.begin();
+       i != bazstuff2.arr.end(); )
+  {
+    if (ceph_argparse_double_dash(bazstuff2.arr, i)) {
+      break;
+    } else if (ceph_argparse_withint(bazstuff2.arr, i, &foo, &err2, "--foo", (char*)NULL)) {
+      ASSERT_NE(string(""), err2.str());
+    }
+    else {
+      ++i;
+    }
+  }
+
+  // double dash test
+  VectorContainer bazstuff3(BAZSTUFF3);
+  foo = -1, bar = -1;
+  for (std::vector<const char*>::iterator i = bazstuff3.arr.begin();
+       i != bazstuff3.arr.end(); )
+  {
+    if (ceph_argparse_double_dash(bazstuff3.arr, i)) {
+      break;
+    } else if (ceph_argparse_withint(bazstuff3.arr, i, &foo, &err, "--foo", (char*)NULL)) {
+      ASSERT_EQ(string(""), err.str());
+    } else if (ceph_argparse_withint(bazstuff3.arr, i, &bar, &err, "--bar", (char*)NULL)) {
+      ASSERT_EQ(string(""), err.str());
+    }
+    else {
+      ++i;
+    }
+  }
+  ASSERT_EQ(foo, 40);
+  ASSERT_EQ(bar, -1);
+}