Index: base/command_line_parser.cc |
diff --git a/base/command_line_parser.cc b/base/command_line_parser.cc |
deleted file mode 100644 |
index c52c0a38668f28e5584d0dcec241803ddf43c78b..0000000000000000000000000000000000000000 |
--- a/base/command_line_parser.cc |
+++ /dev/null |
@@ -1,389 +0,0 @@ |
-// Copyright 2008-2009 Google Inc. |
-// |
-// Licensed under the Apache License, Version 2.0 (the "License"); |
-// you may not use this file except in compliance with the License. |
-// You may obtain a copy of the License at |
-// |
-// http://www.apache.org/licenses/LICENSE-2.0 |
-// |
-// Unless required by applicable law or agreed to in writing, software |
-// distributed under the License is distributed on an "AS IS" BASIS, |
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
-// See the License for the specific language governing permissions and |
-// limitations under the License. |
-// ======================================================================== |
- |
-#include "omaha/base/command_line_parser.h" |
-#include "omaha/base/command_line_parser_internal.h" |
-#include <shellapi.h> |
-#include "omaha/base/debug.h" |
-#include "omaha/base/error.h" |
-#include "omaha/base/logging.h" |
-#include "omaha/base/path.h" |
- |
-namespace omaha { |
- |
-namespace internal { |
- |
-void CommandLineParserArgs::Reset() { |
- switch_arguments_.clear(); |
-} |
- |
-// Assumes switch_name is already lower case. |
-HRESULT CommandLineParserArgs::AddSwitch(const CString& switch_name) { |
- ASSERT1(CString(switch_name).MakeLower().Compare(switch_name) == 0); |
- if (switch_arguments_.find(switch_name) != switch_arguments_.end()) { |
- return E_INVALIDARG; |
- } |
- |
- StringVector string_vector; |
- switch_arguments_[switch_name] = string_vector; |
- return S_OK; |
-} |
- |
-// Assumes switch_name is already lower case. |
-HRESULT CommandLineParserArgs::AddSwitchArgument(const CString& switch_name, |
- const CString& value) { |
- ASSERT1(CString(switch_name).MakeLower().Compare(switch_name) == 0); |
- ASSERT1(!switch_name.IsEmpty()); |
- if (switch_name.IsEmpty()) { |
- // We don't have a switch yet, so this is just a base argument. |
- // Example command line: "foo.exe myarg /someswitch" |
- // Here, myarg would be a base argument. |
- // TODO(omaha): base_args_.push_back(switch_name_str); |
- return E_INVALIDARG; |
- } |
- |
- SwitchAndArgumentsMap::iterator iter = switch_arguments_.find(switch_name); |
- if (iter == switch_arguments_.end()) { |
- return E_UNEXPECTED; |
- } |
- (*iter).second.push_back(value); |
- |
- return S_OK; |
-} |
- |
-int CommandLineParserArgs::GetSwitchCount() const { |
- return switch_arguments_.size(); |
-} |
- |
-bool CommandLineParserArgs::HasSwitch(const CString& switch_name) const { |
- CString switch_name_lower = switch_name; |
- switch_name_lower.MakeLower(); |
- return switch_arguments_.find(switch_name_lower) != switch_arguments_.end(); |
-} |
- |
-// The value at a particular index may change if switch_names are added |
-// since we're using a map underneath. But this keeps us from having to write |
-// an interator and expose it externally. |
-HRESULT CommandLineParserArgs::GetSwitchNameAtIndex(int index, |
- CString* name) const { |
- ASSERT1(name); |
- |
- if (index >= static_cast<int>(switch_arguments_.size())) { |
- return E_INVALIDARG; |
- } |
- |
- SwitchAndArgumentsMapIter iter = switch_arguments_.begin(); |
- for (int i = 0; i < index; ++i) { |
- ++iter; |
- } |
- |
- *name = (*iter).first; |
- |
- return S_OK; |
-} |
- |
-HRESULT CommandLineParserArgs::GetSwitchArgumentCount( |
- const CString& switch_name, |
- int* count) const { |
- ASSERT1(count); |
- |
- CString switch_name_lower = switch_name; |
- switch_name_lower.MakeLower(); |
- |
- SwitchAndArgumentsMapIter iter = switch_arguments_.find(switch_name_lower); |
- if (iter == switch_arguments_.end()) { |
- return E_INVALIDARG; |
- } |
- |
- *count = (*iter).second.size(); |
- return S_OK; |
-} |
- |
-HRESULT CommandLineParserArgs::GetSwitchArgumentValue( |
- const CString& switch_name, |
- int argument_index, |
- CString* argument_value) const { |
- ASSERT1(argument_value); |
- |
- CString switch_name_lower = switch_name; |
- switch_name_lower.MakeLower(); |
- |
- int count = 0; |
- HRESULT hr = GetSwitchArgumentCount(switch_name_lower, &count); |
- if (FAILED(hr)) { |
- return hr; |
- } |
- |
- if (argument_index >= count) { |
- return E_INVALIDARG; |
- } |
- |
- SwitchAndArgumentsMapIter iter = switch_arguments_.find(switch_name_lower); |
- if (iter == switch_arguments_.end()) { |
- return E_INVALIDARG; |
- } |
- |
- *argument_value = (*iter).second[argument_index]; |
- return S_OK; |
-} |
- |
-} // namespace internal |
- |
-CommandLineParser::CommandLineParser() { |
- required_args_.reset(new internal::CommandLineParserArgs); |
- optional_args_.reset(new internal::CommandLineParserArgs); |
-} |
- |
-CommandLineParser::~CommandLineParser() { |
-} |
- |
-HRESULT CommandLineParser::ParseFromString(const wchar_t* command_line) { |
- CString command_line_str(command_line); |
- command_line_str.Trim(_T(" ")); |
- |
- if (command_line_str.IsEmpty()) { |
- // If the first arg to CommandLineToArgvW "is an empty string the function |
- // returns the path to the current executable file." However, it does not |
- // correctly handle the case when the path contains spaces - it breaks the |
- // path up into separate argv elements. To avoid issues while maintaining |
- // the expected behavior, manually get the command line in the empty case. |
- // See http://msdn.microsoft.com/en-us/library/bb776391.aspx. |
- VERIFY1(::GetModuleFileName(NULL, |
- CStrBuf(command_line_str, MAX_PATH), |
- MAX_PATH)); |
- EnclosePath(&command_line_str); |
- } |
- |
- int argc = 0; |
- wchar_t** argv = ::CommandLineToArgvW(command_line_str, &argc); |
- if (!argv) { |
- return HRESULTFromLastError(); |
- } |
- |
- HRESULT hr = ParseFromArgv(argc, argv); |
- ::LocalFree(argv); |
- return hr; |
-} |
- |
-// TODO(Omaha): Move the rule parser into a separate class. |
-// TODO(Omaha): Fail the regular command parser if [/ switch is passed. |
-// ParseFromArgv parses either a rule or a command line. |
-// |
-// Rules have required and optional parameters. An example of a rule is: |
-// "gu.exe /install <extraargs> [/oem [/appargs <appargs> [/silent" |
-// This creates a rule for a command line that requires "/install" for the rule |
-// to match. The other parameters are optional, indicated by prefixes of "[/". |
-// |
-// Command lines do not use "[/", and use "/" for all parameters. |
-// A command line that looks like this: |
-// "gu.exe /install <extraargs> /oem /appargs <appargs>" |
-// will match the rule above. |
-HRESULT CommandLineParser::ParseFromArgv(int argc, wchar_t** argv) { |
- if (argc == 0 || !argv) { |
- return E_INVALIDARG; |
- } |
- |
- Reset(); |
- |
- if (argc == 1) { |
- // We only have the program name. So, we're done parsing. |
- ASSERT1(!IsSwitch(argv[0])); |
- return S_OK; |
- } |
- |
- CString current_switch_name; |
- bool is_optional_switch = false; |
- |
- // Start parsing at the first argument after the program name (index 1). |
- for (int i = 1; i < argc; ++i) { |
- HRESULT hr = S_OK; |
- CString token = argv[i]; |
- token.Trim(_T(" ")); |
- if (IsSwitch(token)) { |
- hr = StripSwitchNameFromArgv(token, ¤t_switch_name); |
- if (FAILED(hr)) { |
- return hr; |
- } |
- hr = AddSwitch(current_switch_name); |
- if (FAILED(hr)) { |
- CORE_LOG(LE, (_T("[AddSwitch failed][%s][0x%x]"), |
- current_switch_name, hr)); |
- return hr; |
- } |
- is_optional_switch = false; |
- } else if (IsOptionalSwitch(token)) { |
- hr = StripOptionalSwitchNameFromArgv(token, ¤t_switch_name); |
- if (FAILED(hr)) { |
- return hr; |
- } |
- hr = AddOptionalSwitch(current_switch_name); |
- if (FAILED(hr)) { |
- CORE_LOG(LE, (_T("[AddOptionalSwitch failed][%s][0x%x]"), |
- current_switch_name, hr)); |
- return hr; |
- } |
- is_optional_switch = true; |
- } else { |
- hr = is_optional_switch ? |
- AddOptionalSwitchArgument(current_switch_name, token) : |
- AddSwitchArgument(current_switch_name, token); |
- |
- if (FAILED(hr)) { |
- CORE_LOG(LE, (_T("[Adding switch argument failed][%d][%s][%s][0x%x]"), |
- is_optional_switch, current_switch_name, token, hr)); |
- return hr; |
- } |
- } |
- } |
- |
- return S_OK; |
-} |
- |
-bool CommandLineParser::IsSwitch(const CString& param) const { |
- // Switches must have a prefix (/) or (-), and at least one character. |
- if (param.GetLength() < 2) { |
- return false; |
- } |
- |
- // All switches must start with / or -, and not contain any spaces. |
- // Since the argv parser strips out the enclosing quotes around an argument, |
- // we need to handle the following cases properly: |
- // * foo.exe /switch arg -- /switch is a switch, arg is an arg |
- // * foo.exe /switch "/x y" -- /switch is a switch, '/x y' is an arg and it |
- // will get here _without_ the quotes. |
- // If param_str starts with / and contains no spaces, then it's a switch. |
- return ((param[0] == _T('/')) || (param[0] == _T('-'))) && |
- (param.Find(_T(" ")) == -1) && |
- (param.Find(_T("%20")) == -1); |
-} |
- |
-bool CommandLineParser::IsOptionalSwitch(const CString& param) const { |
- // Optional switches must have a prefix ([/) or ([-), and at least one |
- // character. |
- return param[0] == _T('[') && IsSwitch(param.Right(param.GetLength() - 1)); |
-} |
- |
-HRESULT CommandLineParser::StripSwitchNameFromArgv(const CString& param, |
- CString* switch_name) { |
- ASSERT1(switch_name); |
- |
- if (!IsSwitch(param)) { |
- return E_INVALIDARG; |
- } |
- |
- *switch_name = param.Right(param.GetLength() - 1); |
- switch_name->Trim(_T(" ")); |
- switch_name->MakeLower(); |
- return S_OK; |
-} |
- |
-HRESULT CommandLineParser::StripOptionalSwitchNameFromArgv(const CString& param, |
- CString* name) { |
- ASSERT1(name); |
- |
- if (!IsOptionalSwitch(param)) { |
- return E_INVALIDARG; |
- } |
- |
- return StripSwitchNameFromArgv(param.Right(param.GetLength() - 1), name); |
-} |
- |
-void CommandLineParser::Reset() { |
- required_args_->Reset(); |
- optional_args_->Reset(); |
-} |
- |
-HRESULT CommandLineParser::AddSwitch(const CString& switch_name) { |
- ASSERT1(switch_name == CString(switch_name).MakeLower()); |
- return required_args_->AddSwitch(switch_name); |
-} |
- |
-HRESULT CommandLineParser::AddSwitchArgument(const CString& switch_name, |
- const CString& argument_value) { |
- ASSERT1(switch_name == CString(switch_name).MakeLower()); |
- return required_args_->AddSwitchArgument(switch_name, argument_value); |
-} |
- |
-int CommandLineParser::GetSwitchCount() const { |
- return required_args_->GetSwitchCount(); |
-} |
- |
-bool CommandLineParser::HasSwitch(const CString& switch_name) const { |
- return required_args_->HasSwitch(switch_name); |
-} |
- |
-// The value at a particular index may change if switch_names are added |
-// since we're using a map underneath. But this keeps us from having to write |
-// an interator and expose it externally. |
-HRESULT CommandLineParser::GetSwitchNameAtIndex(int index, |
- CString* switch_name) const { |
- return required_args_->GetSwitchNameAtIndex(index, switch_name); |
-} |
- |
-HRESULT CommandLineParser::GetSwitchArgumentCount(const CString& switch_name, |
- int* count) const { |
- return required_args_->GetSwitchArgumentCount(switch_name, count); |
-} |
- |
-HRESULT CommandLineParser::GetSwitchArgumentValue( |
- const CString& switch_name, |
- int argument_index, |
- CString* argument_value) const { |
- return required_args_->GetSwitchArgumentValue(switch_name, |
- argument_index, |
- argument_value); |
-} |
- |
-HRESULT CommandLineParser::AddOptionalSwitch(const CString& switch_name) { |
- ASSERT1(switch_name == CString(switch_name).MakeLower()); |
- return optional_args_->AddSwitch(switch_name); |
-} |
- |
-HRESULT CommandLineParser::AddOptionalSwitchArgument(const CString& switch_name, |
- const CString& value) { |
- ASSERT1(switch_name == CString(switch_name).MakeLower()); |
- return optional_args_->AddSwitchArgument(switch_name, value); |
-} |
- |
-int CommandLineParser::GetOptionalSwitchCount() const { |
- return optional_args_->GetSwitchCount(); |
-} |
- |
-bool CommandLineParser::HasOptionalSwitch(const CString& switch_name) const { |
- return optional_args_->HasSwitch(switch_name); |
-} |
- |
-// The value at a particular index may change if switch_names are added |
-// since we're using a map underneath. But this keeps us from having to write |
-// an interator and expose it externally. |
-HRESULT CommandLineParser::GetOptionalSwitchNameAtIndex(int index, |
- CString* name) const { |
- return optional_args_->GetSwitchNameAtIndex(index, name); |
-} |
- |
-HRESULT CommandLineParser::GetOptionalSwitchArgumentCount(const CString& name, |
- int* count) const { |
- return optional_args_->GetSwitchArgumentCount(name, count); |
-} |
- |
-HRESULT CommandLineParser::GetOptionalSwitchArgumentValue(const CString& name, |
- int argument_index, |
- CString* val) const { |
- return optional_args_->GetSwitchArgumentValue(name, |
- argument_index, |
- val); |
-} |
- |
-} // namespace omaha |