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)// This class works with command lines: building and parsing. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Arguments with prefixes ('--', '-', and on Windows, '/') are switches. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Switches will precede all other arguments without switch prefixes. 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Switches can optionally have values, delimited by '=', e.g., "-switch=value". 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An argument of "--" will terminate switch parsing during initialization, 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// interpreting subsequent tokens as non-switch arguments, regardless of prefix. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// There is a singleton read-only CommandLine that represents the command line 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that the current process was started with. It must be initialized in main(). 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef BASE_COMMAND_LINE_H_ 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_COMMAND_LINE_H_ 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stddef.h> 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base_export.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace base { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FilePath; 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT CommandLine { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The native command line string type. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::wstring StringType; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::string StringType; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef StringType::value_type CharType; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::vector<StringType> StringVector; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<std::string, StringType> SwitchMap; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A constructor for CommandLines that only carry switches and arguments. 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum NoProgram { NO_PROGRAM }; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit CommandLine(NoProgram no_program); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct a new command line with |program| as argv[0]. 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit CommandLine(const base::FilePath& program); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct a new command line from an argument list. 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine(int argc, const CharType* const* argv); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit CommandLine(const StringVector& argv); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~CommandLine(); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize the current process CommandLine singleton. On Windows, ignores 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // its arguments (we instead parse GetCommandLineW() directly) because we 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // don't trust the CRT's parsing of the command line, but it still must be 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // called to set up the command line. Returns false if initialization has 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // already occurred, and true otherwise. Only the caller receiving a 'true' 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // return value should take responsibility for calling Reset. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool Init(int argc, const char* const* argv); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Destroys the current process CommandLine singleton. This is necessary if 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // you want to reset the base library to its initial state (for example, in an 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // outer library that needs to be able to terminate, and be re-initialized). 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If Init is called only once, as in main(), Reset() is not necessary. 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void Reset(); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the singleton CommandLine representing the current process's 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // command line. Note: returned value is mutable, but not thread safe; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // only mutate if you know what you're doing! 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static CommandLine* ForCurrentProcess(); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Returns true if the CommandLine has been initialized for the given process. 767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch static bool InitializedForCurrentProcess(); 777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static CommandLine FromString(const std::wstring& command_line); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize from an argv vector. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void InitFromArgv(int argc, const CharType* const* argv); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void InitFromArgv(const StringVector& argv); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Constructs and returns the represented command line string. 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CAUTION! This should be avoided on POSIX because quoting behavior is 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // unclear. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringType GetCommandLineString() const; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Constructs and returns the represented arguments string. 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CAUTION! This should be avoided on POSIX because quoting behavior is 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // unclear. 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringType GetArgumentsString() const; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the original command line string as a vector of strings. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const StringVector& argv() const { return argv_; } 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get and Set the program part of the command line string (the first item). 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath GetProgram() const; 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SetProgram(const base::FilePath& program); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if this command line contains the given switch. 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (Switch names are case-insensitive). 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool HasSwitch(const std::string& switch_string) const; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the value associated with the given switch. If the switch has no 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // value or isn't present, this method returns the empty string. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string GetSwitchValueASCII(const std::string& switch_string) const; 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath GetSwitchValuePath(const std::string& switch_string) const; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringType GetSwitchValueNative(const std::string& switch_string) const; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get a copy of all switches, along with their values. 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SwitchMap& GetSwitches() const { return switches_; } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Append a switch [with optional value] to the command line. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: Switches will precede arguments regardless of appending order. 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AppendSwitch(const std::string& switch_string); 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void AppendSwitchPath(const std::string& switch_string, 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& path); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AppendSwitchNative(const std::string& switch_string, 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const StringType& value); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AppendSwitchASCII(const std::string& switch_string, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& value); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copy a set of switches (and any values) from another command line. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Commonly used when launching a subprocess. 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CopySwitchesFrom(const CommandLine& source, 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* const switches[], 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t count); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the remaining arguments to the command. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringVector GetArgs() const; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Append an argument to the command line. Note that the argument is quoted 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // properly such that it is interpreted as one argument to the target command. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // AppendArg is primarily for ASCII; non-ASCII input is interpreted as UTF-8. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: Switches will precede arguments regardless of appending order. 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AppendArg(const std::string& value); 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void AppendArgPath(const base::FilePath& value); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AppendArgNative(const StringType& value); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Append the switches and arguments from another command line to this one. 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If |include_program| is true, include |other|'s program as well. 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AppendArguments(const CommandLine& other, bool include_program); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Insert a command before the current command. 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Common for debuggers, like "valgrind" or "gdb --args". 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void PrependWrapper(const StringType& wrapper); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize by parsing the given command line string. 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The program name is assumed to be the first item in the string. 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ParseFromString(const std::wstring& command_line); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Disallow default constructor; a program name must be explicitly specified. 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine(); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allow the copy constructor. A common pattern is to copy of the current 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // process's command line and then add some flags to it. For example: 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CommandLine cl(*CommandLine::ForCurrentProcess()); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cl.AppendSwitch(...); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The singleton CommandLine representing the current process's command line. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static CommandLine* current_process_commandline_; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The argv array: { program, [(--|-|/)switch[=value]]*, [--], [argument]* } 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringVector argv_; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parsed-out switch keys and values. 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SwitchMap switches_; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The index after the program and switches, any arguments start here. 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t begin_args_; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // BASE_COMMAND_LINE_H_ 179