this doesn't work rn
parent
17e6b507ea
commit
6935ae4785
|
@ -1,6 +1,6 @@
|
|||
cmake_minimum_required(VERSION 3.20)
|
||||
include(cmake/color.cmake)
|
||||
set(BLT_VERSION 4.0.30)
|
||||
set(BLT_VERSION 4.0.31)
|
||||
|
||||
set(BLT_TARGET BLT)
|
||||
|
||||
|
|
|
@ -231,8 +231,11 @@ namespace blt::argparse
|
|||
template <typename T>
|
||||
auto ensure_is_string(T&& t)
|
||||
{
|
||||
if constexpr (std::is_arithmetic_v<meta::remove_cvref_t<T>> && !(std::is_same_v<T, char>
|
||||
|| std::is_same_v<T, unsigned char> || std::is_same_v<T, signed char>))
|
||||
using NO_REF = meta::remove_cvref_t<T>;
|
||||
if constexpr (std::is_same_v<NO_REF, bool>)
|
||||
return t ? "true" : "false";
|
||||
else if constexpr (std::is_arithmetic_v<NO_REF> && !(std::is_same_v<NO_REF, char>
|
||||
|| std::is_same_v<NO_REF, unsigned char> || std::is_same_v<NO_REF, signed char>))
|
||||
return std::to_string(std::forward<T>(t));
|
||||
else
|
||||
return std::forward<T>(t);
|
||||
|
@ -582,7 +585,9 @@ namespace blt::argparse
|
|||
class argument_parser_t
|
||||
{
|
||||
friend argument_subparser_t;
|
||||
|
||||
explicit argument_parser_t(const argument_subparser_t* parent): m_parent(parent)
|
||||
{
|
||||
}
|
||||
public:
|
||||
explicit argument_parser_t(const std::optional<std::string_view> description = {}, const std::optional<std::string_view> epilogue = {},
|
||||
const std::optional<std::string_view> version = {},
|
||||
|
@ -739,6 +744,7 @@ namespace blt::argparse
|
|||
std::optional<std::string> m_description;
|
||||
std::optional<std::string> m_epilogue;
|
||||
std::optional<std::string> m_version;
|
||||
const argument_subparser_t* m_parent = nullptr;
|
||||
std::vector<std::pair<std::string_view, argument_subparser_t>> m_subparsers;
|
||||
std::vector<std::unique_ptr<argument_builder_t>> m_argument_builders;
|
||||
hashmap_t<std::string_view, argument_builder_t*> m_flag_arguments;
|
||||
|
@ -748,6 +754,7 @@ namespace blt::argparse
|
|||
|
||||
class argument_subparser_t
|
||||
{
|
||||
friend argument_parser_t;
|
||||
public:
|
||||
explicit argument_subparser_t(const argument_parser_t& parent): m_parent(&parent)
|
||||
{
|
||||
|
@ -760,9 +767,16 @@ namespace blt::argparse
|
|||
std::conjunction_v<std::disjunction<std::is_convertible<Aliases, std::string_view>, std::is_constructible<
|
||||
std::string_view, Aliases>>...>,
|
||||
"Arguments must be of type string_view, convertible to string_view or be string_view constructable");
|
||||
m_parsers.emplace(name, argument_parser_t{});
|
||||
((m_aliases[std::string_view{aliases}] = &m_parsers[name]), ...);
|
||||
return &m_parsers[name];
|
||||
m_parsers.emplace_back(new argument_parser_t{this});
|
||||
m_aliases[name] = m_parsers.back().get();
|
||||
((m_aliases[std::string_view{aliases}] = m_parsers.back().get()), ...);
|
||||
return m_parsers.back().get();
|
||||
}
|
||||
|
||||
argument_subparser_t* set_help(const std::optional<std::string>& help)
|
||||
{
|
||||
m_help = help;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
@ -781,10 +795,15 @@ namespace blt::argparse
|
|||
std::pair<argument_string_t, argument_storage_t> parse(argument_consumer_t& consumer); // NOLINT
|
||||
|
||||
private:
|
||||
[[nodiscard]] std::vector<std::vector<std::string_view>> get_allowed_strings() const;
|
||||
[[nodiscard]] hashmap_t<argument_parser_t*, std::vector<std::string_view>> get_allowed_strings() const;
|
||||
|
||||
// annoying compatability because im lazy
|
||||
static std::vector<std::vector<std::string_view>> to_vec(const hashmap_t<argument_parser_t*, std::vector<std::string_view>>& map);
|
||||
|
||||
const argument_parser_t* m_parent;
|
||||
hashmap_t<std::string_view, argument_parser_t> m_parsers;
|
||||
std::optional<std::string> m_last_parsed_parser; // bad hack
|
||||
std::optional<std::string> m_help;
|
||||
std::vector<std::unique_ptr<argument_parser_t>> m_parsers;
|
||||
hashmap_t<std::string_view, argument_parser_t*> m_aliases;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -76,7 +76,9 @@ namespace blt::argparse
|
|||
}
|
||||
else if constexpr (std::is_same_v<T, char> || std::is_same_v<T, unsigned char> || std::is_same_v<T, signed char>)
|
||||
{
|
||||
return std::string() + t;
|
||||
std::string str;
|
||||
str += t;
|
||||
return str;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -400,7 +402,23 @@ namespace blt::argparse
|
|||
{
|
||||
help += "Subcommands:";
|
||||
help.newline();
|
||||
|
||||
for (const auto& [key, value] : m_subparsers)
|
||||
{
|
||||
help += '\t';
|
||||
auto map = value.get_allowed_strings();
|
||||
// TODO: make an unzip?
|
||||
for (const auto& [parser, strings] : map)
|
||||
{
|
||||
for (const auto& [i, str] : enumerate(strings))
|
||||
{
|
||||
help += str;
|
||||
if (i != strings.size() - 1)
|
||||
help += ", ";
|
||||
}
|
||||
help += parser.he
|
||||
help.newline();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_flag_arguments.empty())
|
||||
|
@ -461,7 +479,7 @@ namespace blt::argparse
|
|||
{
|
||||
auto& [builder, flag_list] = pair;
|
||||
str += builder->m_help.value_or("");
|
||||
if (builder->m_default_value)
|
||||
if (builder->m_default_value && !(builder->m_action == action_t::STORE_TRUE || builder->m_action == action_t::STORE_FALSE))
|
||||
{
|
||||
if (!std::isblank(str.str().back()))
|
||||
str += " ";
|
||||
|
@ -514,6 +532,17 @@ namespace blt::argparse
|
|||
aligner += m_name.value_or("");
|
||||
aligner += ' ';
|
||||
|
||||
auto parent = m_parent;
|
||||
while (parent != nullptr)
|
||||
{
|
||||
if (!parent->m_last_parsed_parser)
|
||||
throw detail::missing_value_error(
|
||||
"Error: Help called on subparser but unable to find parser chain. This condition should be impossible.");
|
||||
aligner += parent->m_last_parsed_parser.value();
|
||||
aligner += ' ';
|
||||
parent = parent->m_parent->m_parent;
|
||||
}
|
||||
|
||||
hashmap_t<std::string, std::vector<std::string>> singleFlags;
|
||||
std::vector<std::pair<argument_string_t, argument_builder_t*>> compoundFlags;
|
||||
|
||||
|
@ -960,36 +989,28 @@ namespace blt::argparse
|
|||
throw detail::missing_argument_error("Subparser requires an argument.");
|
||||
const auto key = consumer.consume();
|
||||
if (key.is_flag())
|
||||
throw detail::subparse_error(key.get_argument(), get_allowed_strings());
|
||||
const auto it = m_parsers.find(key.get_name());
|
||||
argument_parser_t* parser;
|
||||
if (it == m_parsers.end())
|
||||
{
|
||||
const auto it2 = m_aliases.find(key.get_name());
|
||||
if (it2 == m_aliases.end())
|
||||
throw detail::subparse_error(key.get_argument(), get_allowed_strings());
|
||||
parser = it2->second;
|
||||
}
|
||||
else
|
||||
parser = &it->second;
|
||||
parser->m_name = m_parent->m_name;
|
||||
return {key, parser->parse(consumer)};
|
||||
throw detail::subparse_error(key.get_argument(), to_vec(get_allowed_strings()));
|
||||
const auto it = m_aliases.find(key.get_name());
|
||||
if (it == m_aliases.end())
|
||||
throw detail::subparse_error(key.get_argument(), to_vec(get_allowed_strings()));
|
||||
it->second->m_name = m_parent->m_name;
|
||||
m_last_parsed_parser = key.get_name();
|
||||
return {key, it->second->parse(consumer)};
|
||||
}
|
||||
|
||||
std::vector<std::vector<std::string_view>> argument_subparser_t::get_allowed_strings() const
|
||||
hashmap_t<argument_parser_t*, std::vector<std::string_view>> argument_subparser_t::get_allowed_strings() const
|
||||
{
|
||||
hashmap_t<argument_parser_t*, std::vector<std::string_view>> map;
|
||||
for (const auto& [key, value] : m_aliases)
|
||||
map[value].emplace_back(key);
|
||||
return map;
|
||||
}
|
||||
|
||||
std::vector<std::vector<std::string_view>> argument_subparser_t::to_vec(const hashmap_t<argument_parser_t*, std::vector<std::string_view>>& map)
|
||||
{
|
||||
std::vector<std::vector<std::string_view>> vec;
|
||||
for (const auto& [key, value] : m_parsers)
|
||||
{
|
||||
std::vector<std::string_view> aliases;
|
||||
aliases.push_back(key);
|
||||
for (const auto& [alias, parser] : m_aliases)
|
||||
{
|
||||
if (parser == &value)
|
||||
aliases.push_back(alias);
|
||||
}
|
||||
vec.emplace_back(std::move(aliases));
|
||||
}
|
||||
for (const auto& [key, value] : map)
|
||||
vec.push_back(value);
|
||||
return vec;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue