command_line.h revision c7f5f8508d98d5952d42ed7648c2a8f30a4da156
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
31class InProcessBrowserTest;
32
33class 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