diff options
author | msw@chromium.org <msw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-01 02:28:42 +0000 |
---|---|---|
committer | msw@chromium.org <msw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-01 02:28:42 +0000 |
commit | 06cc083a42b907f52084f809124c38bafd88f09f (patch) | |
tree | 9166946d78435b43c6c4f4d42954d9cb632112c0 /base | |
parent | 87ba2e6056bfe771ddc6ce540cf3d4e413d4e6f4 (diff) | |
download | chromium_src-06cc083a42b907f52084f809124c38bafd88f09f.zip chromium_src-06cc083a42b907f52084f809124c38bafd88f09f.tar.gz chromium_src-06cc083a42b907f52084f809124c38bafd88f09f.tar.bz2 |
Reorganize CommandLine code.
The majority of these changes are purely moving code.
Conducted some minor (and hopefully straightforward) refactoring.
BUG=73195
TEST=none
Review URL: http://codereview.chromium.org/6596020
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@76339 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/command_line.cc | 453 | ||||
-rw-r--r-- | base/command_line.h | 188 |
2 files changed, 297 insertions, 344 deletions
diff --git a/base/command_line.cc b/base/command_line.cc index c0a0f19..eefd6ac 100644 --- a/base/command_line.cc +++ b/base/command_line.cc @@ -27,31 +27,29 @@ CommandLine* CommandLine::current_process_commandline_ = NULL; -// Since we use a lazy match, make sure that longer versions (like L"--") -// are listed before shorter versions (like L"-") of similar prefixes. +namespace { +typedef CommandLine::StringType::value_type CharType; + +const CharType kSwitchTerminator[] = FILE_PATH_LITERAL("--"); +const CharType kSwitchValueSeparator[] = FILE_PATH_LITERAL("="); +// Since we use a lazy match, make sure that longer versions (like "--") are +// listed before shorter versions (like "-") of similar prefixes. #if defined(OS_WIN) -const wchar_t* const kSwitchPrefixes[] = {L"--", L"-", L"/"}; -const wchar_t kSwitchTerminator[] = L"--"; -const wchar_t kSwitchValueSeparator[] = L"="; +const CharType* const kSwitchPrefixes[] = {L"--", L"-", L"/"}; #elif defined(OS_POSIX) // Unixes don't use slash as a switch. -const char* const kSwitchPrefixes[] = {"--", "-"}; -const char kSwitchTerminator[] = "--"; -const char kSwitchValueSeparator[] = "="; +const CharType* const kSwitchPrefixes[] = {"--", "-"}; #endif #if defined(OS_WIN) -namespace { -// Lowercase a string. This is used to lowercase switch names. -// Is this what we really want? It seems crazy to me. I've left it in -// for backwards compatibility on Windows. -void Lowercase(std::string* parameter) { - transform(parameter->begin(), parameter->end(), parameter->begin(), - tolower); +// Lowercase a string for case-insensitivity of switches. +// Is this desirable? It exists for backwards compatibility on Windows. +void Lowercase(std::string* arg) { + transform(arg->begin(), arg->end(), arg->begin(), tolower); } -// Quote a string if necessary, such that CommandLineToArgvW() will -// always process it as a single argument. +// Quote a string if necessary, such that CommandLineToArgvW() will always +// process it as a single argument. std::wstring WindowsStyleQuote(const std::wstring& arg) { // We follow the quoting rules of CommandLineToArgvW. // http://msdn.microsoft.com/en-us/library/17w5ykft.aspx @@ -93,94 +91,117 @@ std::wstring WindowsStyleQuote(const std::wstring& arg) { return out; } -} // namespace #endif -CommandLine::~CommandLine() { -} - -#if defined(OS_WIN) -CommandLine::CommandLine(NoProgram no_program) { -} - -void CommandLine::ParseFromString(const std::wstring& command_line) { - TrimWhitespace(command_line, TRIM_ALL, &command_line_string_); - - if (command_line_string_.empty()) - return; - - int num_args = 0; - wchar_t** args = NULL; - - args = CommandLineToArgvW(command_line_string_.c_str(), &num_args); - - // Populate program_ with the trimmed version of the first arg. - TrimWhitespace(args[0], TRIM_ALL, &program_); - - bool parse_switches = true; - for (int i = 1; i < num_args; ++i) { - std::wstring arg; - TrimWhitespace(args[i], TRIM_ALL, &arg); - - if (!parse_switches) { - args_.push_back(arg); - continue; - } +// Returns true and fills in |switch_string| and |switch_value| if +// |parameter_string| represents a switch. +bool IsSwitch(const CommandLine::StringType& parameter_string, + std::string* switch_string, + CommandLine::StringType* switch_value) { + switch_string->clear(); + switch_value->clear(); - if (arg == kSwitchTerminator) { - parse_switches = false; + for (size_t i = 0; i < arraysize(kSwitchPrefixes); ++i) { + CommandLine::StringType prefix(kSwitchPrefixes[i]); + if (parameter_string.find(prefix) != 0) continue; - } - std::string switch_string; - std::wstring switch_value; - if (IsSwitch(arg, &switch_string, &switch_value)) { - switches_[switch_string] = switch_value; + const size_t switch_start = prefix.length(); + const size_t equals_position = parameter_string.find( + kSwitchValueSeparator, switch_start); + CommandLine::StringType switch_native; + if (equals_position == CommandLine::StringType::npos) { + switch_native = parameter_string.substr(switch_start); } else { - args_.push_back(arg); + switch_native = parameter_string.substr( + switch_start, equals_position - switch_start); + *switch_value = parameter_string.substr(equals_position + 1); } +#if defined(OS_WIN) + *switch_string = WideToASCII(switch_native); + Lowercase(switch_string); +#else + *switch_string = switch_native; +#endif + + return true; } - if (args) - LocalFree(args); + return false; } -// static -CommandLine CommandLine::FromString(const std::wstring& command_line) { - CommandLine cmd; - cmd.ParseFromString(command_line); - return cmd; +} // namespace + +CommandLine::CommandLine(NoProgram no_program) { +#if defined(OS_POSIX) + // Push an empty argument, because we always assume argv_[0] is a program. + argv_.push_back(""); +#endif } CommandLine::CommandLine(const FilePath& program) { +#if defined(OS_WIN) if (!program.empty()) { program_ = program.value(); // TODO(evanm): proper quoting here. command_line_string_ = L'"' + program.value() + L'"'; } -} - #elif defined(OS_POSIX) -CommandLine::CommandLine(NoProgram no_program) { - // Push an empty argument, because we always assume argv_[0] is a program. - argv_.push_back(""); + argv_.push_back(program.value()); +#endif } +#if defined(OS_POSIX) CommandLine::CommandLine(int argc, const char* const* argv) { InitFromArgv(argc, argv); } -CommandLine::CommandLine(const std::vector<std::string>& argv) { +CommandLine::CommandLine(const StringVector& argv) { InitFromArgv(argv); } +#endif // OS_POSIX +// static +void CommandLine::Init(int argc, const char* const* argv) { + delete current_process_commandline_; + current_process_commandline_ = new CommandLine; +#if defined(OS_WIN) + current_process_commandline_->ParseFromString(::GetCommandLineW()); +#elif defined(OS_POSIX) + current_process_commandline_->InitFromArgv(argc, argv); +#endif +} + +// static +void CommandLine::Reset() { + DCHECK(current_process_commandline_); + delete current_process_commandline_; + current_process_commandline_ = NULL; +} + +// static +CommandLine* CommandLine::ForCurrentProcess() { + DCHECK(current_process_commandline_); + return current_process_commandline_; +} + +#if defined(OS_WIN) +// static +CommandLine CommandLine::FromString(const std::wstring& command_line) { + CommandLine cmd; + cmd.ParseFromString(command_line); + return cmd; +} +#endif // OS_WIN + +#if defined(OS_POSIX) void CommandLine::InitFromArgv(int argc, const char* const* argv) { for (int i = 0; i < argc; ++i) argv_.push_back(argv[i]); InitFromArgv(argv_); } -void CommandLine::InitFromArgv(const std::vector<std::string>& argv) { +void CommandLine::InitFromArgv(const StringVector& argv) { argv_ = argv; bool parse_switches = true; for (size_t i = 1; i < argv_.size(); ++i) { @@ -197,7 +218,7 @@ void CommandLine::InitFromArgv(const std::vector<std::string>& argv) { } std::string switch_string; - std::string switch_value; + StringType switch_value; if (IsSwitch(arg, &switch_string, &switch_value)) { switches_[switch_string] = switch_value; } else { @@ -205,72 +226,25 @@ void CommandLine::InitFromArgv(const std::vector<std::string>& argv) { } } } +#endif // OS_POSIX -CommandLine::CommandLine(const FilePath& program) { - argv_.push_back(program.value()); -} - -#endif - -// static -bool CommandLine::IsSwitch(const StringType& parameter_string, - std::string* switch_string, - StringType* switch_value) { - switch_string->clear(); - switch_value->clear(); - - for (size_t i = 0; i < arraysize(kSwitchPrefixes); ++i) { - StringType prefix(kSwitchPrefixes[i]); - if (parameter_string.find(prefix) != 0) - continue; - - const size_t switch_start = prefix.length(); - const size_t equals_position = parameter_string.find( - kSwitchValueSeparator, switch_start); - StringType switch_native; - if (equals_position == StringType::npos) { - switch_native = parameter_string.substr(switch_start); - } else { - switch_native = parameter_string.substr( - switch_start, equals_position - switch_start); - *switch_value = parameter_string.substr(equals_position + 1); - } +CommandLine::StringType CommandLine::command_line_string() const { #if defined(OS_WIN) - *switch_string = WideToASCII(switch_native); - Lowercase(switch_string); -#else - *switch_string = switch_native; + return command_line_string_; +#elif defined(OS_POSIX) + return JoinString(argv_, ' '); #endif - - return true; - } - - return false; } -// static -void CommandLine::Init(int argc, const char* const* argv) { - delete current_process_commandline_; - current_process_commandline_ = new CommandLine; +FilePath CommandLine::GetProgram() const { #if defined(OS_WIN) - current_process_commandline_->ParseFromString(::GetCommandLineW()); -#elif defined(OS_POSIX) - current_process_commandline_->InitFromArgv(argc, argv); + return FilePath(program_); +#else + DCHECK_GT(argv_.size(), 0U); + return FilePath(argv_[0]); #endif } -void CommandLine::Reset() { - DCHECK(current_process_commandline_ != NULL); - delete current_process_commandline_; - current_process_commandline_ = NULL; -} - -// static -CommandLine* CommandLine::ForCurrentProcess() { - DCHECK(current_process_commandline_); - return current_process_commandline_; -} - bool CommandLine::HasSwitch(const std::string& switch_string) const { std::string lowercased_switch(switch_string); #if defined(OS_WIN) @@ -305,8 +279,7 @@ CommandLine::StringType CommandLine::GetSwitchValueNative( Lowercase(&lowercased_switch); #endif - std::map<std::string, StringType>::const_iterator result = - switches_.find(lowercased_switch); + SwitchMap::const_iterator result = switches_.find(lowercased_switch); if (result == switches_.end()) { return CommandLine::StringType(); @@ -315,31 +288,30 @@ CommandLine::StringType CommandLine::GetSwitchValueNative( } } -FilePath CommandLine::GetProgram() const { -#if defined(OS_WIN) - return FilePath(program_); -#else - DCHECK_GT(argv_.size(), 0U); - return FilePath(argv_[0]); -#endif -} - -#if defined(OS_POSIX) -std::string CommandLine::command_line_string() const { - return JoinString(argv_, ' '); +size_t CommandLine::GetSwitchCount() const { + return switches_.size(); } -#endif -#if defined(OS_WIN) void CommandLine::AppendSwitch(const std::string& switch_string) { +#if defined(OS_WIN) command_line_string_.append(L" "); command_line_string_.append(kSwitchPrefixes[0] + ASCIIToWide(switch_string)); switches_[switch_string] = L""; +#elif defined(OS_POSIX) + argv_.push_back(kSwitchPrefixes[0] + switch_string); + switches_[switch_string] = ""; +#endif +} + +void CommandLine::AppendSwitchPath(const std::string& switch_string, + const FilePath& path) { + AppendSwitchNative(switch_string, path.value()); } void CommandLine::AppendSwitchNative(const std::string& switch_string, - const std::wstring& value) { - std::wstring combined_switch_string = + const CommandLine::StringType& value) { +#if defined(OS_WIN) + StringType combined_switch_string = kSwitchPrefixes[0] + ASCIIToWide(switch_string); if (!value.empty()) combined_switch_string += kSwitchValueSeparator + WindowsStyleQuote(value); @@ -348,26 +320,79 @@ void CommandLine::AppendSwitchNative(const std::string& switch_string, command_line_string_.append(combined_switch_string); switches_[switch_string] = value; +#elif defined(OS_POSIX) + StringType combined_switch_string = kSwitchPrefixes[0] + switch_string; + if (!value.empty()) + combined_switch_string += kSwitchValueSeparator + value; + argv_.push_back(combined_switch_string); + switches_[switch_string] = value; +#endif } void CommandLine::AppendSwitchASCII(const std::string& switch_string, const std::string& value_string) { +#if defined(OS_WIN) AppendSwitchNative(switch_string, ASCIIToWide(value_string)); +#elif defined(OS_POSIX) + AppendSwitchNative(switch_string, value_string); +#endif +} + +void CommandLine::AppendSwitches(const CommandLine& other) { + SwitchMap::const_iterator i; + for (i = other.switches_.begin(); i != other.switches_.end(); ++i) + AppendSwitchNative(i->first, i->second); +} + +void CommandLine::CopySwitchesFrom(const CommandLine& source, + const char* const switches[], + size_t count) { + for (size_t i = 0; i < count; ++i) { + if (source.HasSwitch(switches[i])) { + StringType value = source.GetSwitchValueNative(switches[i]); + AppendSwitchNative(switches[i], value); + } + } } void CommandLine::AppendArg(const std::string& value) { +#if defined(OS_WIN) DCHECK(IsStringUTF8(value)); AppendArgNative(UTF8ToWide(value)); +#elif defined(OS_POSIX) + AppendArgNative(value); +#endif } -void CommandLine::AppendArgNative(const std::wstring& value) { +void CommandLine::AppendArgPath(const FilePath& path) { + AppendArgNative(path.value()); +} + +void CommandLine::AppendArgNative(const CommandLine::StringType& value) { +#if defined(OS_WIN) command_line_string_.append(L" "); command_line_string_.append(WindowsStyleQuote(value)); args_.push_back(value); +#elif defined(OS_POSIX) + DCHECK(IsStringUTF8(value)); + argv_.push_back(value); +#endif +} + +void CommandLine::AppendArgs(const CommandLine& other) { + if(other.args_.size() <= 0) + return; +#if defined(OS_WIN) + command_line_string_.append(L" --"); +#endif // OS_WIN + StringVector::const_iterator i; + for (i = other.args_.begin(); i != other.args_.end(); ++i) + AppendArgNative(*i); } void CommandLine::AppendArguments(const CommandLine& other, bool include_program) { +#if defined(OS_WIN) // Verify include_program is used correctly. DCHECK(!include_program || !other.GetProgram().empty()); if (include_program) @@ -377,54 +402,7 @@ void CommandLine::AppendArguments(const CommandLine& other, command_line_string_ += L' '; command_line_string_ += other.command_line_string_; - - std::map<std::string, StringType>::const_iterator i; - for (i = other.switches_.begin(); i != other.switches_.end(); ++i) - switches_[i->first] = i->second; -} - -void CommandLine::PrependWrapper(const std::wstring& wrapper) { - if (wrapper.empty()) - return; - // The wrapper may have embedded arguments (like "gdb --args"). In this case, - // we don't pretend to do anything fancy, we just split on spaces. - std::vector<std::wstring> wrapper_and_args; - base::SplitString(wrapper, ' ', &wrapper_and_args); - program_ = wrapper_and_args[0]; - command_line_string_ = wrapper + L" " + command_line_string_; -} - #elif defined(OS_POSIX) -void CommandLine::AppendSwitch(const std::string& switch_string) { - argv_.push_back(kSwitchPrefixes[0] + switch_string); - switches_[switch_string] = ""; -} - -void CommandLine::AppendSwitchNative(const std::string& switch_string, - const std::string& value) { - std::string combined_switch_string = kSwitchPrefixes[0] + switch_string; - if (!value.empty()) - combined_switch_string += kSwitchValueSeparator + value; - argv_.push_back(combined_switch_string); - switches_[switch_string] = value; -} - -void CommandLine::AppendSwitchASCII(const std::string& switch_string, - const std::string& value_string) { - AppendSwitchNative(switch_string, value_string); -} - -void CommandLine::AppendArg(const std::string& value) { - AppendArgNative(value); -} - -void CommandLine::AppendArgNative(const std::string& value) { - DCHECK(IsStringUTF8(value)); - argv_.push_back(value); -} - -void CommandLine::AppendArguments(const CommandLine& other, - bool include_program) { // Verify include_program is used correctly. // Logic could be shorter but this is clearer. DCHECK_EQ(include_program, !other.GetProgram().empty()); @@ -436,66 +414,69 @@ void CommandLine::AppendArguments(const CommandLine& other, // arguments to our arg vector. for (size_t i = 1; i < other.argv_.size(); ++i) argv_.push_back(other.argv_[i]); +#endif - std::map<std::string, StringType>::const_iterator i; + SwitchMap::const_iterator i; for (i = other.switches_.begin(); i != other.switches_.end(); ++i) switches_[i->first] = i->second; } -void CommandLine::PrependWrapper(const std::string& wrapper) { +void CommandLine::PrependWrapper(const CommandLine::StringType& wrapper) { // The wrapper may have embedded arguments (like "gdb --args"). In this case, // we don't pretend to do anything fancy, we just split on spaces. - std::vector<std::string> wrapper_and_args; + if (wrapper.empty()) + return; + StringVector wrapper_and_args; +#if defined(OS_WIN) + base::SplitString(wrapper, ' ', &wrapper_and_args); + program_ = wrapper_and_args[0]; + command_line_string_ = wrapper + L" " + command_line_string_; +#elif defined(OS_POSIX) base::SplitString(wrapper, ' ', &wrapper_and_args); argv_.insert(argv_.begin(), wrapper_and_args.begin(), wrapper_and_args.end()); +#endif } -#endif +#if defined(OS_WIN) +void CommandLine::ParseFromString(const std::wstring& command_line) { + TrimWhitespace(command_line, TRIM_ALL, &command_line_string_); -void CommandLine::AppendSwitchPath(const std::string& switch_string, - const FilePath& path) { - AppendSwitchNative(switch_string, path.value()); -} + if (command_line_string_.empty()) + return; -void CommandLine::AppendSwitches(const CommandLine& other) { - std::map<std::string, StringType>::const_iterator i; - for (i = other.switches_.begin(); i != other.switches_.end(); ++i) - AppendSwitchNative(i->first, i->second); -} + int num_args = 0; + wchar_t** args = NULL; -void CommandLine::AppendArgPath(const FilePath& path) { - AppendArgNative(path.value()); -} + args = CommandLineToArgvW(command_line_string_.c_str(), &num_args); -void CommandLine::AppendArgs(const CommandLine& other) { - if(other.args_.size() <= 0) - return; + // Populate program_ with the trimmed version of the first arg. + TrimWhitespace(args[0], TRIM_ALL, &program_); -#if defined(OS_WIN) - command_line_string_.append(L" --"); -#endif // OS_WIN - std::vector<StringType>::const_iterator i; - for (i = other.args_.begin(); i != other.args_.end(); ++i) - AppendArgNative(*i); -} + bool parse_switches = true; + for (int i = 1; i < num_args; ++i) { + std::wstring arg; + TrimWhitespace(args[i], TRIM_ALL, &arg); -void CommandLine::CopySwitchesFrom(const CommandLine& source, - const char* const switches[], - size_t count) { - for (size_t i = 0; i < count; ++i) { - if (source.HasSwitch(switches[i])) { - StringType value = source.GetSwitchValueNative(switches[i]); - AppendSwitchNative(switches[i], value); + if (!parse_switches) { + args_.push_back(arg); + continue; } - } -} -// private -CommandLine::CommandLine() { -} + if (arg == kSwitchTerminator) { + parse_switches = false; + continue; + } -// static -CommandLine* CommandLine::ForCurrentProcessMutable() { - DCHECK(current_process_commandline_); - return current_process_commandline_; + std::string switch_string; + std::wstring switch_value; + if (IsSwitch(arg, &switch_string, &switch_value)) { + switches_[switch_string] = switch_value; + } else { + args_.push_back(arg); + } + } + + if (args) + LocalFree(args); } +#endif diff --git a/base/command_line.h b/base/command_line.h index db61458..a6313ee 100644 --- a/base/command_line.h +++ b/base/command_line.h @@ -3,15 +3,13 @@ // found in the LICENSE file. // This class works with command lines: building and parsing. -// Switches can optionally have a value attached using an equals sign, -// as in "-switch=value". Arguments that aren't prefixed with a -// switch prefix are saved as extra arguments. An argument of "--" -// will terminate switch parsing, causing everything after to be -// considered as extra arguments. +// Switches can optionally have a value attached using an equals sign, as in +// "-switch=value". Arguments that aren't prefixed with a switch prefix are +// saved as extra arguments. An argument of "--" will terminate switch parsing, +// causing everything after to be considered as extra arguments. -// There is a singleton read-only CommandLine that represents the command -// line that the current process was started with. It must be initialized -// in main() (or whatever the platform's equivalent function is). +// There is a singleton read-only CommandLine that represents the command line +// that the current process was started with. It must be initialized in main(). #ifndef BASE_COMMAND_LINE_H_ #define BASE_COMMAND_LINE_H_ @@ -25,111 +23,91 @@ #include "build/build_config.h" class FilePath; -class InProcessBrowserTest; class CommandLine { public: #if defined(OS_WIN) - // The type of native command line arguments. + // The native command line string type. typedef std::wstring StringType; #elif defined(OS_POSIX) - // The type of native command line arguments. typedef std::string StringType; #endif + typedef std::vector<StringType> StringVector; // The type of map for parsed-out switch key and values. typedef std::map<std::string, StringType> SwitchMap; - // A constructor for CommandLines that are used only to carry switches and - // arguments. + // A constructor for CommandLines that only carry switches and arguments. enum NoProgram { NO_PROGRAM }; explicit CommandLine(NoProgram no_program); - // Construct a new, empty command line. - // |program| is the name of the program to run (aka argv[0]). + // Construct a new command line with |program| as argv[0]. explicit CommandLine(const FilePath& program); #if defined(OS_POSIX) CommandLine(int argc, const char* const* argv); - explicit CommandLine(const std::vector<std::string>& argv); + explicit CommandLine(const StringVector& argv); #endif - ~CommandLine(); - -#if defined(OS_WIN) - // Initialize by parsing the given command-line string. - // The program name is assumed to be the first item in the string. - void ParseFromString(const std::wstring& command_line); - static CommandLine FromString(const std::wstring& command_line); -#elif defined(OS_POSIX) - // Initialize from an argv vector. - void InitFromArgv(int argc, const char* const* argv); - void InitFromArgv(const std::vector<std::string>& argv); -#endif - - // Initialize the current process CommandLine singleton. On Windows, - // ignores its arguments (we instead parse GetCommandLineW() - // directly) because we don't trust the CRT's parsing of the command - // line, but it still must be called to set up the command line. + // Initialize the current process CommandLine singleton. On Windows, ignores + // its arguments (we instead parse GetCommandLineW() directly) because we + // don't trust the CRT's parsing of the command line, but it still must be + // called to set up the command line. static void Init(int argc, const char* const* argv); // Destroys the current process CommandLine singleton. This is necessary if - // you want to reset the base library to its initial state (for example in an + // you want to reset the base library to its initial state (for example, in an // outer library that needs to be able to terminate, and be re-initialized). - // If Init is called only once, e.g. in main(), calling Reset() is not - // necessary. + // If Init is called only once, as in main(), Reset() is not necessary. static void Reset(); // Get the singleton CommandLine representing the current process's - // command line. Note: returned value is mutable, but not thread safe; + // command line. Note: returned value is mutable, but not thread safe; // only mutate if you know what you're doing! static CommandLine* ForCurrentProcess(); +#if defined(OS_WIN) + static CommandLine FromString(const std::wstring& command_line); +#endif + +#if defined(OS_POSIX) + // Initialize from an argv vector. + void InitFromArgv(int argc, const char* const* argv); + void InitFromArgv(const StringVector& argv); +#endif + + // Returns the represented command line string. + // CAUTION! This should be avoided because quoting behavior is unclear. + StringType command_line_string() const; + +#if defined(OS_POSIX) + // Returns the original command line string as a vector of strings. + const StringVector& argv() const { return argv_; } +#endif + + // Returns the program part of the command line string (the first item). + FilePath GetProgram() const; + // Returns true if this command line contains the given switch. - // (Switch names are case-insensitive.) + // (Switch names are case-insensitive). bool HasSwitch(const std::string& switch_string) const; - // Returns the value associated with the given switch. If the - // switch has no value or isn't present, this method returns - // the empty string. + // Returns the value associated with the given switch. If the switch has no + // value or isn't present, this method returns the empty string. std::string GetSwitchValueASCII(const std::string& switch_string) const; FilePath GetSwitchValuePath(const std::string& switch_string) const; StringType GetSwitchValueNative(const std::string& switch_string) const; // Get the number of switches in this process. - size_t GetSwitchCount() const { return switches_.size(); } + // TODO(msw): Remove unnecessary API. + size_t GetSwitchCount() const; - // Get a copy of all switches, along with their values - const SwitchMap& GetSwitches() const { - return switches_; - } + // Get a copy of all switches, along with their values. + const SwitchMap& GetSwitches() const { return switches_; } - // Get the remaining arguments to the command. - const std::vector<StringType>& args() const { return args_; } - -#if defined(OS_WIN) - // Returns the original command line string. - const std::wstring& command_line_string() const { - return command_line_string_; - } -#elif defined(OS_POSIX) - // Returns the original command line string as a vector of strings. - const std::vector<std::string>& argv() const { - return argv_; - } - // Try to match the same result as command_line_string() would get you - // on windows. - std::string command_line_string() const; -#endif - - // Returns the program part of the command line string (the first item). - FilePath GetProgram() const; - - // Append a switch to the command line. + // Append a switch [with optional value] to the command line. + // CAUTION! Appending a switch after the "--" switch terminator is futile! void AppendSwitch(const std::string& switch_string); - - // Append a switch and value to the command line. - // CAUTION! Appending a switch after the "--" kSwitchTerminator is futile! void AppendSwitchPath(const std::string& switch_string, const FilePath& path); void AppendSwitchNative(const std::string& switch_string, const StringType& value); @@ -137,11 +115,17 @@ class CommandLine { const std::string& value); void AppendSwitches(const CommandLine& other); - // Append an argument to the command line. - // Note on quoting: the argument will be quoted properly such that it is - // interpreted as one argument to the target command. - // AppendArg is primarily for ASCII; non-ASCII input will be - // interpreted as UTF-8. + // Copy a set of switches (and any values) from another command line. + // Commonly used when launching a subprocess. + void CopySwitchesFrom(const CommandLine& source, const char* const switches[], + size_t count); + + // Get the remaining arguments to the command. + const StringVector& args() const { return args_; } + + // Append an argument to the command line. Note that the argument is quoted + // properly such that it is interpreted as one argument to the target command. + // AppendArg is primarily for ASCII; non-ASCII input is interpreted as UTF-8. void AppendArg(const std::string& value); void AppendArgPath(const FilePath& value); void AppendArgNative(const StringType& value); @@ -152,55 +136,43 @@ class CommandLine { void AppendArguments(const CommandLine& other, bool include_program); - // Insert a command before the current command. Common for debuggers, - // like "valgrind" or "gdb --args". + // Insert a command before the current command. + // Common for debuggers, like "valgrind" or "gdb --args". void PrependWrapper(const StringType& wrapper); - // Copy a set of switches (and their values, if any) from another command - // line. Commonly used when launching a subprocess. - void CopySwitchesFrom(const CommandLine& source, const char* const switches[], - size_t count); +#if defined(OS_WIN) + // Initialize by parsing the given command line string. + // The program name is assumed to be the first item in the string. + void ParseFromString(const std::wstring& command_line); +#endif private: - friend class InProcessBrowserTest; - - CommandLine(); + // Disallow default constructor; a program name must be explicitly specified. + CommandLine() {} - // Used by InProcessBrowserTest. - static CommandLine* ForCurrentProcessMutable(); - - // Returns true and fills in |switch_string| and |switch_value| - // if |parameter_string| represents a switch. - static bool IsSwitch(const StringType& parameter_string, - std::string* switch_string, - StringType* switch_value); - - // The singleton CommandLine instance representing the current process's - // command line. + // The singleton CommandLine representing the current process's command line. static CommandLine* current_process_commandline_; // We store a platform-native version of the command line, used when building - // up a new command line to be executed. This ifdef delimits that code. - + // up a new command line to be executed. This ifdef delimits that code. #if defined(OS_WIN) - // The quoted, space-separated command-line string. - std::wstring command_line_string_; + // The quoted, space-separated command line string. + StringType command_line_string_; // The name of the program. - std::wstring program_; + StringType program_; #elif defined(OS_POSIX) // The argv array, with the program name in argv_[0]. - std::vector<std::string> argv_; + StringVector argv_; #endif - // Parsed-out values. + // Parsed-out switch keys and values. SwitchMap switches_; - // Non-switch command-line arguments. - std::vector<StringType> args_; + // Non-switch command line arguments. + StringVector args_; - // We allow copy constructors, because a common pattern is to grab a - // copy of the current process's command line and then add some - // flags to it. E.g.: + // Allow the copy constructor. A common pattern is to copy the current + // process's command line and then add some flags to it. For example: // CommandLine cl(*CommandLine::ForCurrentProcess()); // cl.AppendSwitch(...); }; |