From d75b25d50f4df655d1e69ff900cfeee823039296 Mon Sep 17 00:00:00 2001 From: Joel Klinghed Date: Wed, 3 Sep 2025 00:49:27 +0200 Subject: Initial commit Only a basic argument parser to start with. --- src/args.cc | 373 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 373 insertions(+) create mode 100644 src/args.cc (limited to 'src/args.cc') diff --git a/src/args.cc b/src/args.cc new file mode 100644 index 0000000..68f296b --- /dev/null +++ b/src/args.cc @@ -0,0 +1,373 @@ +#include "args.hh" + +#include +#include +#include +#include +#include +#include + +namespace { + +std::string kEmpty; + +class OptionImpl : public Args::OptionArgument { + public: + enum Type { + NoArgument, + RequiredArgument, + OptionalArgument, + }; + + OptionImpl(Type type, char shortname, std::string longname, + std::string arg, std::string help) + : type(type), shortname(shortname), longname(std::move(longname)), + arg(std::move(arg)), help(std::move(help)) {} + + const Type type; + const char shortname; + const std::string longname; + const std::string arg; + const std::string help; + + bool is_set() const override { return is_set_; } + + bool has_argument() const override { return value_.has_value(); } + + const std::string& argument() const override { + if (value_.has_value()) + return value_.value(); + assert(false); + return kEmpty; + } + + void clear() { + is_set_ = false; + value_.reset(); + } + + void set_argument(std::string value) { + assert(type == Type::RequiredArgument || type == Type::OptionalArgument); + is_set_= true; + value_ = std::move(value); + } + + void set_no_argument() { + assert(type == Type::NoArgument || type == Type::OptionalArgument); + is_set_= true; + value_.reset(); + } + + private: + bool is_set_{false}; + std::optional value_; +}; + +class ArgsImpl : public Args { + public: + explicit ArgsImpl(std::string prgname) + : prgname_(std::move(prgname)) {} + + std::shared_ptr