diff options
Diffstat (limited to 'base/command_line.h')
-rw-r--r-- | base/command_line.h | 159 |
1 files changed, 100 insertions, 59 deletions
diff --git a/base/command_line.h b/base/command_line.h index 56aa2fc..f1a2005 100644 --- a/base/command_line.h +++ b/base/command_line.h @@ -2,46 +2,60 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// This file contains a class that can be used to extract the salient -// elements of a command line in a relatively lightweight manner. +// This class works with command lines: building and parsing. // Switches can optionally have a value attached using an equals sign, // as in "-switch=value". Arguments that aren't prefixed with a -// switch prefix are considered "loose parameters". Switch names -// are case-insensitive. An argument of "--" will terminate switch parsing, -// causing everything after to be considered as loose parameters. +// switch prefix are considered "loose parameters". Switch names are +// case-insensitive. An argument of "--" will terminate switch +// parsing, causing everything after to be considered as loose +// parameters. + +// There is a singleton read-only CommandLine that represents the command +// line that the current process was started with. It must be initialized +// in main() (or whatever the platform's equivalent function is). #ifndef BASE_COMMAND_LINE_H_ #define BASE_COMMAND_LINE_H_ +#include "build/build_config.h" + #include <map> #include <string> #include <vector> #include "base/basictypes.h" +#include "base/logging.h" #include "base/scoped_ptr.h" class CommandLine { public: - // Creates a parsed version of the command line used to launch - // the current process. - CommandLine(); - #if defined(OS_WIN) // Creates a parsed version of the given command-line string. - // The program name is assumed to be the first item in the string. - CommandLine(const std::wstring& command_line); + // The program name is assumed to be the first item in the string. + void ParseFromString(const std::wstring& command_line); #elif defined(OS_POSIX) + // Initialize from an argv vector (or directly from main()'s argv). CommandLine(int argc, const char* const* argv); - CommandLine(const std::vector<std::string>& argv); + explicit CommandLine(const std::vector<std::string>& argv); #endif - ~CommandLine(); + // Construct a new, empty command line. + // |program| is the name of the program to run (aka argv[0]). + // TODO(port): should be a FilePath. + explicit CommandLine(const std::wstring& program); + + // Initialize the current process CommandLine singleton. On Windows, + // ignores its arguments (we instead parse GetCommandLineW() + // directly) because we don't trust the CRT's parsing of the command + // line, but it still must be called to set up the command line. + static void Init(int argc, const char* const* argv); - // On non-Windows platforms, main() must call SetArgcArgv() before accessing - // any members of this class. - // On Windows, this call is a no-op (we instead parse GetCommandLineW() - // directly) because we don't trust the CRT's parsing of the command line. - static void SetArgcArgv(int argc, const char* const* argv); + // Get the singleton CommandLine representing the current process's + // command line. + static const CommandLine* ForCurrentProcess() { + DCHECK(current_process_commandline_); + return current_process_commandline_; + } // Returns true if this command line contains the given switch. // (Switch names are case-insensitive.) @@ -52,40 +66,25 @@ class CommandLine { // the empty string. std::wstring GetSwitchValue(const std::wstring& switch_string) const; - // Returns the number of "loose values" found in the command line. - // Loose values are arguments that aren't switches. - // (The program name is also excluded from the set of loose values.) - size_t GetLooseValueCount() const; - - typedef std::vector<std::wstring>::const_iterator LooseValueIterator; - - // Returns a const_iterator to the list of loose values. - LooseValueIterator GetLooseValuesBegin() const; - - // Returns the end const_iterator for the list of loose values. - LooseValueIterator GetLooseValuesEnd() const; + // Get the remaining arguments to the command. + // WARNING: this is incorrect on POSIX; we must do string conversions. + std::vector<std::wstring> GetLooseValues() const; - // Simply returns the original command line string. - std::wstring command_line_string() const; - -#if defined(OS_POSIX) +#if defined(OS_WIN) + // Returns the original command line string. + const std::wstring& command_line_string() const { + return command_line_string_; + } +#elif defined(OS_POSIX) // Returns the original command line string as a vector of strings. - const std::vector<std::string>& argv() const; + const std::vector<std::string>& argv() const { + return argv_; + } #endif // Returns the program part of the command line string (the first item). std::wstring program() const; - // An array containing the prefixes that identify an argument as - // a switch. - static const wchar_t* const kSwitchPrefixes[]; - - // The string that's used to separate switches from their values. - static const wchar_t kSwitchValueSeparator[]; - - // Treat everything after this argument as loose parameters. - static const wchar_t kSwitchTerminator[]; - // Return a copy of the string prefixed with a switch prefix. // Used internally. static std::wstring PrefixedSwitchString(const std::wstring& switch_string); @@ -98,27 +97,69 @@ class CommandLine { // Appends the given switch string (preceded by a space and a switch // prefix) to the given string. - static void AppendSwitch(std::wstring* command_line_string, - const std::wstring& switch_string); + void AppendSwitch(const std::wstring& switch_string); // Appends the given switch string (preceded by a space and a switch // prefix) to the given string, with the given value attached. - static void AppendSwitchWithValue(std::wstring* command_line_string, - const std::wstring& switch_string, - const std::wstring& value_string); + void AppendSwitchWithValue(const std::wstring& switch_string, + const std::wstring& value_string); + + // Append a loose value to the command line. + void AppendLooseValue(const std::wstring& value); + + // Append the arguments from another command line to this one. + // If |include_program| is true, include |other|'s program as well. + void AppendArguments(const CommandLine& other, + bool include_program); private: - class Data; + CommandLine() {} + + // The singleton CommandLine instance representing the current process's + // command line. + static CommandLine* current_process_commandline_; + + // We store a platform-native version of the command line, used when building + // up a new command line to be executed. This ifdef delimits that code. + +#if defined(OS_WIN) + // The quoted, space-separated command-line string. + std::wstring command_line_string_; + + // The name of the program. + std::wstring program_; + + // The type of native command line arguments. + typedef std::wstring StringType; + +#elif defined(OS_POSIX) + // The argv array, with the program name in argv_[0]. + std::vector<std::string> argv_; + + // The type of native command line arguments. + typedef std::string StringType; + + // Shared by the two POSIX constructor forms. Initalize from argv_. + void InitFromArgv(); +#endif + + // Returns true and fills in |switch_string| and |switch_value| + // if |parameter_string| represents a switch. + static bool IsSwitch(const StringType& parameter_string, + std::string* switch_string, + StringType* switch_value); + + // Parsed-out values. + std::map<std::string, StringType> switches_; - // True if we are responsible for deleting our |data_| pointer. In some cases - // we cache the result of parsing the command line and |data_|'s lifetime is - // managed by someone else (e.g., the |Singleton| class). - bool we_own_data_; + // Non-switch command-line arguments. + std::vector<StringType> loose_values_; - // A pointer to the parsed version of the command line. - Data* data_; - - DISALLOW_EVIL_CONSTRUCTORS(CommandLine); + // We allow copy constructors, because a common pattern is to grab a + // copy of the current process's command line and then add some + // flags to it. E.g.: + // CommandLine cl(*CommandLine::ForCurrentProcess()); + // cl.AppendSwitch(...); }; #endif // BASE_COMMAND_LINE_H_ |