mirror of
https://github.com/inspircd/inspircd.git
synced 2025-03-09 10:39:02 -04:00
Replace consolecolors with a vendored library.
This library supports much more than consolecolors including the Windows 8 console API.
This commit is contained in:
parent
4fd71323d3
commit
ec46f6acda
@ -1,172 +0,0 @@
|
||||
/*
|
||||
* InspIRCd -- Internet Relay Chat Daemon
|
||||
*
|
||||
* Copyright (C) 2019 linuxdaemon <linuxdaemon.irc@gmail.com>
|
||||
* Copyright (C) 2013, 2019, 2021 Sadie Powell <sadie@witchery.services>
|
||||
* Copyright (C) 2012 ChrisTX <xpipe@hotmail.de>
|
||||
*
|
||||
* This file is part of InspIRCd. InspIRCd is free software: you can
|
||||
* redistribute it and/or modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation, version 2.
|
||||
*
|
||||
* This program 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 General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdio>
|
||||
#include <ostream>
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <iostream>
|
||||
# include <io.h>
|
||||
# define isatty(x) _isatty((x))
|
||||
# define fileno(x) _fileno((x))
|
||||
extern WindowsStream StandardError;
|
||||
extern WindowsStream StandardOutput;
|
||||
#else
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
inline bool CanUseColors()
|
||||
{
|
||||
#ifdef INSPIRCD_DISABLE_COLORS
|
||||
return false;
|
||||
#else
|
||||
return isatty(fileno(stdout));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
inline WindowsStream& GetStreamHandle(std::ostream& os)
|
||||
{
|
||||
if (os.rdbuf() == std::cerr.rdbuf())
|
||||
return StandardError;
|
||||
|
||||
if (os.rdbuf() == std::cout.rdbuf())
|
||||
return StandardOutput;
|
||||
|
||||
// This will never happen.
|
||||
throw std::invalid_argument("Tried to write color codes to a stream other than stdout or stderr!");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
inline std::ostream& con_green(std::ostream& stream)
|
||||
{
|
||||
if (CanUseColors())
|
||||
{
|
||||
const WindowsStream& ws = GetStreamHandle(stream);
|
||||
SetConsoleTextAttribute(ws.Handle, FOREGROUND_GREEN | FOREGROUND_INTENSITY | ws.BackgroundColor);
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline std::ostream& con_red(std::ostream& stream)
|
||||
{
|
||||
if (CanUseColors())
|
||||
{
|
||||
const WindowsStream& ws = GetStreamHandle(stream);
|
||||
SetConsoleTextAttribute(ws.Handle, FOREGROUND_RED | FOREGROUND_INTENSITY | ws.BackgroundColor);
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline std::ostream& con_white(std::ostream& stream)
|
||||
{
|
||||
if (CanUseColors())
|
||||
{
|
||||
const WindowsStream& ws = GetStreamHandle(stream);
|
||||
SetConsoleTextAttribute(ws.Handle, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN | ws.BackgroundColor);
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline std::ostream& con_white_bright(std::ostream& stream)
|
||||
{
|
||||
if (CanUseColors())
|
||||
{
|
||||
const WindowsStream& ws = GetStreamHandle(stream);
|
||||
SetConsoleTextAttribute(ws.Handle, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY | ws.BackgroundColor);
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline std::ostream& con_bright(std::ostream& stream)
|
||||
{
|
||||
if (CanUseColors())
|
||||
{
|
||||
const WindowsStream& ws = GetStreamHandle(stream);
|
||||
SetConsoleTextAttribute(ws.Handle, FOREGROUND_INTENSITY | ws.BackgroundColor);
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline std::ostream& con_reset(std::ostream& stream)
|
||||
{
|
||||
if (CanUseColors())
|
||||
{
|
||||
const WindowsStream& ws = GetStreamHandle(stream);
|
||||
SetConsoleTextAttribute(ws.Handle, ws.ForegroundColor);
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline std::ostream& con_green(std::ostream& stream)
|
||||
{
|
||||
if (!CanUseColors())
|
||||
return stream;
|
||||
return stream << "\033[1;32m";
|
||||
}
|
||||
|
||||
inline std::ostream& con_red(std::ostream& stream)
|
||||
{
|
||||
if (!CanUseColors())
|
||||
return stream;
|
||||
return stream << "\033[1;31m";
|
||||
}
|
||||
|
||||
inline std::ostream& con_white(std::ostream& stream)
|
||||
{
|
||||
if (!CanUseColors())
|
||||
return stream;
|
||||
return stream << "\033[0m";
|
||||
}
|
||||
|
||||
inline std::ostream& con_white_bright(std::ostream& stream)
|
||||
{
|
||||
if (!CanUseColors())
|
||||
return stream;
|
||||
return stream << "\033[1m";
|
||||
}
|
||||
|
||||
inline std::ostream& con_bright(std::ostream& stream)
|
||||
{
|
||||
if (!CanUseColors())
|
||||
return stream;
|
||||
return stream << "\033[1m";
|
||||
}
|
||||
|
||||
inline std::ostream& con_reset(std::ostream& stream)
|
||||
{
|
||||
if (!CanUseColors())
|
||||
return stream;
|
||||
return stream << "\033[0m";
|
||||
}
|
||||
|
||||
#endif
|
@ -45,7 +45,7 @@ SYSTEM = @SYSTEM_NAME@
|
||||
SOURCEPATH = @SOURCE_DIR@
|
||||
BUILDPATH ?= $(SOURCEPATH)/build/@COMPILER_NAME@-@COMPILER_VERSION@
|
||||
SOCKETENGINE = @SOCKETENGINE@
|
||||
CORECXXFLAGS = -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -pipe -I"$(SOURCEPATH)/include" -Wall -Wextra -Wfatal-errors -Wformat=2 -Wmissing-format-attribute -Woverloaded-virtual -Wpedantic -Wno-format-nonliteral -Wno-unused-parameter
|
||||
CORECXXFLAGS = -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -pipe -I"$(SOURCEPATH)/include" -I"$(SOURCEPATH)/vendor" -Wall -Wextra -Wfatal-errors -Wformat=2 -Wmissing-format-attribute -Woverloaded-virtual -Wpedantic -Wno-format-nonliteral -Wno-unused-parameter
|
||||
LDLIBS = @COMPILER_EXTRA_LDLIBS@
|
||||
CORELDFLAGS = -fPIE -L.
|
||||
PICLDFLAGS = -fPIC -shared
|
||||
|
@ -37,18 +37,14 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "inspircd.h"
|
||||
#include "consolecolors.h"
|
||||
#include "exitcodes.h"
|
||||
#include "xline.h"
|
||||
|
||||
// Needs to be included after inspircd.h to avoid reincluding winsock.
|
||||
#include <rang/rang.hpp>
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <ya_getopt.h>
|
||||
|
||||
// Manages formatting lines written to stderr on Windows.
|
||||
WindowsStream StandardError(STD_ERROR_HANDLE);
|
||||
|
||||
// Manages formatting lines written to stdout on Windows.
|
||||
WindowsStream StandardOutput(STD_OUTPUT_HANDLE);
|
||||
#else
|
||||
# include <getopt.h>
|
||||
# include <grp.h>
|
||||
@ -78,19 +74,19 @@ namespace
|
||||
if (getegid() != 0 && geteuid() != 0)
|
||||
return;
|
||||
|
||||
std::cout << con_red << "Warning!" << con_reset << " You have started as root. Running as root is generally not required" << std::endl
|
||||
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;
|
||||
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 " << con_bright << "--runasroot" << con_reset << " option to disable this wait." << std::endl;
|
||||
<< "then you can pass the " << rang::style::bold << "--runasroot" << rang::style::reset << " option to disable this wait." << std::endl;
|
||||
sleep(30);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "If you are sure that you need to run as root then you can pass the " << con_bright << "--runasroot" << con_reset << std::endl
|
||||
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);
|
||||
}
|
||||
@ -236,7 +232,7 @@ namespace
|
||||
if (childpid < 0)
|
||||
{
|
||||
ServerInstance->Logs.Log("STARTUP", LOG_DEFAULT, "fork() failed: %s", strerror(errno));
|
||||
std::cout << con_red << "Error:" << con_reset << " unable to fork into background: " << strerror(errno);
|
||||
std::cout << rang::style::bold << rang::fg::red << "Error:" << rang::style::reset << " unable to fork into background: " << strerror(errno);
|
||||
ServerInstance->Exit(EXIT_STATUS_FORK);
|
||||
}
|
||||
else if (childpid > 0)
|
||||
@ -310,8 +306,8 @@ namespace
|
||||
|
||||
default:
|
||||
// An unknown option was specified.
|
||||
std::cout << con_red << "Error:" << con_reset << " unknown option '" << argv[optind-1] << "'." << std::endl
|
||||
<< con_bright << "Usage: " << con_reset << argv[0] << " [--config <file>] [--debug] [--nofork] [--nolog]" << std::endl
|
||||
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 <file>] [--debug] [--nofork] [--nolog]" << std::endl
|
||||
<< std::string(strlen(argv[0]) + 8, ' ') << "[--nopid] [--runasroot] [--version]" << std::endl;
|
||||
ServerInstance->Exit(EXIT_STATUS_ARGV);
|
||||
}
|
||||
@ -362,17 +358,17 @@ namespace
|
||||
|
||||
if (!pl.empty())
|
||||
{
|
||||
std::cout << con_red << "Warning!" << con_reset << " Some of your listener" << (pl.size() == 1 ? "s" : "") << " failed to bind:" << std::endl
|
||||
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;
|
||||
|
||||
for (const auto& fp : pl)
|
||||
{
|
||||
std::cout << " " << con_bright << fp.sa.str() << con_reset << ": " << strerror(fp.error) << '.' << std::endl
|
||||
std::cout << " " << rang::style::bold << fp.sa.str() << rang::style::reset << ": " << strerror(fp.error) << '.' << std::endl
|
||||
<< " " << "Created from <bind> tag at " << fp.tag->source.str() << std::endl
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
std::cout << con_bright << "Hints:" << con_reset << std::endl
|
||||
std::cout << rang::style::bold << "Hints:" << rang::style::reset << std::endl
|
||||
<< "- For TCP/IP listeners try using a public IP address in <bind:address> instead" << std::endl
|
||||
<< " of * or leaving it blank." << std::endl
|
||||
<< "- For UNIX socket listeners try enabling <bind:rewrite> to replace old sockets." << std::endl;
|
||||
@ -482,8 +478,8 @@ InspIRCd::InspIRCd(int argc, char** argv)
|
||||
Modules.AddServices(provs, sizeof(provs)/sizeof(provs[0]));
|
||||
}
|
||||
|
||||
std::cout << con_green << "InspIRCd - Internet Relay Chat Daemon" << con_reset << std::endl
|
||||
<< "See " << con_green << "/INFO" << con_reset << " for contributors & authors" << std::endl
|
||||
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;
|
||||
|
||||
if (Config->cmdline.forcedebug)
|
||||
@ -507,7 +503,7 @@ InspIRCd::InspIRCd(int argc, char** argv)
|
||||
if (!Config->cmdline.nofork)
|
||||
ForkIntoBackground();
|
||||
|
||||
std::cout << "InspIRCd Process ID: " << con_green << getpid() << con_reset << std::endl;
|
||||
std::cout << "InspIRCd Process ID: " << rang::style::bold << rang::fg::green << getpid() << rang::style::reset << std::endl;
|
||||
|
||||
/* During startup we read the configuration now, not in
|
||||
* a separate thread
|
||||
|
@ -27,9 +27,11 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "inspircd.h"
|
||||
#include "consolecolors.h"
|
||||
#include "exitcodes.h"
|
||||
|
||||
// Needs to be included after inspircd.h to avoid reincluding winsock.
|
||||
#include <rang/rang.hpp>
|
||||
|
||||
bool ModuleManager::Load(const std::string& modname, bool defer)
|
||||
{
|
||||
/* Don't allow people to specify paths for modules, it doesn't work as expected */
|
||||
@ -147,7 +149,7 @@ void ModuleManager::LoadCoreModules(std::map<std::string, ServiceList>& servicem
|
||||
if (!Load(name, true))
|
||||
{
|
||||
ServerInstance->Logs.Log("MODULE", LOG_DEFAULT, this->LastError());
|
||||
std::cout << std::endl << "[" << con_red << "*" << con_reset << "] " << this->LastError() << std::endl << std::endl;
|
||||
std::cout << std::endl << "[" << rang::style::bold << rang::fg::red << "*" << rang::style::reset << "] " << this->LastError() << std::endl << std::endl;
|
||||
ServerInstance->Exit(EXIT_STATUS_MODULE);
|
||||
}
|
||||
}
|
||||
|
@ -34,9 +34,11 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "inspircd.h"
|
||||
#include "consolecolors.h"
|
||||
#include "exitcodes.h"
|
||||
|
||||
// Needs to be included after inspircd.h to avoid reincluding winsock.
|
||||
#include <rang/rang.hpp>
|
||||
|
||||
static insp::intrusive_list<dynamic_reference_base>* dynrefs = NULL;
|
||||
|
||||
void dynamic_reference_base::reset_all()
|
||||
@ -516,11 +518,11 @@ void ModuleManager::LoadAll()
|
||||
continue;
|
||||
|
||||
this->NewServices = &servicemap[name];
|
||||
std::cout << "[" << con_green << "*" << con_reset << "] Loading module:\t" << con_green << name << con_reset << std::endl;
|
||||
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;
|
||||
if (!this->Load(name, true))
|
||||
{
|
||||
ServerInstance->Logs.Log("MODULE", LOG_DEFAULT, this->LastError());
|
||||
std::cout << std::endl << "[" << con_red << "*" << con_reset << "] " << this->LastError() << std::endl << std::endl;
|
||||
std::cout << std::endl << "[" << rang::style::bold << rang::fg::red << "*" << rang::style::reset << "] " << this->LastError() << std::endl << std::endl;
|
||||
ServerInstance->Exit(EXIT_STATUS_MODULE);
|
||||
}
|
||||
}
|
||||
@ -539,7 +541,7 @@ void ModuleManager::LoadAll()
|
||||
{
|
||||
LastModuleError = "Unable to initialize " + modname + ": " + modexcept.GetReason();
|
||||
ServerInstance->Logs.Log("MODULE", LOG_DEFAULT, LastModuleError);
|
||||
std::cout << std::endl << "[" << con_red << "*" << con_reset << "] " << LastModuleError << std::endl << std::endl;
|
||||
std::cout << std::endl << "[" << rang::style::bold << rang::fg::red << "*" << rang::style::reset << "] " << LastModuleError << std::endl << std::endl;
|
||||
ServerInstance->Exit(EXIT_STATUS_MODULE);
|
||||
}
|
||||
}
|
||||
@ -561,7 +563,7 @@ void ModuleManager::LoadAll()
|
||||
{
|
||||
LastModuleError = "Unable to read the configuration for " + modname + ": " + modexcept.GetReason();
|
||||
ServerInstance->Logs.Log("MODULE", LOG_DEFAULT, LastModuleError);
|
||||
std::cout << std::endl << "[" << con_red << "*" << con_reset << "] " << LastModuleError << std::endl << std::endl;
|
||||
std::cout << std::endl << "[" << rang::style::bold << rang::fg::red << "*" << rang::style::reset << "] " << LastModuleError << std::endl << std::endl;
|
||||
ServerInstance->Exit(EXIT_STATUS_CONFIG);
|
||||
}
|
||||
}
|
||||
|
@ -29,9 +29,11 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "inspircd.h"
|
||||
#include "consolecolors.h"
|
||||
#include "exitcodes.h"
|
||||
|
||||
// Needs to be included after inspircd.h to avoid reincluding winsock.
|
||||
#include <rang/rang.hpp>
|
||||
|
||||
/** Reference table, contains all current handlers
|
||||
**/
|
||||
std::vector<EventHandler*> SocketEngine::ref;
|
||||
@ -71,7 +73,7 @@ void EventHandler::OnEventHandlerError(int errornum)
|
||||
|
||||
void SocketEngine::InitError()
|
||||
{
|
||||
std::cerr << con_red << "FATAL ERROR!" << con_reset << " Socket engine initialization failed. " << strerror(errno) << '.' << std::endl;
|
||||
std::cerr << rang::style::bold << rang::fg::red << "FATAL ERROR!" << rang::style::reset << " Socket engine initialization failed. " << strerror(errno) << '.' << std::endl;
|
||||
exit(EXIT_STATUS_SOCKETENGINE);
|
||||
}
|
||||
|
||||
|
10
vendor/README.md
vendored
10
vendor/README.md
vendored
@ -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)
|
||||
|
||||
## 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)
|
||||
|
502
vendor/rang/rang.hpp
vendored
Normal file
502
vendor/rang/rang.hpp
vendored
Normal file
@ -0,0 +1,502 @@
|
||||
#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 <unistd.h>
|
||||
|
||||
#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 <windows.h>
|
||||
#include <io.h>
|
||||
#include <memory>
|
||||
|
||||
// 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 <algorithm>
|
||||
#include <atomic>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
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<control> &controlMode() noexcept
|
||||
{
|
||||
static std::atomic<control> value(control::Auto);
|
||||
return value;
|
||||
}
|
||||
|
||||
inline std::atomic<winTerm> &winTermMode() noexcept
|
||||
{
|
||||
static std::atomic<winTerm> 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<decltype(&GetFileInformationByHandleEx)>(
|
||||
GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),
|
||||
"GetFileInformationByHandleEx"));
|
||||
if (!ptrGetFileInformationByHandleEx) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HANDLE h = reinterpret_cast<HANDLE>(_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<MY_FILE_NAME_INFO>(
|
||||
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 <typename T>
|
||||
using enableStd = typename std::enable_if<
|
||||
std::is_same<T, rang::style>::value || std::is_same<T, rang::fg>::value
|
||||
|| std::is_same<T, rang::bg>::value || std::is_same<T, rang::fgB>::value
|
||||
|| std::is_same<T, rang::bgB>::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<BYTE>(rev[rgb]);
|
||||
}
|
||||
|
||||
inline void setWinSGR(rang::bg col, SGR &state) noexcept
|
||||
{
|
||||
if (col != rang::bg::reset) {
|
||||
state.bgColor = ansi2attr(static_cast<BYTE>(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<BYTE>(col) - 30);
|
||||
} else {
|
||||
state.fgColor = defaultState().fgColor;
|
||||
}
|
||||
}
|
||||
|
||||
inline void setWinSGR(rang::bgB col, SGR &state) noexcept
|
||||
{
|
||||
state.bgColor = (BACKGROUND_INTENSITY >> 4)
|
||||
| ansi2attr(static_cast<BYTE>(col) - 100);
|
||||
}
|
||||
|
||||
inline void setWinSGR(rang::fgB col, SGR &state) noexcept
|
||||
{
|
||||
state.fgColor
|
||||
= FOREGROUND_INTENSITY | ansi2attr(static_cast<BYTE>(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 <typename T>
|
||||
inline void setWinColorAnsi(std::ostream &os, T const value)
|
||||
{
|
||||
os << "\033[" << static_cast<int>(value) << "m";
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
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 <typename T>
|
||||
inline enableStd<T> 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 <typename T>
|
||||
inline enableStd<T> setColor(std::ostream &os, T const value)
|
||||
{
|
||||
return os << "\033[" << static_cast<int>(value) << "m";
|
||||
}
|
||||
#endif
|
||||
} // namespace rang_implementation
|
||||
|
||||
template <typename T>
|
||||
inline rang_implementation::enableStd<T> 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 */
|
7
vendor/update.toml
vendored
7
vendor/update.toml
vendored
@ -13,6 +13,13 @@ files = "http_parser.[ch]"
|
||||
git = "https://github.com/nodejs/http-parser"
|
||||
license = "MIT License"
|
||||
|
||||
[rang]
|
||||
author = "Abhinav Gauniyal"
|
||||
depth = 1
|
||||
files = "include/rang.hpp"
|
||||
git = "https://github.com/agauniyal/rang/"
|
||||
license = "Unlicense"
|
||||
|
||||
[sha2]
|
||||
author = "Olivier Gay"
|
||||
email = "olivier.gay@a3.epfl.ch"
|
||||
|
@ -60,7 +60,7 @@ foreach(INSPIRCD_VENDOR ${INSPIRCD_VENDORS})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
include_directories("${INSPIRCD_BASE}/win" "${INSPIRCD_BASE}/include")
|
||||
include_directories("${INSPIRCD_BASE}/win" "${INSPIRCD_BASE}/include" "${INSPIRCD_BASE}/vendor")
|
||||
|
||||
include_directories(${EXTRA_INCLUDES})
|
||||
link_directories(${EXTRA_LIBS})
|
||||
|
@ -55,16 +55,3 @@ DWORD CWin32Exception::GetErrorCode()
|
||||
{
|
||||
return dwErrorCode;
|
||||
}
|
||||
|
||||
WindowsStream::WindowsStream(DWORD handle)
|
||||
: BackgroundColor(0)
|
||||
, ForegroundColor(FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN)
|
||||
{
|
||||
this->Handle = GetStdHandle(handle);
|
||||
CONSOLE_SCREEN_BUFFER_INFO bufinf;
|
||||
if (GetConsoleScreenBufferInfo(this->Handle, &bufinf))
|
||||
{
|
||||
this->BackgroundColor = bufinf.wAttributes & 0x00F0;
|
||||
this->ForegroundColor = bufinf.wAttributes & 0x00FF;
|
||||
}
|
||||
}
|
||||
|
@ -190,11 +190,3 @@ struct sockaddr_un final
|
||||
ADDRESS_FAMILY sun_family;
|
||||
char sun_path[6];
|
||||
};
|
||||
|
||||
struct WindowsStream final
|
||||
{
|
||||
WORD BackgroundColor;
|
||||
WORD ForegroundColor;
|
||||
HANDLE Handle;
|
||||
WindowsStream(DWORD handle);
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user