/* sys/consoleinterface.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ #include "sys/consoleinterface.h" namespace sys { const size_t DEFAULT_LOGSIZE = 2048; /* -- ANSI color code support -------------------------------------- */ bool con_ansicolor = false; bool ansi() { return con_ansicolor; } void set_ansi(const bool ansi) { con_ansicolor = ansi; if (con_ansicolor) { // ANSI default color std::cout << "\033[0;39m"; } } void fallback_print(const std::string &text) { bool is_color_code = false; int ansi_bold = 0; int ansi_color = 39; const char *c = text.c_str(); while (*c) { if ((*c) == '\n') { std::cout << std::endl; } else if ((*c) == '^') { is_color_code = true; ansi_bold = 0; ansi_color = 39; switch (*(c + 1)) { case '0': // black ansi_color = 0; ansi_bold = 1; break; case '1': // red ansi_color = 31; break; case '2': // green ansi_color = 32; break; case '3': // yellow ansi_color = 1; ansi_color = 33; break; case '4': // blue ansi_color = 34; break; case '5': // cyan ansi_color = 36; break; case '6': // magenta ansi_color = 35; break; case '7': // white is mapped to foreground color ansi_bold = 1; ansi_color = 39; break; case 'N': // normal ansi_bold = 0; ansi_color = 39; break; case 'B': // bold ansi_bold = 1; ansi_color = 39; break; case 'D': // debug ansi_bold = 0; ansi_color = 39; break; case 'R': // error ansi_bold = 0; ansi_color = 31; break; case 'W': // warning ansi_bold = 1; ansi_color = 33; break; case 'F': // fancy ansi_bold = 0; ansi_color = 32; break; default: is_color_code = false; } if (is_color_code) { if (con_ansicolor) std::cout << "\033[" << ansi_bold << ";" << ansi_color << "m"; c++; } else { std::cout << *c; } } else { std::cout << *c; } c++; } } /* -- ConsoleBuffer ------------------------------------------------ */ int ConsoleBuffer::overflow(int c) { if (c == Traits::eof()) return Traits::not_eof(c); if (c == '\n') { if (ConsoleInterface::instance()) { ConsoleInterface::instance()->event_text(con_buffer); } else { fallback_print(con_buffer); std::cout << std::endl; } con_buffer.clear(); } else { con_buffer += c; } return c; } /* -- ConsoleStream ------------------------------------------------ */ ConsoleStream con_out; ConsoleStream::ConsoleStream() : std::basic_ostream(&con_buffer) { clear(); } ConsoleStream::~ConsoleStream() { if (con_ansicolor) { // ANSI default color std::cout << "\033[0;39m" << std::endl; } } /* -- Console ------------------------------------------------------ */ ConsoleInterface *ConsoleInterface::consoleinterface_instance = 0; ConsoleInterface::ConsoleInterface() { if (consoleinterface_instance) { std::cerr << "multiple sys::ConsoleInterface instances!" << std::endl; sys::quit(2); } consoleinterface_rcon = false; consoleinterface_instance = this; consoleinterface_logsize = DEFAULT_LOGSIZE; } ConsoleInterface::~ConsoleInterface() { consoleinterface_instance = 0; } ConsoleInterface *ConsoleInterface::instance() { return consoleinterface_instance; } void ConsoleInterface::set_rcon(bool enable) { consoleinterface_rcon = enable; } void ConsoleInterface::set_logsize(const size_t logsize) { consoleinterface_logsize = logsize < 16 ? 16 : logsize; } void ConsoleInterface::event_text(const std::string & text) { if (rcon()) { consoleinterface_rconbuf.push_back(text); } else { while (consoleinterface_log.size() >= consoleinterface_logsize) { consoleinterface_log.pop_front(); } consoleinterface_log.push_back(text); print(text); } } void ConsoleInterface::print(const std::string & text) { fallback_print(text); std::cout << std::endl; } } // namespace sys