feat(parser): add platform-specific parsers and argument conventions
Implement platform-specific parsers for Windows, Linux, and macOS Add GNU argument convention implementations Create fake parser for testing purposes Update CMakeLists to include new headers
This commit is contained in:
32
include/conventions/base_convention.hpp
Normal file
32
include/conventions/base_convention.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#ifndef BASE_CONVENTION_HPP
|
||||
#define BASE_CONVENTION_HPP
|
||||
|
||||
namespace argument_parser::conventions {
|
||||
enum class argument_type {
|
||||
SHORT,
|
||||
LONG,
|
||||
ERROR
|
||||
};
|
||||
|
||||
using parsed_argument = std::pair<argument_type, std::string>;
|
||||
|
||||
class base_convention {
|
||||
public:
|
||||
virtual std::string extract_value(std::string const&) const = 0;
|
||||
virtual parsed_argument get_argument(std::string const&) const = 0;
|
||||
virtual bool requires_next_token() const = 0;
|
||||
virtual std::string name() const = 0;
|
||||
virtual std::string short_prec() const = 0;
|
||||
virtual std::string long_prec() const = 0;
|
||||
protected:
|
||||
base_convention() = default;
|
||||
~base_convention() = default;
|
||||
};
|
||||
using convention = base_convention;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,98 @@
|
||||
#pragma once
|
||||
#include "base_convention.hpp"
|
||||
#include <stdexcept>
|
||||
|
||||
#ifndef GNU_ARGUMENT_CONVENTION_HPP
|
||||
#define GNU_ARGUMENT_CONVENTION_HPP
|
||||
|
||||
namespace argument_parser::conventions::implementations {
|
||||
|
||||
class gnu_argument_convention : public base_convention {
|
||||
public:
|
||||
parsed_argument get_argument(std::string const& raw) const override {
|
||||
if (raw.starts_with(long_prec()))
|
||||
return {argument_type::LONG, raw.substr(2)};
|
||||
else if (raw.starts_with(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 extract_value(std::string const& /*raw*/) const override {
|
||||
// In non-equal GNU, value comes in next token
|
||||
throw std::runtime_error("No inline value in standard GNU convention.");
|
||||
}
|
||||
|
||||
bool requires_next_token() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string name() const override {
|
||||
return "GNU-style long options";
|
||||
}
|
||||
|
||||
std::string short_prec() const override {
|
||||
return "-";
|
||||
}
|
||||
|
||||
std::string long_prec() const override {
|
||||
return "--";
|
||||
}
|
||||
|
||||
static gnu_argument_convention instance;
|
||||
private:
|
||||
gnu_argument_convention() = default;
|
||||
};
|
||||
|
||||
class gnu_equal_argument_convention : public base_convention {
|
||||
public:
|
||||
parsed_argument get_argument(std::string const& raw) const override {
|
||||
auto pos = raw.find('=');
|
||||
auto arg = pos != std::string::npos ? raw.substr(0, pos) : raw;
|
||||
if (arg.starts_with(long_prec()))
|
||||
return {argument_type::LONG, arg.substr(2) };
|
||||
else if (arg.starts_with(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 extract_value(std::string const& raw) const override {
|
||||
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 requires_next_token() const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string name() const override {
|
||||
return "GNU-style long options (equal signed form)";
|
||||
}
|
||||
|
||||
std::string short_prec() const override {
|
||||
return "-";
|
||||
}
|
||||
|
||||
std::string long_prec() const override {
|
||||
return "--";
|
||||
}
|
||||
|
||||
static gnu_equal_argument_convention instance;
|
||||
private:
|
||||
gnu_equal_argument_convention() = default;
|
||||
};
|
||||
|
||||
inline gnu_argument_convention gnu_argument_convention::instance{};
|
||||
inline gnu_equal_argument_convention gnu_equal_argument_convention::instance{};
|
||||
}
|
||||
|
||||
namespace argument_parser::conventions {
|
||||
static inline const implementations::gnu_argument_convention gnu_argument_convention = implementations::gnu_argument_convention::instance;
|
||||
static inline const implementations::gnu_equal_argument_convention gnu_equal_argument_convention = implementations::gnu_equal_argument_convention::instance;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user