tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

command_line.h (6925B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
      4 // Use of this source code is governed by a BSD-style license that can be
      5 // found in the LICENSE file.
      6 
      7 // This class works with command lines: building and parsing.
      8 // Switches can optionally have a value attached using an equals sign,
      9 // as in "-switch=value".  Arguments that aren't prefixed with a
     10 // switch prefix are considered "loose parameters".  Switch names are
     11 // case-insensitive.  An argument of "--" will terminate switch
     12 // parsing, causing everything after to be considered as loose
     13 // parameters.
     14 
     15 // There is a singleton read-only CommandLine that represents the command
     16 // line that the current process was started with.  It must be initialized
     17 // in main() (or whatever the platform's equivalent function is).
     18 
     19 #ifndef BASE_COMMAND_LINE_H_
     20 #define BASE_COMMAND_LINE_H_
     21 
     22 #include <map>
     23 #include <string>
     24 #include <vector>
     25 
     26 #include "base/basictypes.h"
     27 #include "base/logging.h"
     28 
     29 class InProcessBrowserTest;
     30 
     31 class CommandLine {
     32 public:
     33 #if defined(XP_WIN)
     34  // Creates a parsed version of the given command-line string.
     35  // The program name is assumed to be the first item in the string.
     36  void ParseFromString(const std::wstring& command_line);
     37 #else
     38  // Initialize from an argv vector (or directly from main()'s argv).
     39  CommandLine(int argc, const char* const* argv);
     40  explicit CommandLine(const std::vector<std::string>& argv);
     41 #endif
     42 
     43  // Construct a new, empty command line.
     44  // |program| is the name of the program to run (aka argv[0]).
     45  // TODO(port): should be a FilePath.
     46  explicit CommandLine(const std::wstring& program);
     47 
     48  // Initialize the current process CommandLine singleton.  On Windows,
     49  // ignores its arguments (we instead parse GetCommandLineW()
     50  // directly) because we don't trust the CRT's parsing of the command
     51  // line, but it still must be called to set up the command line.
     52  static void Init(int argc, const char* const* argv);
     53 
     54  // Destroys the current process CommandLine singleton. This is necessary if
     55  // you want to reset the base library to its initial state (for example in an
     56  // outer library that needs to be able to terminate, and be re-initialized).
     57  // If Init is called only once, e.g. in main(), calling Terminate() is not
     58  // necessary.
     59  static void Terminate();
     60 
     61  // Get the singleton CommandLine representing the current process's
     62  // command line.
     63  static const CommandLine* ForCurrentProcess() {
     64    DCHECK(current_process_commandline_);
     65    return current_process_commandline_;
     66  }
     67 
     68  static bool IsInitialized() { return !!current_process_commandline_; }
     69 
     70  // Returns true if this command line contains the given switch.
     71  // (Switch names are case-insensitive.)
     72  bool HasSwitch(const std::wstring& switch_string) const;
     73 
     74  // Returns the value associated with the given switch.  If the
     75  // switch has no value or isn't present, this method returns
     76  // the empty string.
     77  std::wstring GetSwitchValue(const std::wstring& switch_string) const;
     78 
     79  // Get the remaining arguments to the command.
     80  // WARNING: this is incorrect on POSIX; we must do string conversions.
     81  std::vector<std::wstring> GetLooseValues() const;
     82 
     83 #if defined(XP_WIN)
     84  // Returns the original command line string.
     85  const std::wstring& command_line_string() const {
     86    return command_line_string_;
     87  }
     88 #else
     89  // Returns the original command line string as a vector of strings.
     90  const std::vector<std::string>& argv() const { return argv_; }
     91 #endif
     92 
     93  // Returns the program part of the command line string (the first item).
     94  std::wstring program() const;
     95 
     96  // Return a copy of the string prefixed with a switch prefix.
     97  // Used internally.
     98  static std::wstring PrefixedSwitchString(const std::wstring& switch_string);
     99 
    100  // Return a copy of the string prefixed with a switch prefix,
    101  // and appended with the given value. Used internally.
    102  static std::wstring PrefixedSwitchStringWithValue(
    103      const std::wstring& switch_string, const std::wstring& value_string);
    104 
    105  // Appends the given switch string (preceded by a space and a switch
    106  // prefix) to the given string.
    107  void AppendSwitch(const std::wstring& switch_string);
    108 
    109  // Appends the given switch string (preceded by a space and a switch
    110  // prefix) to the given string, with the given value attached.
    111  void AppendSwitchWithValue(const std::wstring& switch_string,
    112                             const std::wstring& value_string);
    113 
    114  // Append a loose value to the command line.
    115  void AppendLooseValue(const std::wstring& value);
    116 
    117 #if defined(XP_WIN)
    118  void AppendLooseValue(const wchar_t* value) {
    119    AppendLooseValue(std::wstring(value));
    120  }
    121 #endif
    122 
    123  // Append the arguments from another command line to this one.
    124  // If |include_program| is true, include |other|'s program as well.
    125  void AppendArguments(const CommandLine& other, bool include_program);
    126 
    127  // On POSIX systems it's common to run processes via a wrapper (like
    128  // "valgrind" or "gdb --args").
    129  void PrependWrapper(const std::wstring& wrapper);
    130 
    131 private:
    132  friend class InProcessBrowserTest;
    133 
    134  CommandLine() {}
    135 
    136  // Used by InProcessBrowserTest.
    137  static CommandLine* ForCurrentProcessMutable() {
    138    DCHECK(current_process_commandline_);
    139    return current_process_commandline_;
    140  }
    141 
    142  // The singleton CommandLine instance representing the current process's
    143  // command line.
    144  static CommandLine* current_process_commandline_;
    145 
    146  // We store a platform-native version of the command line, used when building
    147  // up a new command line to be executed.  This ifdef delimits that code.
    148 
    149 #if defined(XP_WIN)
    150  // The quoted, space-separated command-line string.
    151  std::wstring command_line_string_;
    152 
    153  // The name of the program.
    154  std::wstring program_;
    155 
    156  // The type of native command line arguments.
    157  typedef std::wstring StringType;
    158 
    159 #else
    160  // The argv array, with the program name in argv_[0].
    161  std::vector<std::string> argv_;
    162 
    163  // The type of native command line arguments.
    164  typedef std::string StringType;
    165 
    166  // Shared by the two POSIX constructor forms.  Initalize from argv_.
    167  void InitFromArgv();
    168 #endif
    169 
    170  // Returns true and fills in |switch_string| and |switch_value|
    171  // if |parameter_string| represents a switch.
    172  static bool IsSwitch(const StringType& parameter_string,
    173                       std::string* switch_string, StringType* switch_value);
    174 
    175  // Parsed-out values.
    176  std::map<std::string, StringType> switches_;
    177 
    178  // Non-switch command-line arguments.
    179  std::vector<StringType> loose_values_;
    180 
    181  // We allow copy constructors, because a common pattern is to grab a
    182  // copy of the current process's command line and then add some
    183  // flags to it.  E.g.:
    184  //   CommandLine cl(*CommandLine::ForCurrentProcess());
    185  //   cl.AppendSwitch(...);
    186 };
    187 
    188 #endif  // BASE_COMMAND_LINE_H_