]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
common: -- support for env_to_vec 1352/head
authorLoic Dachary <loic@dachary.org>
Mon, 3 Mar 2014 17:17:01 +0000 (18:17 +0100)
committerLoic Dachary <loic@dachary.org>
Mon, 3 Mar 2014 17:17:01 +0000 (18:17 +0100)
When CEPH_ARGS is parsed each side of the -- must be appended to the
corresponding side of the existing argument list. For instance when

   -a -b -- foo bar

is merged with a CEPH_ARGS containing

   -c -d -- frob nitz

it must become

   -a -b -c -d -- foo bar frob nitz

http://tracker.ceph.com/issues/7578 fixes #7578

Signed-off-by: Loic Dachary <loic@dachary.org>
src/common/ceph_argparse.cc
src/test/ceph_argparse.cc

index e66e716e611e6371b0fcde46118c97092faf5a2b..eb000dc4e186a78e66057980ec08a3b4f89e3418 100644 (file)
@@ -56,6 +56,25 @@ void string_to_vec(std::vector<std::string>& args, std::string argstr)
   }
 }
 
+bool split_dashdash(const std::vector<const char*>& args,
+                   std::vector<const char*>& options,
+                   std::vector<const char*>& arguments) {
+  bool dashdash = false;
+  for (std::vector<const char*>::const_iterator i = args.begin();
+       i != args.end();
+       i++) {
+    if (dashdash) {
+      arguments.push_back(*i);
+    } else {
+      if (strcmp(*i, "--") == 0)
+       dashdash = true;
+      else
+       options.push_back(*i);
+    }
+  }
+  return dashdash;
+}
+
 void env_to_vec(std::vector<const char*>& args, const char *name)
 {
   if (!name)
@@ -64,13 +83,32 @@ void env_to_vec(std::vector<const char*>& args, const char *name)
   if (!p)
     return;
 
+  bool dashdash = false;
+  std::vector<const char*> options;
+  std::vector<const char*> arguments;
+  if (split_dashdash(args, options, arguments))
+    dashdash = true;
+
+  std::vector<const char*> env_options;
+  std::vector<const char*> env_arguments;
   static vector<string> str_vec;
+  std::vector<const char*> env;
   str_vec.clear();
   get_str_vec(p, " ", str_vec);
   for (vector<string>::iterator i = str_vec.begin();
        i != str_vec.end();
        ++i)
-    args.push_back(i->c_str());
+    env.push_back(i->c_str());
+  if (split_dashdash(env, env_options, env_arguments))
+    dashdash = true;
+
+  args.clear();
+  args.insert(args.end(), options.begin(), options.end());
+  args.insert(args.end(), env_options.begin(), env_options.end());
+  if (dashdash)
+    args.push_back("--");
+  args.insert(args.end(), arguments.begin(), arguments.end());
+  args.insert(args.end(), env_arguments.begin(), env_arguments.end());
 }
 
 void argv_to_vec(int argc, const char **argv,
index e4b5d6bfccdc977c39eb22a0910f3c6a87cae1da..cc2ec9134e31d4cbb17f92dcdd9a85a65fb83c39 100644 (file)
@@ -334,3 +334,112 @@ TEST(CephArgParse, WithInt) {
   ASSERT_EQ(foo, 40);
   ASSERT_EQ(bar, -1);
 }
+
+TEST(CephArgParse, env_to_vec) {
+  {
+    std::vector<const char*> args;
+    unsetenv("CEPH_ARGS");
+    unsetenv("WHATEVER");
+    env_to_vec(args);
+    EXPECT_EQ(0, args.size());
+    env_to_vec(args, "WHATEVER");
+    EXPECT_EQ(0, args.size());
+    args.push_back("a");
+    setenv("CEPH_ARGS", "b c", 0);
+    env_to_vec(args);
+    EXPECT_EQ(3, args.size());
+    EXPECT_EQ(string("b"), args[1]);
+    EXPECT_EQ(string("c"), args[2]);
+    setenv("WHATEVER", "d e", 0);
+    env_to_vec(args, "WHATEVER");
+    EXPECT_EQ(5, args.size());
+    EXPECT_EQ(string("d"), args[3]);
+    EXPECT_EQ(string("e"), args[4]);
+  }
+  {
+    std::vector<const char*> args;
+    unsetenv("CEPH_ARGS");
+    args.push_back("a");
+    args.push_back("--");
+    args.push_back("c");
+    setenv("CEPH_ARGS", "b -- d", 0);
+    env_to_vec(args);
+    EXPECT_EQ(5, args.size());
+    EXPECT_EQ(string("a"), args[0]);
+    EXPECT_EQ(string("b"), args[1]);
+    EXPECT_EQ(string("--"), args[2]);
+    EXPECT_EQ(string("c"), args[3]);
+    EXPECT_EQ(string("d"), args[4]);
+  }
+  {
+    std::vector<const char*> args;
+    unsetenv("CEPH_ARGS");
+    args.push_back("a");
+    args.push_back("--");
+    setenv("CEPH_ARGS", "b -- c", 0);
+    env_to_vec(args);
+    EXPECT_EQ(4, args.size());
+    EXPECT_EQ(string("a"), args[0]);
+    EXPECT_EQ(string("b"), args[1]);
+    EXPECT_EQ(string("--"), args[2]);
+    EXPECT_EQ(string("c"), args[3]);
+  }
+  {
+    std::vector<const char*> args;
+    unsetenv("CEPH_ARGS");
+    args.push_back("--");
+    args.push_back("c");
+    setenv("CEPH_ARGS", "b -- d", 0);
+    env_to_vec(args);
+    EXPECT_EQ(4, args.size());
+    EXPECT_EQ(string("b"), args[0]);
+    EXPECT_EQ(string("--"), args[1]);
+    EXPECT_EQ(string("c"), args[2]);
+    EXPECT_EQ(string("d"), args[3]);
+  }
+  {
+    std::vector<const char*> args;
+    unsetenv("CEPH_ARGS");
+    args.push_back("b");
+    setenv("CEPH_ARGS", "c -- d", 0);
+    env_to_vec(args);
+    EXPECT_EQ(4, args.size());
+    EXPECT_EQ(string("b"), args[0]);
+    EXPECT_EQ(string("c"), args[1]);
+    EXPECT_EQ(string("--"), args[2]);
+    EXPECT_EQ(string("d"), args[3]);
+  }
+  {
+    std::vector<const char*> args;
+    unsetenv("CEPH_ARGS");
+    args.push_back("a");
+    args.push_back("--");
+    args.push_back("c");
+    setenv("CEPH_ARGS", "-- d", 0);
+    env_to_vec(args);
+    EXPECT_EQ(4, args.size());
+    EXPECT_EQ(string("a"), args[0]);
+    EXPECT_EQ(string("--"), args[1]);
+    EXPECT_EQ(string("c"), args[2]);
+    EXPECT_EQ(string("d"), args[3]);
+  }
+  {
+    std::vector<const char*> args;
+    unsetenv("CEPH_ARGS");
+    args.push_back("a");
+    args.push_back("--");
+    args.push_back("c");
+    setenv("CEPH_ARGS", "d", 0);
+    env_to_vec(args);
+    EXPECT_EQ(4, args.size());
+    EXPECT_EQ(string("a"), args[0]);
+    EXPECT_EQ(string("d"), args[1]);
+    EXPECT_EQ(string("--"), args[2]);
+    EXPECT_EQ(string("c"), args[3]);
+  }
+}
+/*
+ * Local Variables:
+ * compile-command: "cd .. ; make unittest_ceph_argparse && ./unittest_ceph_argparse"
+ * End:
+ */