From 0667469832f8844aed4fef03d0c031d216d11884 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Tue, 19 Apr 2022 11:37:37 +0100 Subject: [PATCH] Replace getopt/ya_getopt with Lyra. --- src/inspircd.cpp | 98 +- vendor/README.md | 20 +- vendor/lyra/LICENSE.txt | 23 + vendor/lyra/lyra.hpp | 4409 +++++++++++++++++++++++++++++++++ vendor/update.toml | 13 +- vendor/ya_getopt/ya_getopt.c | 318 --- vendor/ya_getopt/ya_getopt.h | 77 - win/inspircd_win32wrapper.cpp | 2 - 8 files changed, 4507 insertions(+), 453 deletions(-) create mode 100644 vendor/lyra/LICENSE.txt create mode 100644 vendor/lyra/lyra.hpp delete mode 100644 vendor/ya_getopt/ya_getopt.c delete mode 100644 vendor/ya_getopt/ya_getopt.h diff --git a/src/inspircd.cpp b/src/inspircd.cpp index 601b320f0..8df74c5b3 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -36,6 +36,15 @@ #include #include +#ifdef __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wshadow" +#endif +#include +#ifdef __GNUC__ +# pragma GCC diagnostic pop +#endif + #include "inspircd.h" #include "exitcodes.h" #include "xline.h" @@ -43,10 +52,7 @@ // Needs to be included after inspircd.h to avoid reincluding winsock. #include -#ifdef _WIN32 -# include -#else -# include +#ifndef _WIN32 # include # include # include @@ -275,42 +281,52 @@ namespace // Parses the command line options. void ParseOptions() { - int do_debug = 0, do_nofork = 0, do_nolog = 0; - int do_nopid = 0, do_runasroot = 0, do_version = 0; - struct option longopts[] = + std::string config; + bool do_debug = false; + bool do_help = false; + bool do_nofork = false; + bool do_nolog = false; + bool do_nopid = false; + bool do_runasroot = false; + bool do_version = false; + + auto cli = lyra::cli() + | lyra::opt(config, "FILE") + ["-c"]["--config"] + ("The location of the main config file.") + | lyra::opt(do_debug) + ["-d"]["--debug"] + ("Start in debug mode.") + | lyra::opt(do_nofork) + ["-F"]["--nofork"] + ("Disable forking into the background.") + | lyra::opt(do_help) + ["-h"]["--help"] + ("Show help and exit.") + | lyra::opt(do_nolog) + ["-L"]["--nolog"] + ("Disable writing logs to disk.") + | lyra::opt(do_nopid) + ["-P"]["--nopid"] + ("Disable writing the pid file.") + | lyra::opt(do_runasroot) + ["-r"]["--runasroot"] + ("Allow starting as root (not recommended).") + | lyra::opt(do_version) + ["-v"]["--version"] + ("Show version and exit."); + + auto result = cli.parse({ServerInstance->Config->cmdline.argc, ServerInstance->Config->cmdline.argv}); + if (!result) { - { "config", required_argument, NULL, 'c' }, - { "debug", no_argument, &do_debug, 1 }, - { "nofork", no_argument, &do_nofork, 1 }, - { "nolog", no_argument, &do_nolog, 1 }, - { "nopid", no_argument, &do_nopid, 1 }, - { "runasroot", no_argument, &do_runasroot, 1 }, - { "version", no_argument, &do_version, 1 }, - { 0, 0, 0, 0 } - }; + std::cerr << rang::style::bold << rang::fg::red << "Error: " << rang::style::reset << result.message() << '.' << std::endl; + ServerInstance->Exit(EXIT_STATUS_ARGV); + } - char** argv = ServerInstance->Config->cmdline.argv; - int ret; - while ((ret = getopt_long(ServerInstance->Config->cmdline.argc, argv, ":c:", longopts, NULL)) != -1) + if (do_help) { - switch (ret) - { - case 0: - // A long option was specified. - break; - - case 'c': - // The -c option was specified. - ServerInstance->ConfigFileName = ExpandPath(optarg); - break; - - default: - // An unknown option was specified. - std::cout << rang::style::bold << rang::fg::red << "Error:" << rang::style::reset << " unknown option '" << argv[optind-1] << "'." << std::endl - << rang::style::bold << "Usage: " << rang::style::reset << argv[0] << " [--config ] [--debug] [--nofork] [--nolog]" << std::endl - << std::string(strlen(argv[0]) + 8, ' ') << "[--nopid] [--runasroot] [--version]" << std::endl; - ServerInstance->Exit(EXIT_STATUS_ARGV); - } + std::cout << cli << std::endl; + ServerInstance->Exit(EXIT_STATUS_NOERROR); } if (do_version) @@ -320,9 +336,11 @@ namespace } // Store the relevant parsed arguments - ServerInstance->Config->cmdline.forcedebug = !!do_debug; - ServerInstance->Config->cmdline.nofork = !!do_nofork; - ServerInstance->Config->cmdline.runasroot = !!do_runasroot; + if (!config.empty()) + ServerInstance->ConfigFileName = ExpandPath(config.c_str()); + ServerInstance->Config->cmdline.forcedebug = do_debug; + ServerInstance->Config->cmdline.nofork = do_nofork; + ServerInstance->Config->cmdline.runasroot = do_runasroot; ServerInstance->Config->cmdline.writelog = !do_nolog; ServerInstance->Config->cmdline.writepid = !do_nopid; } diff --git a/vendor/README.md b/vendor/README.md index 7ffb84e3d..e30546b7b 100644 --- a/vendor/README.md +++ b/vendor/README.md @@ -22,6 +22,16 @@ This directory contains vendored dependencies that are shipped with InspIRCd to **Website** — [https://github.com/nodejs/http-parser](https://github.com/nodejs/http-parser) +## lyra + +**Author** — Build Frameworks Group + +**License** — Boost Software License + +**Version** — 1.6 + +**Website** — [https://github.com/bfgroup/Lyra](https://github.com/bfgroup/Lyra) + ## md5 **Author** — [Solar Designer](mailto:solar@openwall.com) @@ -61,13 +71,3 @@ This directory contains vendored dependencies that are shipped with InspIRCd to **Version** — v3.2.1 **Website** — [https://github.com/nemtrif/utfcpp](https://github.com/nemtrif/utfcpp) - -## ya_getopt - -**Author** — Kubo Takehiro - -**License** — 2-clause BSD License - -**Version** — 6ce4310 - -**Website** — [https://github.com/kubo/ya_getopt](https://github.com/kubo/ya_getopt) diff --git a/vendor/lyra/LICENSE.txt b/vendor/lyra/LICENSE.txt new file mode 100644 index 000000000..36b7cd93c --- /dev/null +++ b/vendor/lyra/LICENSE.txt @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +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, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/vendor/lyra/lyra.hpp b/vendor/lyra/lyra.hpp new file mode 100644 index 000000000..86a36694d --- /dev/null +++ b/vendor/lyra/lyra.hpp @@ -0,0 +1,4409 @@ +// Copyright 2018-2022 RenĂ© Ferdinand Rivera Morell +// Copyright 2021 Max Ferger +// Copyright 2017 Two Blue Cubes Ltd. All rights reserved. +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LYRA_LYRA_HPP +#define LYRA_LYRA_HPP + + +#ifndef LYRA_VERSION_HPP +#define LYRA_VERSION_HPP + +#define LYRA_VERSION_MAJOR 1 +#define LYRA_VERSION_MINOR 6 +#define LYRA_VERSION_PATCH 0 + +#define LYRA_VERSION \ + (((LYRA_VERSION_MAJOR)*10000000) + ((LYRA_VERSION_MINOR)*100000) \ + + (LYRA_VERSION_PATCH)) + +#endif // LYRA_VERSION_HPP + + +#ifndef LYRA_ARG_HPP +#define LYRA_ARG_HPP + + +#ifndef LYRA_DETAIL_PRINT_HPP +#define LYRA_DETAIL_PRINT_HPP + +#include +#include + +#ifndef LYRA_DEBUG +# define LYRA_DEBUG 0 +#endif + +namespace lyra { namespace detail { + +constexpr bool is_debug = LYRA_DEBUG; + +template +std::string to_string(T && t) +{ + return std::string(std::move(t)); +} + +using std::to_string; + +struct print +{ + print(const char * scope = nullptr) + : scope(scope) + { + if (is_debug) print::depth() += 1; + if (scope) debug(scope, "..."); + } + + ~print() + { + if (scope) debug("...", scope); + if (is_debug) print::depth() -= 1; + } + + template + void debug(A... arg) + { + if (is_debug) + { + std::cerr << "[DEBUG]" + << std::string((print::depth() - 1) * 2, ' '); + std::string args[] = { to_string(arg)... }; + for (auto & arg_string : args) + { + std::cerr << " " << arg_string; + } + std::cerr << "\n"; + } + } + + private: + const char * scope; + + static std::size_t & depth() + { + static std::size_t d = 0; + return d; + } +}; + +}} // namespace lyra::detail + +#if LYRA_DEBUG +# define LYRA_PRINT_SCOPE ::lyra::detail::print lyra_print_scope +# define LYRA_PRINT_DEBUG lyra_print_scope.debug +#else +# define LYRA_PRINT_SCOPE(...) while (false) +# define LYRA_PRINT_DEBUG(...) while (false) +#endif + +#endif + +#ifndef LYRA_PARSER_HPP +#define LYRA_PARSER_HPP + + +#ifndef LYRA_ARGS_HPP +#define LYRA_ARGS_HPP + +#include +#include +#include + +namespace lyra { + +/* tag::reference[] + +[#lyra_args] += `lyra::args` + +Transport for raw args (copied from main args, supplied via init list, or from +a pair of iterators). + +*/ // end::reference[] +class args +{ + public: + args(int argc, char const * const * argv) + : m_exeName(argv[0]) + , m_args(argv + 1, argv + argc) + {} + + args(std::initializer_list args) + : m_exeName(*args.begin()) + , m_args(args.begin() + 1, args.end()) + {} + + template + args(const It & start, const It & end) + : m_exeName(*start) + , m_args(start + 1, end) + {} + + std::string exe_name() const { return m_exeName; } + + std::vector::const_iterator begin() const + { + return m_args.begin(); + } + + std::vector::const_iterator end() const + { + return m_args.end(); + } + + private: + std::string m_exeName; + std::vector m_args; +}; + +} // namespace lyra + +#endif + +#ifndef LYRA_DETAIL_BOUND_HPP +#define LYRA_DETAIL_BOUND_HPP + + +#ifndef LYRA_DETAIL_FROM_STRING_HPP +#define LYRA_DETAIL_FROM_STRING_HPP + + +#ifndef LYRA_DETAIL_TRAIT_UTILS_HPP +#define LYRA_DETAIL_TRAIT_UTILS_HPP + +#include +#include + +namespace lyra { namespace detail { + +template +struct is_callable +{ + template + static auto test(U * p) + -> decltype((*p)(std::declval()...), void(), std::true_type()); + + template + static auto test(...) -> decltype(std::false_type()); + + static constexpr bool value = decltype(test(0))::value; +}; + +template +struct remove_cvref +{ + typedef + typename std::remove_cv::type>::type + type; +}; + +template +struct is_invocable +{ + template + static auto test(U * p) + -> decltype((&U::operator()), void(), std::true_type()); + + template + static auto test(...) -> decltype(std::false_type()); + + static constexpr bool value + = decltype(test::type>(0))::value; +}; + +template +struct make_void +{ + typedef void type; +}; +template +using valid_t = typename make_void::type; + +template class Primary> +struct is_specialization_of : std::false_type +{}; +template