15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <ostream> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h" 145e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h> 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <shellapi.h> 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using base::FilePath; 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandLine* CommandLine::current_process_commandline_ = NULL; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const CommandLine::CharType kSwitchTerminator[] = FILE_PATH_LITERAL("--"); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const CommandLine::CharType kSwitchValueSeparator[] = FILE_PATH_LITERAL("="); 3068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Since we use a lazy match, make sure that longer versions (like "--") are 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// listed before shorter versions (like "-") of similar prefixes. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 3468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// By putting slash last, we can control whether it is treaded as a switch 3568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// value by changing the value of switch_prefix_count to be one less than 3668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// the array size. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const CommandLine::CharType* const kSwitchPrefixes[] = {L"--", L"-", L"/"}; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Unixes don't use slash as a switch. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const CommandLine::CharType* const kSwitchPrefixes[] = {"--", "-"}; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)size_t switch_prefix_count = arraysize(kSwitchPrefixes); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t GetSwitchPrefixLength(const CommandLine::StringType& string) { 4568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (size_t i = 0; i < switch_prefix_count; ++i) { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine::StringType prefix(kSwitchPrefixes[i]); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (string.compare(0, prefix.length(), prefix) == 0) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return prefix.length(); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Fills in |switch_string| and |switch_value| if |string| is a switch. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This will preserve the input switch prefix in the output |switch_string|. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsSwitch(const CommandLine::StringType& string, 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine::StringType* switch_string, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine::StringType* switch_value) { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch_string->clear(); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch_value->clear(); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t prefix_length = GetSwitchPrefixLength(string); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prefix_length == 0 || prefix_length == string.length()) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t equals_position = string.find(kSwitchValueSeparator); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *switch_string = string.substr(0, equals_position); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (equals_position != CommandLine::StringType::npos) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *switch_value = string.substr(equals_position + 1); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Append switches and arguments, keeping switches before arguments. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppendSwitchesAndArguments(CommandLine& command_line, 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CommandLine::StringVector& argv) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool parse_switches = true; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 1; i < argv.size(); ++i) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine::StringType arg = argv[i]; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TrimWhitespace(arg, TRIM_ALL, &arg); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine::StringType switch_string; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine::StringType switch_value; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parse_switches &= (arg != kSwitchTerminator); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parse_switches && IsSwitch(arg, &switch_string, &switch_value)) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line.AppendSwitchNative(WideToASCII(switch_string), switch_value); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line.AppendSwitchNative(switch_string, switch_value); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line.AppendArgNative(arg); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Lowercase switches for backwards compatiblity *on Windows*. 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string LowerASCIIOnWindows(const std::string& string) { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return StringToLowerASCII(string); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return string; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Quote a string as necessary for CommandLineToArgvW compatiblity *on Windows*. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::wstring QuoteForCommandLineToArgvW(const std::wstring& arg) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We follow the quoting rules of CommandLineToArgvW. 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://msdn.microsoft.com/en-us/library/17w5ykft.aspx 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (arg.find_first_of(L" \\\"") == std::wstring::npos) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No quoting necessary. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return arg; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring out; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.push_back(L'"'); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < arg.size(); ++i) { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (arg[i] == '\\') { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find the extent of this run of backslashes. 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t start = i, end = start + 1; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; end < arg.size() && arg[end] == '\\'; ++end) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* empty */; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t backslash_count = end - start; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Backslashes are escapes only if the run is followed by a double quote. 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since we also will end the string with a double quote, we escape for 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // either a double quote or the end of the string. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (end == arg.size() || arg[end] == '"') { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // To quote, we need to output 2x as many backslashes. 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backslash_count *= 2; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t j = 0; j < backslash_count; ++j) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.push_back('\\'); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Advance i to one before the end to balance i++ in loop. 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = end - 1; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (arg[i] == '"') { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.push_back('\\'); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.push_back('"'); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.push_back(arg[i]); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out.push_back('"'); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return out; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandLine::CommandLine(NoProgram no_program) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : argv_(1), 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) begin_args_(1) { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandLine::CommandLine(const FilePath& program) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : argv_(1), 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) begin_args_(1) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetProgram(program); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandLine::CommandLine(int argc, const CommandLine::CharType* const* argv) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : argv_(1), 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) begin_args_(1) { 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitFromArgv(argc, argv); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandLine::CommandLine(const StringVector& argv) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : argv_(1), 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) begin_args_(1) { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitFromArgv(argv); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandLine::~CommandLine() { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(OS_WIN) 17868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// static 17968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void CommandLine::set_slash_is_not_a_switch() { 18068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // The last switch prefix should be slash, so adjust the size to skip it. 18168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(wcscmp(kSwitchPrefixes[arraysize(kSwitchPrefixes) - 1], L"/") == 0); 18268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) switch_prefix_count = arraysize(kSwitchPrefixes) - 1; 18368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 18468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif 18568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CommandLine::Init(int argc, const char* const* argv) { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (current_process_commandline_) { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this is intentional, Reset() must be called first. If we are using 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the shared build mode, we have to share a single object across multiple 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // shared libraries. 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_process_commandline_ = new CommandLine(NO_PROGRAM); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_process_commandline_->ParseFromString(::GetCommandLineW()); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_process_commandline_->InitFromArgv(argc, argv); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandLine::Reset() { 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(current_process_commandline_); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete current_process_commandline_; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_process_commandline_ = NULL; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandLine* CommandLine::ForCurrentProcess() { 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(current_process_commandline_); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return current_process_commandline_; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// static 2197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool CommandLine::InitializedForCurrentProcess() { 2207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return !!current_process_commandline_; 2217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandLine CommandLine::FromString(const std::wstring& command_line) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine cmd(NO_PROGRAM); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd.ParseFromString(command_line); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return cmd; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandLine::InitFromArgv(int argc, 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CommandLine::CharType* const* argv) { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringVector new_argv; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < argc; ++i) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_argv.push_back(argv[i]); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitFromArgv(new_argv); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandLine::InitFromArgv(const StringVector& argv) { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) argv_ = StringVector(1); 2427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) switches_.clear(); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) begin_args_ = 1; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetProgram(argv.empty() ? FilePath() : FilePath(argv[0])); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendSwitchesAndArguments(*this, argv); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandLine::StringType CommandLine::GetCommandLineString() const { 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringType string(argv_[0]); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string = QuoteForCommandLineToArgvW(string); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringType params(GetArgumentsString()); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!params.empty()) { 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string.append(StringType(FILE_PATH_LITERAL(" "))); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string.append(params); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return string; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandLine::StringType CommandLine::GetArgumentsString() const { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringType params; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Append switches and arguments. 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool parse_switches = true; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 1; i < argv_.size(); ++i) { 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringType arg = argv_[i]; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringType switch_string; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringType switch_value; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parse_switches &= arg != kSwitchTerminator; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i > 1) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.append(StringType(FILE_PATH_LITERAL(" "))); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parse_switches && IsSwitch(arg, &switch_string, &switch_value)) { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.append(switch_string); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!switch_value.empty()) { 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch_value = QuoteForCommandLineToArgvW(switch_value); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.append(kSwitchValueSeparator + switch_value); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arg = QuoteForCommandLineToArgvW(arg); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.append(arg); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return params; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FilePath CommandLine::GetProgram() const { 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FilePath(argv_[0]); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandLine::SetProgram(const FilePath& program) { 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TrimWhitespace(program.value(), TRIM_ALL, &argv_[0]); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CommandLine::HasSwitch(const std::string& switch_string) const { 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return switches_.find(LowerASCIIOnWindows(switch_string)) != switches_.end(); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string CommandLine::GetSwitchValueASCII( 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& switch_string) const { 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringType value = GetSwitchValueNative(switch_string); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsStringASCII(value)) { 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(WARNING) << "Value of switch (" << switch_string << ") must be ASCII."; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::string(); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WideToASCII(value); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return value; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FilePath CommandLine::GetSwitchValuePath( 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& switch_string) const { 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FilePath(GetSwitchValueNative(switch_string)); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandLine::StringType CommandLine::GetSwitchValueNative( 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& switch_string) const { 324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SwitchMap::const_iterator result = 325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) switches_.find(LowerASCIIOnWindows(switch_string)); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result == switches_.end() ? StringType() : result->second; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandLine::AppendSwitch(const std::string& switch_string) { 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendSwitchNative(switch_string, StringType()); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandLine::AppendSwitchPath(const std::string& switch_string, 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FilePath& path) { 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendSwitchNative(switch_string, path.value()); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandLine::AppendSwitchNative(const std::string& switch_string, 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CommandLine::StringType& value) { 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string switch_key(LowerASCIIOnWindows(switch_string)); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringType combined_switch_string(ASCIIToWide(switch_key)); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringType combined_switch_string(switch_string); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t prefix_length = GetSwitchPrefixLength(combined_switch_string); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switches_[switch_key.substr(prefix_length)] = value; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Preserve existing switch prefixes in |argv_|; only append one if necessary. 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prefix_length == 0) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) combined_switch_string = kSwitchPrefixes[0] + combined_switch_string; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!value.empty()) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) combined_switch_string += kSwitchValueSeparator + value; 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Append the switch and update the switches/arguments divider |begin_args_|. 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) argv_.insert(argv_.begin() + begin_args_++, combined_switch_string); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandLine::AppendSwitchASCII(const std::string& switch_string, 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& value_string) { 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendSwitchNative(switch_string, ASCIIToWide(value_string)); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendSwitchNative(switch_string, value_string); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandLine::CopySwitchesFrom(const CommandLine& source, 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* const switches[], 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t count) { 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < count; ++i) { 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (source.HasSwitch(switches[i])) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendSwitchNative(switches[i], source.GetSwitchValueNative(switches[i])); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandLine::StringVector CommandLine::GetArgs() const { 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Gather all arguments after the last switch (may include kSwitchTerminator). 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringVector args(argv_.begin() + begin_args_, argv_.end()); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Erase only the first kSwitchTerminator (maybe "--" is a legitimate page?) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringVector::iterator switch_terminator = 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::find(args.begin(), args.end(), kSwitchTerminator); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (switch_terminator != args.end()) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.erase(switch_terminator); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return args; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandLine::AppendArg(const std::string& value) { 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsStringUTF8(value)); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendArgNative(UTF8ToWide(value)); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendArgNative(value); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandLine::AppendArgPath(const FilePath& path) { 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendArgNative(path.value()); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandLine::AppendArgNative(const CommandLine::StringType& value) { 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) argv_.push_back(value); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandLine::AppendArguments(const CommandLine& other, 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool include_program) { 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (include_program) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetProgram(other.GetProgram()); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendSwitchesAndArguments(*this, other.argv()); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandLine::PrependWrapper(const CommandLine::StringType& wrapper) { 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (wrapper.empty()) 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The wrapper may have embedded arguments (like "gdb --args"). In this case, 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we don't pretend to do anything fancy, we just split on spaces. 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringVector wrapper_argv; 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SplitString(wrapper, FILE_PATH_LITERAL(' '), &wrapper_argv); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prepend the wrapper and update the switches/arguments |begin_args_|. 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) argv_.insert(argv_.begin(), wrapper_argv.begin(), wrapper_argv.end()); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) begin_args_ += wrapper_argv.size(); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandLine::ParseFromString(const std::wstring& command_line) { 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring command_line_string; 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TrimWhitespace(command_line, TRIM_ALL, &command_line_string); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (command_line_string.empty()) 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_args = 0; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wchar_t** args = NULL; 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args = ::CommandLineToArgvW(command_line_string.c_str(), &num_args); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DPLOG_IF(FATAL, !args) << "CommandLineToArgvW failed on command line: " 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << command_line; 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitFromArgv(num_args, args); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LocalFree(args); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 439