| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/command_line.h" | 5 #include "base/command_line.h" |
| 6 | 6 |
| 7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
| 8 #include <windows.h> | 8 #include <windows.h> |
| 9 #include <shellapi.h> | 9 #include <shellapi.h> |
| 10 #endif | 10 #endif |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 // accessing this object on multiple threads. To ensure thread safety, the | 50 // accessing this object on multiple threads. To ensure thread safety, the |
| 51 // public interface of this object is const only. | 51 // public interface of this object is const only. |
| 52 // | 52 // |
| 53 // Do NOT add any non-const methods to this object. You have been warned. | 53 // Do NOT add any non-const methods to this object. You have been warned. |
| 54 class CommandLine::Data { | 54 class CommandLine::Data { |
| 55 public: | 55 public: |
| 56 #if defined(OS_WIN) | 56 #if defined(OS_WIN) |
| 57 Data() { | 57 Data() { |
| 58 Init(GetCommandLineW()); | 58 Init(GetCommandLineW()); |
| 59 } | 59 } |
| 60 |
| 61 Data(const wstring& command_line) { |
| 62 Init(command_line); |
| 63 } |
| 60 #elif defined(OS_POSIX) | 64 #elif defined(OS_POSIX) |
| 61 Data() { | 65 Data() { |
| 62 // Owner must call Init(). | 66 // Owner must call Init(). |
| 63 } | 67 } |
| 64 #endif | |
| 65 | 68 |
| 66 #if defined(OS_WIN) | |
| 67 Data(const wstring& command_line) { | |
| 68 Init(command_line); | |
| 69 } | |
| 70 #elif defined(OS_POSIX) | |
| 71 Data(int argc, const char* const* argv) { | 69 Data(int argc, const char* const* argv) { |
| 72 Init(argc, argv); | 70 Init(argc, argv); |
| 73 } | 71 } |
| 74 #endif | 72 #endif // defined(OS_POSIX) |
| 75 | 73 |
| 76 #if defined(OS_WIN) | 74 #if defined(OS_WIN) |
| 77 // Does the actual parsing of the command line. | 75 // Does the actual parsing of the command line. |
| 78 void Init(const std::wstring& command_line) { | 76 void Init(const std::wstring& command_line) { |
| 79 TrimWhitespace(command_line, TRIM_ALL, &command_line_string_); | 77 TrimWhitespace(command_line, TRIM_ALL, &command_line_string_); |
| 80 | 78 |
| 81 if (command_line_string_.empty()) | 79 if (command_line_string_.empty()) |
| 82 return; | 80 return; |
| 83 | 81 |
| 84 int num_args = 0; | 82 int num_args = 0; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 109 if (IsSwitch(arg, &switch_string, &switch_value)) { | 107 if (IsSwitch(arg, &switch_string, &switch_value)) { |
| 110 switches_[switch_string] = switch_value; | 108 switches_[switch_string] = switch_value; |
| 111 } else { | 109 } else { |
| 112 loose_values_.push_back(arg); | 110 loose_values_.push_back(arg); |
| 113 } | 111 } |
| 114 } | 112 } |
| 115 | 113 |
| 116 if (args) | 114 if (args) |
| 117 LocalFree(args); | 115 LocalFree(args); |
| 118 } | 116 } |
| 119 | |
| 120 #elif defined(OS_POSIX) | 117 #elif defined(OS_POSIX) |
| 121 // Does the actual parsing of the command line. | 118 // Does the actual parsing of the command line. |
| 122 void Init(int argc, const char* const* argv) { | 119 void Init(int argc, const char* const* argv) { |
| 123 if (argc < 1) | 120 if (argc < 1) |
| 124 return; | 121 return; |
| 125 program_ = base::SysNativeMBToWide(argv[0]); | 122 program_ = base::SysNativeMBToWide(argv[0]); |
| 123 argv_.push_back(std::string(argv[0])); |
| 126 command_line_string_ = program_; | 124 command_line_string_ = program_; |
| 127 | 125 |
| 128 bool parse_switches = true; | 126 bool parse_switches = true; |
| 129 for (int i = 1; i < argc; ++i) { | 127 for (int i = 1; i < argc; ++i) { |
| 130 std::wstring arg = base::SysNativeMBToWide(argv[i]); | 128 std::wstring arg = base::SysNativeMBToWide(argv[i]); |
| 129 argv_.push_back(argv[i]); |
| 131 command_line_string_.append(L" "); | 130 command_line_string_.append(L" "); |
| 132 command_line_string_.append(arg); | 131 command_line_string_.append(arg); |
| 133 | 132 |
| 134 if (!parse_switches) { | 133 if (!parse_switches) { |
| 135 loose_values_.push_back(arg); | 134 loose_values_.push_back(arg); |
| 136 continue; | 135 continue; |
| 137 } | 136 } |
| 138 | 137 |
| 139 if (arg == kSwitchTerminator) { | 138 if (arg == kSwitchTerminator) { |
| 140 parse_switches = false; | 139 parse_switches = false; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 161 } | 160 } |
| 162 | 161 |
| 163 const std::map<std::wstring, std::wstring>& switches() const { | 162 const std::map<std::wstring, std::wstring>& switches() const { |
| 164 return switches_; | 163 return switches_; |
| 165 } | 164 } |
| 166 | 165 |
| 167 const std::vector<std::wstring>& loose_values() const { | 166 const std::vector<std::wstring>& loose_values() const { |
| 168 return loose_values_; | 167 return loose_values_; |
| 169 } | 168 } |
| 170 | 169 |
| 170 #if defined(OS_POSIX) |
| 171 const std::vector<std::string>& argv() const { |
| 172 return argv_; |
| 173 } |
| 174 #endif |
| 175 |
| 171 private: | 176 private: |
| 172 // Returns true if parameter_string represents a switch. If true, | 177 // Returns true if parameter_string represents a switch. If true, |
| 173 // switch_string and switch_value are set. (If false, both are | 178 // switch_string and switch_value are set. (If false, both are |
| 174 // set to the empty string.) | 179 // set to the empty string.) |
| 175 static bool IsSwitch(const wstring& parameter_string, | 180 static bool IsSwitch(const wstring& parameter_string, |
| 176 wstring* switch_string, | 181 wstring* switch_string, |
| 177 wstring* switch_value) { | 182 wstring* switch_value) { |
| 178 | 183 |
| 179 *switch_string = L""; | 184 *switch_string = L""; |
| 180 *switch_value = L""; | 185 *switch_value = L""; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 199 return true; | 204 return true; |
| 200 } | 205 } |
| 201 | 206 |
| 202 return false; | 207 return false; |
| 203 } | 208 } |
| 204 | 209 |
| 205 std::wstring command_line_string_; | 210 std::wstring command_line_string_; |
| 206 std::wstring program_; | 211 std::wstring program_; |
| 207 std::map<std::wstring, std::wstring> switches_; | 212 std::map<std::wstring, std::wstring> switches_; |
| 208 std::vector<std::wstring> loose_values_; | 213 std::vector<std::wstring> loose_values_; |
| 214 std::vector<std::string> argv_; |
| 209 | 215 |
| 210 DISALLOW_EVIL_CONSTRUCTORS(Data); | 216 DISALLOW_EVIL_CONSTRUCTORS(Data); |
| 211 }; | 217 }; |
| 212 | 218 |
| 213 CommandLine::CommandLine() | 219 CommandLine::CommandLine() |
| 214 : we_own_data_(false), // The Singleton class will manage it for us. | 220 : we_own_data_(false), // The Singleton class will manage it for us. |
| 215 data_(Singleton<Data>::get()) { | 221 data_(Singleton<Data>::get()) { |
| 216 DCHECK(!data_->command_line_string().empty()) << | 222 DCHECK(!data_->command_line_string().empty()) << |
| 217 "You must call CommandLine::SetArgcArgv before making any CommandLine " | 223 "You must call CommandLine::SetArgcArgv before making any CommandLine " |
| 218 "calls."; | 224 "calls."; |
| 219 } | 225 } |
| 220 | 226 |
| 221 #if defined(OS_WIN) | 227 #if defined(OS_WIN) |
| 222 CommandLine::CommandLine(const wstring& command_line) | 228 CommandLine::CommandLine(const wstring& command_line) |
| 223 : we_own_data_(true), | 229 : we_own_data_(true), |
| 224 data_(new Data(command_line)) { | 230 data_(new Data(command_line)) { |
| 225 } | 231 } |
| 226 #elif defined(OS_POSIX) | 232 #elif defined(OS_POSIX) |
| 227 CommandLine::CommandLine(const int argc, const char* const* argv) | 233 CommandLine::CommandLine(const int argc, const char* const* argv) |
| 228 : we_own_data_(true), | 234 : we_own_data_(true), |
| 229 data_(new Data(argc, argv)) { | 235 data_(new Data(argc, argv)) { |
| 230 } | 236 } |
| 237 |
| 238 CommandLine::CommandLine(const std::vector<std::string>& argv) |
| 239 : we_own_data_(true) { |
| 240 const char* argv_copy[argv.size()]; |
| 241 for (size_t i = 0; i < argv.size(); i++) { |
| 242 argv_copy[i] = argv[i].c_str(); |
| 243 } |
| 244 data_ = new Data(argv.size(), argv_copy); |
| 245 } |
| 231 #endif | 246 #endif |
| 232 | 247 |
| 233 CommandLine::~CommandLine() { | 248 CommandLine::~CommandLine() { |
| 234 if (we_own_data_) | 249 if (we_own_data_) |
| 235 delete data_; | 250 delete data_; |
| 236 } | 251 } |
| 237 | 252 |
| 238 // static | 253 // static |
| 239 void CommandLine::SetArgcArgv(int argc, const char* const* argv) { | 254 void CommandLine::SetArgcArgv(int argc, const char* const* argv) { |
| 240 #if !defined(OS_WIN) | 255 #if !defined(OS_WIN) |
| (...skipping 30 matching lines...) Expand all Loading... |
| 271 } | 286 } |
| 272 | 287 |
| 273 CommandLine::LooseValueIterator CommandLine::GetLooseValuesEnd() const { | 288 CommandLine::LooseValueIterator CommandLine::GetLooseValuesEnd() const { |
| 274 return data_->loose_values().end(); | 289 return data_->loose_values().end(); |
| 275 } | 290 } |
| 276 | 291 |
| 277 std::wstring CommandLine::command_line_string() const { | 292 std::wstring CommandLine::command_line_string() const { |
| 278 return data_->command_line_string(); | 293 return data_->command_line_string(); |
| 279 } | 294 } |
| 280 | 295 |
| 296 #if defined(OS_POSIX) |
| 297 const std::vector<std::string>& CommandLine::argv() const { |
| 298 return data_->argv(); |
| 299 } |
| 300 #endif |
| 301 |
| 281 std::wstring CommandLine::program() const { | 302 std::wstring CommandLine::program() const { |
| 282 return data_->program(); | 303 return data_->program(); |
| 283 } | 304 } |
| 284 | 305 |
| 285 // static | 306 // static |
| 307 wstring CommandLine::PrefixedSwitchString(const wstring& switch_string) { |
| 308 return StringPrintf(L"%ls%ls", |
| 309 kSwitchPrefixes[0], |
| 310 switch_string.c_str()); |
| 311 } |
| 312 |
| 313 // static |
| 314 wstring CommandLine::PrefixedSwitchStringWithValue( |
| 315 const wstring& switch_string, const wstring& value_string) { |
| 316 if (value_string.empty()) { |
| 317 return PrefixedSwitchString(switch_string); |
| 318 } |
| 319 |
| 320 return StringPrintf(L"%ls%ls%ls%ls", |
| 321 kSwitchPrefixes[0], |
| 322 switch_string.c_str(), |
| 323 kSwitchValueSeparator, |
| 324 value_string.c_str()); |
| 325 } |
| 326 |
| 327 // static |
| 286 void CommandLine::AppendSwitch(wstring* command_line_string, | 328 void CommandLine::AppendSwitch(wstring* command_line_string, |
| 287 const wstring& switch_string) { | 329 const wstring& switch_string) { |
| 288 DCHECK(command_line_string); | 330 DCHECK(command_line_string); |
| 331 wstring prefixed_switch_string = PrefixedSwitchString(switch_string); |
| 289 command_line_string->append(L" "); | 332 command_line_string->append(L" "); |
| 290 command_line_string->append(kSwitchPrefixes[0]); | 333 command_line_string->append(prefixed_switch_string); |
| 291 command_line_string->append(switch_string); | |
| 292 } | 334 } |
| 293 | 335 |
| 294 // static | 336 // static |
| 295 void CommandLine::AppendSwitchWithValue(wstring* command_line_string, | 337 void CommandLine::AppendSwitchWithValue(wstring* command_line_string, |
| 296 const wstring& switch_string, | 338 const wstring& switch_string, |
| 297 const wstring& value_string) { | 339 const wstring& value_string) { |
| 298 AppendSwitch(command_line_string, switch_string); | 340 wstring value_string_edit; |
| 299 | 341 |
| 300 if (value_string.empty()) | |
| 301 return; | |
| 302 | |
| 303 command_line_string->append(kSwitchValueSeparator); | |
| 304 // NOTE(jhughes): If the value contains a quotation mark at one | 342 // NOTE(jhughes): If the value contains a quotation mark at one |
| 305 // end but not both, you may get unusable output. | 343 // end but not both, you may get unusable output. |
| 306 if ((value_string.find(L" ") != std::wstring::npos) && | 344 if (!value_string.empty() && |
| 345 (value_string.find(L" ") != std::wstring::npos) && |
| 307 (value_string[0] != L'"') && | 346 (value_string[0] != L'"') && |
| 308 (value_string[value_string.length() - 1] != L'"')) { | 347 (value_string[value_string.length() - 1] != L'"')) { |
| 309 // need to provide quotes | 348 // need to provide quotes |
| 310 StringAppendF(command_line_string, L"\"%ls\"", value_string.c_str()); | 349 value_string_edit = StringPrintf(L"\"%ls\"", value_string.c_str()); |
| 311 } else { | 350 } else { |
| 312 command_line_string->append(value_string); | 351 value_string_edit = value_string; |
| 313 } | 352 } |
| 353 |
| 354 wstring combined_switch_string = |
| 355 PrefixedSwitchStringWithValue(switch_string, value_string_edit); |
| 356 |
| 357 command_line_string->append(L" "); |
| 358 command_line_string->append(combined_switch_string); |
| 314 } | 359 } |
| 315 | 360 |
| OLD | NEW |