command_line.h revision 731df977c0511bca2206b5f333555b1205ff1f43
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 saved as extra arguments.  An argument of "--"
9// will terminate switch parsing, causing everything after to be
10// considered as extra arguments.
11
12// There is a singleton read-only CommandLine that represents the command
13// line that the current process was started with.  It must be initialized
14// in main() (or whatever the platform's equivalent function is).
15
16#ifndef BASE_COMMAND_LINE_H_
17#define BASE_COMMAND_LINE_H_
18#pragma once
19
20#include "build/build_config.h"
21
22#include <map>
23#include <string>
24#include <vector>
25
26#include "base/basictypes.h"
27
28class FilePath;
29class InProcessBrowserTest;
30
31class CommandLine {
32 public:
33  // A constructor for CommandLines that are used only to carry switches and
34  // arguments.
35  enum NoProgram { NO_PROGRAM };
36  explicit CommandLine(NoProgram no_program);
37  ~CommandLine();
38
39#if defined(OS_WIN)
40  // The type of native command line arguments.
41  typedef std::wstring StringType;
42
43  // Initialize by parsing the given command-line string.
44  // The program name is assumed to be the first item in the string.
45  void ParseFromString(const std::wstring& command_line);
46  static CommandLine FromString(const std::wstring& command_line);
47#elif defined(OS_POSIX)
48  // The type of native command line arguments.
49  typedef std::string StringType;
50
51  // Initialize from an argv vector.
52  void InitFromArgv(int argc, const char* const* argv);
53  void InitFromArgv(const std::vector<std::string>& argv);
54
55  CommandLine(int argc, const char* const* argv);
56  explicit CommandLine(const std::vector<std::string>& argv);
57#endif
58
59  // Construct a new, empty command line.
60  // |program| is the name of the program to run (aka argv[0]).
61  explicit CommandLine(const FilePath& program);
62
63  // Initialize the current process CommandLine singleton.  On Windows,
64  // ignores its arguments (we instead parse GetCommandLineW()
65  // directly) because we don't trust the CRT's parsing of the command
66  // line, but it still must be called to set up the command line.
67  static void Init(int argc, const char* const* argv);
68
69#if defined(OS_POSIX) && !defined(OS_MACOSX)
70  // Sets the current process' arguments that show in "ps" etc. to those
71  // in |current_process_commandline_|. Used by the zygote host so that
72  // renderers show up with --type=renderer.
73  static void SetProcTitle();
74#endif
75
76  // Destroys the current process CommandLine singleton. This is necessary if
77  // you want to reset the base library to its initial state (for example in an
78  // outer library that needs to be able to terminate, and be re-initialized).
79  // If Init is called only once, e.g. in main(), calling Reset() is not
80  // necessary.
81  static void Reset();
82
83  // Get the singleton CommandLine representing the current process's
84  // command line.  Note: returned value is mutable, but not thread safe;
85  // only mutate if you know what you're doing!
86  static CommandLine* ForCurrentProcess();
87
88  // Returns true if this command line contains the given switch.
89  // (Switch names are case-insensitive.)
90  bool HasSwitch(const std::string& switch_string) const;
91
92  // Returns the value associated with the given switch.  If the
93  // switch has no value or isn't present, this method returns
94  // the empty string.
95  std::string GetSwitchValueASCII(const std::string& switch_string) const;
96  FilePath GetSwitchValuePath(const std::string& switch_string) const;
97  StringType GetSwitchValueNative(const std::string& switch_string) const;
98
99  // Get the number of switches in this process.
100  size_t GetSwitchCount() const { return switches_.size(); }
101
102  // The type of map for parsed-out switch key and values.
103  typedef std::map<std::string, StringType> SwitchMap;
104
105  // Get a copy of all switches, along with their values
106  const SwitchMap& GetSwitches() const {
107    return switches_;
108  }
109
110  // Get the remaining arguments to the command.
111  const std::vector<StringType>& args() const { return args_; }
112
113#if defined(OS_WIN)
114  // Returns the original command line string.
115  const std::wstring& command_line_string() const {
116    return command_line_string_;
117  }
118#elif defined(OS_POSIX)
119  // Returns the original command line string as a vector of strings.
120  const std::vector<std::string>& argv() const {
121    return argv_;
122  }
123  // Try to match the same result as command_line_string() would get you
124  // on windows.
125  std::string command_line_string() const;
126#endif
127
128  // Returns the program part of the command line string (the first item).
129  FilePath GetProgram() const;
130
131  // Append a switch to the command line.
132  void AppendSwitch(const std::string& switch_string);
133
134  // Append a switch and value to the command line.
135  void AppendSwitchPath(const std::string& switch_string, const FilePath& path);
136  void AppendSwitchNative(const std::string& switch_string,
137                          const StringType& value);
138  void AppendSwitchASCII(const std::string& switch_string,
139                         const std::string& value);
140
141  // Append an argument to the command line.
142  // Note on quoting: the argument will be quoted properly such that it is
143  // interpreted as one argument to the target command.
144  // AppendArg is primarily for ASCII; non-ASCII input will be
145  // interpreted as UTF-8.
146  void AppendArg(const std::string& value);
147  void AppendArgPath(const FilePath& value);
148  void AppendArgNative(const StringType& value);
149
150  // Append the arguments from another command line to this one.
151  // If |include_program| is true, include |other|'s program as well.
152  void AppendArguments(const CommandLine& other,
153                       bool include_program);
154
155  // Insert a command before the current command.  Common for debuggers,
156  // like "valgrind" or "gdb --args".
157  void PrependWrapper(const StringType& wrapper);
158
159  // Copy a set of switches (and their values, if any) from another command
160  // line.  Commonly used when launching a subprocess.
161  void CopySwitchesFrom(const CommandLine& source, const char* const switches[],
162                        size_t count);
163
164  // APIs that work with wstrings are deprecated.
165  // TODO(evanm): remove all of these.
166#if defined(OS_WIN)
167  // Deprecated on non-Windows.
168  bool HasSwitch(const std::wstring& switch_string) const;
169#endif
170
171 private:
172  friend class InProcessBrowserTest;
173
174  CommandLine();
175
176  // Used by InProcessBrowserTest.
177  static CommandLine* ForCurrentProcessMutable();
178
179  // The singleton CommandLine instance representing the current process's
180  // command line.
181  static CommandLine* current_process_commandline_;
182
183  // We store a platform-native version of the command line, used when building
184  // up a new command line to be executed.  This ifdef delimits that code.
185
186#if defined(OS_WIN)
187  // The quoted, space-separated command-line string.
188  std::wstring command_line_string_;
189  // The name of the program.
190  std::wstring program_;
191#elif defined(OS_POSIX)
192  // The argv array, with the program name in argv_[0].
193  std::vector<std::string> argv_;
194#endif
195
196  // Returns true and fills in |switch_string| and |switch_value|
197  // if |parameter_string| represents a switch.
198  static bool IsSwitch(const StringType& parameter_string,
199                       std::string* switch_string,
200                       StringType* switch_value);
201
202  // Parsed-out values.
203  SwitchMap switches_;
204
205  // Non-switch command-line arguments.
206  std::vector<StringType> args_;
207
208  // We allow copy constructors, because a common pattern is to grab a
209  // copy of the current process's command line and then add some
210  // flags to it.  E.g.:
211  //   CommandLine cl(*CommandLine::ForCurrentProcess());
212  //   cl.AppendSwitch(...);
213};
214
215#endif  // BASE_COMMAND_LINE_H_
216