~nabijaczleweli/klapki

0b163a2586e868e48a1bfdd7feb91bb923028678 — наб 1 year, 10 days ago 9be7f90
Basic arg parsing
10 files changed, 281 insertions(+), 16 deletions(-)

M Makefile
M README.md
M configMakefile
M src/config.cpp
M src/config.hpp
M src/main.cpp
A src/ops.cpp
M src/ops.hpp
A src/util.cpp
A src/util.hpp
M Makefile => Makefile +3 -2
@@ 25,8 25,8 @@ include configMakefile

LDDLLS := fmt
LDAR := $(LNCXXAR) $(foreach l,fmt,-L$(BLDDIR)$(l)) $(foreach dll,$(LDDLLS),-l$(dll))
INCAR := $(foreach l,$(foreach l,fmt,$(l)/include) jsonpp,-isystemext/$(l)) $(foreach l,,-isystem$(BLDDIR)$(l)/include)
VERAR := $(foreach l,BARBERSANDREBARBS CEREAL CIMPOLER_META CPP_LOCALISER CPR FMT JSONPP SEED11 SEMVER WHEREAMI_CPP,-D$(l)_VERSION='$($(l)_VERSION)')
INCAR := $(foreach l,$(foreach l,fmt,$(l)/include),-isystemext/$(l)) $(foreach l,,-isystem$(BLDDIR)$(l)/include)
VERAR := $(foreach l,KLAPKI,-D$(l)_VERSION='$($(l)_VERSION)')
SOURCES := $(sort $(wildcard src/*.cpp src/**/*.cpp src/**/**/*.cpp src/**/**/**/*.cpp))
HEADERS := $(sort $(wildcard src/*.hpp src/**/*.hpp src/**/**/*.hpp src/**/**/**/*.hpp))



@@ 45,6 45,7 @@ fmt : $(BLDDIR)fmt/libfmt$(ARCH)

$(OUTDIR)klapki$(EXE) : $(subst $(SRCDIR),$(OBJDIR),$(subst .cpp,$(OBJ),$(SOURCES)))
	$(CXX) $(CXXAR) -o$@ $^ $(PIC) $(LDAR)
	$(STRIP) $(STRIPAR) $@

$(BLDDIR)audiere/lib/libaudiere$(DLL) : ext/audiere/CMakeLists.txt
	@mkdir -p $(abspath $(dir $@)../build)

M README.md => README.md +1 -0
@@ 10,6 10,7 @@ dunno yet

#### probably a building sexion here

<!-- libssl-dev not required -->

#### From Debian repository


M configMakefile => configMakefile +3 -0
@@ 37,6 37,9 @@ else
	LNCXXAR :=
endif

#KLAPKI_VERSION := "$(patsubst v%,%,$(shell git describe --tags --abbrev=0))"
KLAPKI_VERSION := "0.0.0-$(shell git rev-list HEAD --count)"

INCCMAKEAR := CXXFLAGS="$(INCCXXAR)"
LNCMAKEAR := LDFLAGS="$(LNCXXAR)"


M src/config.cpp => src/config.cpp +72 -4
@@ 21,10 21,78 @@


#include "config.hpp"
#include "fmt/format.h"
#include "util.hpp"
#include <cstdlib>
#include <fmt/format.h>
#include <limits.h>
#include <sys/utsname.h>
#include <unistd.h>


klapki::config klapki::read_config(const char ** argv) {
	fmt::print("henlo {}\n", argv[0]);
	return {argv[0], {{}, {}}};
static std::variant<std::string_view, std::string> get_host() {
	if(auto host = std::getenv("KLAPKI_HOST"))
		return std::string_view{host};
	else {
		auto mid = klapki::readline("/etc/machine-id");
		if(!mid.empty())
			return std::move(mid);

		char hostname[HOST_NAME_MAX + 1];
		gethostname(hostname, sizeof(hostname) / sizeof(*hostname));
		return std::string{hostname};
	}
}


const char * klapki::config::host() const noexcept {
	return std::visit([](auto && h) { return h.data(); }, this->host_raw);
}


std::variant<klapki::config, std::string> klapki::read_config(const char ** argv) {
	const auto argv0 = argv[0];
	++argv;

	bool verbose = false;
	for(; *argv && argv[0][0] == '-'; ++argv) {
		for(auto opts = argv[0] + 1; *opts; ++opts)
			switch(opts[0]) {
				case 'v':
					verbose = true;
					break;

				case 'h':
					return fmt::format("klapki {}\n"
					                   "Usage: {} [-vh]… <op [arg]…>\n"
					                   "\n"
					                   "-v\tVerbose operation\n"
					                   "-h\tShow this help\n"
					                   "\n"
					                   "Recognised ops:\n"
					                   "\tdump",
					                   KLAPKI_VERSION, argv0);

				default:
					return fmt::format("{}: unknown flag {}", argv0, opts[0]);
			}
	}

	std::vector<ops::op_t> ops;
	if(verbose)
		ops.emplace_back(ops::dump{});
	while(*argv) {
		auto pop = op::from_cmdline(argv0, argv);
		if(auto err = std::get_if<std::string>(&pop))
			return std::move(*err);
		else {
			ops.emplace_back(std::move(std::get<ops::op_t>(pop)));
			if(verbose)
				ops.emplace_back(ops::dump{});
		}
	}

	if(ops.empty())
		return fmt::format("{}: nothing to do?", argv0);

	return config{argv0, std::move(ops), get_host()};
}

M src/config.hpp => src/config.hpp +26 -4
@@ 20,18 20,40 @@
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


#pragma once


#include "ops.hpp"
#include <string>
#include <string_view>
#include <variant>
#include <vector>
#include <string>


namespace klapki {
	struct config {
		std::string host;
		const char * argv0;
		const char * host() const noexcept;
		bool verbose;
		std::vector<ops::op_t> ops;

		std::vector<ops::op> ops;
		std::variant<std::string_view, std::string> host_raw;
	};

	config read_config(const char ** argv);
	std::variant<config, std::string> read_config(const char ** argv);
}


template <>
struct fmt::formatter<klapki::config> {
	constexpr auto parse(format_parse_context & ctx) { return ctx.begin(); }

	template <typename FormatContext>
	auto format(const klapki::config & cfg, FormatContext & ctx) {
		return format_to(ctx.out(),
		                 "Host   : {}\n"
		                 "Verbose: {}\n"
		                 "Ops    : {}",
		                 cfg.host(), cfg.verbose, klapki::mops{cfg.ops});
	}
};

M src/main.cpp => src/main.cpp +11 -4
@@ 21,14 21,21 @@


#include "config.hpp"
#include "fmt/format.h"
#include "util.hpp"
#include <fmt/format.h>


namespace klapki {
	static int main(const char ** argv) {
		const auto cfg = read_config(argv);
		fmt::print("yes: {}\n", cfg.ops.size());
		return 0;
		return std::visit(visit_variant{[](config && cfg) {
			                                fmt::print("{}\n", cfg);
			                                return 0;
		                                },
		                                [](std::string && errmsg) {
			                                fmt::print("{}\n", errmsg);
			                                return 1;
		                                }},
		                  read_config(argv));
	}
}


A src/ops.cpp => src/ops.cpp +37 -0
@@ 0,0 1,37 @@
// The MIT License (MIT)

// Copyright (c) 2020 nabijaczleweli

// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


#include "ops.hpp"
#include <cstring>


std::variant<klapki::ops::op_t, std::string> klapki::op::from_cmdline(const char * argv0, const char **& argv) {
	if(!*argv)
		return "Parser error: klapki::op::from_cmdline() invoked with no arguments left to parse";

	const auto opname = argv[0];
	++argv;
	if(!std::strcmp(opname, "dump"))
		return ops::dump{};
	else
		return fmt::format("{}: unknown op {}", argv0, opname);
}

M src/ops.hpp => src/ops.hpp +56 -2
@@ 20,12 20,66 @@
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


#pragma once


#include "util.hpp"
#include <fmt/format.h>
#include <variant>
#include <vector>


namespace klapki::ops {
	struct version {};
	struct dump {};

	using op = std::variant<ops::version>;
	using op_t = std::variant<dump>;
}


namespace klapki {
	struct op {
		const ops::op_t & op;

		static std::variant<ops::op_t, std::string> from_cmdline(const char * argv0, const char **& argv);
	};
	struct mops {
		const std::vector<ops::op_t> & ops;
	};
}


template <>
struct fmt::formatter<klapki::op> {
	constexpr auto parse(format_parse_context & ctx) { return ctx.begin(); }

	template <typename FormatContext>
	auto format(const klapki::op & op, FormatContext & ctx) {
		return std::visit(
		    klapki::visit_variant{
		        [&](const klapki::ops::dump &) { return format_to(ctx.out(), "{{dump}}"); },
		    },
		    op.op);
	}
};

template <>
struct fmt::formatter<klapki::mops> {
	constexpr auto parse(format_parse_context & ctx) { return ctx.begin(); }

	template <typename FormatContext>
	auto format(const klapki::mops & ops, FormatContext & ctx) {
		auto out = ctx.out();

		bool first = true;
		for(auto && el : ops.ops) {
			if(!first)
				out = format_to(out, ", ");
			else
				first = false;

			out = format_to(out, "{}", klapki::op{el});
		}

		return out;
	}
};

A src/util.cpp => src/util.cpp +32 -0
@@ 0,0 1,32 @@
// The MIT License (MIT)

// Copyright (c) 2020 nabijaczleweli

// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


#include "util.hpp"
#include <fstream>


std::string klapki::readline(const char * from) {
	std::ifstream in(from);
	std::string ret;
	std::getline(in, ret);
	return ret;
}

A src/util.hpp => src/util.hpp +40 -0
@@ 0,0 1,40 @@
// The MIT License (MIT)

// Copyright (c) 2020 nabijaczleweli

// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


#pragma once



#include <string>


namespace klapki {
	std::string readline(const char * from);

	// Stolen from https://en.cppreference.com/w/cpp/utility/variant/visit
	template <class... Ts>
	struct visit_variant : Ts... {
		using Ts::operator()...;
	};
	template <class... Ts>
	visit_variant(Ts...)->visit_variant<Ts...>;
}