blob: e180ddfd69f295e520e059a65c84cfadaa575f32 [file] [log] [blame]
[email protected]4766b2882010-05-03 21:42:521// Copyright (c) 2010 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commitd7cae122008-07-26 21:49:384
[email protected]f3adb5c2008-08-07 20:07:325#include "base/command_line.h"
6
7#if defined(OS_WIN)
initial.commitd7cae122008-07-26 21:49:388#include <windows.h>
9#include <shellapi.h>
[email protected]f07bd1e2010-01-03 02:20:0810#elif defined(OS_POSIX)
11#include <limits.h>
[email protected]7f113f32009-09-10 18:02:1712#include <stdlib.h>
13#include <unistd.h>
[email protected]f3adb5c2008-08-07 20:07:3214#endif
[email protected]f07bd1e2010-01-03 02:20:0815#if defined(OS_LINUX)
16#include <sys/prctl.h>
17#endif
initial.commitd7cae122008-07-26 21:49:3818
19#include <algorithm>
20
[email protected]8f681e42009-10-09 20:37:5621#include "base/file_path.h"
initial.commitd7cae122008-07-26 21:49:3822#include "base/logging.h"
23#include "base/singleton.h"
initial.commitd7cae122008-07-26 21:49:3824#include "base/string_util.h"
[email protected]05b5d792008-08-07 22:28:2425#include "base/sys_string_conversions.h"
[email protected]f1d81922010-07-31 17:47:0926#include "base/utf_string_conversions.h"
initial.commitd7cae122008-07-26 21:49:3827
[email protected]7f113f32009-09-10 18:02:1728#if defined(OS_LINUX)
29// Linux/glibc doesn't natively have setproctitle().
30#include "base/setproctitle_linux.h"
31#endif
32
[email protected]bb975362009-01-21 01:00:2233CommandLine* CommandLine::current_process_commandline_ = NULL;
initial.commitd7cae122008-07-26 21:49:3834
35// Since we use a lazy match, make sure that longer versions (like L"--")
36// are listed before shorter versions (like L"-") of similar prefixes.
[email protected]5d426332008-08-08 20:46:2137#if defined(OS_WIN)
[email protected]bb975362009-01-21 01:00:2238const wchar_t* const kSwitchPrefixes[] = {L"--", L"-", L"/"};
39const wchar_t kSwitchTerminator[] = L"--";
40const wchar_t kSwitchValueSeparator[] = L"=";
[email protected]5d426332008-08-08 20:46:2141#elif defined(OS_POSIX)
[email protected]1a48f312008-08-12 01:14:3742// Unixes don't use slash as a switch.
[email protected]bb975362009-01-21 01:00:2243const char* const kSwitchPrefixes[] = {"--", "-"};
44const char kSwitchTerminator[] = "--";
45const char kSwitchValueSeparator[] = "=";
[email protected]5d426332008-08-08 20:46:2146#endif
initial.commitd7cae122008-07-26 21:49:3847
[email protected]f3adb5c2008-08-07 20:07:3248#if defined(OS_WIN)
[email protected]bb975362009-01-21 01:00:2249// Lowercase a string. This is used to lowercase switch names.
50// Is this what we really want? It seems crazy to me. I've left it in
51// for backwards compatibility on Windows.
[email protected]b7e0a2a2009-10-13 02:07:2552static void Lowercase(std::string* parameter) {
[email protected]bb975362009-01-21 01:00:2253 transform(parameter->begin(), parameter->end(), parameter->begin(),
54 tolower);
initial.commitd7cae122008-07-26 21:49:3855}
[email protected]bb975362009-01-21 01:00:2256#endif
initial.commitd7cae122008-07-26 21:49:3857
[email protected]3a3d47472010-07-15 21:03:5458CommandLine::~CommandLine() {
59}
60
[email protected]f3adb5c2008-08-07 20:07:3261#if defined(OS_WIN)
[email protected]51343d5a2009-10-26 22:39:3362CommandLine::CommandLine(ArgumentsOnly args_only) {
63}
64
[email protected]bb975362009-01-21 01:00:2265void CommandLine::ParseFromString(const std::wstring& command_line) {
66 TrimWhitespace(command_line, TRIM_ALL, &command_line_string_);
67
68 if (command_line_string_.empty())
69 return;
70
71 int num_args = 0;
72 wchar_t** args = NULL;
73
74 args = CommandLineToArgvW(command_line_string_.c_str(), &num_args);
75
76 // Populate program_ with the trimmed version of the first arg.
77 TrimWhitespace(args[0], TRIM_ALL, &program_);
78
79 bool parse_switches = true;
80 for (int i = 1; i < num_args; ++i) {
81 std::wstring arg;
82 TrimWhitespace(args[i], TRIM_ALL, &arg);
83
84 if (!parse_switches) {
[email protected]2e4c50c2010-07-21 15:57:2385 args_.push_back(arg);
[email protected]bb975362009-01-21 01:00:2286 continue;
87 }
88
89 if (arg == kSwitchTerminator) {
90 parse_switches = false;
91 continue;
92 }
93
94 std::string switch_string;
95 std::wstring switch_value;
96 if (IsSwitch(arg, &switch_string, &switch_value)) {
97 switches_[switch_string] = switch_value;
98 } else {
[email protected]2e4c50c2010-07-21 15:57:2399 args_.push_back(arg);
[email protected]bb975362009-01-21 01:00:22100 }
101 }
102
103 if (args)
104 LocalFree(args);
105}
[email protected]8f681e42009-10-09 20:37:56106
[email protected]5d91c9e2010-07-28 17:25:28107// static
108CommandLine CommandLine::FromString(const std::wstring& command_line) {
109 CommandLine cmd;
110 cmd.ParseFromString(command_line);
111 return cmd;
112}
113
[email protected]8f681e42009-10-09 20:37:56114CommandLine::CommandLine(const FilePath& program) {
115 if (!program.empty()) {
116 program_ = program.value();
117 command_line_string_ = L'"' + program.value() + L'"';
118 }
119}
120
[email protected]f3adb5c2008-08-07 20:07:32121#elif defined(OS_POSIX)
[email protected]51343d5a2009-10-26 22:39:33122CommandLine::CommandLine(ArgumentsOnly args_only) {
123 // Push an empty argument, because we always assume argv_[0] is a program.
124 argv_.push_back("");
125}
126
[email protected]5d91c9e2010-07-28 17:25:28127CommandLine::CommandLine(int argc, const char* const* argv) {
128 InitFromArgv(argc, argv);
129}
130
131CommandLine::CommandLine(const std::vector<std::string>& argv) {
132 InitFromArgv(argv);
133}
134
[email protected]0189bbd2009-10-12 22:50:39135void CommandLine::InitFromArgv(int argc, const char* const* argv) {
[email protected]bb975362009-01-21 01:00:22136 for (int i = 0; i < argc; ++i)
137 argv_.push_back(argv[i]);
[email protected]0189bbd2009-10-12 22:50:39138 InitFromArgv(argv_);
[email protected]f3adb5c2008-08-07 20:07:32139}
[email protected]10e42bf2008-10-15 21:59:08140
[email protected]0189bbd2009-10-12 22:50:39141void CommandLine::InitFromArgv(const std::vector<std::string>& argv) {
142 argv_ = argv;
[email protected]bb975362009-01-21 01:00:22143 bool parse_switches = true;
144 for (size_t i = 1; i < argv_.size(); ++i) {
145 const std::string& arg = argv_[i];
146
147 if (!parse_switches) {
[email protected]2e4c50c2010-07-21 15:57:23148 args_.push_back(arg);
[email protected]bb975362009-01-21 01:00:22149 continue;
150 }
151
152 if (arg == kSwitchTerminator) {
153 parse_switches = false;
154 continue;
155 }
156
157 std::string switch_string;
158 std::string switch_value;
159 if (IsSwitch(arg, &switch_string, &switch_value)) {
160 switches_[switch_string] = switch_value;
161 } else {
[email protected]2e4c50c2010-07-21 15:57:23162 args_.push_back(arg);
[email protected]bb975362009-01-21 01:00:22163 }
[email protected]10e42bf2008-10-15 21:59:08164 }
[email protected]bb975362009-01-21 01:00:22165}
166
[email protected]8f681e42009-10-09 20:37:56167CommandLine::CommandLine(const FilePath& program) {
168 argv_.push_back(program.value());
169}
170
[email protected]f3adb5c2008-08-07 20:07:32171#endif
initial.commitd7cae122008-07-26 21:49:38172
[email protected]bb975362009-01-21 01:00:22173// static
174bool CommandLine::IsSwitch(const StringType& parameter_string,
175 std::string* switch_string,
176 StringType* switch_value) {
177 switch_string->clear();
178 switch_value->clear();
179
180 for (size_t i = 0; i < arraysize(kSwitchPrefixes); ++i) {
181 StringType prefix(kSwitchPrefixes[i]);
182 if (parameter_string.find(prefix) != 0)
183 continue;
184
185 const size_t switch_start = prefix.length();
186 const size_t equals_position = parameter_string.find(
187 kSwitchValueSeparator, switch_start);
188 StringType switch_native;
189 if (equals_position == StringType::npos) {
190 switch_native = parameter_string.substr(switch_start);
191 } else {
192 switch_native = parameter_string.substr(
193 switch_start, equals_position - switch_start);
194 *switch_value = parameter_string.substr(equals_position + 1);
195 }
196#if defined(OS_WIN)
[email protected]bb975362009-01-21 01:00:22197 *switch_string = WideToASCII(switch_native);
[email protected]b7e0a2a2009-10-13 02:07:25198 Lowercase(switch_string);
[email protected]bb975362009-01-21 01:00:22199#else
200 *switch_string = switch_native;
201#endif
202
203 return true;
204 }
205
206 return false;
initial.commitd7cae122008-07-26 21:49:38207}
208
[email protected]1a48f312008-08-12 01:14:37209// static
[email protected]bb975362009-01-21 01:00:22210void CommandLine::Init(int argc, const char* const* argv) {
[email protected]75e10302009-10-13 01:47:01211 delete current_process_commandline_;
[email protected]bb975362009-01-21 01:00:22212 current_process_commandline_ = new CommandLine;
[email protected]0189bbd2009-10-12 22:50:39213#if defined(OS_WIN)
[email protected]bb975362009-01-21 01:00:22214 current_process_commandline_->ParseFromString(::GetCommandLineW());
215#elif defined(OS_POSIX)
[email protected]0189bbd2009-10-12 22:50:39216 current_process_commandline_->InitFromArgv(argc, argv);
[email protected]4883a4e2009-06-06 19:59:36217#endif
[email protected]75e10302009-10-13 01:47:01218
219#if defined(OS_LINUX)
220 if (argv)
221 setproctitle_init(const_cast<char**>(argv));
222#endif
[email protected]4883a4e2009-06-06 19:59:36223}
224
[email protected]e43eddf12009-12-29 00:32:52225#if defined(OS_POSIX) && !defined(OS_MACOSX)
[email protected]7f113f32009-09-10 18:02:17226// static
227void CommandLine::SetProcTitle() {
228 // Build a single string which consists of all the arguments separated
229 // by spaces. We can't actually keep them separate due to the way the
230 // setproctitle() function works.
231 std::string title;
[email protected]f07bd1e2010-01-03 02:20:08232 bool have_argv0 = false;
233#if defined(OS_LINUX)
234 // In Linux we sometimes exec ourselves from /proc/self/exe, but this makes us
235 // show up as "exe" in process listings. Read the symlink /proc/self/exe and
236 // use the path it points at for our process title. Note that this is only for
237 // display purposes and has no TOCTTOU security implications.
238 char buffer[PATH_MAX];
239 // Note: readlink() does not append a null byte to terminate the string.
240 ssize_t length = readlink("/proc/self/exe", buffer, sizeof(buffer));
241 DCHECK(length <= static_cast<ssize_t>(sizeof(buffer)));
242 if (length > 0) {
243 have_argv0 = true;
244 title.assign(buffer, length);
245 // If the binary has since been deleted, Linux appends " (deleted)" to the
246 // symlink target. Remove it, since this is not really part of our name.
247 const std::string kDeletedSuffix = " (deleted)";
248 if (EndsWith(title, kDeletedSuffix, true))
249 title.resize(title.size() - kDeletedSuffix.size());
250#if defined(PR_SET_NAME)
251 // If PR_SET_NAME is available at compile time, we try using it. We ignore
252 // any errors if the kernel does not support it at runtime though. When
253 // available, this lets us set the short process name that shows when the
254 // full command line is not being displayed in most process listings.
255 prctl(PR_SET_NAME, FilePath(title).BaseName().value().c_str());
256#endif
257 }
258#endif
[email protected]7f113f32009-09-10 18:02:17259 for (size_t i = 1; i < current_process_commandline_->argv_.size(); ++i) {
260 if (!title.empty())
261 title += " ";
262 title += current_process_commandline_->argv_[i];
263 }
[email protected]f07bd1e2010-01-03 02:20:08264 // Disable prepending argv[0] with '-' if we prepended it ourselves above.
265 setproctitle(have_argv0 ? "-%s" : "%s", title.c_str());
[email protected]7f113f32009-09-10 18:02:17266}
[email protected]7f113f32009-09-10 18:02:17267#endif
268
[email protected]02fb75ab2009-10-12 16:11:40269void CommandLine::Reset() {
[email protected]a2318cda2009-02-25 21:13:53270 DCHECK(current_process_commandline_ != NULL);
271 delete current_process_commandline_;
272 current_process_commandline_ = NULL;
273}
274
[email protected]b7e0a2a2009-10-13 02:07:25275bool CommandLine::HasSwitch(const std::string& switch_string) const {
276 std::string lowercased_switch(switch_string);
[email protected]bb975362009-01-21 01:00:22277#if defined(OS_WIN)
initial.commitd7cae122008-07-26 21:49:38278 Lowercase(&lowercased_switch);
[email protected]bb975362009-01-21 01:00:22279#endif
[email protected]b7e0a2a2009-10-13 02:07:25280 return switches_.find(lowercased_switch) != switches_.end();
initial.commitd7cae122008-07-26 21:49:38281}
282
[email protected]5d91c9e2010-07-28 17:25:28283bool CommandLine::HasSwitch(const std::wstring& switch_string) const {
284 return HasSwitch(WideToASCII(switch_string));
285}
286
287std::string CommandLine::GetSwitchValueASCII(
288 const std::string& switch_string) const {
289 return WideToASCII(GetSwitchValue(switch_string));
290}
291
292FilePath CommandLine::GetSwitchValuePath(
293 const std::string& switch_string) const {
[email protected]4f08c83f2010-07-29 23:02:34294 return FilePath(GetSwitchValueNative(switch_string));
[email protected]5d91c9e2010-07-28 17:25:28295}
296
[email protected]4f08c83f2010-07-29 23:02:34297CommandLine::StringType CommandLine::GetSwitchValueNative(
[email protected]b7e0a2a2009-10-13 02:07:25298 const std::string& switch_string) const {
299 std::string lowercased_switch(switch_string);
[email protected]bb975362009-01-21 01:00:22300#if defined(OS_WIN)
initial.commitd7cae122008-07-26 21:49:38301 Lowercase(&lowercased_switch);
[email protected]bb975362009-01-21 01:00:22302#endif
initial.commitd7cae122008-07-26 21:49:38303
[email protected]bb975362009-01-21 01:00:22304 std::map<std::string, StringType>::const_iterator result =
[email protected]b7e0a2a2009-10-13 02:07:25305 switches_.find(lowercased_switch);
initial.commitd7cae122008-07-26 21:49:38306
[email protected]bb975362009-01-21 01:00:22307 if (result == switches_.end()) {
[email protected]4f08c83f2010-07-29 23:02:34308 return CommandLine::StringType();
initial.commitd7cae122008-07-26 21:49:38309 } else {
initial.commitd7cae122008-07-26 21:49:38310 return result->second;
initial.commitd7cae122008-07-26 21:49:38311 }
312}
313
[email protected]5d91c9e2010-07-28 17:25:28314std::wstring CommandLine::GetSwitchValue(
[email protected]4f08c83f2010-07-29 23:02:34315 const std::string& switch_string) const {
316 // TODO(evanm): deprecate.
317 CommandLine::StringType value = GetSwitchValueNative(switch_string);
318#if defined(OS_WIN)
319 return value;
320#else
321 return base::SysNativeMBToWide(value);
322#endif
323}
324
325std::wstring CommandLine::GetSwitchValue(
[email protected]5d91c9e2010-07-28 17:25:28326 const std::wstring& switch_string) const {
[email protected]4f08c83f2010-07-29 23:02:34327 // TODO(evanm): deprecate.
[email protected]5d91c9e2010-07-28 17:25:28328 return GetSwitchValue(WideToASCII(switch_string));
329}
330
331FilePath CommandLine::GetProgram() const {
332 return FilePath::FromWStringHack(program());
333}
334
[email protected]bb975362009-01-21 01:00:22335#if defined(OS_WIN)
[email protected]bb975362009-01-21 01:00:22336std::wstring CommandLine::program() const {
337 return program_;
initial.commitd7cae122008-07-26 21:49:38338}
[email protected]bb975362009-01-21 01:00:22339#else
[email protected]bb975362009-01-21 01:00:22340std::wstring CommandLine::program() const {
[email protected]8f681e42009-10-09 20:37:56341 DCHECK_GT(argv_.size(), 0U);
[email protected]b44bd3032009-08-26 03:58:53342 return base::SysNativeMBToWide(argv_[0]);
[email protected]10e42bf2008-10-15 21:59:08343}
344#endif
345
[email protected]d3b04ab2010-05-21 17:14:57346#if defined(OS_POSIX)
347std::string CommandLine::command_line_string() const {
348 return JoinString(argv_, ' ');
349}
350#endif
initial.commitd7cae122008-07-26 21:49:38351
352// static
[email protected]bb975362009-01-21 01:00:22353std::wstring CommandLine::PrefixedSwitchString(
[email protected]b7e0a2a2009-10-13 02:07:25354 const std::string& switch_string) {
[email protected]9bdf62462009-10-09 23:55:42355#if defined(OS_WIN)
[email protected]b7e0a2a2009-10-13 02:07:25356 return kSwitchPrefixes[0] + ASCIIToWide(switch_string);
[email protected]9bdf62462009-10-09 23:55:42357#else
[email protected]b7e0a2a2009-10-13 02:07:25358 return ASCIIToWide(kSwitchPrefixes[0] + switch_string);
[email protected]9bdf62462009-10-09 23:55:42359#endif
[email protected]10e42bf2008-10-15 21:59:08360}
361
362// static
[email protected]bb975362009-01-21 01:00:22363std::wstring CommandLine::PrefixedSwitchStringWithValue(
[email protected]b7e0a2a2009-10-13 02:07:25364 const std::string& switch_string, const std::wstring& value_string) {
[email protected]10e42bf2008-10-15 21:59:08365 if (value_string.empty()) {
366 return PrefixedSwitchString(switch_string);
367 }
368
[email protected]9bdf62462009-10-09 23:55:42369 return PrefixedSwitchString(switch_string +
370#if defined(OS_WIN)
[email protected]b7e0a2a2009-10-13 02:07:25371 WideToASCII(kSwitchValueSeparator)
[email protected]9bdf62462009-10-09 23:55:42372#else
[email protected]b7e0a2a2009-10-13 02:07:25373 kSwitchValueSeparator
[email protected]9bdf62462009-10-09 23:55:42374#endif
[email protected]b7e0a2a2009-10-13 02:07:25375 ) + value_string;
[email protected]10e42bf2008-10-15 21:59:08376}
377
[email protected]bb975362009-01-21 01:00:22378#if defined(OS_WIN)
[email protected]b7e0a2a2009-10-13 02:07:25379void CommandLine::AppendSwitch(const std::string& switch_string) {
[email protected]bb975362009-01-21 01:00:22380 std::wstring prefixed_switch_string = PrefixedSwitchString(switch_string);
381 command_line_string_.append(L" ");
382 command_line_string_.append(prefixed_switch_string);
[email protected]b7e0a2a2009-10-13 02:07:25383 switches_[switch_string] = L"";
initial.commitd7cae122008-07-26 21:49:38384}
385
[email protected]d420c31e2010-07-30 02:14:22386void CommandLine::AppendSwitchASCII(const std::string& switch_string,
387 const std::string& value_string) {
388 AppendSwitchNative(switch_string, ASCIIToWide(value_string));
389}
390
[email protected]4f08c83f2010-07-29 23:02:34391void CommandLine::AppendSwitchNative(const std::string& switch_string,
392 const std::wstring& value_string) {
[email protected]bb975362009-01-21 01:00:22393 std::wstring value_string_edit;
initial.commitd7cae122008-07-26 21:49:38394
initial.commitd7cae122008-07-26 21:49:38395 // NOTE(jhughes): If the value contains a quotation mark at one
396 // end but not both, you may get unusable output.
[email protected]10e42bf2008-10-15 21:59:08397 if (!value_string.empty() &&
398 (value_string.find(L" ") != std::wstring::npos) &&
initial.commitd7cae122008-07-26 21:49:38399 (value_string[0] != L'"') &&
400 (value_string[value_string.length() - 1] != L'"')) {
401 // need to provide quotes
[email protected]10e42bf2008-10-15 21:59:08402 value_string_edit = StringPrintf(L"\"%ls\"", value_string.c_str());
initial.commitd7cae122008-07-26 21:49:38403 } else {
[email protected]10e42bf2008-10-15 21:59:08404 value_string_edit = value_string;
initial.commitd7cae122008-07-26 21:49:38405 }
[email protected]10e42bf2008-10-15 21:59:08406
[email protected]bb975362009-01-21 01:00:22407 std::wstring combined_switch_string =
[email protected]b7e0a2a2009-10-13 02:07:25408 PrefixedSwitchStringWithValue(switch_string, value_string_edit);
[email protected]10e42bf2008-10-15 21:59:08409
[email protected]bb975362009-01-21 01:00:22410 command_line_string_.append(L" ");
411 command_line_string_.append(combined_switch_string);
412
[email protected]b7e0a2a2009-10-13 02:07:25413 switches_[switch_string] = value_string;
initial.commitd7cae122008-07-26 21:49:38414}
license.botbf09a502008-08-24 00:55:55415
[email protected]bb975362009-01-21 01:00:22416void CommandLine::AppendLooseValue(const std::wstring& value) {
417 // TODO(evan): quoting?
418 command_line_string_.append(L" ");
419 command_line_string_.append(value);
[email protected]2e4c50c2010-07-21 15:57:23420 args_.push_back(value);
[email protected]bb975362009-01-21 01:00:22421}
422
423void CommandLine::AppendArguments(const CommandLine& other,
424 bool include_program) {
425 // Verify include_program is used correctly.
426 // Logic could be shorter but this is clearer.
[email protected]4766b2882010-05-03 21:42:52427 DCHECK_EQ(include_program, !other.GetProgram().empty());
[email protected]bb975362009-01-21 01:00:22428 command_line_string_ += L" " + other.command_line_string_;
429 std::map<std::string, StringType>::const_iterator i;
430 for (i = other.switches_.begin(); i != other.switches_.end(); ++i)
431 switches_[i->first] = i->second;
432}
433
[email protected]e5e19c32009-04-20 22:10:02434void CommandLine::PrependWrapper(const std::wstring& wrapper) {
435 // The wrapper may have embedded arguments (like "gdb --args"). In this case,
436 // we don't pretend to do anything fancy, we just split on spaces.
437 std::vector<std::wstring> wrapper_and_args;
438 SplitString(wrapper, ' ', &wrapper_and_args);
439 program_ = wrapper_and_args[0];
440 command_line_string_ = wrapper + L" " + command_line_string_;
441}
442
[email protected]bb975362009-01-21 01:00:22443#elif defined(OS_POSIX)
[email protected]b7e0a2a2009-10-13 02:07:25444void CommandLine::AppendSwitch(const std::string& switch_string) {
445 argv_.push_back(kSwitchPrefixes[0] + switch_string);
446 switches_[switch_string] = "";
[email protected]bb975362009-01-21 01:00:22447}
448
[email protected]4f08c83f2010-07-29 23:02:34449void CommandLine::AppendSwitchNative(const std::string& switch_string,
450 const std::string& value) {
451 argv_.push_back(kSwitchPrefixes[0] + switch_string +
452 kSwitchValueSeparator + value);
453 switches_[switch_string] = value;
454}
455
[email protected]d420c31e2010-07-30 02:14:22456void CommandLine::AppendSwitchASCII(const std::string& switch_string,
457 const std::string& value_string) {
458 AppendSwitchNative(switch_string, value_string);
459}
460
[email protected]bb975362009-01-21 01:00:22461void CommandLine::AppendLooseValue(const std::wstring& value) {
[email protected]b44bd3032009-08-26 03:58:53462 argv_.push_back(base::SysWideToNativeMB(value));
[email protected]bb975362009-01-21 01:00:22463}
464
465void CommandLine::AppendArguments(const CommandLine& other,
466 bool include_program) {
467 // Verify include_program is used correctly.
468 // Logic could be shorter but this is clearer.
[email protected]4766b2882010-05-03 21:42:52469 DCHECK_EQ(include_program, !other.GetProgram().empty());
[email protected]bb975362009-01-21 01:00:22470 size_t first_arg = include_program ? 0 : 1;
471 for (size_t i = first_arg; i < other.argv_.size(); ++i)
472 argv_.push_back(other.argv_[i]);
473 std::map<std::string, StringType>::const_iterator i;
474 for (i = other.switches_.begin(); i != other.switches_.end(); ++i)
475 switches_[i->first] = i->second;
476}
[email protected]052f1d482009-02-10 00:52:14477
478void CommandLine::PrependWrapper(const std::wstring& wrapper_wide) {
479 // The wrapper may have embedded arguments (like "gdb --args"). In this case,
480 // we don't pretend to do anything fancy, we just split on spaces.
[email protected]b44bd3032009-08-26 03:58:53481 const std::string wrapper = base::SysWideToNativeMB(wrapper_wide);
[email protected]052f1d482009-02-10 00:52:14482 std::vector<std::string> wrapper_and_args;
483 SplitString(wrapper, ' ', &wrapper_and_args);
484 argv_.insert(argv_.begin(), wrapper_and_args.begin(), wrapper_and_args.end());
485}
486
[email protected]bb975362009-01-21 01:00:22487#endif
[email protected]3a3d47472010-07-15 21:03:54488
[email protected]4f08c83f2010-07-29 23:02:34489void CommandLine::AppendSwitchPath(const std::string& switch_string,
490 const FilePath& path) {
491 AppendSwitchNative(switch_string, path.value());
492}
493
[email protected]4f08c83f2010-07-29 23:02:34494void CommandLine::CopySwitchesFrom(const CommandLine& source,
495 const char* const switches[],
496 size_t count) {
497 for (size_t i = 0; i < count; ++i) {
498 if (source.HasSwitch(switches[i])) {
499 StringType value = source.GetSwitchValueNative(switches[i]);
500 AppendSwitchNative(switches[i], value);
501 }
502 }
503}
504
[email protected]3a3d47472010-07-15 21:03:54505// private
506CommandLine::CommandLine() {
507}