From 8982734a1b3cb9013718af5d57b5712f1b22c1c7 Mon Sep 17 00:00:00 2001 From: Loic Dachary Date: Mon, 3 Mar 2014 18:17:01 +0100 Subject: [PATCH] common: -- support for env_to_vec 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 --- src/common/ceph_argparse.cc | 40 ++++++++++++- src/test/ceph_argparse.cc | 109 ++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+), 1 deletion(-) diff --git a/src/common/ceph_argparse.cc b/src/common/ceph_argparse.cc index e66e716e611e6..eb000dc4e186a 100644 --- a/src/common/ceph_argparse.cc +++ b/src/common/ceph_argparse.cc @@ -56,6 +56,25 @@ void string_to_vec(std::vector& args, std::string argstr) } } +bool split_dashdash(const std::vector& args, + std::vector& options, + std::vector& arguments) { + bool dashdash = false; + for (std::vector::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& args, const char *name) { if (!name) @@ -64,13 +83,32 @@ void env_to_vec(std::vector& args, const char *name) if (!p) return; + bool dashdash = false; + std::vector options; + std::vector arguments; + if (split_dashdash(args, options, arguments)) + dashdash = true; + + std::vector env_options; + std::vector env_arguments; static vector str_vec; + std::vector env; str_vec.clear(); get_str_vec(p, " ", str_vec); for (vector::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, diff --git a/src/test/ceph_argparse.cc b/src/test/ceph_argparse.cc index e4b5d6bfccdc9..cc2ec9134e31d 100644 --- a/src/test/ceph_argparse.cc +++ b/src/test/ceph_argparse.cc @@ -334,3 +334,112 @@ TEST(CephArgParse, WithInt) { ASSERT_EQ(foo, 40); ASSERT_EQ(bar, -1); } + +TEST(CephArgParse, env_to_vec) { + { + std::vector 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 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 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 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 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 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 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: + */ -- 2.39.5