gotta think of a way of handling the whole "templates are silly" thing
parent
6e5caf3ac5
commit
a78ad58479
|
@ -1,6 +1,6 @@
|
|||
cmake_minimum_required(VERSION 3.20)
|
||||
include(cmake/color.cmake)
|
||||
set(BLT_VERSION 4.0.8)
|
||||
set(BLT_VERSION 4.0.9)
|
||||
|
||||
set(BLT_TARGET BLT)
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <blt/std/types.h>
|
||||
#include <blt/std/hashmap.h>
|
||||
#include <blt/fs/path_helper.h>
|
||||
#include <blt/meta/meta.h>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
@ -51,11 +52,10 @@ namespace blt::argparse
|
|||
STORE_FALSE,
|
||||
APPEND,
|
||||
APPEND_CONST,
|
||||
EXTEND,
|
||||
COUNT,
|
||||
HELP,
|
||||
VERSION,
|
||||
EXTEND,
|
||||
SUBCOMMAND
|
||||
VERSION
|
||||
};
|
||||
|
||||
enum class nargs_t
|
||||
|
@ -120,13 +120,41 @@ namespace blt::argparse
|
|||
std::vector<std::vector<std::string_view>> m_allowed_strings;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
constexpr auto invalid_option_lambda = [](const T)
|
||||
{
|
||||
std::cerr << "Invalid type - expected list type, found '" << blt::type_string<T>() << "'" << std::endl;
|
||||
std::exit(1);
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
struct arg_data_helper_t
|
||||
{
|
||||
using variant_t = std::variant<Args..., std::vector<Args>...>;
|
||||
using arg_t = meta::arg_helper<Args...>;
|
||||
using arg_vec_t = meta::arg_helper<std::vector<Args>...>;
|
||||
|
||||
template <template<typename> typename... Defaults>
|
||||
static auto make_lists_only_visitor(Defaults<std::vector<Args>>&&... d)
|
||||
{
|
||||
return lambda_visitor{
|
||||
invalid_option_lambda<Args...>,
|
||||
std::forward<Defaults>(d)...
|
||||
};
|
||||
}
|
||||
|
||||
template <template<typename> typename... Defaults>
|
||||
static auto make_reject_lists_visitor_t(Defaults<Args>&&... d)
|
||||
{
|
||||
return lambda_visitor{
|
||||
invalid_option_lambda<std::vector<Args>...>,
|
||||
std::forward<Defaults>(d)...
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
using arg_data_t = arg_data_helper_t<i8, i16, i32, i64, u8, u16, u32, u64, float, double, std::string_view>::variant_t;
|
||||
using arg_meta_type_helper_t = arg_data_helper_t<i8, i16, i32, i64, u8, u16, u32, u64, float, double, std::string_view>;
|
||||
using arg_data_t = arg_meta_type_helper_t::variant_t;
|
||||
|
||||
template <typename T>
|
||||
struct arg_string_converter_t
|
||||
|
@ -414,6 +442,8 @@ namespace blt::argparse
|
|||
|
||||
void print_usage();
|
||||
|
||||
void print_version();
|
||||
|
||||
argument_parser_t& set_name(const std::string_view name)
|
||||
{
|
||||
m_name = name;
|
||||
|
@ -456,8 +486,9 @@ namespace blt::argparse
|
|||
private:
|
||||
void parse_flag(argument_storage_t& parsed_args, argument_consumer_t& consumer, std::string_view arg);
|
||||
void parse_positional(argument_storage_t& parsed_args, argument_consumer_t& consumer, std::string_view arg);
|
||||
static void handle_missing_and_default_args(hashmap_t<std::string_view, argument_builder_t*>& arguments, const hashset_t<std::string_view>& found,
|
||||
argument_storage_t& parsed_args, std::string_view type);
|
||||
static void handle_missing_and_default_args(hashmap_t<std::string_view, argument_builder_t*>& arguments,
|
||||
const hashset_t<std::string_view>& found,
|
||||
argument_storage_t& parsed_args, std::string_view type);
|
||||
|
||||
std::optional<std::string> m_name;
|
||||
std::optional<std::string> m_usage;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
namespace blt::argparse
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// Unit Tests for class argument_string_t
|
||||
|
@ -248,6 +249,10 @@ namespace blt::argparse
|
|||
{
|
||||
}
|
||||
|
||||
void argument_parser_t::print_version()
|
||||
{
|
||||
}
|
||||
|
||||
void argument_parser_t::parse_flag(argument_storage_t& parsed_args, argument_consumer_t& consumer, const std::string_view arg)
|
||||
{
|
||||
auto& flag = m_flag_arguments[arg];
|
||||
|
@ -266,9 +271,9 @@ namespace blt::argparse
|
|||
parsed_args.m_data.insert({dest, *flag->m_const_value});
|
||||
}
|
||||
break;
|
||||
[[fallthrough]] case nargs_t::ALL_AT_LEAST_ONE:
|
||||
[[fallthrough]] case nargs_t::ALL_AT_LEAST_ONE:
|
||||
if (!consumer.can_consume())
|
||||
std::cout << "Error expected at least one argument to be consumed by '" << arg << '\'' << std::endl;
|
||||
std::cerr << "Error expected at least one argument to be consumed by '" << arg << '\'' << std::endl;
|
||||
case nargs_t::ALL:
|
||||
std::vector<std::string_view> args;
|
||||
while (consumer.can_consume() && !consumer.peek().is_flag())
|
||||
|
@ -277,8 +282,79 @@ namespace blt::argparse
|
|||
break;
|
||||
}
|
||||
},
|
||||
[](const i32 argc)
|
||||
[&parsed_args, &consumer, &dest, &flag, arg, this](const i32 argc)
|
||||
{
|
||||
std::vector<std::string_view> args;
|
||||
for (i32 i = 0; i < argc; ++i)
|
||||
{
|
||||
if (!consumer.can_consume())
|
||||
{
|
||||
std::cerr << "Error expected " << argc << " arguments to be consumed by '" << arg << "' but found " << i <<
|
||||
std::endl;
|
||||
std::exit(1);
|
||||
}
|
||||
if (consumer.peek().is_flag())
|
||||
{
|
||||
std::cerr << "Error expected " << argc << " arguments to be consumed by '" << arg << "' but found a flag '" <<
|
||||
consumer.peek().get_argument() << "' instead!" << std::endl;
|
||||
std::exit(1);
|
||||
}
|
||||
args.push_back(consumer.consume().get_argument());
|
||||
}
|
||||
if (args.size() != argc)
|
||||
{
|
||||
std::cerr <<
|
||||
"This error condition should not be possible. "
|
||||
"Args consumed didn't equal the arguments requested and previous checks didn't fail. "
|
||||
"Please report as an issue on the GitHub"
|
||||
<< std::endl;
|
||||
std::exit(1);
|
||||
}
|
||||
if (argc == 0)
|
||||
{
|
||||
}
|
||||
else if (argc == 1)
|
||||
{
|
||||
switch (flag->m_action)
|
||||
{
|
||||
case action_t::STORE:
|
||||
break;
|
||||
case action_t::APPEND:
|
||||
case action_t::EXTEND:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case action_t::APPEND_CONST:
|
||||
// if (parsed_args.contains(dest))
|
||||
// {
|
||||
// std::visit(detail::arg_meta_type_helper_t::make_lists_only_visitor(handle_insert), parsed_args.m_data[dest]);
|
||||
// }
|
||||
case action_t::STORE_CONST:
|
||||
std::cerr << "Store const flag called with an argument. This condition doesn't make sense." << std::endl;
|
||||
print_usage();
|
||||
std::exit(1);
|
||||
case action_t::STORE_TRUE:
|
||||
std::cerr << "Store true flag called with an argument. This condition doesn't make sense." << std::endl;
|
||||
print_usage();
|
||||
std::exit(1);
|
||||
case action_t::STORE_FALSE:
|
||||
std::cerr << "Store false flag called with an argument. This condition doesn't make sense." << std::endl;
|
||||
print_usage();
|
||||
std::exit(1);
|
||||
case action_t::COUNT:
|
||||
parsed_args.m_data.insert({dest, args.size()});
|
||||
break;
|
||||
case action_t::HELP:
|
||||
print_help();
|
||||
std::exit(1);
|
||||
case action_t::VERSION:
|
||||
print_version();
|
||||
break;
|
||||
}
|
||||
flag->m_dest_func(dest, parsed_args, args.front());
|
||||
}
|
||||
else
|
||||
flag->m_dest_vec_func(dest, parsed_args, args);
|
||||
}
|
||||
}, flag->m_nargs);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue