forked from lthn/blockchain
Enhances local network privacy by disabling UPnP (discovery (SSDP), etc.), and also speeds up the daemon on startup if UPnP is not needed. In other words, allows the option to completely disable the use of UPnP.
188 lines
5.7 KiB
C++
188 lines
5.7 KiB
C++
// Copyright (c) 2014-2018 Zano Project
|
|
// Copyright (c) 2014-2018 The Louisdor Project
|
|
// Copyright (c) 2012-2013 The Cryptonote developers
|
|
// Distributed under the MIT/X11 software license, see the accompanying
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
#pragma once
|
|
|
|
#include <iostream>
|
|
#include <type_traits>
|
|
|
|
#include <boost/program_options/parsers.hpp>
|
|
#include <boost/program_options/options_description.hpp>
|
|
#include <boost/program_options/variables_map.hpp>
|
|
#include "include_base_utils.h"
|
|
|
|
namespace command_line
|
|
{
|
|
template<typename T, bool required = false>
|
|
struct arg_descriptor;
|
|
|
|
template<typename T>
|
|
struct arg_descriptor<T, false>
|
|
{
|
|
typedef T value_type;
|
|
|
|
const char* name;
|
|
const char* description;
|
|
T default_value;
|
|
bool not_use_default;
|
|
};
|
|
|
|
template<typename T>
|
|
struct arg_descriptor<std::vector<T>, false>
|
|
{
|
|
typedef std::vector<T> value_type;
|
|
|
|
const char* name;
|
|
const char* description;
|
|
};
|
|
|
|
template<typename T>
|
|
struct arg_descriptor<T, true>
|
|
{
|
|
static_assert(!std::is_same<T, bool>::value, "Boolean switch can't be required");
|
|
|
|
typedef T value_type;
|
|
|
|
const char* name;
|
|
const char* description;
|
|
};
|
|
|
|
template<typename T>
|
|
boost::program_options::typed_value<T, char>* make_semantic(const arg_descriptor<T, true>& /*arg*/)
|
|
{
|
|
return boost::program_options::value<T>()->required();
|
|
}
|
|
|
|
template<typename T>
|
|
boost::program_options::typed_value<T, char>* make_semantic(const arg_descriptor<T, false>& arg)
|
|
{
|
|
auto semantic = boost::program_options::value<T>();
|
|
if (!arg.not_use_default)
|
|
semantic->default_value(arg.default_value);
|
|
return semantic;
|
|
}
|
|
|
|
template<typename T>
|
|
boost::program_options::typed_value<T, char>* make_semantic(const arg_descriptor<T, false>& arg, const T& def)
|
|
{
|
|
auto semantic = boost::program_options::value<T>();
|
|
if (!arg.not_use_default)
|
|
semantic->default_value(def);
|
|
return semantic;
|
|
}
|
|
|
|
template<typename T>
|
|
boost::program_options::typed_value<std::vector<T>, char>* make_semantic(const arg_descriptor<std::vector<T>, false>& /*arg*/)
|
|
{
|
|
auto semantic = boost::program_options::value< std::vector<T> >();
|
|
semantic->default_value(std::vector<T>(), "");
|
|
return semantic;
|
|
}
|
|
|
|
template<typename T, bool required>
|
|
void add_arg(boost::program_options::options_description& description, const arg_descriptor<T, required>& arg, bool unique = true)
|
|
{
|
|
if (0 != description.find_nothrow(arg.name, false))
|
|
{
|
|
CHECK_AND_ASSERT_MES(!unique, void(), "Argument already exists: " << arg.name);
|
|
return;
|
|
}
|
|
|
|
description.add_options()(arg.name, make_semantic(arg), arg.description);
|
|
}
|
|
|
|
template<typename T>
|
|
void add_arg(boost::program_options::options_description& description, const arg_descriptor<T, false>& arg, const T& def, bool unique = true)
|
|
{
|
|
if (0 != description.find_nothrow(arg.name, false))
|
|
{
|
|
CHECK_AND_ASSERT_MES(!unique, void(), "Argument already exists: " << arg.name);
|
|
return;
|
|
}
|
|
|
|
description.add_options()(arg.name, make_semantic(arg, def), arg.description);
|
|
}
|
|
|
|
template<>
|
|
inline void add_arg(boost::program_options::options_description& description, const arg_descriptor<bool, false>& arg, bool unique)
|
|
{
|
|
if (0 != description.find_nothrow(arg.name, false))
|
|
{
|
|
CHECK_AND_ASSERT_MES(!unique, void(), "Argument already exists: " << arg.name);
|
|
return;
|
|
}
|
|
|
|
description.add_options()(arg.name, boost::program_options::bool_switch(), arg.description);
|
|
}
|
|
|
|
template<typename charT>
|
|
boost::program_options::basic_parsed_options<charT> parse_command_line(int argc, const charT* const argv[],
|
|
const boost::program_options::options_description& desc, bool allow_unregistered = false)
|
|
{
|
|
auto parser = boost::program_options::command_line_parser(argc, argv);
|
|
parser.options(desc);
|
|
if (allow_unregistered)
|
|
{
|
|
parser.allow_unregistered();
|
|
}
|
|
return parser.run();
|
|
}
|
|
|
|
template<typename F>
|
|
bool handle_error_helper(const boost::program_options::options_description& desc, F parser)
|
|
{
|
|
try
|
|
{
|
|
return parser();
|
|
}
|
|
catch (std::exception& e)
|
|
{
|
|
std::cerr << "Failed to parse arguments: " << e.what() << std::endl;
|
|
std::cerr << desc << std::endl;
|
|
return false;
|
|
}
|
|
catch (...)
|
|
{
|
|
std::cerr << "Failed to parse arguments: unknown exception" << std::endl;
|
|
std::cerr << desc << std::endl;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
template<typename T, bool required>
|
|
bool has_arg(const boost::program_options::variables_map& vm, const arg_descriptor<T, required>& arg)
|
|
{
|
|
auto value = vm[arg.name];
|
|
return !value.empty();
|
|
}
|
|
|
|
|
|
template<typename T, bool required>
|
|
T get_arg(const boost::program_options::variables_map& vm, const arg_descriptor<T, required>& arg)
|
|
{
|
|
return vm[arg.name].template as<T>();
|
|
}
|
|
|
|
template<>
|
|
inline bool has_arg<bool, false>(const boost::program_options::variables_map& vm, const arg_descriptor<bool, false>& arg)
|
|
{
|
|
return get_arg<bool, false>(vm, arg);
|
|
}
|
|
|
|
|
|
extern const arg_descriptor<bool> arg_help;
|
|
extern const arg_descriptor<bool> arg_version;
|
|
extern const arg_descriptor<std::string> arg_data_dir;
|
|
extern const arg_descriptor<std::string> arg_config_file;
|
|
extern const arg_descriptor<bool> arg_os_version;
|
|
extern const arg_descriptor<std::string> arg_log_dir;
|
|
extern const arg_descriptor<std::string> arg_log_file;
|
|
extern const arg_descriptor<int> arg_log_level;
|
|
extern const arg_descriptor<bool> arg_console;
|
|
extern const arg_descriptor<bool> arg_show_details;
|
|
extern const arg_descriptor<bool> arg_show_rpc_autodoc;
|
|
extern const arg_descriptor<bool> arg_disable_upnp;
|
|
}
|