Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(715)

Side by Side Diff: base/command_line.cc

Issue 6462024: Register Application Restart with Windows Restart Manager (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/command_line.h ('k') | chrome/browser/browser_main.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/file_path.h" 9 #include "base/file_path.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
(...skipping 22 matching lines...) Expand all
34 const wchar_t kSwitchTerminator[] = L"--"; 34 const wchar_t kSwitchTerminator[] = L"--";
35 const wchar_t kSwitchValueSeparator[] = L"="; 35 const wchar_t kSwitchValueSeparator[] = L"=";
36 #elif defined(OS_POSIX) 36 #elif defined(OS_POSIX)
37 // Unixes don't use slash as a switch. 37 // Unixes don't use slash as a switch.
38 const char* const kSwitchPrefixes[] = {"--", "-"}; 38 const char* const kSwitchPrefixes[] = {"--", "-"};
39 const char kSwitchTerminator[] = "--"; 39 const char kSwitchTerminator[] = "--";
40 const char kSwitchValueSeparator[] = "="; 40 const char kSwitchValueSeparator[] = "=";
41 #endif 41 #endif
42 42
43 #if defined(OS_WIN) 43 #if defined(OS_WIN)
44 namespace {
44 // Lowercase a string. This is used to lowercase switch names. 45 // Lowercase a string. This is used to lowercase switch names.
45 // Is this what we really want? It seems crazy to me. I've left it in 46 // Is this what we really want? It seems crazy to me. I've left it in
46 // for backwards compatibility on Windows. 47 // for backwards compatibility on Windows.
47 static void Lowercase(std::string* parameter) { 48 void Lowercase(std::string* parameter) {
48 transform(parameter->begin(), parameter->end(), parameter->begin(), 49 transform(parameter->begin(), parameter->end(), parameter->begin(),
49 tolower); 50 tolower);
50 } 51 }
52
53 // Quote a string if necessary, such that CommandLineToArgvW() will
54 // always process it as a single argument.
55 std::wstring WindowsStyleQuote(const std::wstring& arg) {
56 // We follow the quoting rules of CommandLineToArgvW.
57 // http://msdn.microsoft.com/en-us/library/17w5ykft.aspx
58 if (arg.find_first_of(L" \\\"") == std::wstring::npos) {
59 // No quoting necessary.
60 return arg;
61 }
62
63 std::wstring out;
64 out.push_back(L'"');
65 for (size_t i = 0; i < arg.size(); ++i) {
66 if (arg[i] == '\\') {
67 // Find the extent of this run of backslashes.
68 size_t start = i, end = start + 1;
69 for (; end < arg.size() && arg[end] == '\\'; ++end)
70 /* empty */;
71 size_t backslash_count = end - start;
72
73 // Backslashes are escapes only if the run is followed by a double quote.
74 // Since we also will end the string with a double quote, we escape for
75 // either a double quote or the end of the string.
76 if (end == arg.size() || arg[end] == '"') {
77 // To quote, we need to output 2x as many backslashes.
78 backslash_count *= 2;
79 }
80 for (size_t j = 0; j < backslash_count; ++j)
81 out.push_back('\\');
82
83 // Advance i to one before the end to balance i++ in loop.
84 i = end - 1;
85 } else if (arg[i] == '"') {
86 out.push_back('\\');
87 out.push_back('"');
88 } else {
89 out.push_back(arg[i]);
90 }
91 }
92 out.push_back('"');
93
94 return out;
95 }
96 } // namespace
51 #endif 97 #endif
52 98
53 CommandLine::~CommandLine() { 99 CommandLine::~CommandLine() {
54 } 100 }
55 101
56 #if defined(OS_WIN) 102 #if defined(OS_WIN)
57 CommandLine::CommandLine(NoProgram no_program) { 103 CommandLine::CommandLine(NoProgram no_program) {
58 } 104 }
59 105
60 void CommandLine::ParseFromString(const std::wstring& command_line) { 106 void CommandLine::ParseFromString(const std::wstring& command_line) {
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 } 330 }
285 #endif 331 #endif
286 332
287 #if defined(OS_WIN) 333 #if defined(OS_WIN)
288 void CommandLine::AppendSwitch(const std::string& switch_string) { 334 void CommandLine::AppendSwitch(const std::string& switch_string) {
289 command_line_string_.append(L" "); 335 command_line_string_.append(L" ");
290 command_line_string_.append(kSwitchPrefixes[0] + ASCIIToWide(switch_string)); 336 command_line_string_.append(kSwitchPrefixes[0] + ASCIIToWide(switch_string));
291 switches_[switch_string] = L""; 337 switches_[switch_string] = L"";
292 } 338 }
293 339
294 void CommandLine::AppendSwitchASCII(const std::string& switch_string,
295 const std::string& value_string) {
296 AppendSwitchNative(switch_string, ASCIIToWide(value_string));
297 }
298
299 // Quote a string if necessary, such that CommandLineToArgvW() will
300 // always process it as a single argument.
301 static std::wstring WindowsStyleQuote(const std::wstring& arg) {
302 // We follow the quoting rules of CommandLineToArgvW.
303 // http://msdn.microsoft.com/en-us/library/17w5ykft.aspx
304 if (arg.find_first_of(L" \\\"") == std::wstring::npos) {
305 // No quoting necessary.
306 return arg;
307 }
308
309 std::wstring out;
310 out.push_back(L'"');
311 for (size_t i = 0; i < arg.size(); ++i) {
312 if (arg[i] == '\\') {
313 // Find the extent of this run of backslashes.
314 size_t start = i, end = start + 1;
315 for (; end < arg.size() && arg[end] == '\\'; ++end)
316 /* empty */;
317 size_t backslash_count = end - start;
318
319 // Backslashes are escapes only if the run is followed by a double quote.
320 // Since we also will end the string with a double quote, we escape for
321 // either a double quote or the end of the string.
322 if (end == arg.size() || arg[end] == '"') {
323 // To quote, we need to output 2x as many backslashes.
324 backslash_count *= 2;
325 }
326 for (size_t j = 0; j < backslash_count; ++j)
327 out.push_back('\\');
328
329 // Advance i to one before the end to balance i++ in loop.
330 i = end - 1;
331 } else if (arg[i] == '"') {
332 out.push_back('\\');
333 out.push_back('"');
334 } else {
335 out.push_back(arg[i]);
336 }
337 }
338 out.push_back('"');
339
340 return out;
341 }
342
343 void CommandLine::AppendSwitchNative(const std::string& switch_string, 340 void CommandLine::AppendSwitchNative(const std::string& switch_string,
344 const std::wstring& value) { 341 const std::wstring& value) {
345 std::wstring combined_switch_string = 342 std::wstring combined_switch_string =
346 kSwitchPrefixes[0] + ASCIIToWide(switch_string); 343 kSwitchPrefixes[0] + ASCIIToWide(switch_string);
347 if (!value.empty()) 344 if (!value.empty())
348 combined_switch_string += kSwitchValueSeparator + WindowsStyleQuote(value); 345 combined_switch_string += kSwitchValueSeparator + WindowsStyleQuote(value);
349 346
350 command_line_string_.append(L" "); 347 command_line_string_.append(L" ");
351 command_line_string_.append(combined_switch_string); 348 command_line_string_.append(combined_switch_string);
352 349
353 switches_[switch_string] = value; 350 switches_[switch_string] = value;
354 } 351 }
355 352
353 void CommandLine::AppendSwitchASCII(const std::string& switch_string,
354 const std::string& value_string) {
355 AppendSwitchNative(switch_string, ASCIIToWide(value_string));
356 }
357
356 void CommandLine::AppendArg(const std::string& value) { 358 void CommandLine::AppendArg(const std::string& value) {
357 DCHECK(IsStringUTF8(value)); 359 DCHECK(IsStringUTF8(value));
358 AppendArgNative(UTF8ToWide(value)); 360 AppendArgNative(UTF8ToWide(value));
359 } 361 }
360 362
361 void CommandLine::AppendArgNative(const std::wstring& value) { 363 void CommandLine::AppendArgNative(const std::wstring& value) {
362 command_line_string_.append(L" "); 364 command_line_string_.append(L" ");
363 command_line_string_.append(WindowsStyleQuote(value)); 365 command_line_string_.append(WindowsStyleQuote(value));
364 args_.push_back(value); 366 args_.push_back(value);
365 } 367 }
366 368
367 void CommandLine::AppendArguments(const CommandLine& other, 369 void CommandLine::AppendArguments(const CommandLine& other,
368 bool include_program) { 370 bool include_program) {
369 // Verify include_program is used correctly. 371 // Verify include_program is used correctly.
370 // Logic could be shorter but this is clearer. 372 DCHECK(!include_program || !other.GetProgram().empty());
371 DCHECK_EQ(include_program, !other.GetProgram().empty());
372 if (include_program) 373 if (include_program)
373 program_ = other.program_; 374 program_ = other.program_;
374 375
375 if (!command_line_string_.empty()) 376 if (!command_line_string_.empty())
376 command_line_string_ += L' '; 377 command_line_string_ += L' ';
377 378
378 command_line_string_ += other.command_line_string_; 379 command_line_string_ += other.command_line_string_;
379 380
380 std::map<std::string, StringType>::const_iterator i; 381 std::map<std::string, StringType>::const_iterator i;
381 for (i = other.switches_.begin(); i != other.switches_.end(); ++i) 382 for (i = other.switches_.begin(); i != other.switches_.end(); ++i)
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 void CommandLine::PrependWrapper(const std::string& wrapper) { 445 void CommandLine::PrependWrapper(const std::string& wrapper) {
445 // The wrapper may have embedded arguments (like "gdb --args"). In this case, 446 // The wrapper may have embedded arguments (like "gdb --args"). In this case,
446 // we don't pretend to do anything fancy, we just split on spaces. 447 // we don't pretend to do anything fancy, we just split on spaces.
447 std::vector<std::string> wrapper_and_args; 448 std::vector<std::string> wrapper_and_args;
448 base::SplitString(wrapper, ' ', &wrapper_and_args); 449 base::SplitString(wrapper, ' ', &wrapper_and_args);
449 argv_.insert(argv_.begin(), wrapper_and_args.begin(), wrapper_and_args.end()); 450 argv_.insert(argv_.begin(), wrapper_and_args.begin(), wrapper_and_args.end());
450 } 451 }
451 452
452 #endif 453 #endif
453 454
454 void CommandLine::AppendArgPath(const FilePath& path) {
455 AppendArgNative(path.value());
456 }
457
458 void CommandLine::AppendSwitchPath(const std::string& switch_string, 455 void CommandLine::AppendSwitchPath(const std::string& switch_string,
459 const FilePath& path) { 456 const FilePath& path) {
460 AppendSwitchNative(switch_string, path.value()); 457 AppendSwitchNative(switch_string, path.value());
461 } 458 }
462 459
460 void CommandLine::AppendSwitches(const CommandLine& other) {
461 std::map<std::string, StringType>::const_iterator i;
462 for (i = other.switches_.begin(); i != other.switches_.end(); ++i)
463 AppendSwitchNative(i->first, i->second);
464 }
465
466 void CommandLine::AppendArgPath(const FilePath& path) {
467 AppendArgNative(path.value());
468 }
469
470 void CommandLine::AppendArgs(const CommandLine& other) {
471 if(other.args_.size() <= 0)
472 return;
473
474 #if defined(OS_WIN)
475 command_line_string_.append(L" --");
476 #endif // OS_WIN
477 std::vector<StringType>::const_iterator i;
478 for (i = other.args_.begin(); i != other.args_.end(); ++i)
479 AppendArgNative(*i);
480 }
481
463 void CommandLine::CopySwitchesFrom(const CommandLine& source, 482 void CommandLine::CopySwitchesFrom(const CommandLine& source,
464 const char* const switches[], 483 const char* const switches[],
465 size_t count) { 484 size_t count) {
466 for (size_t i = 0; i < count; ++i) { 485 for (size_t i = 0; i < count; ++i) {
467 if (source.HasSwitch(switches[i])) { 486 if (source.HasSwitch(switches[i])) {
468 StringType value = source.GetSwitchValueNative(switches[i]); 487 StringType value = source.GetSwitchValueNative(switches[i]);
469 AppendSwitchNative(switches[i], value); 488 AppendSwitchNative(switches[i], value);
470 } 489 }
471 } 490 }
472 } 491 }
473 492
474 // private 493 // private
475 CommandLine::CommandLine() { 494 CommandLine::CommandLine() {
476 } 495 }
477 496
478 // static 497 // static
479 CommandLine* CommandLine::ForCurrentProcessMutable() { 498 CommandLine* CommandLine::ForCurrentProcessMutable() {
480 DCHECK(current_process_commandline_); 499 DCHECK(current_process_commandline_);
481 return current_process_commandline_; 500 return current_process_commandline_;
482 } 501 }
OLDNEW
« no previous file with comments | « base/command_line.h ('k') | chrome/browser/browser_main.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698