i am tired
parent
0b2dad0dda
commit
44a57e5ec2
|
@ -1,6 +1,6 @@
|
|||
cmake_minimum_required(VERSION 3.20)
|
||||
include(cmake/color.cmake)
|
||||
set(BLT_VERSION 4.0.3)
|
||||
set(BLT_VERSION 4.0.4)
|
||||
|
||||
set(BLT_TARGET BLT)
|
||||
|
||||
|
|
|
@ -44,14 +44,6 @@ namespace blt::argparse
|
|||
|
||||
namespace detail
|
||||
{
|
||||
inline hashset_t<std::string_view> allowed_flag_prefixes = {"-", "--", "+"};
|
||||
|
||||
std::string flag_prefixes_as_string();
|
||||
hashset_t<char> prefix_characters();
|
||||
|
||||
inline std::string flag_prefix_list_string = flag_prefixes_as_string();
|
||||
inline auto prefix_characters_set = prefix_characters();
|
||||
|
||||
class bad_flag final : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
|
@ -111,24 +103,22 @@ namespace blt::argparse
|
|||
class argument_string_t
|
||||
{
|
||||
public:
|
||||
explicit argument_string_t(const char* input): m_argument(input)
|
||||
explicit argument_string_t(const char* input, const hashset_t<char>& allowed_flag_prefix): m_argument(input),
|
||||
allowed_flag_prefix(&allowed_flag_prefix)
|
||||
{
|
||||
if (input == nullptr)
|
||||
throw detail::bad_flag("Argument cannot be null!");
|
||||
process_argument();
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string_view get_flag() const
|
||||
{
|
||||
if (!m_flag_section)
|
||||
process_argument();
|
||||
return *m_flag_section;
|
||||
return m_flag_section;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string_view get_name() const
|
||||
{
|
||||
if (!m_name_section)
|
||||
process_argument();
|
||||
return *m_name_section;
|
||||
return m_name_section;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string_view value() const
|
||||
|
@ -138,9 +128,7 @@ namespace blt::argparse
|
|||
|
||||
[[nodiscard]] bool is_flag() const
|
||||
{
|
||||
if (!m_is_flag)
|
||||
process_argument();
|
||||
return *m_is_flag;
|
||||
return !m_flag_section.empty();
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string_view get_argument() const
|
||||
|
@ -149,31 +137,21 @@ namespace blt::argparse
|
|||
}
|
||||
|
||||
private:
|
||||
void process_argument() const
|
||||
void process_argument()
|
||||
{
|
||||
size_t start = m_argument.size();
|
||||
for (auto [i, c] : enumerate(m_argument))
|
||||
size_t start = 0;
|
||||
for (; start < m_argument.size() && allowed_flag_prefix->contains(m_argument[start]); start++)
|
||||
{
|
||||
if (!detail::prefix_characters_set.contains(c))
|
||||
{
|
||||
start = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_is_flag = (start != 0);
|
||||
|
||||
m_flag_section = {m_argument.data(), start};
|
||||
m_name_section = {m_argument.data() + start, m_argument.size() - start};
|
||||
|
||||
if (!m_flag_section->empty() && !detail::allowed_flag_prefixes.contains(*m_flag_section))
|
||||
throw detail::bad_flag(
|
||||
"Invalid flag " + std::string(*m_flag_section) + " detected, flag is not in allowed list of flags! Must be one of " +
|
||||
detail::flag_prefix_list_string);
|
||||
}
|
||||
|
||||
std::string_view m_argument;
|
||||
mutable std::optional<bool> m_is_flag;
|
||||
mutable std::optional<std::string_view> m_flag_section;
|
||||
mutable std::optional<std::string_view> m_name_section;
|
||||
std::string_view m_flag_section;
|
||||
std::string_view m_name_section;
|
||||
const hashset_t<char>* allowed_flag_prefix;
|
||||
};
|
||||
|
||||
class argument_consumer_t
|
||||
|
@ -230,8 +208,8 @@ namespace blt::argparse
|
|||
class argument_parser_t
|
||||
{
|
||||
public:
|
||||
argument_parser_t(const std::optional<std::string_view> name = {}, const std::optional<std::string_view> usage = {}):
|
||||
m_name(name.value_or(std::optional<std::string>{})), m_usage(usage.value_or(std::optional<std::string>{}))
|
||||
explicit argument_parser_t(const std::optional<std::string_view> name = {}, const std::optional<std::string_view> usage = {}):
|
||||
m_name(name), m_usage(usage)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -252,8 +230,16 @@ namespace blt::argparse
|
|||
{
|
||||
public:
|
||||
|
||||
private:
|
||||
argument_parser_t add_subparser(const std::string_view dest)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
argument_parser_t add_subparser(std::string& dest)
|
||||
{
|
||||
|
||||
}
|
||||
private:
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -22,34 +22,7 @@ namespace blt::argparse
|
|||
{
|
||||
namespace detail
|
||||
{
|
||||
std::string flag_prefixes_as_string()
|
||||
{
|
||||
std::string result;
|
||||
for (auto [i, v] : enumerate(allowed_flag_prefixes))
|
||||
{
|
||||
result += '\'';
|
||||
result += v;
|
||||
result += '\'';
|
||||
if (i != allowed_flag_prefixes.size() - 2)
|
||||
result += ", ";
|
||||
else if (i != allowed_flag_prefixes.size() - 1)
|
||||
{
|
||||
if (allowed_flag_prefixes.size() > 2)
|
||||
result += ',';
|
||||
result += " or ";
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
hashset_t<char> prefix_characters()
|
||||
{
|
||||
hashset_t<char> result;
|
||||
for (auto [i, v] : enumerate(allowed_flag_prefixes))
|
||||
for (auto c : v)
|
||||
result.insert(c);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -57,93 +30,92 @@ namespace blt::argparse
|
|||
{
|
||||
// Unit Tests for class argument_string_t
|
||||
// Test Case 1: Ensure the constructor handles flags correctly
|
||||
void test_argument_string_t_flag_basic()
|
||||
void test_argument_string_t_flag_basic(const hashset_t<char>& prefixes)
|
||||
{
|
||||
const argument_string_t arg("-f");
|
||||
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()
|
||||
void test_argument_string_t_long_flag(const hashset_t<char>& prefixes)
|
||||
{
|
||||
const argument_string_t arg("--file");
|
||||
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()
|
||||
void test_argument_string_t_positional_argument(const hashset_t<char>& prefixes)
|
||||
{
|
||||
const argument_string_t arg("filename.txt");
|
||||
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()
|
||||
void test_argument_string_t_empty_input(const hashset_t<char>& prefixes)
|
||||
{
|
||||
const argument_string_t arg("");
|
||||
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()
|
||||
void test_argument_string_t_single_hyphen(const hashset_t<char>& prefixes)
|
||||
{
|
||||
const argument_string_t arg("-");
|
||||
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()
|
||||
void test_argument_string_t_double_hyphen(const hashset_t<char>& prefixes)
|
||||
{
|
||||
const argument_string_t arg("--");
|
||||
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()
|
||||
void test_argument_string_t_with_spaces(const hashset_t<char>& prefixes)
|
||||
{
|
||||
const argument_string_t arg(" ");
|
||||
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()
|
||||
void test_argument_string_t_numeric_flag(const hashset_t<char>& prefixes)
|
||||
{
|
||||
const argument_string_t arg("-123");
|
||||
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()
|
||||
void test_argument_string_t_plus_flag_basic(const hashset_t<char>& prefixes)
|
||||
{
|
||||
const argument_string_t arg("+f");
|
||||
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()
|
||||
void test_argument_string_t_single_plus(const hashset_t<char>& prefixes)
|
||||
{
|
||||
const argument_string_t arg("+");
|
||||
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()
|
||||
void test_argument_string_t_double_plus(const hashset_t<char>& prefixes)
|
||||
{
|
||||
const argument_string_t arg("++");
|
||||
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.");
|
||||
|
@ -151,17 +123,18 @@ namespace blt::argparse
|
|||
|
||||
void run_all_tests_argument_string_t()
|
||||
{
|
||||
test_argument_string_t_flag_basic();
|
||||
test_argument_string_t_long_flag();
|
||||
test_argument_string_t_positional_argument();
|
||||
test_argument_string_t_empty_input();
|
||||
test_argument_string_t_single_hyphen();
|
||||
test_argument_string_t_double_hyphen();
|
||||
test_argument_string_t_with_spaces();
|
||||
test_argument_string_t_numeric_flag();
|
||||
test_argument_string_t_plus_flag_basic();
|
||||
test_argument_string_t_single_plus();
|
||||
test_argument_string_t_double_plus();
|
||||
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);
|
||||
}
|
||||
|
||||
void test()
|
||||
|
|
Loading…
Reference in New Issue