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. --- .dir-locals.el | 12 ++ .gitignore | 2 + meson.build | 46 ++++++ src/args.cc | 373 +++++++++++++++++++++++++++++++++++++++++++++++++ src/args.hh | 70 ++++++++++ src/config.h.in | 1 + src/main.cc | 33 +++++ subprojects/gtest.wrap | 16 +++ test/args.cc | 358 +++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 911 insertions(+) create mode 100644 .dir-locals.el create mode 100644 .gitignore create mode 100644 meson.build create mode 100644 src/args.cc create mode 100644 src/args.hh create mode 100644 src/config.h.in create mode 100644 src/main.cc create mode 100644 subprojects/gtest.wrap create mode 100644 test/args.cc diff --git a/.dir-locals.el b/.dir-locals.el new file mode 100644 index 0000000..573c58e --- /dev/null +++ b/.dir-locals.el @@ -0,0 +1,12 @@ +;;; Directory Local Variables -*- no-byte-compile: t; -*- +;;; For more information see (info "(emacs) Directory Variables") + +((c++-mode . ((eval + . + (let ((project-path + (locate-dominating-file default-directory ".dir-locals.el"))) + (setq-local flycheck-clangcheck-build-path + (concat project-path "build")) + (setq-local flycheck-clang-language-standard "c++20") + (setq-local flycheck-clang-definitions '("HAVE_CONFIG_H")) + (setq-local flycheck-clang-include-path '("../src" "../build"))))))) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..db9f3cd --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/build/ +/compile_commands.json diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..15dc548 --- /dev/null +++ b/meson.build @@ -0,0 +1,46 @@ +project( + 'jkc', + 'cpp', + version : '0.1', + meson_version : '>= 1.3.0', + default_options : ['warning_level=3', 'cpp_std=c++20'], +) + +conf_data = configuration_data() +conf_data.set('version', meson.project_version()) +configure_file(input: 'src/config.h.in', + output: 'config.h', + configuration : conf_data) + +dependencies = [ +] + +inc = include_directories('src') + +exe = executable( + 'jkc', + sources: [ + 'src/args.cc', + 'src/args.hh', + 'src/main.cc', + ], + include_directories: inc, + install : true, + dependencies : dependencies, +) + +gtest_main_dep = dependency('gtest_main', fallback : ['gtest_main']) + +test_dependencies = [ + gtest_main_dep, +] + +test('args', executable( + 'test_args', + sources: [ + 'src/args.cc', + 'src/args.hh', + 'test/args.cc', + ], + include_directories: inc, + dependencies : test_dependencies)) 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