command_line.h revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This class works with command lines: building and parsing.
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Switches can optionally have a value attached using an equals sign,
7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// as in "-switch=value".  Arguments that aren't prefixed with a
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// switch prefix are saved as extra arguments.  An argument of "--"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// will terminate switch parsing, causing everything after to be
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// considered as extra arguments.
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// There is a singleton read-only CommandLine that represents the command
13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// line that the current process was started with.  It must be initialized
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// in main() (or whatever the platform's equivalent function is).
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef BASE_COMMAND_LINE_H_
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define BASE_COMMAND_LINE_H_
183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "build/build_config.h"
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <map>
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string>
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <vector>
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/basictypes.h"
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass FilePath;
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass InProcessBrowserTest;
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass CommandLine {
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public:
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // A constructor for CommandLines that are used only to carry arguments.
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  enum ArgumentsOnly { ARGUMENTS_ONLY };
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  explicit CommandLine(ArgumentsOnly args_only);
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ~CommandLine();
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN)
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The type of native command line arguments.
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef std::wstring StringType;
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Initialize by parsing the given command-line string.
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The program name is assumed to be the first item in the string.
44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void ParseFromString(const std::wstring& command_line);
453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  static CommandLine FromString(const std::wstring& command_line);
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#elif defined(OS_POSIX)
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The type of native command line arguments.
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef std::string StringType;
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Initialize from an argv vector.
51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void InitFromArgv(int argc, const char* const* argv);
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void InitFromArgv(const std::vector<std::string>& argv);
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CommandLine(int argc, const char* const* argv);
553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  explicit CommandLine(const std::vector<std::string>& argv);
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Construct a new, empty command line.
59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // |program| is the name of the program to run (aka argv[0]).
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  explicit CommandLine(const FilePath& program);
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Initialize the current process CommandLine singleton.  On Windows,
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // ignores its arguments (we instead parse GetCommandLineW()
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // directly) because we don't trust the CRT's parsing of the command
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // line, but it still must be called to set up the command line.
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static void Init(int argc, const char* const* argv);
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_POSIX) && !defined(OS_MACOSX)
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Sets the current process' arguments that show in "ps" etc. to those
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // in |current_process_commandline_|. Used by the zygote host so that
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // renderers show up with --type=renderer.
72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static void SetProcTitle();
73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Destroys the current process CommandLine singleton. This is necessary if
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // you want to reset the base library to its initial state (for example in an
77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // outer library that needs to be able to terminate, and be re-initialized).
78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // If Init is called only once, e.g. in main(), calling Reset() is not
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // necessary.
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static void Reset();
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Get the singleton CommandLine representing the current process's
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // command line.  Note: returned value is mutable, but not thread safe;
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // only mutate if you know what you're doing!
853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  static CommandLine* ForCurrentProcess();
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Returns true if this command line contains the given switch.
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // (Switch names are case-insensitive.)
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bool HasSwitch(const std::string& switch_string) const;
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Returns the value associated with the given switch.  If the
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // switch has no value or isn't present, this method returns
93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // the empty string.
943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string GetSwitchValueASCII(const std::string& switch_string) const;
953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  FilePath GetSwitchValuePath(const std::string& switch_string) const;
963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  StringType GetSwitchValueNative(const std::string& switch_string) const;
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Get the number of switches in this process.
99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  size_t GetSwitchCount() const { return switches_.size(); }
100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The type of map for parsed-out switch key and values.
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef std::map<std::string, StringType> SwitchMap;
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Get a copy of all switches, along with their values
1053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const SwitchMap& GetSwitches() const {
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return switches_;
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Get the remaining arguments to the command.
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const std::vector<StringType>& args() const { return args_; }
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN)
113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Returns the original command line string.
114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const std::wstring& command_line_string() const {
115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return command_line_string_;
116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#elif defined(OS_POSIX)
118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Returns the original command line string as a vector of strings.
119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const std::vector<std::string>& argv() const {
120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return argv_;
121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Try to match the same result as command_line_string() would get you
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // on windows.
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string command_line_string() const;
125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Returns the program part of the command line string (the first item).
1283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  FilePath GetProgram() const;
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Append a switch to the command line.
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void AppendSwitch(const std::string& switch_string);
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Append a switch and value to the command line.
1343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void AppendSwitchPath(const std::string& switch_string, const FilePath& path);
1353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void AppendSwitchNative(const std::string& switch_string,
1363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                          const StringType& value);
1373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void AppendSwitchASCII(const std::string& switch_string,
1383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         const std::string& value);
1393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Append an argument to the command line.
1413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Note on quoting: the argument will be quoted properly such that it is
1423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // interpreted as one argument to the target command.
1433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // AppendArg is primarily for ASCII; non-ASCII input will be
1443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // interpreted as UTF-8.
1453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void AppendArg(const std::string& value);
1463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void AppendArgPath(const FilePath& value);
1473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void AppendArgNative(const StringType& value);
148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Append the arguments from another command line to this one.
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // If |include_program| is true, include |other|'s program as well.
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  void AppendArguments(const CommandLine& other,
152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                       bool include_program);
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Insert a command before the current command.  Common for debuggers,
1553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // like "valgrind" or "gdb --args".
1563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void PrependWrapper(const StringType& wrapper);
1573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Copy a set of switches (and their values, if any) from another command
1593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // line.  Commonly used when launching a subprocess.
1603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void CopySwitchesFrom(const CommandLine& source, const char* const switches[],
1613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        size_t count);
1623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // APIs that work with wstrings are deprecated.
1643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // TODO(evanm): remove all of these.
1653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::wstring GetSwitchValue(const std::string& switch_string) const;
1663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::wstring GetSwitchValue(const std::wstring& switch_string) const;
1673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::wstring program() const;
1683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#if defined(OS_WIN)
1693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Deprecated on non-Windows.
1703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool HasSwitch(const std::wstring& switch_string) const;
1713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#endif
172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private:
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  friend class InProcessBrowserTest;
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CommandLine();
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Used by InProcessBrowserTest.
1793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  static CommandLine* ForCurrentProcessMutable();
180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The singleton CommandLine instance representing the current process's
182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // command line.
183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static CommandLine* current_process_commandline_;
184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We store a platform-native version of the command line, used when building
186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // up a new command line to be executed.  This ifdef delimits that code.
187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN)
189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The quoted, space-separated command-line string.
190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::wstring command_line_string_;
191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The name of the program.
192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::wstring program_;
193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#elif defined(OS_POSIX)
194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // The argv array, with the program name in argv_[0].
195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  std::vector<std::string> argv_;
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Returns true and fills in |switch_string| and |switch_value|
199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // if |parameter_string| represents a switch.
200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  static bool IsSwitch(const StringType& parameter_string,
201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                       std::string* switch_string,
202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                       StringType* switch_value);
203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Parsed-out values.
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SwitchMap switches_;
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // Non-switch command-line arguments.
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<StringType> args_;
209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // We allow copy constructors, because a common pattern is to grab a
211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // copy of the current process's command line and then add some
212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  // flags to it.  E.g.:
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //   CommandLine cl(*CommandLine::ForCurrentProcess());
214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  //   cl.AppendSwitch(...);
215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif  // BASE_COMMAND_LINE_H_
218