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); FromString(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 CommandLine(int argc,const char * const * argv)53 CommandLine(int argc, const char* const* argv) { 54 InitFromArgv(argc, argv); 55 } CommandLine(const std::vector<std::string> & argv)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. Terminate()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! ForCurrentProcess()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. HasSwitch(const std::wstring & switch_string)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. GetSwitchValueASCII(const std::string & switch_string)110 std::string GetSwitchValueASCII(const std::string& switch_string) const { 111 return WideToASCII(GetSwitchValue(switch_string)); 112 } GetSwitchValuePath(const std::string & switch_string)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; GetSwitchValue(const std::wstring & switch_string)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. GetSwitchCount()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. 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. argv()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). GetProgram()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); AppendSwitchWithValue(const std::string & switch_string,const std::string & 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 CommandLine()189 CommandLine() {} 190 191 // Used by InProcessBrowserTest. ForCurrentProcessMutable()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