silly works now i need to bed"
parent
fe6ce712e7
commit
735371b7bd
|
@ -1,6 +1,6 @@
|
|||
cmake_minimum_required(VERSION 3.20)
|
||||
include(cmake/color.cmake)
|
||||
set(BLT_VERSION 4.0.10)
|
||||
set(BLT_VERSION 4.0.11)
|
||||
|
||||
set(BLT_TARGET BLT)
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ namespace blt::argparse
|
|||
|
||||
[[nodiscard]] std::string error_string() const;
|
||||
|
||||
[[nodiscard]] const char* what() const override
|
||||
[[nodiscard]] const char* what() const noexcept override
|
||||
{
|
||||
return "Please use error_string() method instead of what(). This exception should *always* be caught!";
|
||||
}
|
||||
|
@ -134,21 +134,40 @@ namespace blt::argparse
|
|||
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)
|
||||
template <typename PerObjectAction>
|
||||
static auto make_lists_only_visitor_per_object_in_vec(const PerObjectAction& action)
|
||||
{
|
||||
return lambda_visitor{
|
||||
invalid_option_lambda<Args...>,
|
||||
std::forward<Defaults>(d)...
|
||||
([&action](std::vector<Args> arg_vec)
|
||||
{
|
||||
for (const auto& arg : arg_vec)
|
||||
action(arg_vec, arg);
|
||||
})...
|
||||
};
|
||||
}
|
||||
|
||||
template <template<typename> typename... Defaults>
|
||||
static auto make_reject_lists_visitor_t(Defaults<Args>&&... d)
|
||||
template <typename DefaultAction>
|
||||
static auto make_lists_only_visitor_on_vec(const DefaultAction& action)
|
||||
{
|
||||
return lambda_visitor{
|
||||
invalid_option_lambda<Args>...,
|
||||
([&action](std::vector<Args> arg_vec)
|
||||
{
|
||||
action(arg_vec);
|
||||
})...
|
||||
};
|
||||
}
|
||||
|
||||
template <typename DefaultAction>
|
||||
static auto make_reject_lists_visitor_t(const DefaultAction& action)
|
||||
{
|
||||
return lambda_visitor{
|
||||
invalid_option_lambda<std::vector<Args>...>,
|
||||
std::forward<Defaults>(d)...
|
||||
([&action](Args arg)
|
||||
{
|
||||
action(arg);
|
||||
})...
|
||||
};
|
||||
}
|
||||
};
|
||||
|
@ -346,7 +365,7 @@ namespace blt::argparse
|
|||
private:
|
||||
void add(const argument_storage_t& values)
|
||||
{
|
||||
for (const auto value : values)
|
||||
for (const auto& value : values.m_data)
|
||||
m_data.insert(value);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,165 +0,0 @@
|
|||
/*
|
||||
* <Short Description>
|
||||
* Copyright (C) 2025 Brett Terpstra
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <blt/parse/argparse_v2.h>
|
||||
#include <blt/std/assert.h>
|
||||
|
||||
namespace blt::argparse
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
// Unit Tests for class argument_string_t
|
||||
// Test Case 1: Ensure the constructor handles flags correctly
|
||||
void test_argument_string_t_flag_basic(const hashset_t<char>& prefixes)
|
||||
{
|
||||
const argument_string_t arg("-f", prefixes);
|
||||
BLT_ASSERT(arg.is_flag() && "Expected argument to be identified as a flag.");
|
||||
BLT_ASSERT(arg.value() == "f" && "Flag value should match the input string.");
|
||||
}
|
||||
|
||||
// Test Case 2: Ensure the constructor handles long flags correctly
|
||||
void test_argument_string_t_long_flag(const hashset_t<char>& prefixes)
|
||||
{
|
||||
const argument_string_t arg("--file", prefixes);
|
||||
BLT_ASSERT(arg.is_flag() && "Expected argument to be identified as a flag.");
|
||||
BLT_ASSERT(arg.value() == "file" && "Long flag value should match the input string.");
|
||||
}
|
||||
|
||||
// Test Case 3: Ensure positional arguments are correctly identified
|
||||
void test_argument_string_t_positional_argument(const hashset_t<char>& prefixes)
|
||||
{
|
||||
const argument_string_t arg("filename.txt", prefixes);
|
||||
BLT_ASSERT(!arg.is_flag() && "Expected argument to be identified as positional.");
|
||||
BLT_ASSERT(arg.value() == "filename.txt" && "Positional argument value should match the input string.");
|
||||
}
|
||||
|
||||
// Test Case 5: Handle an empty string
|
||||
void test_argument_string_t_empty_input(const hashset_t<char>& prefixes)
|
||||
{
|
||||
const argument_string_t arg("", prefixes);
|
||||
BLT_ASSERT(!arg.is_flag() && "Expected an empty input to be treated as positional, not a flag.");
|
||||
BLT_ASSERT(arg.value().empty() && "Empty input should have an empty value.");
|
||||
}
|
||||
|
||||
// Test Case 6: Handle edge case of a single hyphen (`-`) which might be ambiguous
|
||||
void test_argument_string_t_single_hyphen(const hashset_t<char>& prefixes)
|
||||
{
|
||||
const argument_string_t arg("-", prefixes);
|
||||
BLT_ASSERT(arg.is_flag() && "Expected single hyphen (`-`) to be treated as a flag.");
|
||||
BLT_ASSERT(arg.value().empty() && "Single hyphen flag should have empty value.");
|
||||
BLT_ASSERT(arg.get_flag() == "-" && "Single hyphen flag should match the input string.");
|
||||
}
|
||||
|
||||
// Test Case 8: Handle arguments with prefix only (like "--")
|
||||
void test_argument_string_t_double_hyphen(const hashset_t<char>& prefixes)
|
||||
{
|
||||
const argument_string_t arg("--", prefixes);
|
||||
BLT_ASSERT(arg.is_flag() && "Double hyphen ('--') should be treated as a flag.");
|
||||
BLT_ASSERT(arg.value().empty() && "Double hyphen flag should have empty value.");
|
||||
BLT_ASSERT(arg.get_flag() == "--" && "Double hyphen value should match the input string.");
|
||||
}
|
||||
|
||||
// Test Case 9: Validate edge case of an argument with spaces
|
||||
void test_argument_string_t_with_spaces(const hashset_t<char>& prefixes)
|
||||
{
|
||||
const argument_string_t arg(" ", prefixes);
|
||||
BLT_ASSERT(!arg.is_flag() && "Arguments with spaces should not be treated as flags.");
|
||||
BLT_ASSERT(arg.value() == " " && "Arguments with spaces should match the input string.");
|
||||
}
|
||||
|
||||
// Test Case 10: Validate arguments with numeric characters
|
||||
void test_argument_string_t_numeric_flag(const hashset_t<char>& prefixes)
|
||||
{
|
||||
const argument_string_t arg("-123", prefixes);
|
||||
BLT_ASSERT(arg.is_flag() && "Numeric flags should still be treated as flags.");
|
||||
BLT_ASSERT(arg.value() == "123" && "Numeric flag value should match the input string.");
|
||||
}
|
||||
|
||||
// Test Case 11: Ensure the constructor handles '+' flag correctly
|
||||
void test_argument_string_t_plus_flag_basic(const hashset_t<char>& prefixes)
|
||||
{
|
||||
const argument_string_t arg("+f", prefixes);
|
||||
BLT_ASSERT(arg.is_flag() && "Expected argument to be identified as a flag.");
|
||||
BLT_ASSERT(arg.value() == "f" && "Plus flag value should match the input string.");
|
||||
}
|
||||
|
||||
// Test Case 13: Handle edge case of a single plus (`+`) which might be ambiguous
|
||||
void test_argument_string_t_single_plus(const hashset_t<char>& prefixes)
|
||||
{
|
||||
const argument_string_t arg("+", prefixes);
|
||||
BLT_ASSERT(arg.is_flag() && "Expected single plus (`+`) to be treated as a flag.");
|
||||
BLT_ASSERT(arg.value().empty() && "Single plus flag should have empty value.");
|
||||
BLT_ASSERT(arg.get_flag() == "+" && "Single plus flag should match the input string.");
|
||||
}
|
||||
|
||||
// Test Case 14: Handle arguments with prefix only (like '++')
|
||||
void test_argument_string_t_double_plus(const hashset_t<char>& prefixes)
|
||||
{
|
||||
const argument_string_t arg("++", prefixes);
|
||||
BLT_ASSERT(arg.is_flag() && "Double plus ('++') should be treated as a flag.");
|
||||
BLT_ASSERT(arg.value().empty() && "Double plus flag should have empty value.");
|
||||
BLT_ASSERT(arg.get_flag() == "++" && "Double plus value should match the input string.");
|
||||
}
|
||||
|
||||
void run_all_tests_argument_string_t()
|
||||
{
|
||||
const hashset_t<char> prefixes = {'-', '+'};
|
||||
test_argument_string_t_flag_basic(prefixes);
|
||||
test_argument_string_t_long_flag(prefixes);
|
||||
test_argument_string_t_positional_argument(prefixes);
|
||||
test_argument_string_t_empty_input(prefixes);
|
||||
test_argument_string_t_single_hyphen(prefixes);
|
||||
test_argument_string_t_double_hyphen(prefixes);
|
||||
test_argument_string_t_with_spaces(prefixes);
|
||||
test_argument_string_t_numeric_flag(prefixes);
|
||||
test_argument_string_t_plus_flag_basic(prefixes);
|
||||
test_argument_string_t_single_plus(prefixes);
|
||||
test_argument_string_t_double_plus(prefixes);
|
||||
}
|
||||
|
||||
std::string subparse_error::error_string() const
|
||||
{
|
||||
std::string message = "Subparser Error: ";
|
||||
message += m_found_string;
|
||||
message += " is not a valid command. Allowed commands are: {";
|
||||
for (const auto [i, allowed_string] : enumerate(m_allowed_strings))
|
||||
{
|
||||
message += allowed_string;
|
||||
if (i != m_allowed_strings.size() - 1)
|
||||
message += ' ';
|
||||
}
|
||||
message += "}";
|
||||
return message;
|
||||
}
|
||||
|
||||
void test()
|
||||
{
|
||||
run_all_tests_argument_string_t();
|
||||
}
|
||||
}
|
||||
|
||||
void argument_string_t::process_argument()
|
||||
{
|
||||
size_t start = 0;
|
||||
for (; start < m_argument.size() && m_allowed_flag_prefix->contains(m_argument[start]); start++)
|
||||
{
|
||||
}
|
||||
|
||||
m_flag_section = {m_argument.data(), start};
|
||||
m_name_section = {m_argument.data() + start, m_argument.size() - start};
|
||||
}
|
||||
}
|
|
@ -255,7 +255,7 @@ namespace blt::argparse
|
|||
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];
|
||||
auto dest = flag->m_dest.value_or(arg);
|
||||
auto dest = flag->m_dest.value_or(std::string{arg});
|
||||
std::visit(lambda_visitor{
|
||||
[&parsed_args, &consumer, &dest, &flag, arg](const nargs_t arg_enum)
|
||||
{
|
||||
|
@ -270,9 +270,10 @@ namespace blt::argparse
|
|||
parsed_args.m_data.insert({dest, *flag->m_const_value});
|
||||
}
|
||||
break;
|
||||
[[fallthrough]] case nargs_t::ALL_AT_LEAST_ONE:
|
||||
case nargs_t::ALL_AT_LEAST_ONE:
|
||||
if (!consumer.can_consume())
|
||||
std::cerr << "Error expected at least one argument to be consumed by '" << arg << '\'' << std::endl;
|
||||
[[fallthrough]];
|
||||
case nargs_t::ALL:
|
||||
std::vector<std::string_view> args;
|
||||
while (consumer.can_consume() && !consumer.peek().is_flag())
|
||||
|
@ -300,7 +301,7 @@ namespace blt::argparse
|
|||
}
|
||||
args.push_back(consumer.consume().get_argument());
|
||||
}
|
||||
if (args.size() != argc)
|
||||
if (args.size() != static_cast<size_t>(argc))
|
||||
{
|
||||
std::cerr <<
|
||||
"This error condition should not be possible. "
|
||||
|
@ -338,12 +339,12 @@ namespace blt::argparse
|
|||
std::cerr << "Constant value for flag '" << arg << "' type doesn't values already present!" << std::endl;
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
auto visitor = detail::arg_meta_type_helper_t::make_lists_only_visitor_on_vec([&flag](auto& vec)
|
||||
{
|
||||
vec.push_back(std::get<typename std::remove_const<std::remove_reference_t<decltype(vec)>>::value_type>(*flag->m_const_value));
|
||||
});
|
||||
std::visit(visitor, data);
|
||||
}
|
||||
// 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();
|
||||
|
@ -391,7 +392,7 @@ namespace blt::argparse
|
|||
std::cerr << "Error: " << type << " argument '" << key << "' was not found but is required by the program" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
auto dest = value->m_dest.value_or(key);
|
||||
auto dest = value->m_dest.value_or(std::string{key});
|
||||
if (value->m_default_value && !parsed_args.contains(dest))
|
||||
parsed_args.m_data.insert({dest, *value->m_default_value});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue