1dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/command_line.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <algorithm> 8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <ostream> 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/basictypes.h" 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/file_path.h" 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h" 133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_split.h" 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/string_util.h" 153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h" 163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "build/build_config.h" 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 183f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#if defined(OS_WIN) 193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include <windows.h> 203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include <shellapi.h> 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottCommandLine* CommandLine::current_process_commandline_ = NULL; 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 25dc0f95d653279beabeb9817299e2902918ba123eKristian Monsennamespace { 26dc0f95d653279beabeb9817299e2902918ba123eKristian Monsentypedef CommandLine::StringType::value_type CharType; 27dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 28dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenconst CharType kSwitchTerminator[] = FILE_PATH_LITERAL("--"); 29dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenconst CharType kSwitchValueSeparator[] = FILE_PATH_LITERAL("="); 30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Since we use a lazy match, make sure that longer versions (like "--") are 31dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// listed before shorter versions (like "-") of similar prefixes. 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN) 33dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenconst CharType* const kSwitchPrefixes[] = {L"--", L"-", L"/"}; 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#elif defined(OS_POSIX) 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Unixes don't use slash as a switch. 36dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenconst CharType* const kSwitchPrefixes[] = {"--", "-"}; 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN) 40dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Lowercase a string for case-insensitivity of switches. 41dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Is this desirable? It exists for backwards compatibility on Windows. 42dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid Lowercase(std::string* arg) { 43dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen transform(arg->begin(), arg->end(), arg->begin(), tolower); 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 46dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Quote a string if necessary, such that CommandLineToArgvW() will always 47dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// process it as a single argument. 48dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstd::wstring WindowsStyleQuote(const std::wstring& arg) { 49dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // We follow the quoting rules of CommandLineToArgvW. 50dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // http://msdn.microsoft.com/en-us/library/17w5ykft.aspx 51dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (arg.find_first_of(L" \\\"") == std::wstring::npos) { 52dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // No quoting necessary. 53dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return arg; 54dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 56dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::wstring out; 57dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.push_back(L'"'); 58dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen for (size_t i = 0; i < arg.size(); ++i) { 59dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (arg[i] == '\\') { 60dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Find the extent of this run of backslashes. 61dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen size_t start = i, end = start + 1; 62dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen for (; end < arg.size() && arg[end] == '\\'; ++end) 63dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen /* empty */; 64dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen size_t backslash_count = end - start; 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 66dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Backslashes are escapes only if the run is followed by a double quote. 67dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Since we also will end the string with a double quote, we escape for 68dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // either a double quote or the end of the string. 69dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (end == arg.size() || arg[end] == '"') { 70dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // To quote, we need to output 2x as many backslashes. 71dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen backslash_count *= 2; 72dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 73dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen for (size_t j = 0; j < backslash_count; ++j) 74dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.push_back('\\'); 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 76dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Advance i to one before the end to balance i++ in loop. 77dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen i = end - 1; 78dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } else if (arg[i] == '"') { 79dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.push_back('\\'); 80dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.push_back('"'); 81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } else { 82dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.push_back(arg[i]); 83dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 84dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 85dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen out.push_back('"'); 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 87dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return out; 88dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 89dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 91dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Returns true and fills in |switch_string| and |switch_value| if 92dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// |parameter_string| represents a switch. 93dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool IsSwitch(const CommandLine::StringType& parameter_string, 94dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string* switch_string, 95dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CommandLine::StringType* switch_value) { 96dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen switch_string->clear(); 97dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen switch_value->clear(); 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 99dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen for (size_t i = 0; i < arraysize(kSwitchPrefixes); ++i) { 100dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CommandLine::StringType prefix(kSwitchPrefixes[i]); 101dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (parameter_string.find(prefix) != 0) 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott continue; 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 104dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const size_t switch_start = prefix.length(); 105dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const size_t equals_position = parameter_string.find( 106dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen kSwitchValueSeparator, switch_start); 107dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CommandLine::StringType switch_native; 108dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (equals_position == CommandLine::StringType::npos) { 109dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen switch_native = parameter_string.substr(switch_start); 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 111dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen switch_native = parameter_string.substr( 112dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen switch_start, equals_position - switch_start); 113dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen *switch_value = parameter_string.substr(equals_position + 1); 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 115dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_WIN) 116dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen *switch_string = WideToASCII(switch_native); 117dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen Lowercase(switch_string); 118dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#else 119dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen *switch_string = switch_native; 120dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif 121dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 122dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return true; 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 125dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return false; 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 128dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} // namespace 129dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 130dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenCommandLine::CommandLine(NoProgram no_program) { 131dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_POSIX) 132dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Push an empty argument, because we always assume argv_[0] is a program. 133dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen argv_.push_back(""); 134dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif 1353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottCommandLine::CommandLine(const FilePath& program) { 138dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_WIN) 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!program.empty()) { 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott program_ = program.value(); 1413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // TODO(evanm): proper quoting here. 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott command_line_string_ = L'"' + program.value() + L'"'; 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#elif defined(OS_POSIX) 145dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen argv_.push_back(program.value()); 146dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 149dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_POSIX) 1503345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickCommandLine::CommandLine(int argc, const char* const* argv) { 1513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick InitFromArgv(argc, argv); 1523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 154dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenCommandLine::CommandLine(const StringVector& argv) { 1553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick InitFromArgv(argv); 1563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 157dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif // OS_POSIX 158dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 159dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenCommandLine::~CommandLine() { 160dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 161dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 162dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// static 163dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid CommandLine::Init(int argc, const char* const* argv) { 164dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen delete current_process_commandline_; 165dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen current_process_commandline_ = new CommandLine; 166dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_WIN) 167dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen current_process_commandline_->ParseFromString(::GetCommandLineW()); 168dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#elif defined(OS_POSIX) 169dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen current_process_commandline_->InitFromArgv(argc, argv); 170dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif 171dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 172dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 173dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// static 174dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid CommandLine::Reset() { 175dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(current_process_commandline_); 176dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen delete current_process_commandline_; 177dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen current_process_commandline_ = NULL; 178dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 1793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 180dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// static 181dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenCommandLine* CommandLine::ForCurrentProcess() { 182dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(current_process_commandline_); 183dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return current_process_commandline_; 184dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 185dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 186dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_WIN) 187dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// static 188dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenCommandLine CommandLine::FromString(const std::wstring& command_line) { 189dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CommandLine cmd; 190dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen cmd.ParseFromString(command_line); 191dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return cmd; 192dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 193dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif // OS_WIN 194dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 195dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_POSIX) 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid CommandLine::InitFromArgv(int argc, const char* const* argv) { 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < argc; ++i) 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott argv_.push_back(argv[i]); 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott InitFromArgv(argv_); 200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 202dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid CommandLine::InitFromArgv(const StringVector& argv) { 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott argv_ = argv; 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool parse_switches = true; 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (size_t i = 1; i < argv_.size(); ++i) { 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::string& arg = argv_[i]; 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!parse_switches) { 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch args_.push_back(arg); 210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott continue; 211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (arg == kSwitchTerminator) { 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott parse_switches = false; 215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott continue; 216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string switch_string; 219dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen StringType switch_value; 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (IsSwitch(arg, &switch_string, &switch_value)) { 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott switches_[switch_string] = switch_value; 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch args_.push_back(arg); 224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 227dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif // OS_POSIX 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 229dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenCommandLine::StringType CommandLine::command_line_string() const { 230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN) 231dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return command_line_string_; 232dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#elif defined(OS_POSIX) 233dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return JoinString(argv_, ' '); 234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 237dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenFilePath CommandLine::GetProgram() const { 238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN) 239dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return FilePath(program_); 240dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#else 241dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK_GT(argv_.size(), 0U); 242dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return FilePath(argv_[0]); 243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool CommandLine::HasSwitch(const std::string& switch_string) const { 247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string lowercased_switch(switch_string); 248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN) 249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Lowercase(&lowercased_switch); 250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return switches_.find(lowercased_switch) != switches_.end(); 252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstd::string CommandLine::GetSwitchValueASCII( 2553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string& switch_string) const { 256731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CommandLine::StringType value = GetSwitchValueNative(switch_string); 257731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!IsStringASCII(value)) { 258731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick LOG(WARNING) << "Value of --" << switch_string << " must be ASCII."; 259731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return ""; 260731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 261731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#if defined(OS_WIN) 262731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return WideToASCII(value); 263731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#else 264731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return value; 265731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#endif 2663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2683345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickFilePath CommandLine::GetSwitchValuePath( 2693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string& switch_string) const { 2703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return FilePath(GetSwitchValueNative(switch_string)); 2713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2733345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickCommandLine::StringType CommandLine::GetSwitchValueNative( 274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::string& switch_string) const { 275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string lowercased_switch(switch_string); 276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN) 277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Lowercase(&lowercased_switch); 278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 280dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SwitchMap::const_iterator result = switches_.find(lowercased_switch); 281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (result == switches_.end()) { 2833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return CommandLine::StringType(); 284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return result->second; 2863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 289dc0f95d653279beabeb9817299e2902918ba123eKristian Monsensize_t CommandLine::GetSwitchCount() const { 290dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return switches_.size(); 291731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid CommandLine::AppendSwitch(const std::string& switch_string) { 294dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_WIN) 295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott command_line_string_.append(L" "); 2963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick command_line_string_.append(kSwitchPrefixes[0] + ASCIIToWide(switch_string)); 297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott switches_[switch_string] = L""; 298dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#elif defined(OS_POSIX) 299dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen argv_.push_back(kSwitchPrefixes[0] + switch_string); 300dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen switches_[switch_string] = ""; 301dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif 302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 304dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid CommandLine::AppendSwitchPath(const std::string& switch_string, 305dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const FilePath& path) { 306dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen AppendSwitchNative(switch_string, path.value()); 3073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 3083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid CommandLine::AppendSwitchNative(const std::string& switch_string, 310dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const CommandLine::StringType& value) { 311dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_WIN) 312dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen StringType combined_switch_string = 3133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kSwitchPrefixes[0] + ASCIIToWide(switch_string); 3143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!value.empty()) 3153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick combined_switch_string += kSwitchValueSeparator + WindowsStyleQuote(value); 316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott command_line_string_.append(L" "); 318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott command_line_string_.append(combined_switch_string); 319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick switches_[switch_string] = value; 321dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#elif defined(OS_POSIX) 322dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen StringType combined_switch_string = kSwitchPrefixes[0] + switch_string; 323dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!value.empty()) 324dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen combined_switch_string += kSwitchValueSeparator + value; 325dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen argv_.push_back(combined_switch_string); 326dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen switches_[switch_string] = value; 327dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif 328dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 329dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 330dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid CommandLine::AppendSwitchASCII(const std::string& switch_string, 331dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const std::string& value_string) { 332dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_WIN) 333dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen AppendSwitchNative(switch_string, ASCIIToWide(value_string)); 334dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#elif defined(OS_POSIX) 335dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen AppendSwitchNative(switch_string, value_string); 336dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif 337dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 338dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 339dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid CommandLine::AppendSwitches(const CommandLine& other) { 340dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SwitchMap::const_iterator i; 341dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen for (i = other.switches_.begin(); i != other.switches_.end(); ++i) 342dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen AppendSwitchNative(i->first, i->second); 343dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 344dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 345dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid CommandLine::CopySwitchesFrom(const CommandLine& source, 346dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const char* const switches[], 347dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen size_t count) { 348dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen for (size_t i = 0; i < count; ++i) { 349dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (source.HasSwitch(switches[i])) { 350dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen StringType value = source.GetSwitchValueNative(switches[i]); 351dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen AppendSwitchNative(switches[i], value); 352dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 353dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 3543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 3553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid CommandLine::AppendArg(const std::string& value) { 357dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_WIN) 3583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(IsStringUTF8(value)); 3593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick AppendArgNative(UTF8ToWide(value)); 360dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#elif defined(OS_POSIX) 361dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen AppendArgNative(value); 362dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif 363dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 364dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 365dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid CommandLine::AppendArgPath(const FilePath& path) { 366dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen AppendArgNative(path.value()); 367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 369dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid CommandLine::AppendArgNative(const CommandLine::StringType& value) { 370dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_WIN) 371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott command_line_string_.append(L" "); 3723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick command_line_string_.append(WindowsStyleQuote(value)); 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch args_.push_back(value); 374dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#elif defined(OS_POSIX) 375dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(IsStringUTF8(value)); 376dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen argv_.push_back(value); 377dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif 378dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 379dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 380dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid CommandLine::AppendArgs(const CommandLine& other) { 381dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if(other.args_.size() <= 0) 382dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return; 383dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_WIN) 384dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen command_line_string_.append(L" --"); 385dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif // OS_WIN 386dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen StringVector::const_iterator i; 387dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen for (i = other.args_.begin(); i != other.args_.end(); ++i) 388dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen AppendArgNative(*i); 389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid CommandLine::AppendArguments(const CommandLine& other, 392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool include_program) { 393dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_WIN) 394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Verify include_program is used correctly. 395dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(!include_program || !other.GetProgram().empty()); 3964a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (include_program) 3974a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch program_ = other.program_; 3984a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 3994a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (!command_line_string_.empty()) 4004a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch command_line_string_ += L' '; 4014a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 4024a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch command_line_string_ += other.command_line_string_; 403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#elif defined(OS_POSIX) 404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Verify include_program is used correctly. 405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Logic could be shorter but this is clearer. 406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(include_program, !other.GetProgram().empty()); 4074a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 4084a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (include_program) 4094a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch argv_[0] = other.argv_[0]; 4104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 4114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // Skip the first arg when copying since it's the program but push all 4124a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // arguments to our arg vector. 4134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch for (size_t i = 1; i < other.argv_.size(); ++i) 414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott argv_.push_back(other.argv_[i]); 415dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif 4164a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 417dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SwitchMap::const_iterator i; 418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (i = other.switches_.begin(); i != other.switches_.end(); ++i) 419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott switches_[i->first] = i->second; 420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 422dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid CommandLine::PrependWrapper(const CommandLine::StringType& wrapper) { 423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The wrapper may have embedded arguments (like "gdb --args"). In this case, 424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // we don't pretend to do anything fancy, we just split on spaces. 425dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (wrapper.empty()) 426dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return; 427dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen StringVector wrapper_and_args; 428dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_WIN) 429dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::SplitString(wrapper, ' ', &wrapper_and_args); 430dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen program_ = wrapper_and_args[0]; 431dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen command_line_string_ = wrapper + L" " + command_line_string_; 432dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#elif defined(OS_POSIX) 433731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick base::SplitString(wrapper, ' ', &wrapper_and_args); 434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott argv_.insert(argv_.begin(), wrapper_and_args.begin(), wrapper_and_args.end()); 435dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif 436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 438dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_WIN) 439dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid CommandLine::ParseFromString(const std::wstring& command_line) { 440dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TrimWhitespace(command_line, TRIM_ALL, &command_line_string_); 441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 442dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (command_line_string_.empty()) 443dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return; 4443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 445dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int num_args = 0; 446dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen wchar_t** args = NULL; 4473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 448dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen args = CommandLineToArgvW(command_line_string_.c_str(), &num_args); 449dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 450dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Populate program_ with the trimmed version of the first arg. 451dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TrimWhitespace(args[0], TRIM_ALL, &program_); 452dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 453dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen bool parse_switches = true; 454dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen for (int i = 1; i < num_args; ++i) { 455dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::wstring arg; 456dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TrimWhitespace(args[i], TRIM_ALL, &arg); 457dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 458dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!parse_switches) { 459dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen args_.push_back(arg); 460dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen continue; 461dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 462dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 463dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (arg == kSwitchTerminator) { 464dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen parse_switches = false; 465dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen continue; 466dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 467dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 468dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string switch_string; 469dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::wstring switch_value; 470dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (IsSwitch(arg, &switch_string, &switch_value)) { 471dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen switches_[switch_string] = switch_value; 472dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } else { 473dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen args_.push_back(arg); 4743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 4753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 4763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 477dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (args) 478dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LocalFree(args); 479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 480dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif 4813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 482dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenCommandLine::CommandLine() { 4833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 484