Store the command line in a more convenient format on non-windows platforms.
Review URL: http://codereview.chromium.org/7249 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3426 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
@ -57,21 +57,19 @@ class CommandLine::Data {
|
||||
Data() {
|
||||
Init(GetCommandLineW());
|
||||
}
|
||||
#elif defined(OS_POSIX)
|
||||
Data() {
|
||||
// Owner must call Init().
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
Data(const wstring& command_line) {
|
||||
Init(command_line);
|
||||
}
|
||||
#elif defined(OS_POSIX)
|
||||
Data() {
|
||||
// Owner must call Init().
|
||||
}
|
||||
|
||||
Data(int argc, const char* const* argv) {
|
||||
Init(argc, argv);
|
||||
}
|
||||
#endif
|
||||
#endif // defined(OS_POSIX)
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Does the actual parsing of the command line.
|
||||
@ -116,18 +114,19 @@ class CommandLine::Data {
|
||||
if (args)
|
||||
LocalFree(args);
|
||||
}
|
||||
|
||||
#elif defined(OS_POSIX)
|
||||
// Does the actual parsing of the command line.
|
||||
void Init(int argc, const char* const* argv) {
|
||||
if (argc < 1)
|
||||
return;
|
||||
program_ = base::SysNativeMBToWide(argv[0]);
|
||||
argv_.push_back(std::string(argv[0]));
|
||||
command_line_string_ = program_;
|
||||
|
||||
bool parse_switches = true;
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
std::wstring arg = base::SysNativeMBToWide(argv[i]);
|
||||
argv_.push_back(argv[i]);
|
||||
command_line_string_.append(L" ");
|
||||
command_line_string_.append(arg);
|
||||
|
||||
@ -168,6 +167,12 @@ class CommandLine::Data {
|
||||
return loose_values_;
|
||||
}
|
||||
|
||||
#if defined(OS_POSIX)
|
||||
const std::vector<std::string>& argv() const {
|
||||
return argv_;
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
// Returns true if parameter_string represents a switch. If true,
|
||||
// switch_string and switch_value are set. (If false, both are
|
||||
@ -206,6 +211,7 @@ class CommandLine::Data {
|
||||
std::wstring program_;
|
||||
std::map<std::wstring, std::wstring> switches_;
|
||||
std::vector<std::wstring> loose_values_;
|
||||
std::vector<std::string> argv_;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(Data);
|
||||
};
|
||||
@ -228,6 +234,15 @@ CommandLine::CommandLine(const int argc, const char* const* argv)
|
||||
: we_own_data_(true),
|
||||
data_(new Data(argc, argv)) {
|
||||
}
|
||||
|
||||
CommandLine::CommandLine(const std::vector<std::string>& argv)
|
||||
: we_own_data_(true) {
|
||||
const char* argv_copy[argv.size()];
|
||||
for (size_t i = 0; i < argv.size(); i++) {
|
||||
argv_copy[i] = argv[i].c_str();
|
||||
}
|
||||
data_ = new Data(argv.size(), argv_copy);
|
||||
}
|
||||
#endif
|
||||
|
||||
CommandLine::~CommandLine() {
|
||||
@ -278,38 +293,68 @@ std::wstring CommandLine::command_line_string() const {
|
||||
return data_->command_line_string();
|
||||
}
|
||||
|
||||
#if defined(OS_POSIX)
|
||||
const std::vector<std::string>& CommandLine::argv() const {
|
||||
return data_->argv();
|
||||
}
|
||||
#endif
|
||||
|
||||
std::wstring CommandLine::program() const {
|
||||
return data_->program();
|
||||
}
|
||||
|
||||
// static
|
||||
wstring CommandLine::PrefixedSwitchString(const wstring& switch_string) {
|
||||
return StringPrintf(L"%ls%ls",
|
||||
kSwitchPrefixes[0],
|
||||
switch_string.c_str());
|
||||
}
|
||||
|
||||
// static
|
||||
wstring CommandLine::PrefixedSwitchStringWithValue(
|
||||
const wstring& switch_string, const wstring& value_string) {
|
||||
if (value_string.empty()) {
|
||||
return PrefixedSwitchString(switch_string);
|
||||
}
|
||||
|
||||
return StringPrintf(L"%ls%ls%ls%ls",
|
||||
kSwitchPrefixes[0],
|
||||
switch_string.c_str(),
|
||||
kSwitchValueSeparator,
|
||||
value_string.c_str());
|
||||
}
|
||||
|
||||
// static
|
||||
void CommandLine::AppendSwitch(wstring* command_line_string,
|
||||
const wstring& switch_string) {
|
||||
DCHECK(command_line_string);
|
||||
wstring prefixed_switch_string = PrefixedSwitchString(switch_string);
|
||||
command_line_string->append(L" ");
|
||||
command_line_string->append(kSwitchPrefixes[0]);
|
||||
command_line_string->append(switch_string);
|
||||
command_line_string->append(prefixed_switch_string);
|
||||
}
|
||||
|
||||
// static
|
||||
void CommandLine::AppendSwitchWithValue(wstring* command_line_string,
|
||||
const wstring& switch_string,
|
||||
const wstring& value_string) {
|
||||
AppendSwitch(command_line_string, switch_string);
|
||||
wstring value_string_edit;
|
||||
|
||||
if (value_string.empty())
|
||||
return;
|
||||
|
||||
command_line_string->append(kSwitchValueSeparator);
|
||||
// NOTE(jhughes): If the value contains a quotation mark at one
|
||||
// end but not both, you may get unusable output.
|
||||
if ((value_string.find(L" ") != std::wstring::npos) &&
|
||||
if (!value_string.empty() &&
|
||||
(value_string.find(L" ") != std::wstring::npos) &&
|
||||
(value_string[0] != L'"') &&
|
||||
(value_string[value_string.length() - 1] != L'"')) {
|
||||
// need to provide quotes
|
||||
StringAppendF(command_line_string, L"\"%ls\"", value_string.c_str());
|
||||
value_string_edit = StringPrintf(L"\"%ls\"", value_string.c_str());
|
||||
} else {
|
||||
command_line_string->append(value_string);
|
||||
value_string_edit = value_string;
|
||||
}
|
||||
|
||||
wstring combined_switch_string =
|
||||
PrefixedSwitchStringWithValue(switch_string, value_string_edit);
|
||||
|
||||
command_line_string->append(L" ");
|
||||
command_line_string->append(combined_switch_string);
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@ class CommandLine {
|
||||
CommandLine(const std::wstring& command_line);
|
||||
#elif defined(OS_POSIX)
|
||||
CommandLine(int argc, const char* const* argv);
|
||||
CommandLine(const std::vector<std::string>& argv);
|
||||
#endif
|
||||
|
||||
~CommandLine();
|
||||
@ -67,6 +68,11 @@ class CommandLine {
|
||||
// Simply returns the original command line string.
|
||||
std::wstring command_line_string() const;
|
||||
|
||||
#if defined(OS_POSIX)
|
||||
// Returns the original command line string as a vector of strings.
|
||||
const std::vector<std::string>& argv() const;
|
||||
#endif
|
||||
|
||||
// Returns the program part of the command line string (the first item).
|
||||
std::wstring program() const;
|
||||
|
||||
@ -80,6 +86,16 @@ class CommandLine {
|
||||
// Treat everything after this argument as loose parameters.
|
||||
static const wchar_t kSwitchTerminator[];
|
||||
|
||||
// Return a copy of the string prefixed with a switch prefix.
|
||||
// Used internally.
|
||||
static std::wstring PrefixedSwitchString(const std::wstring& switch_string);
|
||||
|
||||
// Return a copy of the string prefixed with a switch prefix,
|
||||
// and appended with the given value. Used internally.
|
||||
static std::wstring PrefixedSwitchStringWithValue(
|
||||
const std::wstring& switch_string,
|
||||
const std::wstring& value_string);
|
||||
|
||||
// Appends the given switch string (preceded by a space and a switch
|
||||
// prefix) to the given string.
|
||||
static void AppendSwitch(std::wstring* command_line_string,
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "base/command_line.h"
|
||||
#include "base/basictypes.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/string_util.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace {
|
||||
@ -74,6 +75,13 @@ TEST(CommandLineTest, CommandLineConstructor) {
|
||||
EXPECT_EQ(L"in the time of submarines...", *iter);
|
||||
++iter;
|
||||
EXPECT_TRUE(iter == cl.GetLooseValuesEnd());
|
||||
#if defined(OS_POSIX)
|
||||
std::vector<std::string> argvec = cl.argv();
|
||||
|
||||
for (size_t i = 0; i < argvec.size(); i++) {
|
||||
EXPECT_EQ(0, argvec[i].compare(argv[i]));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// These test the command line used to invoke the unit test.
|
||||
@ -89,6 +97,7 @@ TEST(CommandLineTest, EmptyString) {
|
||||
CommandLine cl(L"");
|
||||
#elif defined(OS_POSIX)
|
||||
CommandLine cl(0, NULL);
|
||||
EXPECT_TRUE(cl.argv().size() == 0);
|
||||
#endif
|
||||
EXPECT_TRUE(cl.command_line_string().empty());
|
||||
EXPECT_TRUE(cl.program().empty());
|
||||
@ -96,11 +105,7 @@ TEST(CommandLineTest, EmptyString) {
|
||||
}
|
||||
|
||||
// Test static functions for appending switches to a command line.
|
||||
// TODO(pinkerton): non-windows platforms don't have the requisite ctor here, so
|
||||
// we need something that tests AppendSwitches in another way (if even desired).
|
||||
#if defined(OS_WIN)
|
||||
TEST(CommandLineTest, AppendSwitches) {
|
||||
std::wstring cl_string = L"Program";
|
||||
std::wstring switch1 = L"switch1";
|
||||
std::wstring switch2 = L"switch2";
|
||||
std::wstring value = L"value";
|
||||
@ -109,11 +114,25 @@ TEST(CommandLineTest, AppendSwitches) {
|
||||
std::wstring switch4 = L"switch4";
|
||||
std::wstring value4 = L"\"a value with quotes\"";
|
||||
|
||||
#if defined(OS_WIN)
|
||||
std::wstring cl_string = L"Program";
|
||||
CommandLine::AppendSwitch(&cl_string, switch1);
|
||||
CommandLine::AppendSwitchWithValue(&cl_string, switch2, value);
|
||||
CommandLine::AppendSwitchWithValue(&cl_string, switch3, value3);
|
||||
CommandLine::AppendSwitchWithValue(&cl_string, switch4, value4);
|
||||
CommandLine cl(cl_string);
|
||||
#elif defined(OS_POSIX)
|
||||
std::vector<std::string> argv;
|
||||
argv.push_back(std::string("Program"));
|
||||
argv.push_back(WideToUTF8(CommandLine::PrefixedSwitchString(switch1)));
|
||||
argv.push_back(WideToUTF8(CommandLine::PrefixedSwitchStringWithValue(
|
||||
switch2, value)));
|
||||
argv.push_back(WideToUTF8(CommandLine::PrefixedSwitchStringWithValue(
|
||||
switch3, value3)));
|
||||
argv.push_back(WideToUTF8(CommandLine::PrefixedSwitchStringWithValue(
|
||||
switch4, value4.substr(1, value4.length() - 2))));
|
||||
CommandLine cl(argv);
|
||||
#endif
|
||||
|
||||
EXPECT_TRUE(cl.HasSwitch(switch1));
|
||||
EXPECT_TRUE(cl.HasSwitch(switch2));
|
||||
@ -123,4 +142,4 @@ TEST(CommandLineTest, AppendSwitches) {
|
||||
EXPECT_TRUE(cl.HasSwitch(switch4));
|
||||
EXPECT_EQ(value4.substr(1, value4.length() - 2), cl.GetSwitchValue(switch4));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Reference in New Issue
Block a user