diff --git a/src/configreader.cpp b/src/configreader.cpp index 1c418eae7..e71c22f59 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -31,7 +31,6 @@ #include -#include #ifndef _WIN32 # include #endif @@ -507,9 +506,11 @@ void ServerConfig::Apply(ServerConfig* old, const std::string& useruid) getline(errstr, line, '\n'); if (line.empty()) continue; + // On startup, print out to console (still attached at this point) if (!old) - std::cout << line << std::endl; + fmt::println(line); + // If a user is rehashing, tell them directly if (user) user->WriteRemoteNotice(INSP_FORMAT("*** {}", line)); diff --git a/src/coremods/core_dns.cpp b/src/coremods/core_dns.cpp index 3ad672676..6eba7573d 100644 --- a/src/coremods/core_dns.cpp +++ b/src/coremods/core_dns.cpp @@ -24,7 +24,6 @@ #include "modules/dns.h" #include "modules/stats.h" -#include #include #ifdef _WIN32 diff --git a/src/inspircd.cpp b/src/inspircd.cpp index f6fdcaabf..6d0ed4163 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -36,8 +36,8 @@ #include #include +#include #include -#include #include "inspircd.h" #include "exitcodes.h" @@ -48,6 +48,7 @@ # include # include # include +# include #else # define STDIN_FILENO 0 # define STDOUT_FILENO 1 @@ -77,21 +78,21 @@ namespace if (getegid() != 0 && geteuid() != 0) return; - std::cout << rang::style::bold << rang::fg::red << "Warning!" << rang::style::reset << " You have started as root. Running as root is generally not required" << std::endl - << "and may allow an attacker to gain access to your system if they find a way to" << std::endl - << "exploit your IRC server." << std::endl - << std::endl; + fmt::println("{} You have started as root. Running as root is generally not required", fmt::styled("Warning!", fmt::emphasis::bold | fmt::fg(fmt::terminal_color::red))); + fmt::println("and may allow an attacker to gain access to your system if they find a way to"); + fmt::println("exploit your IRC server."); + fmt::println(""); if (isatty(fileno(stdout))) { - std::cout << "InspIRCd will start in 30 seconds. If you are sure that you need to run as root" << std::endl - << "then you can pass the " << rang::style::bold << "--runasroot" << rang::style::reset << " option to disable this wait." << std::endl; + fmt::println("InspIRCd will start in 30 seconds. If you are sure that you need to run as root"); + fmt::println("then you can pass the {} option to disable this wait.", fmt::styled("--runasroot", fmt::emphasis::bold)); sleep(30); } else { - std::cout << "If you are sure that you need to run as root then you can pass the " << rang::style::bold << "--runasroot" << rang::style::reset << std::endl - << "option to disable this error." << std::endl; - ServerInstance->Exit(EXIT_STATUS_ROOT); + fmt::println("If you are sure that you need to run as root then you can pass the {}", fmt::styled("--runasroot", fmt::emphasis::bold)); + fmt::println("option to disable this error."); + ServerInstance->Exit(EXIT_STATUS_ROOT); } #endif } @@ -235,7 +236,7 @@ namespace if (childpid < 0) { ServerInstance->Logs.Error("STARTUP", "fork() failed: {}", strerror(errno)); - std::cout << rang::style::bold << rang::fg::red << "Error:" << rang::style::reset << " unable to fork into background: " << strerror(errno); + fmt::println("{} unable to fork into background: {}", fmt::styled("Error:", fmt::emphasis::bold | fmt::fg(fmt::terminal_color::red)), strerror(errno)); ServerInstance->Exit(EXIT_STATUS_FORK); } else if (childpid > 0) @@ -316,7 +317,7 @@ namespace auto result = cli.parse({ServerInstance->Config->CommandLine.argc, ServerInstance->Config->CommandLine.argv}); if (!result) { - std::cerr << rang::style::bold << rang::fg::red << "Error: " << rang::style::reset << result.message() << '.' << std::endl; + fmt::println(stderr, "{} {}", fmt::styled("Error:", fmt::emphasis::bold | fmt::fg(fmt::terminal_color::red)), result.message()); ServerInstance->Exit(EXIT_STATUS_ARGV); } @@ -328,7 +329,7 @@ namespace if (do_version) { - std::cout << INSPIRCD_VERSION << std::endl; + fmt::println(INSPIRCD_VERSION); ServerInstance->Exit(EXIT_STATUS_NOERROR); } @@ -373,24 +374,24 @@ namespace if (!pl.empty()) { - std::cout << rang::style::bold << rang::fg::red << "Warning!" << rang::style::reset << " Some of your listener" << (pl.size() == 1 ? "s" : "") << " failed to bind:" << std::endl - << std::endl; + fmt::println("{} Some of your listeners failed to bind:", fmt::styled("Warning!", fmt::emphasis::bold | fmt::fg(fmt::terminal_color::red))); + fmt::println(""); for (const auto& fp : pl) { - std::cout << " "; + fmt::print(" "); if (fp.sa.family() != AF_UNSPEC) - std::cout << rang::style::bold << fp.sa.str() << rang::style::reset << ": "; + fmt::print("{}: ", fmt::styled(fp.sa.str(), fmt::emphasis::bold)); - std::cout << fp.error << '.' << std::endl - << " " << "Created from tag at " << fp.tag->source.str() << std::endl - << std::endl; + fmt::println("{}.", fp.error); + fmt::println("Created from tag at {}", fp.tag->source.str()); + fmt::println(""); } - std::cout << rang::style::bold << "Hints:" << rang::style::reset << std::endl - << "- For TCP/IP listeners try using a public IP address in instead" << std::endl - << " of * or leaving it blank." << std::endl - << "- For UNIX socket listeners try enabling to replace old sockets." << std::endl; + fmt::print(fmt::text_style(fmt::emphasis::bold), "Hints:"); + fmt::println("- For TCP/IP listeners try using a public IP address in instead"); + fmt::println(" of * or leaving it blank."); + fmt::println("- For UNIX socket listeners try enabling to replace old sockets."); } } @@ -454,7 +455,7 @@ void InspIRCd::WritePID() } else { - std::cout << "Failed to write PID-file '" << pidfile << "', exiting." << std::endl; + fmt::println("Failed to write PID-file '{}', exiting.", pidfile); this->Logs.Error("STARTUP", "Failed to write PID-file '{}', exiting.", pidfile); Exit(EXIT_STATUS_PID); } @@ -489,9 +490,9 @@ InspIRCd::InspIRCd(int argc, char** argv) Modules.AddServices(provs, sizeof(provs)/sizeof(provs[0])); } - std::cout << rang::style::bold << rang::fg::green << "InspIRCd - Internet Relay Chat Daemon" << rang::style::reset << std::endl - << "See " << rang::style::bold << rang::fg::green << "/INFO" << rang::style::reset << " for contributors & authors" << std::endl - << std::endl; + fmt::println("{}", fmt::styled("InspIRCd - Internet Relay Chat Daemon", fmt::emphasis::bold | fmt::fg(fmt::terminal_color::green))); + fmt::println("See {} for contributors & authors", fmt::styled("/INFO", fmt::emphasis::bold | fmt::fg(fmt::terminal_color::green))); + fmt::println(""); Logs.RegisterServices(); if (Config->CommandLine.forcedebug) @@ -500,7 +501,8 @@ InspIRCd::InspIRCd(int argc, char** argv) if (!FindConfigFile(ConfigFileName)) { this->Logs.Error("STARTUP", "Unable to open config file {}", ConfigFileName); - std::cout << "ERROR: Cannot open config file: " << ConfigFileName << std::endl << "Exiting..." << std::endl; + fmt::println("ERROR: Cannot open config file: {}", ConfigFileName); + fmt::println("Exiting..."); Exit(EXIT_STATUS_CONFIG); } @@ -510,7 +512,7 @@ InspIRCd::InspIRCd(int argc, char** argv) if (!Config->CommandLine.nofork) ForkIntoBackground(); - std::cout << "InspIRCd Process ID: " << rang::style::bold << rang::fg::green << getpid() << rang::style::reset << std::endl; + fmt::println("InspIRCd Process ID: {}", fmt::styled(getpid(), fmt::emphasis::bold | fmt::fg(fmt::terminal_color::green))); /* During startup we read the configuration now, not in * a separate thread @@ -525,7 +527,8 @@ InspIRCd::InspIRCd(int argc, char** argv) } catch (const CoreException& ex) { - std::cout << "ERROR: Cannot open log files: " << ex.GetReason() << std::endl << "Exiting..." << std::endl; + fmt::println("ERROR: Cannot open log files: {}", ex.GetReason()); + fmt::println("Exiting..."); Exit(EXIT_STATUS_LOG); } @@ -542,7 +545,7 @@ InspIRCd::InspIRCd(int argc, char** argv) // This is needed as all new XLines are marked pending until ApplyLines() is called this->XLines->ApplyLines(); - std::cout << std::endl; + fmt::println(""); TryBindPorts(); @@ -555,18 +558,20 @@ InspIRCd::InspIRCd(int argc, char** argv) } catch (const CoreException& ex) { - std::cout << "ERROR: Cannot open log files: " << ex.GetReason() << std::endl << "Exiting..." << std::endl; + fmt::println("ERROR: Cannot open log files: {}", ex.GetReason()); + fmt::println("Exiting..."); Exit(EXIT_STATUS_LOG); } - std::cout << "InspIRCd is now running as '" << Config->ServerName << "'[" << Config->ServerId << "] with " << SocketEngine::GetMaxFds() << " max open sockets" << std::endl; + fmt::println("InspIRCd is now running as '{}'[{}] with {} max open sockets", + Config->ServerName, Config->ServerId, SocketEngine::GetMaxFds()); #ifndef _WIN32 if (!Config->CommandLine.nofork) { if (kill(getppid(), SIGTERM) == -1) { - std::cout << "Error killing parent process: " << strerror(errno) << std::endl; + fmt::println("Error killing parent process: {}", strerror(errno)); Logs.Warning("STARTUP", "Error killing parent process: {}", strerror(errno)); } } diff --git a/src/modulemanager.cpp b/src/modulemanager.cpp index 2c0b27527..b0ac5f711 100644 --- a/src/modulemanager.cpp +++ b/src/modulemanager.cpp @@ -23,9 +23,8 @@ #include -#include -#include +#include #include "inspircd.h" #include "dynamic.h" @@ -128,7 +127,8 @@ bool ModuleManager::Load(const std::string& modname, bool defer) /* We must load the modules AFTER initializing the socket engine, now */ void ModuleManager::LoadCoreModules(std::map& servicemap) { - std::cout << "Loading core modules " << std::flush; + fmt::print("Loading core modules "); + fflush(stdout); try { @@ -141,21 +141,24 @@ void ModuleManager::LoadCoreModules(std::map& servicem if (!InspIRCd::Match(name, "core_*" DLL_EXTENSION)) continue; - std::cout << "." << std::flush; + fmt::print("."); + fflush(stdout); this->NewServices = &servicemap[name]; if (!Load(name, true)) { - std::cout << std::endl << "[" << rang::style::bold << rang::fg::red << "*" << rang::style::reset << "] " << this->LastError() << std::endl << std::endl; + fmt::println(""); + fmt::println("[{}] {}", fmt::styled("*", fmt::emphasis::bold | fmt::fg(fmt::terminal_color::red)), LastError()); + fmt::println(""); ServerInstance->Exit(EXIT_STATUS_MODULE); } } } catch (const std::filesystem::filesystem_error& err) { - std::cout << "failed: " << err.what() << std::endl; + fmt::println("failed: {}", err.what()); ServerInstance->Exit(EXIT_STATUS_MODULE); } - std::cout << std::endl; + fmt::println(""); } diff --git a/src/modules.cpp b/src/modules.cpp index 74d8acf08..13c73cb28 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -30,9 +30,7 @@ */ -#include - -#include +#include #include "inspircd.h" #include "exitcodes.h" @@ -536,10 +534,12 @@ void ModuleManager::LoadAll() continue; this->NewServices = &servicemap[name]; - std::cout << "[" << rang::style::bold << rang::fg::green << "*" << rang::style::reset << "] Loading module:\t" << rang::style::bold << rang::fg::green << name << rang::style::reset << std::endl; + fmt::println("[{}] Loading module:\t{}", fmt::styled("*", fmt::emphasis::bold | fmt::fg(fmt::terminal_color::green)), name); if (!this->Load(name, true)) { - std::cout << std::endl << "[" << rang::style::bold << rang::fg::red << "*" << rang::style::reset << "] " << this->LastError() << std::endl << std::endl; + fmt::println(""); + fmt::println("[{}] {}", fmt::styled("*", fmt::emphasis::bold | fmt::fg(fmt::terminal_color::red)), LastError()); + fmt::println(""); ServerInstance->Exit(EXIT_STATUS_MODULE); } } @@ -558,7 +558,9 @@ void ModuleManager::LoadAll() { LastModuleError = "Unable to initialize " + modname + ": " + modexcept.GetReason(); ServerInstance->Logs.Error("MODULE", LastModuleError); - std::cout << std::endl << "[" << rang::style::bold << rang::fg::red << "*" << rang::style::reset << "] " << LastModuleError << std::endl << std::endl; + fmt::println(""); + fmt::println("[{}] {}", fmt::styled("*", fmt::emphasis::bold | fmt::fg(fmt::terminal_color::red)), LastModuleError); + fmt::println(""); ServerInstance->Exit(EXIT_STATUS_MODULE); } } @@ -580,7 +582,9 @@ void ModuleManager::LoadAll() { LastModuleError = "Unable to read the configuration for " + modname + ": " + modexcept.GetReason(); ServerInstance->Logs.Error("MODULE", LastModuleError); - std::cout << std::endl << "[" << rang::style::bold << rang::fg::red << "*" << rang::style::reset << "] " << LastModuleError << std::endl << std::endl; + fmt::println(""); + fmt::println("[{}] {}", fmt::styled("*", fmt::emphasis::bold | fmt::fg(fmt::terminal_color::red)), LastModuleError); + fmt::println(""); ServerInstance->Exit(EXIT_STATUS_CONFIG); } } diff --git a/src/socketengine.cpp b/src/socketengine.cpp index 9a42e856d..c760b1a12 100644 --- a/src/socketengine.cpp +++ b/src/socketengine.cpp @@ -26,15 +26,14 @@ */ -#include - -#include - #ifndef _WIN32 # include # include +# include #endif +#include + #include "inspircd.h" #include "exitcodes.h" @@ -71,7 +70,7 @@ void EventHandler::OnEventHandlerError(int errornum) void SocketEngine::InitError() { - std::cerr << rang::style::bold << rang::fg::red << "FATAL ERROR!" << rang::style::reset << " Socket engine initialization failed. " << strerror(errno) << '.' << std::endl; + fmt::println(stderr, "{} Socket engine initialization failed. {}.", fmt::styled("FATAL ERROR!", fmt::emphasis::bold | fmt::fg(fmt::terminal_color::red)), strerror(errno)); InspIRCd::QuickExit(EXIT_STATUS_SOCKETENGINE); } diff --git a/vendor/README.md b/vendor/README.md index e2a2a2118..b8b3c7876 100644 --- a/vendor/README.md +++ b/vendor/README.md @@ -52,16 +52,6 @@ This directory contains vendored dependencies that are shipped with InspIRCd to **Website** — [https://openwall.info/wiki/people/solar/software/public-domain-source-code/md5](https://openwall.info/wiki/people/solar/software/public-domain-source-code/md5) -## rang - -**Author** — Abhinav Gauniyal - -**License** — Unlicense - -**Version** — v3.2 - -**Website** — [https://github.com/agauniyal/rang/](https://github.com/agauniyal/rang/) - ## sha2 **Author** — [Olivier Gay](mailto:olivier.gay@a3.epfl.ch) diff --git a/vendor/rang/LICENSE b/vendor/rang/LICENSE deleted file mode 100644 index cf1ab25da..000000000 --- a/vendor/rang/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -This is free and unencumbered software released into the public domain. - -Anyone is free to copy, modify, publish, use, compile, sell, or -distribute this software, either in source code form or as a compiled -binary, for any purpose, commercial or non-commercial, and by any -means. - -In jurisdictions that recognize copyright laws, the author or authors -of this software dedicate any and all copyright interest in the -software to the public domain. We make this dedication for the benefit -of the public at large and to the detriment of our heirs and -successors. We intend this dedication to be an overt act of -relinquishment in perpetuity of all present and future rights to this -software under copyright law. - -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 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. - -For more information, please refer to diff --git a/vendor/rang/rang.hpp b/vendor/rang/rang.hpp deleted file mode 100644 index 831eda4c5..000000000 --- a/vendor/rang/rang.hpp +++ /dev/null @@ -1,502 +0,0 @@ -#ifndef RANG_DOT_HPP -#define RANG_DOT_HPP - -#if defined(__unix__) || defined(__unix) || defined(__linux__) -#define OS_LINUX -#elif defined(WIN32) || defined(_WIN32) || defined(_WIN64) -#define OS_WIN -#elif defined(__APPLE__) || defined(__MACH__) -#define OS_MAC -#else -#error Unknown Platform -#endif - -#if defined(OS_LINUX) || defined(OS_MAC) -#include - -#elif defined(OS_WIN) - -#if defined(_WIN32_WINNT) && (_WIN32_WINNT < 0x0600) -#error \ - "Please include rang.hpp before any windows system headers or set _WIN32_WINNT at least to _WIN32_WINNT_VISTA" -#elif !defined(_WIN32_WINNT) -#define _WIN32_WINNT _WIN32_WINNT_VISTA -#endif - -#include -#include -#include - -// Only defined in windows 10 onwards, redefining in lower windows since it -// doesn't gets used in lower versions -// https://docs.microsoft.com/en-us/windows/console/getconsolemode -#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING -#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 -#endif - -#endif - -#include -#include -#include -#include -#include - -namespace rang { - -/* For better compability with most of terminals do not use any style settings - * except of reset, bold and reversed. - * Note that on Windows terminals bold style is same as fgB color. - */ -enum class style { - reset = 0, - bold = 1, - dim = 2, - italic = 3, - underline = 4, - blink = 5, - rblink = 6, - reversed = 7, - conceal = 8, - crossed = 9 -}; - -enum class fg { - black = 30, - red = 31, - green = 32, - yellow = 33, - blue = 34, - magenta = 35, - cyan = 36, - gray = 37, - reset = 39 -}; - -enum class bg { - black = 40, - red = 41, - green = 42, - yellow = 43, - blue = 44, - magenta = 45, - cyan = 46, - gray = 47, - reset = 49 -}; - -enum class fgB { - black = 90, - red = 91, - green = 92, - yellow = 93, - blue = 94, - magenta = 95, - cyan = 96, - gray = 97 -}; - -enum class bgB { - black = 100, - red = 101, - green = 102, - yellow = 103, - blue = 104, - magenta = 105, - cyan = 106, - gray = 107 -}; - -enum class control { // Behaviour of rang function calls - Off = 0, // toggle off rang style/color calls - Auto = 1, // (Default) autodect terminal and colorize if needed - Force = 2 // force ansi color output to non terminal streams -}; -// Use rang::setControlMode to set rang control mode - -enum class winTerm { // Windows Terminal Mode - Auto = 0, // (Default) automatically detects wheter Ansi or Native API - Ansi = 1, // Force use Ansi API - Native = 2 // Force use Native API -}; -// Use rang::setWinTermMode to explicitly set terminal API for Windows -// Calling rang::setWinTermMode have no effect on other OS - -namespace rang_implementation { - - inline std::atomic &controlMode() noexcept - { - static std::atomic value(control::Auto); - return value; - } - - inline std::atomic &winTermMode() noexcept - { - static std::atomic termMode(winTerm::Auto); - return termMode; - } - - inline bool supportsColor() noexcept - { -#if defined(OS_LINUX) || defined(OS_MAC) - - static const bool result = [] { - const char *Terms[] - = { "ansi", "color", "console", "cygwin", "gnome", - "konsole", "kterm", "linux", "msys", "putty", - "rxvt", "screen", "vt100", "xterm" }; - - const char *env_p = std::getenv("TERM"); - if (env_p == nullptr) { - return false; - } - return std::any_of(std::begin(Terms), std::end(Terms), - [&](const char *term) { - return std::strstr(env_p, term) != nullptr; - }); - }(); - -#elif defined(OS_WIN) - // All windows versions support colors through native console methods - static constexpr bool result = true; -#endif - return result; - } - -#ifdef OS_WIN - - - inline bool isMsysPty(int fd) noexcept - { - // Dynamic load for binary compability with old Windows - const auto ptrGetFileInformationByHandleEx - = reinterpret_cast( - GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), - "GetFileInformationByHandleEx")); - if (!ptrGetFileInformationByHandleEx) { - return false; - } - - HANDLE h = reinterpret_cast(_get_osfhandle(fd)); - if (h == INVALID_HANDLE_VALUE) { - return false; - } - - // Check that it's a pipe: - if (GetFileType(h) != FILE_TYPE_PIPE) { - return false; - } - - // POD type is binary compatible with FILE_NAME_INFO from WinBase.h - // It have the same alignment and used to avoid UB in caller code - struct MY_FILE_NAME_INFO { - DWORD FileNameLength; - WCHAR FileName[MAX_PATH]; - }; - - auto pNameInfo = std::unique_ptr( - new (std::nothrow) MY_FILE_NAME_INFO()); - if (!pNameInfo) { - return false; - } - - // Check pipe name is template of - // {"cygwin-","msys-"}XXXXXXXXXXXXXXX-ptyX-XX - if (!ptrGetFileInformationByHandleEx(h, FileNameInfo, pNameInfo.get(), - sizeof(MY_FILE_NAME_INFO))) { - return false; - } - std::wstring name(pNameInfo->FileName, pNameInfo->FileNameLength / sizeof(WCHAR)); - if ((name.find(L"msys-") == std::wstring::npos - && name.find(L"cygwin-") == std::wstring::npos) - || name.find(L"-pty") == std::wstring::npos) { - return false; - } - - return true; - } - -#endif - - inline bool isTerminal(const std::streambuf *osbuf) noexcept - { - using std::cerr; - using std::clog; - using std::cout; -#if defined(OS_LINUX) || defined(OS_MAC) - if (osbuf == cout.rdbuf()) { - static const bool cout_term = isatty(fileno(stdout)) != 0; - return cout_term; - } else if (osbuf == cerr.rdbuf() || osbuf == clog.rdbuf()) { - static const bool cerr_term = isatty(fileno(stderr)) != 0; - return cerr_term; - } -#elif defined(OS_WIN) - if (osbuf == cout.rdbuf()) { - static const bool cout_term - = (_isatty(_fileno(stdout)) || isMsysPty(_fileno(stdout))); - return cout_term; - } else if (osbuf == cerr.rdbuf() || osbuf == clog.rdbuf()) { - static const bool cerr_term - = (_isatty(_fileno(stderr)) || isMsysPty(_fileno(stderr))); - return cerr_term; - } -#endif - return false; - } - - template - using enableStd = typename std::enable_if< - std::is_same::value || std::is_same::value - || std::is_same::value || std::is_same::value - || std::is_same::value, - std::ostream &>::type; - - -#ifdef OS_WIN - - struct SGR { // Select Graphic Rendition parameters for Windows console - BYTE fgColor; // foreground color (0-15) lower 3 rgb bits + intense bit - BYTE bgColor; // background color (0-15) lower 3 rgb bits + intense bit - BYTE bold; // emulated as FOREGROUND_INTENSITY bit - BYTE underline; // emulated as BACKGROUND_INTENSITY bit - BOOLEAN inverse; // swap foreground/bold & background/underline - BOOLEAN conceal; // set foreground/bold to background/underline - }; - - enum class AttrColor : BYTE { // Color attributes for console screen buffer - black = 0, - red = 4, - green = 2, - yellow = 6, - blue = 1, - magenta = 5, - cyan = 3, - gray = 7 - }; - - inline HANDLE getConsoleHandle(const std::streambuf *osbuf) noexcept - { - if (osbuf == std::cout.rdbuf()) { - static const HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); - return hStdout; - } else if (osbuf == std::cerr.rdbuf() || osbuf == std::clog.rdbuf()) { - static const HANDLE hStderr = GetStdHandle(STD_ERROR_HANDLE); - return hStderr; - } - return INVALID_HANDLE_VALUE; - } - - inline bool setWinTermAnsiColors(const std::streambuf *osbuf) noexcept - { - HANDLE h = getConsoleHandle(osbuf); - if (h == INVALID_HANDLE_VALUE) { - return false; - } - DWORD dwMode = 0; - if (!GetConsoleMode(h, &dwMode)) { - return false; - } - dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; - if (!SetConsoleMode(h, dwMode)) { - return false; - } - return true; - } - - inline bool supportsAnsi(const std::streambuf *osbuf) noexcept - { - using std::cerr; - using std::clog; - using std::cout; - if (osbuf == cout.rdbuf()) { - static const bool cout_ansi - = (isMsysPty(_fileno(stdout)) || setWinTermAnsiColors(osbuf)); - return cout_ansi; - } else if (osbuf == cerr.rdbuf() || osbuf == clog.rdbuf()) { - static const bool cerr_ansi - = (isMsysPty(_fileno(stderr)) || setWinTermAnsiColors(osbuf)); - return cerr_ansi; - } - return false; - } - - inline const SGR &defaultState() noexcept - { - static const SGR defaultSgr = []() -> SGR { - CONSOLE_SCREEN_BUFFER_INFO info; - WORD attrib = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; - if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), - &info) - || GetConsoleScreenBufferInfo(GetStdHandle(STD_ERROR_HANDLE), - &info)) { - attrib = info.wAttributes; - } - SGR sgr = { 0, 0, 0, 0, FALSE, FALSE }; - sgr.fgColor = attrib & 0x0F; - sgr.bgColor = (attrib & 0xF0) >> 4; - return sgr; - }(); - return defaultSgr; - } - - inline BYTE ansi2attr(BYTE rgb) noexcept - { - static const AttrColor rev[8] - = { AttrColor::black, AttrColor::red, AttrColor::green, - AttrColor::yellow, AttrColor::blue, AttrColor::magenta, - AttrColor::cyan, AttrColor::gray }; - return static_cast(rev[rgb]); - } - - inline void setWinSGR(rang::bg col, SGR &state) noexcept - { - if (col != rang::bg::reset) { - state.bgColor = ansi2attr(static_cast(col) - 40); - } else { - state.bgColor = defaultState().bgColor; - } - } - - inline void setWinSGR(rang::fg col, SGR &state) noexcept - { - if (col != rang::fg::reset) { - state.fgColor = ansi2attr(static_cast(col) - 30); - } else { - state.fgColor = defaultState().fgColor; - } - } - - inline void setWinSGR(rang::bgB col, SGR &state) noexcept - { - state.bgColor = (BACKGROUND_INTENSITY >> 4) - | ansi2attr(static_cast(col) - 100); - } - - inline void setWinSGR(rang::fgB col, SGR &state) noexcept - { - state.fgColor - = FOREGROUND_INTENSITY | ansi2attr(static_cast(col) - 90); - } - - inline void setWinSGR(rang::style style, SGR &state) noexcept - { - switch (style) { - case rang::style::reset: state = defaultState(); break; - case rang::style::bold: state.bold = FOREGROUND_INTENSITY; break; - case rang::style::underline: - case rang::style::blink: - state.underline = BACKGROUND_INTENSITY; - break; - case rang::style::reversed: state.inverse = TRUE; break; - case rang::style::conceal: state.conceal = TRUE; break; - default: break; - } - } - - inline SGR ¤t_state() noexcept - { - static SGR state = defaultState(); - return state; - } - - inline WORD SGR2Attr(const SGR &state) noexcept - { - WORD attrib = 0; - if (state.conceal) { - if (state.inverse) { - attrib = (state.fgColor << 4) | state.fgColor; - if (state.bold) - attrib |= FOREGROUND_INTENSITY | BACKGROUND_INTENSITY; - } else { - attrib = (state.bgColor << 4) | state.bgColor; - if (state.underline) - attrib |= FOREGROUND_INTENSITY | BACKGROUND_INTENSITY; - } - } else if (state.inverse) { - attrib = (state.fgColor << 4) | state.bgColor; - if (state.bold) attrib |= BACKGROUND_INTENSITY; - if (state.underline) attrib |= FOREGROUND_INTENSITY; - } else { - attrib = state.fgColor | (state.bgColor << 4) | state.bold - | state.underline; - } - return attrib; - } - - template - inline void setWinColorAnsi(std::ostream &os, T const value) - { - os << "\033[" << static_cast(value) << "m"; - } - - template - inline void setWinColorNative(std::ostream &os, T const value) - { - const HANDLE h = getConsoleHandle(os.rdbuf()); - if (h != INVALID_HANDLE_VALUE) { - setWinSGR(value, current_state()); - // Out all buffered text to console with previous settings: - os.flush(); - SetConsoleTextAttribute(h, SGR2Attr(current_state())); - } - } - - template - inline enableStd setColor(std::ostream &os, T const value) - { - if (winTermMode() == winTerm::Auto) { - if (supportsAnsi(os.rdbuf())) { - setWinColorAnsi(os, value); - } else { - setWinColorNative(os, value); - } - } else if (winTermMode() == winTerm::Ansi) { - setWinColorAnsi(os, value); - } else { - setWinColorNative(os, value); - } - return os; - } -#else - template - inline enableStd setColor(std::ostream &os, T const value) - { - return os << "\033[" << static_cast(value) << "m"; - } -#endif -} // namespace rang_implementation - -template -inline rang_implementation::enableStd operator<<(std::ostream &os, - const T value) -{ - const control option = rang_implementation::controlMode(); - switch (option) { - case control::Auto: - return rang_implementation::supportsColor() - && rang_implementation::isTerminal(os.rdbuf()) - ? rang_implementation::setColor(os, value) - : os; - case control::Force: return rang_implementation::setColor(os, value); - default: return os; - } -} - -inline void setWinTermMode(const rang::winTerm value) noexcept -{ - rang_implementation::winTermMode() = value; -} - -inline void setControlMode(const control value) noexcept -{ - rang_implementation::controlMode() = value; -} - -} // namespace rang - -#undef OS_LINUX -#undef OS_WIN -#undef OS_MAC - -#endif /* ifndef RANG_DOT_HPP */ diff --git a/vendor/update.toml b/vendor/update.toml index 45656c6d1..700ea0472 100644 --- a/vendor/update.toml +++ b/vendor/update.toml @@ -39,13 +39,6 @@ tarball = "https://www.openwall.com/blists/blists-2.0.tar.gz" version = "v2.0" website = "https://openwall.info/wiki/people/solar/software/public-domain-source-code/md5" -[rang] -author = "Abhinav Gauniyal" -depth = 1 -files = "{include/rang.hpp,LICENSE}" -git = "https://github.com/agauniyal/rang/" -license = "Unlicense" - [sha2] author = "Olivier Gay" email = "olivier.gay@a3.epfl.ch"