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 |
11 | 11 |
12 #include <algorithm> | 12 #include <algorithm> |
13 | 13 |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/singleton.h" | 15 #include "base/singleton.h" |
16 #include "base/string_piece.h" | 16 #include "base/string_piece.h" |
17 #include "base/string_util.h" | 17 #include "base/string_util.h" |
18 #include "base/sys_string_conversions.h" | 18 #include "base/sys_string_conversions.h" |
19 | 19 |
20 using namespace std; | 20 CommandLine* CommandLine::current_process_commandline_ = NULL; |
21 | 21 |
22 // Since we use a lazy match, make sure that longer versions (like L"--") | 22 // Since we use a lazy match, make sure that longer versions (like L"--") |
23 // are listed before shorter versions (like L"-") of similar prefixes. | 23 // are listed before shorter versions (like L"-") of similar prefixes. |
24 #if defined(OS_WIN) | 24 #if defined(OS_WIN) |
25 const wchar_t* const CommandLine::kSwitchPrefixes[] = {L"--", L"-", L"/"}; | 25 const wchar_t* const kSwitchPrefixes[] = {L"--", L"-", L"/"}; |
| 26 const wchar_t kSwitchTerminator[] = L"--"; |
| 27 const wchar_t kSwitchValueSeparator[] = L"="; |
26 #elif defined(OS_POSIX) | 28 #elif defined(OS_POSIX) |
27 // Unixes don't use slash as a switch. | 29 // Unixes don't use slash as a switch. |
28 const wchar_t* const CommandLine::kSwitchPrefixes[] = {L"--", L"-"}; | 30 const char* const kSwitchPrefixes[] = {"--", "-"}; |
29 #endif | 31 const char kSwitchTerminator[] = "--"; |
30 | 32 const char kSwitchValueSeparator[] = "="; |
31 const wchar_t CommandLine::kSwitchValueSeparator[] = L"="; | 33 #endif |
32 const wchar_t CommandLine::kSwitchTerminator[] = L"--"; | 34 |
33 | 35 #if defined(OS_WIN) |
34 // Needed to avoid a typecast on the tolower() function pointer in Lowercase(). | 36 // Lowercase a string. This is used to lowercase switch names. |
35 // MSVC accepts it as-is but GCC requires the typecast. | 37 // Is this what we really want? It seems crazy to me. I've left it in |
36 static int ToLower(int c) { | 38 // for backwards compatibility on Windows. |
37 return tolower(c); | 39 static void Lowercase(std::wstring* parameter) { |
38 } | 40 transform(parameter->begin(), parameter->end(), parameter->begin(), |
39 | 41 tolower); |
40 static void Lowercase(wstring* parameter) { | 42 } |
41 transform(parameter->begin(), parameter->end(), parameter->begin(), | 43 #endif |
42 ToLower); | 44 |
43 } | 45 #if defined(OS_WIN) |
44 | 46 void CommandLine::ParseFromString(const std::wstring& command_line) { |
45 // CommandLine::Data | 47 TrimWhitespace(command_line, TRIM_ALL, &command_line_string_); |
46 // | 48 |
47 // This object holds the parsed data for a command line. We hold this in a | 49 if (command_line_string_.empty()) |
48 // separate object from |CommandLine| so that we can share the parsed data | 50 return; |
49 // across multiple |CommandLine| objects. When we share |Data|, we might be | 51 |
50 // accessing this object on multiple threads. To ensure thread safety, the | 52 int num_args = 0; |
51 // public interface of this object is const only. | 53 wchar_t** args = NULL; |
52 // | 54 |
53 // Do NOT add any non-const methods to this object. You have been warned. | 55 args = CommandLineToArgvW(command_line_string_.c_str(), &num_args); |
54 class CommandLine::Data { | 56 |
55 public: | 57 // Populate program_ with the trimmed version of the first arg. |
56 #if defined(OS_WIN) | 58 TrimWhitespace(args[0], TRIM_ALL, &program_); |
57 Data() { | 59 |
58 Init(GetCommandLineW()); | 60 bool parse_switches = true; |
59 } | 61 for (int i = 1; i < num_args; ++i) { |
60 | 62 std::wstring arg; |
61 Data(const wstring& command_line) { | 63 TrimWhitespace(args[i], TRIM_ALL, &arg); |
62 Init(command_line); | 64 |
63 } | 65 if (!parse_switches) { |
| 66 loose_values_.push_back(arg); |
| 67 continue; |
| 68 } |
| 69 |
| 70 if (arg == kSwitchTerminator) { |
| 71 parse_switches = false; |
| 72 continue; |
| 73 } |
| 74 |
| 75 std::string switch_string; |
| 76 std::wstring switch_value; |
| 77 if (IsSwitch(arg, &switch_string, &switch_value)) { |
| 78 switches_[switch_string] = switch_value; |
| 79 } else { |
| 80 loose_values_.push_back(arg); |
| 81 } |
| 82 } |
| 83 |
| 84 if (args) |
| 85 LocalFree(args); |
| 86 } |
| 87 CommandLine::CommandLine(const std::wstring& program) { |
| 88 if (!program.empty()) { |
| 89 program_ = program; |
| 90 command_line_string_ = L'"' + program + L'"'; |
| 91 } |
| 92 } |
64 #elif defined(OS_POSIX) | 93 #elif defined(OS_POSIX) |
65 Data() { | 94 CommandLine::CommandLine(int argc, const char* const* argv) { |
66 // Owner must call Init(). | 95 for (int i = 0; i < argc; ++i) |
67 } | 96 argv_.push_back(argv[i]); |
68 | 97 InitFromArgv(); |
69 Data(int argc, const char* const* argv) { | 98 } |
70 Init(argc, argv); | 99 CommandLine::CommandLine(const std::vector<std::string>& argv) { |
71 } | 100 argv_ = argv; |
72 #endif // defined(OS_POSIX) | 101 InitFromArgv(); |
73 | 102 } |
74 #if defined(OS_WIN) | 103 |
75 // Does the actual parsing of the command line. | 104 void CommandLine::InitFromArgv() { |
76 void Init(const std::wstring& command_line) { | 105 bool parse_switches = true; |
77 TrimWhitespace(command_line, TRIM_ALL, &command_line_string_); | 106 for (size_t i = 1; i < argv_.size(); ++i) { |
78 | 107 const std::string& arg = argv_[i]; |
79 if (command_line_string_.empty()) | 108 |
80 return; | 109 if (!parse_switches) { |
81 | 110 loose_values_.push_back(arg); |
82 int num_args = 0; | 111 continue; |
83 wchar_t** args = NULL; | 112 } |
84 | 113 |
85 args = CommandLineToArgvW(command_line_string_.c_str(), &num_args); | 114 if (arg == kSwitchTerminator) { |
86 | 115 parse_switches = false; |
87 // Populate program_ with the trimmed version of the first arg. | 116 continue; |
88 TrimWhitespace(args[0], TRIM_ALL, &program_); | 117 } |
89 | 118 |
90 bool parse_switches = true; | 119 std::string switch_string; |
91 for (int i = 1; i < num_args; ++i) { | 120 std::string switch_value; |
92 wstring arg; | 121 if (IsSwitch(arg, &switch_string, &switch_value)) { |
93 TrimWhitespace(args[i], TRIM_ALL, &arg); | 122 switches_[switch_string] = switch_value; |
94 | 123 } else { |
95 if (!parse_switches) { | 124 loose_values_.push_back(arg); |
96 loose_values_.push_back(arg); | 125 } |
97 continue; | 126 } |
98 } | 127 } |
99 | 128 |
100 if (arg == kSwitchTerminator) { | 129 CommandLine::CommandLine(const std::wstring& program) { |
101 parse_switches = false; | 130 argv_.push_back(WideToASCII(program)); |
102 continue; | 131 } |
103 } | 132 #endif |
104 | 133 |
105 wstring switch_string; | 134 // static |
106 wstring switch_value; | 135 bool CommandLine::IsSwitch(const StringType& parameter_string, |
107 if (IsSwitch(arg, &switch_string, &switch_value)) { | 136 std::string* switch_string, |
108 switches_[switch_string] = switch_value; | 137 StringType* switch_value) { |
109 } else { | 138 switch_string->clear(); |
110 loose_values_.push_back(arg); | 139 switch_value->clear(); |
111 } | 140 |
112 } | 141 for (size_t i = 0; i < arraysize(kSwitchPrefixes); ++i) { |
113 | 142 StringType prefix(kSwitchPrefixes[i]); |
114 if (args) | 143 if (parameter_string.find(prefix) != 0) |
115 LocalFree(args); | 144 continue; |
116 } | 145 |
| 146 const size_t switch_start = prefix.length(); |
| 147 const size_t equals_position = parameter_string.find( |
| 148 kSwitchValueSeparator, switch_start); |
| 149 StringType switch_native; |
| 150 if (equals_position == StringType::npos) { |
| 151 switch_native = parameter_string.substr(switch_start); |
| 152 } else { |
| 153 switch_native = parameter_string.substr( |
| 154 switch_start, equals_position - switch_start); |
| 155 *switch_value = parameter_string.substr(equals_position + 1); |
| 156 } |
| 157 #if defined(OS_WIN) |
| 158 Lowercase(&switch_native); |
| 159 *switch_string = WideToASCII(switch_native); |
| 160 #else |
| 161 *switch_string = switch_native; |
| 162 #endif |
| 163 |
| 164 return true; |
| 165 } |
| 166 |
| 167 return false; |
| 168 } |
| 169 |
| 170 // static |
| 171 void CommandLine::Init(int argc, const char* const* argv) { |
| 172 DCHECK(current_process_commandline_ == NULL); |
| 173 #if defined(OS_WIN) |
| 174 current_process_commandline_ = new CommandLine; |
| 175 current_process_commandline_->ParseFromString(::GetCommandLineW()); |
117 #elif defined(OS_POSIX) | 176 #elif defined(OS_POSIX) |
118 // Does the actual parsing of the command line. | 177 current_process_commandline_ = new CommandLine(argc, argv); |
119 void Init(int argc, const char* const* argv) { | 178 #endif |
120 if (argc < 1) | 179 } |
121 return; | 180 |
122 program_ = base::SysNativeMBToWide(argv[0]); | 181 bool CommandLine::HasSwitch(const std::wstring& switch_string) const { |
123 argv_.push_back(std::string(argv[0])); | 182 std::wstring lowercased_switch(switch_string); |
124 command_line_string_ = program_; | 183 #if defined(OS_WIN) |
125 | |
126 bool parse_switches = true; | |
127 for (int i = 1; i < argc; ++i) { | |
128 std::wstring arg = base::SysNativeMBToWide(argv[i]); | |
129 argv_.push_back(argv[i]); | |
130 command_line_string_.append(L" "); | |
131 command_line_string_.append(arg); | |
132 | |
133 if (!parse_switches) { | |
134 loose_values_.push_back(arg); | |
135 continue; | |
136 } | |
137 | |
138 if (arg == kSwitchTerminator) { | |
139 parse_switches = false; | |
140 continue; | |
141 } | |
142 | |
143 wstring switch_string; | |
144 wstring switch_value; | |
145 if (IsSwitch(arg, &switch_string, &switch_value)) { | |
146 switches_[switch_string] = switch_value; | |
147 } else { | |
148 loose_values_.push_back(arg); | |
149 } | |
150 } | |
151 } | |
152 #endif | |
153 | |
154 const std::wstring& command_line_string() const { | |
155 return command_line_string_; | |
156 } | |
157 | |
158 const std::wstring& program() const { | |
159 return program_; | |
160 } | |
161 | |
162 const std::map<std::wstring, std::wstring>& switches() const { | |
163 return switches_; | |
164 } | |
165 | |
166 const std::vector<std::wstring>& loose_values() const { | |
167 return loose_values_; | |
168 } | |
169 | |
170 #if defined(OS_POSIX) | |
171 const std::vector<std::string>& argv() const { | |
172 return argv_; | |
173 } | |
174 #endif | |
175 | |
176 private: | |
177 // Returns true if parameter_string represents a switch. If true, | |
178 // switch_string and switch_value are set. (If false, both are | |
179 // set to the empty string.) | |
180 static bool IsSwitch(const wstring& parameter_string, | |
181 wstring* switch_string, | |
182 wstring* switch_value) { | |
183 | |
184 *switch_string = L""; | |
185 *switch_value = L""; | |
186 | |
187 for (size_t i = 0; i < arraysize(kSwitchPrefixes); ++i) { | |
188 std::wstring prefix(kSwitchPrefixes[i]); | |
189 if (parameter_string.find(prefix) != 0) // check prefix | |
190 continue; | |
191 | |
192 const size_t switch_start = prefix.length(); | |
193 const size_t equals_position = parameter_string.find( | |
194 kSwitchValueSeparator, switch_start); | |
195 if (equals_position == wstring::npos) { | |
196 *switch_string = parameter_string.substr(switch_start); | |
197 } else { | |
198 *switch_string = parameter_string.substr( | |
199 switch_start, equals_position - switch_start); | |
200 *switch_value = parameter_string.substr(equals_position + 1); | |
201 } | |
202 Lowercase(switch_string); | |
203 | |
204 return true; | |
205 } | |
206 | |
207 return false; | |
208 } | |
209 | |
210 std::wstring command_line_string_; | |
211 std::wstring program_; | |
212 std::map<std::wstring, std::wstring> switches_; | |
213 std::vector<std::wstring> loose_values_; | |
214 std::vector<std::string> argv_; | |
215 | |
216 DISALLOW_EVIL_CONSTRUCTORS(Data); | |
217 }; | |
218 | |
219 CommandLine::CommandLine() | |
220 : we_own_data_(false), // The Singleton class will manage it for us. | |
221 data_(Singleton<Data>::get()) { | |
222 DCHECK(!data_->command_line_string().empty()) << | |
223 "You must call CommandLine::SetArgcArgv before making any CommandLine " | |
224 "calls."; | |
225 } | |
226 | |
227 #if defined(OS_WIN) | |
228 CommandLine::CommandLine(const wstring& command_line) | |
229 : we_own_data_(true), | |
230 data_(new Data(command_line)) { | |
231 } | |
232 #elif defined(OS_POSIX) | |
233 CommandLine::CommandLine(const int argc, const char* const* argv) | |
234 : we_own_data_(true), | |
235 data_(new Data(argc, argv)) { | |
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 } | |
246 #endif | |
247 | |
248 CommandLine::~CommandLine() { | |
249 if (we_own_data_) | |
250 delete data_; | |
251 } | |
252 | |
253 // static | |
254 void CommandLine::SetArgcArgv(int argc, const char* const* argv) { | |
255 #if !defined(OS_WIN) | |
256 Singleton<Data>::get()->Init(argc, argv); | |
257 #endif | |
258 } | |
259 | |
260 bool CommandLine::HasSwitch(const wstring& switch_string) const { | |
261 wstring lowercased_switch(switch_string); | |
262 Lowercase(&lowercased_switch); | 184 Lowercase(&lowercased_switch); |
263 return data_->switches().find(lowercased_switch) != data_->switches().end(); | 185 #endif |
264 } | 186 return switches_.find(WideToASCII(lowercased_switch)) != switches_.end(); |
265 | 187 } |
266 wstring CommandLine::GetSwitchValue(const wstring& switch_string) const { | 188 |
267 wstring lowercased_switch(switch_string); | 189 std::wstring CommandLine::GetSwitchValue( |
| 190 const std::wstring& switch_string) const { |
| 191 std::wstring lowercased_switch(switch_string); |
| 192 #if defined(OS_WIN) |
268 Lowercase(&lowercased_switch); | 193 Lowercase(&lowercased_switch); |
269 | 194 #endif |
270 const map<wstring, wstring>::const_iterator result = | 195 |
271 data_->switches().find(lowercased_switch); | 196 std::map<std::string, StringType>::const_iterator result = |
272 | 197 switches_.find(WideToASCII(lowercased_switch)); |
273 if (result == data_->switches().end()) { | 198 |
| 199 if (result == switches_.end()) { |
274 return L""; | 200 return L""; |
275 } else { | 201 } else { |
| 202 #if defined(OS_WIN) |
276 return result->second; | 203 return result->second; |
277 } | 204 #else |
278 } | 205 return ASCIIToWide(result->second); |
279 | 206 #endif |
280 size_t CommandLine::GetLooseValueCount() const { | 207 } |
281 return data_->loose_values().size(); | 208 } |
282 } | 209 |
283 | 210 #if defined(OS_WIN) |
284 CommandLine::LooseValueIterator CommandLine::GetLooseValuesBegin() const { | 211 std::vector<std::wstring> CommandLine::GetLooseValues() const { |
285 return data_->loose_values().begin(); | 212 return loose_values_; |
286 } | 213 } |
287 | |
288 CommandLine::LooseValueIterator CommandLine::GetLooseValuesEnd() const { | |
289 return data_->loose_values().end(); | |
290 } | |
291 | |
292 std::wstring CommandLine::command_line_string() const { | |
293 return data_->command_line_string(); | |
294 } | |
295 | |
296 #if defined(OS_POSIX) | |
297 const std::vector<std::string>& CommandLine::argv() const { | |
298 return data_->argv(); | |
299 } | |
300 #endif | |
301 | |
302 std::wstring CommandLine::program() const { | 214 std::wstring CommandLine::program() const { |
303 return data_->program(); | 215 return program_; |
304 } | 216 } |
305 | 217 #else |
306 // static | 218 std::vector<std::wstring> CommandLine::GetLooseValues() const { |
307 wstring CommandLine::PrefixedSwitchString(const wstring& switch_string) { | 219 std::vector<std::wstring> values; |
| 220 for (size_t i = 0; i < loose_values_.size(); ++i) |
| 221 values.push_back(ASCIIToWide(loose_values_[i])); |
| 222 return values; |
| 223 } |
| 224 std::wstring CommandLine::program() const { |
| 225 DCHECK(argv_.size() > 0); |
| 226 return ASCIIToWide(argv_[0]); |
| 227 } |
| 228 #endif |
| 229 |
| 230 |
| 231 // static |
| 232 std::wstring CommandLine::PrefixedSwitchString( |
| 233 const std::wstring& switch_string) { |
308 return StringPrintf(L"%ls%ls", | 234 return StringPrintf(L"%ls%ls", |
309 kSwitchPrefixes[0], | 235 kSwitchPrefixes[0], |
310 switch_string.c_str()); | 236 switch_string.c_str()); |
311 } | 237 } |
312 | 238 |
313 // static | 239 // static |
314 wstring CommandLine::PrefixedSwitchStringWithValue( | 240 std::wstring CommandLine::PrefixedSwitchStringWithValue( |
315 const wstring& switch_string, const wstring& value_string) { | 241 const std::wstring& switch_string, const std::wstring& value_string) { |
316 if (value_string.empty()) { | 242 if (value_string.empty()) { |
317 return PrefixedSwitchString(switch_string); | 243 return PrefixedSwitchString(switch_string); |
318 } | 244 } |
319 | 245 |
320 return StringPrintf(L"%ls%ls%ls%ls", | 246 return StringPrintf(L"%ls%ls%ls%ls", |
321 kSwitchPrefixes[0], | 247 kSwitchPrefixes[0], |
322 switch_string.c_str(), | 248 switch_string.c_str(), |
323 kSwitchValueSeparator, | 249 kSwitchValueSeparator, |
324 value_string.c_str()); | 250 value_string.c_str()); |
325 } | 251 } |
326 | 252 |
327 // static | 253 #if defined(OS_WIN) |
328 void CommandLine::AppendSwitch(wstring* command_line_string, | 254 void CommandLine::AppendSwitch(const std::wstring& switch_string) { |
329 const wstring& switch_string) { | 255 std::wstring prefixed_switch_string = PrefixedSwitchString(switch_string); |
330 DCHECK(command_line_string); | 256 command_line_string_.append(L" "); |
331 wstring prefixed_switch_string = PrefixedSwitchString(switch_string); | 257 command_line_string_.append(prefixed_switch_string); |
332 command_line_string->append(L" "); | 258 switches_[WideToASCII(switch_string)] = L""; |
333 command_line_string->append(prefixed_switch_string); | |
334 } | 259 } |
335 | 260 |
336 // static | 261 void CommandLine::AppendSwitchWithValue(const std::wstring& switch_string, |
337 void CommandLine::AppendSwitchWithValue(wstring* command_line_string, | 262 const std::wstring& value_string) { |
338 const wstring& switch_string, | 263 std::wstring value_string_edit; |
339 const wstring& value_string) { | |
340 wstring value_string_edit; | |
341 | 264 |
342 // NOTE(jhughes): If the value contains a quotation mark at one | 265 // NOTE(jhughes): If the value contains a quotation mark at one |
343 // end but not both, you may get unusable output. | 266 // end but not both, you may get unusable output. |
344 if (!value_string.empty() && | 267 if (!value_string.empty() && |
345 (value_string.find(L" ") != std::wstring::npos) && | 268 (value_string.find(L" ") != std::wstring::npos) && |
346 (value_string[0] != L'"') && | 269 (value_string[0] != L'"') && |
347 (value_string[value_string.length() - 1] != L'"')) { | 270 (value_string[value_string.length() - 1] != L'"')) { |
348 // need to provide quotes | 271 // need to provide quotes |
349 value_string_edit = StringPrintf(L"\"%ls\"", value_string.c_str()); | 272 value_string_edit = StringPrintf(L"\"%ls\"", value_string.c_str()); |
350 } else { | 273 } else { |
351 value_string_edit = value_string; | 274 value_string_edit = value_string; |
352 } | 275 } |
353 | 276 |
354 wstring combined_switch_string = | 277 std::wstring combined_switch_string = |
355 PrefixedSwitchStringWithValue(switch_string, value_string_edit); | 278 PrefixedSwitchStringWithValue(switch_string, value_string_edit); |
356 | 279 |
357 command_line_string->append(L" "); | 280 command_line_string_.append(L" "); |
358 command_line_string->append(combined_switch_string); | 281 command_line_string_.append(combined_switch_string); |
| 282 |
| 283 switches_[WideToASCII(switch_string)] = value_string; |
359 } | 284 } |
360 | 285 |
| 286 void CommandLine::AppendLooseValue(const std::wstring& value) { |
| 287 // TODO(evan): quoting? |
| 288 command_line_string_.append(L" "); |
| 289 command_line_string_.append(value); |
| 290 } |
| 291 |
| 292 void CommandLine::AppendArguments(const CommandLine& other, |
| 293 bool include_program) { |
| 294 // Verify include_program is used correctly. |
| 295 // Logic could be shorter but this is clearer. |
| 296 DCHECK(include_program ? !other.program().empty() : other.program().empty()); |
| 297 command_line_string_ += L" " + other.command_line_string_; |
| 298 std::map<std::string, StringType>::const_iterator i; |
| 299 for (i = other.switches_.begin(); i != other.switches_.end(); ++i) |
| 300 switches_[i->first] = i->second; |
| 301 } |
| 302 |
| 303 #elif defined(OS_POSIX) |
| 304 void CommandLine::AppendSwitch(const std::wstring& switch_string) { |
| 305 std::string ascii_switch = WideToASCII(switch_string); |
| 306 argv_.push_back(kSwitchPrefixes[0] + ascii_switch); |
| 307 switches_[ascii_switch] = ""; |
| 308 } |
| 309 |
| 310 void CommandLine::AppendSwitchWithValue(const std::wstring& switch_string, |
| 311 const std::wstring& value_string) { |
| 312 std::string ascii_switch = WideToASCII(switch_string); |
| 313 std::string ascii_value = WideToASCII(value_string); |
| 314 |
| 315 argv_.push_back(kSwitchPrefixes[0] + ascii_switch + |
| 316 kSwitchValueSeparator + ascii_value); |
| 317 switches_[ascii_switch] = ascii_value; |
| 318 } |
| 319 |
| 320 void CommandLine::AppendLooseValue(const std::wstring& value) { |
| 321 argv_.push_back(WideToASCII(value)); |
| 322 } |
| 323 |
| 324 void CommandLine::AppendArguments(const CommandLine& other, |
| 325 bool include_program) { |
| 326 // Verify include_program is used correctly. |
| 327 // Logic could be shorter but this is clearer. |
| 328 DCHECK(include_program ? !other.program().empty() : other.program().empty()); |
| 329 |
| 330 size_t first_arg = include_program ? 0 : 1; |
| 331 for (size_t i = first_arg; i < other.argv_.size(); ++i) |
| 332 argv_.push_back(other.argv_[i]); |
| 333 std::map<std::string, StringType>::const_iterator i; |
| 334 for (i = other.switches_.begin(); i != other.switches_.end(); ++i) |
| 335 switches_[i->first] = i->second; |
| 336 } |
| 337 #endif |
| 338 |
OLD | NEW |