]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
injectargs: binary flags only consume 1 token
authorColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Tue, 23 Aug 2011 22:43:52 +0000 (15:43 -0700)
committerColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Tue, 23 Aug 2011 22:46:07 +0000 (15:46 -0700)
Never consume more than one token when parsing a binary flag.

Basically, your choices are --foo=false, --foo=true, and just --foo.
However, only 1 token will ever be examined.

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

index 7481f91a93ef7623e16a5ee2c0c0c80af9a5ea32..d0570d425f217c09f77d97c29fac04379df46786 100644 (file)
 #include "msg/msg_types.h"
 
 #include <deque>
+#include <errno.h>
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string>
 #include <string.h>
+#include <sstream>
 #include <vector>
 
 /*
@@ -276,6 +278,55 @@ bool ceph_argparse_flag(std::vector<const char*> &args,
   }
 }
 
+bool ceph_argparse_binary_flag(std::vector<const char*> &args,
+       std::vector<const char*>::iterator &i, int *ret,
+       std::ostringstream *oss, ...)
+{
+  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)
+      return false;
+    strlen_a = strlen(a);
+    char a2[strlen_a+1];
+    dashes_to_underscores(a, a2);
+    if (strncmp(a2, first, strlen(a2)) == 0) {
+      if (first[strlen_a] == '=') {
+       i = args.erase(i);
+       const char *val = first + strlen_a + 1;
+       if (strcmp(val, "true") == 0) {
+         *ret = 1;
+         return true;
+       }
+       else if (strcmp(val, "false") == 0) {
+         *ret = 0;
+         return true;
+       }
+       if (oss) {
+         (*oss) << "Parse error parsing binary flag  " << a
+                << ". Expected true or false, but got '" << val << "'\n";
+       }
+       *ret = -EINVAL;
+       return true;
+      }
+      else if (first[strlen_a] == '\0') {
+       i = args.erase(i);
+       *ret = 1;
+       return true;
+      }
+    }
+  }
+}
+
 bool ceph_argparse_witharg(std::vector<const char*> &args,
        std::vector<const char*>::iterator &i, std::string *ret, ...)
 {
index 91f9981b908f092bd651215252bfe9ed1fe692e9..01098188f75324ca4b3c71cf0d7badd5a1d9c268 100644 (file)
@@ -96,6 +96,9 @@ bool ceph_argparse_flag(std::vector<const char*> &args,
        std::vector<const char*>::iterator &i, ...);
 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, ...);
 extern CephInitParameters ceph_argparse_early_args
            (std::vector<const char*>& args, uint32_t module_type, int flags,
             std::string *conf_file_list);
index 52021e4949b3ba68be9f882d8f1917bf05139f6a..e97e7fc34474b979292724bdd352090cc49a3caa 100644 (file)
@@ -46,6 +46,7 @@
 
 using std::map;
 using std::multimap;
+using std::ostringstream;
 using std::pair;
 using std::set;
 using std::string;
@@ -679,10 +680,18 @@ int md_config_t::parse_injectargs(std::vector<const char*>& args,
       const config_option *opt = config_optionsp + o;
       std::string as_option("--");
       as_option += opt->name;
-      if ((opt->type == OPT_BOOL) &&
-         ceph_argparse_flag(args, i, as_option.c_str(), (char*)NULL)) {
-       set_val_impl("true", opt);
-       break;
+      if (opt->type == OPT_BOOL) {
+       int res;
+       if (ceph_argparse_binary_flag(args, i, &res, oss, as_option.c_str(),
+                                     (char*)NULL)) {
+         if (res == 0)
+           set_val_impl("false", opt);
+         else if (res == 1)
+           set_val_impl("true", opt);
+         else
+           ret = res;
+         break;
+       }
       }
       else if (ceph_argparse_witharg(args, i, &val,
                                     as_option.c_str(), (char*)NULL)) {
index ffc48d67b73d1a3f9551272f3ce9e59fbd742ba7..288c643dbbaf0a371a976986207077095ee39f95 100644 (file)
@@ -175,7 +175,7 @@ TEST(DaemonConfig, InjectArgsBooleans) {
 
   // parse error
   std::ostringstream chat4;
-  injection = "--debug 1 --log_to_syslog=falsey --debug-ms 40";
+  injection = "--debug 1 --log_to_syslog=falsey --debug-ms 42";
   ret = g_ceph_context->_conf->injectargs(injection, &chat3);
   ASSERT_EQ(ret, -EINVAL);
 
@@ -184,6 +184,12 @@ TEST(DaemonConfig, InjectArgsBooleans) {
   ret = g_ceph_context->_conf->get_val("log_to_syslog", &tmp, sizeof(buf));
   ASSERT_EQ(ret, 0);
   ASSERT_EQ(string("true"), string(buf));
+
+  // debug-ms should still become 42...
+  memset(buf, 0, sizeof(buf));
+  ret = g_ceph_context->_conf->get_val("debug_ms", &tmp, sizeof(buf));
+  ASSERT_EQ(ret, 0);
+  ASSERT_EQ(string("42"), string(buf));
 }
 
 TEST(DaemonConfig, InjectArgsLogfile) {