Added check for tty output

This commit is contained in:
Bob Polis 2023-08-07 16:48:33 +02:00
parent 826cd8c92b
commit b80f093c87
4 changed files with 79 additions and 34 deletions

View File

@ -1,9 +1,13 @@
#include "iomanip.hpp" #include "iomanip.hpp"
#include <unistd.h>
using namespace sc::io;
static std::ostream& gray(std::ostream& out, int val, int code) { static std::ostream& gray(std::ostream& out, int val, int code) {
if (val < 0 || val > 23) { if (val < 0 || val > 23) {
throw std::invalid_argument("gray value out of range"); throw std::invalid_argument("gray value out of range");
} }
if (isatty_ostream(out))
out << "\x1b[" << code << ";5;" << 232 + val << "m"; out << "\x1b[" << code << ";5;" << 232 + val << "m";
return out; return out;
} }
@ -12,151 +16,186 @@ static std::ostream& rgb(std::ostream& out, int r, int g, int b, int code) {
if (r < 0 || r > 5 || g < 0 || g > 5 || b < 0 || b > 5) { if (r < 0 || r > 5 || g < 0 || g > 5 || b < 0 || b > 5) {
throw std::invalid_argument("rgb color component out of range"); throw std::invalid_argument("rgb color component out of range");
} }
if (isatty_ostream(out))
out << "\x1b[" << code << ";5;" << (16 + 36 * r + 6 * g + b) << "m"; out << "\x1b[" << code << ";5;" << (16 + 36 * r + 6 * g + b) << "m";
return out; return out;
} }
bool sc::io::isatty_ostream(const std::ostream& out) {
return (&out == &std::cout && isatty(STDOUT_FILENO)) ||
(&out == &std::cerr && isatty(STDERR_FILENO));
}
std::ostream& sc::io::hide_cursor(std::ostream& out) { std::ostream& sc::io::hide_cursor(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[?25l"; out << "\x1b[?25l";
return out; return out;
} }
std::ostream& sc::io::show_cursor(std::ostream& out) { std::ostream& sc::io::show_cursor(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[?25h"; out << "\x1b[?25h";
return out; return out;
} }
std::ostream& sc::io::reset(std::ostream& out) { std::ostream& sc::io::reset(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[m"; out << "\x1b[m";
return out; return out;
} }
std::ostream& sc::io::bold(std::ostream& out) { std::ostream& sc::io::bold(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[1m"; out << "\x1b[1m";
return out; return out;
} }
std::ostream& sc::io::italic(std::ostream& out) { std::ostream& sc::io::italic(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[3m"; out << "\x1b[3m";
return out; return out;
} }
std::ostream& sc::io::underline(std::ostream& out) { std::ostream& sc::io::underline(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[4m"; out << "\x1b[4m";
return out; return out;
} }
std::ostream& sc::io::overline(std::ostream& out) { std::ostream& sc::io::overline(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[53m"; out << "\x1b[53m";
return out; return out;
} }
std::ostream& sc::io::strikethru(std::ostream& out) { std::ostream& sc::io::strikethru(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[9m"; out << "\x1b[9m";
return out; return out;
} }
std::ostream& sc::io::blinkslow(std::ostream& out) { std::ostream& sc::io::blinkslow(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[5m"; out << "\x1b[5m";
return out; return out;
} }
std::ostream& sc::io::blinkfast(std::ostream& out) { std::ostream& sc::io::blinkfast(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[6m"; out << "\x1b[6m";
return out; return out;
} }
std::ostream& sc::io::reverse(std::ostream& out) { std::ostream& sc::io::reverse(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[7m"; out << "\x1b[7m";
return out; return out;
} }
std::ostream& sc::io::blackf(std::ostream& out) { std::ostream& sc::io::blackf(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[30m"; out << "\x1b[30m";
return out; return out;
} }
std::ostream& sc::io::redf(std::ostream& out) { std::ostream& sc::io::redf(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[31m"; out << "\x1b[31m";
return out; return out;
} }
std::ostream& sc::io::greenf(std::ostream& out) { std::ostream& sc::io::greenf(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[32m"; out << "\x1b[32m";
return out; return out;
} }
std::ostream& sc::io::yellowf(std::ostream& out) { std::ostream& sc::io::yellowf(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[33m"; out << "\x1b[33m";
return out; return out;
} }
std::ostream& sc::io::bluef(std::ostream& out) { std::ostream& sc::io::bluef(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[34m"; out << "\x1b[34m";
return out; return out;
} }
std::ostream& sc::io::magentaf(std::ostream& out) { std::ostream& sc::io::magentaf(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[35m"; out << "\x1b[35m";
return out; return out;
} }
std::ostream& sc::io::cyanf(std::ostream& out) { std::ostream& sc::io::cyanf(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[36m"; out << "\x1b[36m";
return out; return out;
} }
std::ostream& sc::io::whitef(std::ostream& out) { std::ostream& sc::io::whitef(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[37m"; out << "\x1b[37m";
return out; return out;
} }
std::ostream& sc::io::defaultf(std::ostream& out) { std::ostream& sc::io::defaultf(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[39m"; out << "\x1b[39m";
return out; return out;
} }
std::ostream& sc::io::blackb(std::ostream& out) { std::ostream& sc::io::blackb(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[40m"; out << "\x1b[40m";
return out; return out;
} }
std::ostream& sc::io::redb(std::ostream& out) { std::ostream& sc::io::redb(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[41m"; out << "\x1b[41m";
return out; return out;
} }
std::ostream& sc::io::greenb(std::ostream& out) { std::ostream& sc::io::greenb(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[42m"; out << "\x1b[42m";
return out; return out;
} }
std::ostream& sc::io::yellowb(std::ostream& out) { std::ostream& sc::io::yellowb(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[43m"; out << "\x1b[43m";
return out; return out;
} }
std::ostream& sc::io::blueb(std::ostream& out) { std::ostream& sc::io::blueb(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[44m"; out << "\x1b[44m";
return out; return out;
} }
std::ostream& sc::io::magentab(std::ostream& out) { std::ostream& sc::io::magentab(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[45m"; out << "\x1b[45m";
return out; return out;
} }
std::ostream& sc::io::cyanb(std::ostream& out) { std::ostream& sc::io::cyanb(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[46m"; out << "\x1b[46m";
return out; return out;
} }
std::ostream& sc::io::whiteb(std::ostream& out) { std::ostream& sc::io::whiteb(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[47m"; out << "\x1b[47m";
return out; return out;
} }
std::ostream& sc::io::defaultb(std::ostream& out) { std::ostream& sc::io::defaultb(std::ostream& out) {
if (isatty_ostream(out))
out << "\x1b[49m"; out << "\x1b[49m";
return out; return out;
} }

View File

@ -5,6 +5,8 @@
namespace sc { namespace sc {
namespace io { namespace io {
bool isatty_ostream(const std::ostream& out);
std::ostream& hide_cursor(std::ostream& out); std::ostream& hide_cursor(std::ostream& out);
std::ostream& show_cursor(std::ostream& out); std::ostream& show_cursor(std::ostream& out);

View File

@ -11,7 +11,8 @@
using namespace sc; using namespace sc;
term::term(int fd) { term::term(int fd) {
if (isatty(fd)) { _isatty = isatty(fd);
if (_isatty) {
throw_if_min1(ioctl(fd, TIOCGWINSZ, &_ws)); throw_if_min1(ioctl(fd, TIOCGWINSZ, &_ws));
} }
switch (fd) { switch (fd) {
@ -22,11 +23,11 @@ term::term(int fd) {
} }
int term::rows() const { int term::rows() const {
return _ws.ws_row; return _isatty ? _ws.ws_row : 0;
} }
int term::cols() const { int term::cols() const {
return _ws.ws_col; return _isatty ? _ws.ws_col : 0;
} }
void term::progress(int prefixlen, void term::progress(int prefixlen,
@ -34,6 +35,8 @@ void term::progress(int prefixlen,
double cur, double cur,
double total) const double total) const
{ {
if (!_isatty) return;
// use unicode to make nice bar // use unicode to make nice bar
const char* bar[8] = { const char* bar[8] = {
u8"\u258F", u8"\u258E", u8"\u258D", u8"\u258C", u8"\u258F", u8"\u258E", u8"\u258D", u8"\u258C",

View File

@ -12,6 +12,7 @@ namespace sc {
class term { class term {
struct winsize _ws; struct winsize _ws;
std::ostream* _out {nullptr}; std::ostream* _out {nullptr};
bool _isatty {true};
public: public:
term(int fd); term(int fd);