From 1ccbfeabdfff0e1cef374bde3060ad17dea95391 Mon Sep 17 00:00:00 2001 From: Colin Patrick McCabe Date: Fri, 2 Sep 2011 13:37:31 -0700 Subject: [PATCH] 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 --- src/common/ceph_argparse.cc | 72 ++++++++++++++++++++++++++++++------- src/common/ceph_argparse.h | 3 ++ src/test/ceph_argparse.cc | 67 ++++++++++++++++++++++++++++++++++ 3 files changed, 129 insertions(+), 13 deletions(-) diff --git a/src/common/ceph_argparse.cc b/src/common/ceph_argparse.cc index a7e8313e8b1b3..8b39c6698ff30 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 &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 &args, +static bool va_ceph_argparse_binary_flag(std::vector &args, std::vector::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 &args, } } -bool ceph_argparse_witharg(std::vector &args, - std::vector::iterator &i, std::string *ret, ...) +bool ceph_argparse_binary_flag(std::vector &args, + std::vector::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 &args, + std::vector::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 &args, } } +bool ceph_argparse_witharg(std::vector &args, + std::vector::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 &args, + std::vector::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& 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::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 b2f4a3c651d5f..ece8b8ae169c7 100644 --- a/src/common/ceph_argparse.h +++ b/src/common/ceph_argparse.h @@ -104,6 +104,9 @@ bool ceph_argparse_binary_flag(std::vector &args, extern CephInitParameters ceph_argparse_early_args (std::vector& args, uint32_t module_type, int flags, std::string *conf_file_list); +extern bool ceph_argparse_withint(std::vector &args, + std::vector::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 d0f1625b48dfa..c8e996765f07e 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 &args, + std::vector::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::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::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::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); +} -- 2.39.5