add argh fromhttps://github.com/aardvarkk/argh
This commit is contained in:
parent
3b7b0bee82
commit
b0ca75960b
2 changed files with 307 additions and 5 deletions
|
@ -20,13 +20,15 @@ set(MVLC_NNG_MNODE_WARN_FLAGS -Wall -Wextra -Wpedantic)
|
||||||
#)
|
#)
|
||||||
#target_include_directories(dp_common INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
|
#target_include_directories(dp_common INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
add_library(mesytec-mnode-nng mnode_nng.cc mnode_nng_async.cc)
|
add_library(mesytec-mnode mnode_nng.cc mnode_nng_async.cc)
|
||||||
target_include_directories(mesytec-mnode-nng PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>)
|
target_include_directories(mesytec-mnode
|
||||||
target_link_libraries(mesytec-mnode-nng PUBLIC nng PRIVATE spdlog)
|
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
|
||||||
target_compile_features(mesytec-mnode-nng PUBLIC cxx_std_17)
|
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/mesytec-mnode)
|
||||||
|
target_link_libraries(mesytec-mnode PUBLIC nng PRIVATE spdlog)
|
||||||
|
target_compile_features(mesytec-mnode PRIVATE cxx_std_17)
|
||||||
|
|
||||||
add_library(mesytec-mnode-dev INTERFACE)
|
add_library(mesytec-mnode-dev INTERFACE)
|
||||||
target_link_libraries(mesytec-mnode-dev INTERFACE mesytec-mnode-nng mesytec-mvlc)
|
target_link_libraries(mesytec-mnode-dev INTERFACE mesytec-mnode mesytec-mvlc)
|
||||||
|
|
||||||
function(add_mnode_dev_executable name)
|
function(add_mnode_dev_executable name)
|
||||||
add_executable(${name} ${name}.cc)
|
add_executable(${name} ${name}.cc)
|
||||||
|
|
300
src/internal/argh.h
Normal file
300
src/internal/argh.h
Normal file
|
@ -0,0 +1,300 @@
|
||||||
|
// Source: https://github.com/aardvarkk/argh
|
||||||
|
// The MIT License (MIT)
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014 Ian Clarkson
|
||||||
|
//
|
||||||
|
// 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 <algorithm>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class Option {
|
||||||
|
public:
|
||||||
|
Option() : parsed(false), required(false) {}
|
||||||
|
virtual ~Option() {};
|
||||||
|
|
||||||
|
virtual std::string getDefault() = 0;
|
||||||
|
virtual std::string getMessage() = 0;
|
||||||
|
virtual std::string getName() = 0;
|
||||||
|
virtual void setValue(std::string const& val) = 0;
|
||||||
|
|
||||||
|
bool getParsed() { return parsed; }
|
||||||
|
bool getRequired() { return required; }
|
||||||
|
|
||||||
|
virtual void setParsed(bool parsed) { this->parsed = parsed; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool parsed, required;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class OptionImpl : public Option {
|
||||||
|
public:
|
||||||
|
OptionImpl(T& var, T default_val, std::string const& name, bool required, std::string const& msg) : var(var)
|
||||||
|
{
|
||||||
|
this->default_val = default_val;
|
||||||
|
this->name = name;
|
||||||
|
this->required = required;
|
||||||
|
this->msg = msg;
|
||||||
|
this->var = default_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual std::string getDefault() { std::stringstream ss; ss << default_val; return ss.str(); }
|
||||||
|
std::string getName() { return name; }
|
||||||
|
std::string getMessage() { return msg; }
|
||||||
|
virtual void setValue(std::string const& val) { std::stringstream ss(val); ss >> var; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
T default_val;
|
||||||
|
T& var;
|
||||||
|
std::string name;
|
||||||
|
std::string msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
class OptionStringImpl : public OptionImpl<std::string>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OptionStringImpl(std::string& var, std::string const& default_val, std::string const& name, bool required, std::string const& msg) :
|
||||||
|
OptionImpl(var, default_val, name, required, msg)
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::string getDefault() { std::stringstream ss; ss << "\"" << default_val << "\""; return ss.str(); }
|
||||||
|
void setValue(std::string const& val) { var = val; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class MultiOptionImpl : public Option
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MultiOptionImpl(std::vector<T>& var, std::string const& default_vals, std::string const& name, bool required, std::string const& msg, char delim) : var(var)
|
||||||
|
{
|
||||||
|
this->default_vals = default_vals;
|
||||||
|
this->name = name;
|
||||||
|
this->required = required;
|
||||||
|
this->msg = msg;
|
||||||
|
this->delim = delim;
|
||||||
|
setValue(default_vals);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getDefault()
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "\"";
|
||||||
|
ss << default_vals;
|
||||||
|
ss << "\"";
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getName() { return name; }
|
||||||
|
std::string getMessage() { return msg; }
|
||||||
|
virtual void setValue(std::string const& val) {
|
||||||
|
var.clear();
|
||||||
|
std::stringstream ss(val);
|
||||||
|
T elem;
|
||||||
|
for (std::string val_str; std::getline(ss, val_str, delim);) {
|
||||||
|
std::stringstream st(val_str);
|
||||||
|
st >> elem;
|
||||||
|
var.push_back(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string default_vals;
|
||||||
|
std::vector<T>& var;
|
||||||
|
std::string name;
|
||||||
|
std::string msg;
|
||||||
|
char delim;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MultiOptionStringImpl : public MultiOptionImpl<std::string>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MultiOptionStringImpl(std::vector<std::string>& var, std::string const& default_vals, std::string const& name, bool required, std::string const& msg, char delim) :
|
||||||
|
MultiOptionImpl(var, default_vals, name, required, msg, delim)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void setValue(std::string const& val) {
|
||||||
|
var.clear();
|
||||||
|
std::stringstream ss(val);
|
||||||
|
for (std::string val_str; std::getline(ss, val_str, delim);) {
|
||||||
|
var.push_back(val_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class FlagImpl : public Option {
|
||||||
|
public:
|
||||||
|
FlagImpl(bool& flag, std::string const& name, std::string const& msg) :
|
||||||
|
flag(flag),
|
||||||
|
name(name),
|
||||||
|
msg(msg)
|
||||||
|
{
|
||||||
|
flag = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getDefault() { return ""; }
|
||||||
|
std::string getName() { return name; }
|
||||||
|
std::string getMessage() { return msg; }
|
||||||
|
void setParsed(bool parsed) { Option::setParsed(parsed); flag = parsed; }
|
||||||
|
void setValue(std::string const& val) {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool& flag;
|
||||||
|
std::string name;
|
||||||
|
std::string msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Argh {
|
||||||
|
public:
|
||||||
|
Argh(char delim = ',') : delim(delim) {}
|
||||||
|
~Argh() { for (auto o : options) { delete o; } options.clear(); }
|
||||||
|
|
||||||
|
void parse(int argc, char const* argv[]) {
|
||||||
|
for (int i = 0; i < argc; ++i) {
|
||||||
|
for (auto o : options) {
|
||||||
|
if (std::string(argv[i]) == o->getName()) {
|
||||||
|
o->setParsed(true);
|
||||||
|
if (i + 1 < argc) {
|
||||||
|
o->setValue(argv[i + 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseEnv() {
|
||||||
|
for (auto o : options) {
|
||||||
|
auto str = getenv(o->getName().c_str());
|
||||||
|
if (str) {
|
||||||
|
o->setParsed(true);
|
||||||
|
o->setValue(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void addOption(T& var, T const& default_val, std::string const& name, bool required = false, std::string const& msg = "") {
|
||||||
|
options.push_back(new OptionImpl<T>(var, default_val, name, required, msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
void addOption(std::string& var, std::string const& default_val, std::string const& name, bool required = false, std::string const& msg = "") {
|
||||||
|
options.push_back(new OptionStringImpl(var, default_val, name, required, msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void addMultiOption(std::vector<T>& var, std::string const& default_vals, std::string const& name, bool required = false, std::string const& msg = "") {
|
||||||
|
options.push_back(new MultiOptionImpl<T>(var, default_vals, name, required, msg, delim));
|
||||||
|
}
|
||||||
|
|
||||||
|
void addMultiOption(std::vector<std::string>& var, std::string const& default_vals, std::string const& name, bool required = false, std::string const& msg = "") {
|
||||||
|
options.push_back(new MultiOptionStringImpl(var, default_vals, name, required, msg, delim));
|
||||||
|
}
|
||||||
|
|
||||||
|
void addFlag(bool& flag, std::string const& name, std::string const& msg = "") {
|
||||||
|
options.push_back(new FlagImpl(flag, name, msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getUsage() {
|
||||||
|
size_t name_space = getLongestName() + 1;
|
||||||
|
size_t default_space = getLongestDefault() + 1;
|
||||||
|
size_t msg_space = getLongestMessage() + 1;
|
||||||
|
|
||||||
|
std::stringstream ret;
|
||||||
|
ret << std::left;
|
||||||
|
for (auto o : options) {
|
||||||
|
ret
|
||||||
|
<< std::setw(static_cast<int>(name_space)) << o->getName()
|
||||||
|
<< std::setw(static_cast<int>(default_space)) << o->getDefault()
|
||||||
|
<< std::setw(static_cast<int>(msg_space)) << o->getMessage()
|
||||||
|
<< (o->getRequired() ? "REQUIRED" : "NOT REQUIRED")
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
return ret.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isParsed(std::string const& name) {
|
||||||
|
for (auto o : options) {
|
||||||
|
if (name == o->getName() && o->getParsed()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> missingRequired() {
|
||||||
|
std::vector<std::string> missing;
|
||||||
|
for (auto o : options) {
|
||||||
|
if (o->getRequired() && !o->getParsed())
|
||||||
|
missing.push_back(o->getName());
|
||||||
|
}
|
||||||
|
return missing;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool load(std::string const& filename) {
|
||||||
|
std::ifstream ifs(filename);
|
||||||
|
if (!ifs.good()) { return false; }
|
||||||
|
int argc = 0;
|
||||||
|
std::vector<std::string> argv_str;
|
||||||
|
std::vector<char const*> argv;
|
||||||
|
std::string arg;
|
||||||
|
while (std::getline(ifs, arg)) {
|
||||||
|
argv_str.push_back(arg);
|
||||||
|
++argc;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < argc; ++i) {
|
||||||
|
argv.push_back(argv_str[i].c_str());
|
||||||
|
}
|
||||||
|
parse(argc, &*argv.begin());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
size_t getLongestName() {
|
||||||
|
size_t ret = 0;
|
||||||
|
for (auto o : options) {
|
||||||
|
ret = std::max(ret, o->getName().length());
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t getLongestDefault() {
|
||||||
|
size_t ret = 0;
|
||||||
|
for (auto o : options) {
|
||||||
|
ret = std::max(ret, o->getDefault().length());
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t getLongestMessage() {
|
||||||
|
size_t ret = 0;
|
||||||
|
for (auto o : options) {
|
||||||
|
ret = std::max(ret, o->getMessage().length());
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Option*> options;
|
||||||
|
char delim;
|
||||||
|
};
|
Loading…
Reference in a new issue