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 |