vcpkg/toolsrc/src/VcpkgCmdArguments.cpp

227 lines
8.0 KiB
C++
Raw Normal View History

2017-01-28 04:49:09 +08:00
#include "pch.h"
2017-04-28 09:08:52 +08:00
#include "VcpkgCmdArguments.h"
2016-09-19 11:50:08 +08:00
#include "metrics.h"
2017-04-28 09:08:52 +08:00
#include "vcpkg_Commands.h"
2016-09-19 11:50:08 +08:00
#include "vcpkg_System.h"
namespace vcpkg
{
2017-04-28 09:08:52 +08:00
static void parse_value(const std::string* arg_begin,
const std::string* arg_end,
const std::string& option_name,
std::unique_ptr<std::string>& option_field)
2016-09-19 11:50:08 +08:00
{
if (arg_begin == arg_end)
{
2017-04-04 07:31:00 +08:00
System::println(System::Color::error, "Error: expected value after %s", option_name);
2017-04-04 05:41:36 +08:00
Metrics::track_property("error", "error option name");
Commands::Help::print_usage();
Checks::exit_fail(VCPKG_LINE_INFO);
2016-09-19 11:50:08 +08:00
}
if (option_field != nullptr)
{
2017-04-04 07:31:00 +08:00
System::println(System::Color::error, "Error: %s specified multiple times", option_name);
2017-04-04 05:41:36 +08:00
Metrics::track_property("error", "error option specified multiple times");
Commands::Help::print_usage();
Checks::exit_fail(VCPKG_LINE_INFO);
2016-09-19 11:50:08 +08:00
}
option_field = std::make_unique<std::string>(*arg_begin);
}
2017-04-28 09:08:52 +08:00
static void parse_switch(OptBool new_setting, const std::string& option_name, OptBool& option_field)
2016-09-19 11:50:08 +08:00
{
2017-04-26 08:01:21 +08:00
if (option_field != OptBoolC::UNSPECIFIED && option_field != new_setting)
2016-09-19 11:50:08 +08:00
{
2017-04-04 07:31:00 +08:00
System::println(System::Color::error, "Error: conflicting values specified for --%s", option_name);
2017-04-04 05:41:36 +08:00
Metrics::track_property("error", "error conflicting switches");
Commands::Help::print_usage();
Checks::exit_fail(VCPKG_LINE_INFO);
2016-09-19 11:50:08 +08:00
}
option_field = new_setting;
}
VcpkgCmdArguments VcpkgCmdArguments::create_from_command_line(const int argc, const wchar_t* const* const argv)
2016-09-19 11:50:08 +08:00
{
std::vector<std::string> v;
for (int i = 1; i < argc; ++i)
{
v.push_back(Strings::utf16_to_utf8(argv[i]));
}
return VcpkgCmdArguments::create_from_arg_sequence(v.data(), v.data() + v.size());
2016-09-19 11:50:08 +08:00
}
2017-04-28 09:08:52 +08:00
VcpkgCmdArguments VcpkgCmdArguments::create_from_arg_sequence(const std::string* arg_begin,
const std::string* arg_end)
2016-09-19 11:50:08 +08:00
{
VcpkgCmdArguments args;
2016-09-19 11:50:08 +08:00
for (; arg_begin != arg_end; ++arg_begin)
{
std::string arg = *arg_begin;
if (arg.empty())
{
continue;
}
if (arg[0] == '-' && arg[1] != '-')
{
2017-04-04 05:41:36 +08:00
Metrics::track_property("error", "error short options are not supported");
2017-03-23 08:06:09 +08:00
Checks::exit_with_message(VCPKG_LINE_INFO, "Error: short options are not supported: %s", arg);
2016-09-19 11:50:08 +08:00
}
if (arg[0] == '-' && arg[1] == '-')
{
2017-04-27 10:21:40 +08:00
// make argument case insensitive
auto& f = std::use_facet<std::ctype<char>>(std::locale());
f.tolower(&arg[0], &arg[0] + arg.size());
2016-09-19 11:50:08 +08:00
// command switch
if (arg == "--vcpkg-root")
{
++arg_begin;
parse_value(arg_begin, arg_end, "--vcpkg-root", args.vcpkg_root_dir);
continue;
}
if (arg == "--triplet")
{
++arg_begin;
parse_value(arg_begin, arg_end, "--triplet", args.triplet);
2016-09-19 11:50:08 +08:00
continue;
}
if (arg == "--debug")
{
2017-04-26 08:01:21 +08:00
parse_switch(OptBoolC::ENABLED, "debug", args.debug);
2016-09-19 11:50:08 +08:00
continue;
}
if (arg == "--sendmetrics")
{
2017-04-26 08:01:21 +08:00
parse_switch(OptBoolC::ENABLED, "sendmetrics", args.sendmetrics);
2016-09-19 11:50:08 +08:00
continue;
}
if (arg == "--printmetrics")
{
2017-04-26 08:01:21 +08:00
parse_switch(OptBoolC::ENABLED, "printmetrics", args.printmetrics);
2016-09-19 11:50:08 +08:00
continue;
}
if (arg == "--no-sendmetrics")
{
2017-04-26 08:01:21 +08:00
parse_switch(OptBoolC::DISABLED, "sendmetrics", args.sendmetrics);
2016-09-19 11:50:08 +08:00
continue;
}
if (arg == "--no-printmetrics")
{
2017-04-26 08:01:21 +08:00
parse_switch(OptBoolC::DISABLED, "printmetrics", args.printmetrics);
2016-09-19 11:50:08 +08:00
continue;
}
args.optional_command_arguments.insert(arg);
continue;
}
if (args.command.empty())
{
args.command = arg;
}
else
{
args.command_arguments.push_back(arg);
}
}
return args;
}
std::unordered_set<std::string> VcpkgCmdArguments::check_and_get_optional_command_arguments(
const std::vector<std::string>& valid_options) const
2016-09-19 11:50:08 +08:00
{
std::unordered_set<std::string> output;
auto options_copy = this->optional_command_arguments;
for (const std::string& option : valid_options)
{
auto it = options_copy.find(option);
if (it != options_copy.end())
{
output.insert(option);
options_copy.erase(it);
}
}
if (!options_copy.empty())
{
2017-04-04 07:31:00 +08:00
System::println(System::Color::error, "Unknown option(s) for command '%s':", this->command);
2016-09-19 11:50:08 +08:00
for (const std::string& option : options_copy)
{
System::println(option);
2016-09-19 11:50:08 +08:00
}
Checks::exit_fail(VCPKG_LINE_INFO);
2016-09-19 11:50:08 +08:00
}
return output;
}
void VcpkgCmdArguments::check_max_arg_count(const size_t expected_arg_count) const
2016-09-19 11:50:08 +08:00
{
return check_max_arg_count(expected_arg_count, "");
}
void VcpkgCmdArguments::check_min_arg_count(const size_t expected_arg_count) const
{
return check_min_arg_count(expected_arg_count, "");
}
void VcpkgCmdArguments::check_exact_arg_count(const size_t expected_arg_count) const
{
return check_exact_arg_count(expected_arg_count, "");
}
void VcpkgCmdArguments::check_max_arg_count(const size_t expected_arg_count, const std::string& example_text) const
{
const size_t actual_arg_count = command_arguments.size();
if (actual_arg_count > expected_arg_count)
2016-09-19 11:50:08 +08:00
{
2017-04-28 09:08:52 +08:00
System::println(System::Color::error,
"Error: `%s` requires at most %u arguments, but %u were provided",
this->command,
expected_arg_count,
actual_arg_count);
System::print(example_text);
Checks::exit_fail(VCPKG_LINE_INFO);
}
}
void VcpkgCmdArguments::check_min_arg_count(const size_t expected_arg_count, const std::string& example_text) const
{
const size_t actual_arg_count = command_arguments.size();
if (actual_arg_count < expected_arg_count)
{
2017-04-28 09:08:52 +08:00
System::println(System::Color::error,
"Error: `%s` requires at least %u arguments, but %u were provided",
this->command,
expected_arg_count,
actual_arg_count);
System::print(example_text);
Checks::exit_fail(VCPKG_LINE_INFO);
}
}
2017-04-28 09:08:52 +08:00
void VcpkgCmdArguments::check_exact_arg_count(const size_t expected_arg_count,
const std::string& example_text) const
{
const size_t actual_arg_count = command_arguments.size();
if (actual_arg_count != expected_arg_count)
{
2017-04-28 09:08:52 +08:00
System::println(System::Color::error,
"Error: `%s` requires %u arguments, but %u were provided",
this->command,
expected_arg_count,
actual_arg_count);
System::print(example_text);
Checks::exit_fail(VCPKG_LINE_INFO);
2016-09-19 11:50:08 +08:00
}
}
}