h2-mod/src/common/utils/flags.cpp
2022-08-22 01:42:13 +02:00

116 lines
2.0 KiB
C++

#include "flags.hpp"
#include "string.hpp"
#include "nt.hpp"
#include <shellapi.h>
namespace utils::flags
{
namespace
{
bool parsed = false;
using flag_map_t = std::unordered_map<std::string, std::optional<std::string>>;
flag_map_t& get_flags()
{
static flag_map_t map = {};
return map;
}
void parse_flags(flag_map_t& flags)
{
int num_args;
auto* const argv = CommandLineToArgvW(GetCommandLineW(), &num_args);
flags.clear();
if (argv)
{
std::optional<std::string> last_flag{};
for (auto i = 0; i < num_args; ++i)
{
std::wstring wide_flag(argv[i]);
if (wide_flag[0] == L'-')
{
wide_flag.erase(wide_flag.begin());
const auto flag = string::convert(wide_flag);
last_flag = flag;
flags[flag] = {};
}
else if (last_flag.has_value())
{
const auto& flag = last_flag.value();
flags[flag] = string::convert(wide_flag);
last_flag = {};
}
}
LocalFree(argv);
}
}
void check_parse_flags()
{
if (!parsed)
{
parse_flags(get_flags());
parsed = true;
}
}
}
bool has_flag(const std::string& flag)
{
check_parse_flags();
for (const auto& [name, value] : get_flags())
{
if (string::to_lower(name) == string::to_lower(flag))
{
return true;
}
}
return false;
}
std::optional<std::string> get_flag(const std::string& flag)
{
check_parse_flags();
for (const auto& [name, value] : get_flags())
{
if (string::to_lower(name) == string::to_lower(flag))
{
return value;
}
}
return {};
}
std::optional<std::string> get_flag(const std::string& flag, const std::string& shortname)
{
auto value = get_flag(flag);
if (!value.has_value())
{
value = get_flag(shortname);
}
return value;
}
std::string get_flag(const std::string& flag, const std::string& shortname,
const std::string& default_)
{
const auto value = get_flag(flag, shortname);
if (!value.has_value())
{
return default_;
}
return value.value();
}
}