// Copyright (c) 2012-2015, The CryptoNote developers, The Bytecoin developers
//
// This file is part of Bytecoin.
//
// Bytecoin is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Bytecoin is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Bytecoin. If not, see .
#pragma once
#include
#include
#include
#include
#include
namespace command_line
{
template
struct arg_descriptor;
template
struct arg_descriptor
{
typedef T value_type;
const char* name;
const char* description;
T default_value;
bool not_use_default;
};
template
struct arg_descriptor, false>
{
typedef std::vector value_type;
const char* name;
const char* description;
};
template
struct arg_descriptor
{
static_assert(!std::is_same::value, "Boolean switch can't be required");
typedef T value_type;
const char* name;
const char* description;
};
template
boost::program_options::typed_value* make_semantic(const arg_descriptor& /*arg*/)
{
return boost::program_options::value()->required();
}
template
boost::program_options::typed_value* make_semantic(const arg_descriptor& arg)
{
auto semantic = boost::program_options::value();
if (!arg.not_use_default)
semantic->default_value(arg.default_value);
return semantic;
}
template
boost::program_options::typed_value* make_semantic(const arg_descriptor& arg, const T& def)
{
auto semantic = boost::program_options::value();
if (!arg.not_use_default)
semantic->default_value(def);
return semantic;
}
template
boost::program_options::typed_value, char>* make_semantic(const arg_descriptor, false>& /*arg*/)
{
auto semantic = boost::program_options::value< std::vector >();
semantic->default_value(std::vector(), "");
return semantic;
}
template
void add_arg(boost::program_options::options_description& description, const arg_descriptor& arg, bool unique = true)
{
if (unique && 0 != description.find_nothrow(arg.name, false))
{
std::cerr << "Argument already exists: " << arg.name << std::endl;
return;
}
description.add_options()(arg.name, make_semantic(arg), arg.description);
}
template
void add_arg(boost::program_options::options_description& description, const arg_descriptor& arg, const T& def, bool unique = true)
{
if (unique && 0 != description.find_nothrow(arg.name, false))
{
std::cerr << "Argument already exists: " << arg.name << std::endl;
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& arg, bool unique)
{
if (unique && 0 != description.find_nothrow(arg.name, false))
{
std::cerr << "Argument already exists: " << arg.name << std::endl;
return;
}
description.add_options()(arg.name, boost::program_options::bool_switch(), arg.description);
}
template
boost::program_options::basic_parsed_options 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
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
bool has_arg(const boost::program_options::variables_map& vm, const arg_descriptor& arg)
{
auto value = vm[arg.name];
return !value.empty();
}
template
T get_arg(const boost::program_options::variables_map& vm, const arg_descriptor& arg)
{
return vm[arg.name].template as();
}
template<>
inline bool has_arg(const boost::program_options::variables_map& vm, const arg_descriptor& arg)
{
return get_arg(vm, arg);
}
extern const arg_descriptor arg_help;
extern const arg_descriptor arg_version;
extern const arg_descriptor arg_data_dir;
}