Home | History | Annotate | Download | only in base
      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
      3 // found in the LICENSE file.
      4 
      5 // This class works with command lines: building and parsing.
      6 // Switches can optionally have a value attached using an equals sign,
      7 // as in "-switch=value".  Arguments that aren't prefixed with a
      8 // switch prefix are considered "loose parameters".  Switch names are
      9 // case-insensitive.  An argument of "--" will terminate switch
     10 // parsing, causing everything after to be considered as loose
     11 // parameters.
     12 
     13 // There is a singleton read-only CommandLine that represents the command
     14 // line that the current process was started with.  It must be initialized
     15 // in main() (or whatever the platform's equivalent function is).
     16 
     17 #ifndef BASE_COMMAND_LINE_H_
     18 #define BASE_COMMAND_LINE_H_
     19 
     20 #include "build/build_config.h"
     21 
     22 #include <map>
     23 #include <string>
     24 #include <vector>
     25 
     26 #include "base/basictypes.h"
     27 #include "base/file_path.h"
     28 #include "base/logging.h"
     29 #include "base/string_util.h"
     30 
     31 class InProcessBrowserTest;
     32 
     33 class CommandLine {
     34  public:
     35   // A constructor for CommandLines that are used only to carry arguments.
     36   enum ArgumentsOnly { ARGUMENTS_ONLY };
     37   explicit CommandLine(ArgumentsOnly args_only);
     38 
     39 #if defined(OS_WIN)
     40   // Initialize by parsing the given command-line string.
     41   // The program name is assumed to be the first item in the string.
     42   void ParseFromString(const std::wstring& command_line);
     43   static CommandLine FromString(const std::wstring& command_line) {
     44     CommandLine cmd;
     45     cmd.ParseFromString(command_line);
     46     return cmd;
     47   }
     48 #elif defined(OS_POSIX)
     49   // Initialize from an argv vector.
     50   void InitFromArgv(int argc, const char* const* argv);
     51   void InitFromArgv(const std::vector<std::string>& argv);
     52 
     53   CommandLine(int argc, const char* const* argv) {
     54     InitFromArgv(argc, argv);
     55   }
     56   explicit CommandLine(const std::vector<std::string>& argv) {
     57     InitFromArgv(argv);
     58   }
     59 #endif
     60 
     61   // Construct a new, empty command line.
     62   // |program| is the name of the program to run (aka argv[0]).
     63   explicit CommandLine(const FilePath& program);
     64 
     65   // Initialize the current process CommandLine singleton.  On Windows,
     66   // ignores its arguments (we instead parse GetCommandLineW()
     67   // directly) because we don't trust the CRT's parsing of the command
     68   // line, but it still must be called to set up the command line.
     69   static void Init(int argc, const char* const* argv);
     70 
     71 #if defined(OS_POSIX) && !defined(OS_MACOSX)
     72   // Sets the current process' arguments that show in "ps" etc. to those
     73   // in |current_process_commandline_|. Used by the zygote host so that
     74   // renderers show up with --type=renderer.
     75   static void SetProcTitle();
     76 #endif
     77 
     78   // Destroys the current process CommandLine singleton. This is necessary if
     79   // you want to reset the base library to its initial state (for example in an
     80   // outer library that needs to be able to terminate, and be re-initialized).
     81   // If Init is called only once, e.g. in main(), calling Reset() is not
     82   // necessary.
     83   static void Reset();
     84   // The same function snuck into this class under two different names;
     85   // this one remains for backwards compat with the older o3d build.
     86   static void Terminate() { Reset(); }
     87 
     88   // Get the singleton CommandLine representing the current process's
     89   // command line.  Note: returned value is mutable, but not thread safe;
     90   // only mutate if you know what you're doing!
     91   static CommandLine* ForCurrentProcess() {
     92     DCHECK(current_process_commandline_);
     93     return current_process_commandline_;
     94   }
     95 
     96   // Returns true if this command line contains the given switch.
     97   // (Switch names are case-insensitive.)
     98   bool HasSwitch(const std::string& switch_string) const;
     99 
    100   // Deprecated version of the above.
    101   bool HasSwitch(const std::wstring& switch_string) const {
    102     return HasSwitch(WideToASCII(switch_string));
    103   }
    104 
    105   // Returns the value associated with the given switch.  If the
    106   // switch has no value or isn't present, this method returns
    107   // the empty string.
    108   // TODO(evanm): move these into command_line.cpp once we've fixed the
    109   // wstringness.
    110   std::string GetSwitchValueASCII(const std::string& switch_string) const {
    111     return WideToASCII(GetSwitchValue(switch_string));
    112   }
    113   FilePath GetSwitchValuePath(const std::string& switch_string) const {
    114     return FilePath::FromWStringHack(GetSwitchValue(switch_string));
    115   }
    116 
    117   // Deprecated versions of the above.
    118   std::wstring GetSwitchValue(const std::string& switch_string) const;
    119   std::wstring GetSwitchValue(const std::wstring& switch_string) const {
    120     return GetSwitchValue(WideToASCII(switch_string));
    121   }
    122 
    123   // Get the number of switches in this process.
    124   size_t GetSwitchCount() const { return switches_.size(); }
    125 
    126   // Get the remaining arguments to the command.
    127   // WARNING: this is incorrect on POSIX; we must do string conversions.
    128   std::vector<std::wstring> GetLooseValues() const;
    129 
    130 #if defined(OS_WIN)
    131   // Returns the original command line string.
    132   const std::wstring& command_line_string() const {
    133     return command_line_string_;
    134   }
    135 #elif defined(OS_POSIX)
    136   // Returns the original command line string as a vector of strings.
    137   const std::vector<std::string>& argv() const {
    138     return argv_;
    139   }
    140 #endif
    141 
    142   // Returns the program part of the command line string (the first item).
    143   FilePath GetProgram() const {
    144     return FilePath::FromWStringHack(program());
    145   }
    146 
    147   // Returns the program part of the command line string (the first item).
    148   // Deprecated version of the above.
    149   std::wstring program() const;
    150 
    151   // Return a copy of the string prefixed with a switch prefix.
    152   // Used internally.
    153   static std::wstring PrefixedSwitchString(const std::string& switch_string);
    154 
    155   // Return a copy of the string prefixed with a switch prefix,
    156   // and appended with the given value. Used internally.
    157   static std::wstring PrefixedSwitchStringWithValue(
    158                         const std::string& switch_string,
    159                         const std::wstring& value_string);
    160 
    161   // Appends the given switch string (preceded by a space and a switch
    162   // prefix) to the given string.
    163   void AppendSwitch(const std::string& switch_string);
    164 
    165   // Appends the given switch string (preceded by a space and a switch
    166   // prefix) to the given string, with the given value attached.
    167   void AppendSwitchWithValue(const std::string& switch_string,
    168                              const std::wstring& value_string);
    169   void AppendSwitchWithValue(const std::string& switch_string,
    170                              const std::string& value_string) {
    171     AppendSwitchWithValue(switch_string, ASCIIToWide(value_string));
    172   }
    173 
    174   // Append a loose value to the command line.
    175   void AppendLooseValue(const std::wstring& value);
    176 
    177   // Append the arguments from another command line to this one.
    178   // If |include_program| is true, include |other|'s program as well.
    179   void AppendArguments(const CommandLine& other,
    180                        bool include_program);
    181 
    182   // On POSIX systems it's common to run processes via a wrapper (like
    183   // "valgrind" or "gdb --args").
    184   void PrependWrapper(const std::wstring& wrapper);
    185 
    186  private:
    187   friend class InProcessBrowserTest;
    188 
    189   CommandLine() {}
    190 
    191   // Used by InProcessBrowserTest.
    192   static CommandLine* ForCurrentProcessMutable() {
    193     DCHECK(current_process_commandline_);
    194     return current_process_commandline_;
    195   }
    196 
    197   // The singleton CommandLine instance representing the current process's
    198   // command line.
    199   static CommandLine* current_process_commandline_;
    200 
    201   // We store a platform-native version of the command line, used when building
    202   // up a new command line to be executed.  This ifdef delimits that code.
    203 
    204 #if defined(OS_WIN)
    205   // The quoted, space-separated command-line string.
    206   std::wstring command_line_string_;
    207 
    208   // The name of the program.
    209   std::wstring program_;
    210 
    211   // The type of native command line arguments.
    212   typedef std::wstring StringType;
    213 
    214 #elif defined(OS_POSIX)
    215   // The argv array, with the program name in argv_[0].
    216   std::vector<std::string> argv_;
    217 
    218   // The type of native command line arguments.
    219   typedef std::string StringType;
    220 #endif
    221 
    222   // Returns true and fills in |switch_string| and |switch_value|
    223   // if |parameter_string| represents a switch.
    224   static bool IsSwitch(const StringType& parameter_string,
    225                        std::string* switch_string,
    226                        StringType* switch_value);
    227 
    228   // Parsed-out values.
    229   std::map<std::string, StringType> switches_;
    230 
    231   // Non-switch command-line arguments.
    232   std::vector<StringType> loose_values_;
    233 
    234   // We allow copy constructors, because a common pattern is to grab a
    235   // copy of the current process's command line and then add some
    236   // flags to it.  E.g.:
    237   //   CommandLine cl(*CommandLine::ForCurrentProcess());
    238   //   cl.AppendSwitch(...);
    239 };
    240 
    241 #endif  // BASE_COMMAND_LINE_H_
    242