HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Colorful output on terminal

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
terminaloutputcolorful

Problem

I went from manually outputting escape codes in each string to creating a utility struct/class full of static functions and variables that needed to be initialized in source files (static private members are required to) which was a bit ugly for me. Then I was searching for something different and while playing with enums, I found it interesting for my scenario. And then I carefully used namespaces to construct my sort-of function only header and here it is. Also, I'm not supporting pre-C++11 version of compilers.

My aims were – not to use classes since they became ugly with lots of static members and creating an object and using it for colouring doesn't looks so good (however I might try that in future), and to make it fast and also modern C++ish. Along the way, some neat tricks with C++ namespaces made it possible to sort of hide (well at least to code completions) my non-interface elements and give a nice shape to the code.

*I also want to reduce some not so necessary headers (e.g. `) if possible.

``
#ifndef RANG_H
#define RANG_H

#include
#include
#include
extern "C" {
#include
}

namespace rang {

enum class style : unsigned char {
Reset = 0,
bold = 1,
dim = 2,
italic = 3,
underline = 4,
blink = 5,
reversed = 6,
conceal = 7,
crossed = 8
};
enum class fg : unsigned char {
def = 39,
black = 30,
red = 31,
green = 32,
yellow = 33,
blue = 34,
magenta = 35,
cyan = 36,
gray = 37
};
enum class bg : unsigned char {
def = 49,
black = 40,
red = 41,
green = 42,
yellow = 43,
blue = 44,
magenta = 45,
cyan = 46,
gray = 47
};
}

namespace {
bool isAllowed = false;
bool isTerminal()
{
return isatty(STDOUT_FILENO);
}
bool supportsColor()

Solution

I have a few comments.

-
You use isatty to check whether standard output is connected to a terminal, regardless of what stream you're writing to. This means the rest of the functions only work correctly if you pass std::cout as the stream to which they're going to write. Otherwise, you may allow formatting when writing to something that's not a TTY, and you may prohibit formatting when writing to something that is a TTY.

-
The repetition of having three implementations of operator

-
Maybe it's just me, but every time I see code like:

isAllowed = isTerminal() && supportsColor() ? true : false;


... I grit my teeth. The result from
isTeriminal() && supportsColor() is already a perfectly good bool`--you can use it directly:

isAllowed = isTerminal() && supportsColor();


This seems much cleaner and more readable, at least to me.

Code Snippets

isAllowed = isTerminal() && supportsColor() ? true : false;
isAllowed = isTerminal() && supportsColor();

Context

StackExchange Code Review Q#120777, answer score: 5

Revisions (0)

No revisions yet.