summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Patrick McCabe <cmccabe@alumni.cmu.edu>2011-09-02 13:37:31 -0700
committerColin Patrick McCabe <cmccabe@alumni.cmu.edu>2011-09-06 15:28:44 -0700
commit1ccbfeabdfff0e1cef374bde3060ad17dea95391 (patch)
tree2a22d56b87aa793647652dbe58798ebb867e90d3
parentb71f24a78eb7aca76dba77621e19fbcf27a60b64 (diff)
downloadceph-1ccbfeabdfff0e1cef374bde3060ad17dea95391.tar.gz
ceph_argparse: add ceph_argparse_withint
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>
-rw-r--r--src/common/ceph_argparse.cc72
-rw-r--r--src/common/ceph_argparse.h3
-rw-r--r--src/test/ceph_argparse.cc67
3 files changed, 129 insertions, 13 deletions
diff --git a/src/common/ceph_argparse.cc b/src/common/ceph_argparse.cc
index a7e8313e8b1..8b39c6698ff 100644
--- a/src/common/ceph_argparse.cc
+++ b/src/common/ceph_argparse.cc
@@ -13,12 +13,12 @@
*/
#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);
diff --git a/src/common/ceph_argparse.h b/src/common/ceph_argparse.h
index b2f4a3c651d..ece8b8ae169 100644
--- a/src/common/ceph_argparse.h
+++ b/src/common/ceph_argparse.h
@@ -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();
diff --git a/src/test/ceph_argparse.cc b/src/test/ceph_argparse.cc
index d0f1625b48d..c8e996765f0 100644
--- a/src/test/ceph_argparse.cc
+++ b/src/test/ceph_argparse.cc
@@ -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);
+}