// Copyright (c) 2012-2014, 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 #include "include_base_utils.h" 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 (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 void add_arg(boost::program_options::options_description& description, const arg_descriptor& 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& 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 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; }