feat: Introduce a modular argument convention system for GNU and Windows styles, add .clang-format, and update CMake configuration to C++17.

This commit is contained in:
2026-03-15 22:55:23 +04:00
parent 061581c510
commit a1dc3c0149
20 changed files with 371 additions and 284 deletions

View File

@@ -0,0 +1,75 @@
#include "gnu_argument_convention.hpp"
#include "base_convention.hpp"
#include <stdexcept>
bool starts_with(std::string const &s, std::string const &prefix) {
return s.rfind(prefix, 0) == 0;
}
namespace argument_parser::conventions::implementations {
parsed_argument gnu_argument_convention::get_argument(std::string const &raw) const {
if (starts_with(raw, long_prec()))
return {argument_type::LONG, raw.substr(2)};
else if (starts_with(raw, short_prec()))
return {argument_type::SHORT, raw.substr(1)};
else
return {argument_type::ERROR, "GNU standard convention does not allow arguments without a preceding dash."};
}
std::string gnu_argument_convention::extract_value(std::string const & /*raw*/) const {
throw std::runtime_error("No inline value in standard GNU convention.");
}
bool gnu_argument_convention::requires_next_token() const {
return true;
}
std::string gnu_argument_convention::name() const {
return "GNU-style long options";
}
std::string gnu_argument_convention::short_prec() const {
return "-";
}
std::string gnu_argument_convention::long_prec() const {
return "--";
}
} // namespace argument_parser::conventions::implementations
namespace argument_parser::conventions::implementations {
parsed_argument gnu_equal_argument_convention::get_argument(std::string const &raw) const {
auto pos = raw.find('=');
auto arg = pos != std::string::npos ? raw.substr(0, pos) : raw;
if (starts_with(arg, long_prec()))
return {argument_type::LONG, arg.substr(2)};
else if (starts_with(arg, short_prec()))
return {argument_type::SHORT, arg.substr(1)};
else
return {argument_type::ERROR, "GNU standard convention does not allow arguments without a preceding dash."};
}
std::string gnu_equal_argument_convention::extract_value(std::string const &raw) const {
auto pos = raw.find('=');
if (pos == std::string::npos || pos + 1 >= raw.size())
throw std::runtime_error("Expected value after '='.");
return raw.substr(pos + 1);
}
bool gnu_equal_argument_convention::requires_next_token() const {
return false;
}
std::string gnu_equal_argument_convention::name() const {
return "GNU-style long options (equal signed form)";
}
std::string gnu_equal_argument_convention::short_prec() const {
return "-";
}
std::string gnu_equal_argument_convention::long_prec() const {
return "--";
}
} // namespace argument_parser::conventions::implementations