23

I have a program that log things to STDOUT.

Those log entries have an associated "log level" (debug, warning, information, and so on) and I'd like to give the user the ability to color this output, depending on the log level.

What is the way of determining if STDOUT is attached to a terminal that is-color capable ? And how can I output my text with colors then ?

I'm looking for a solution that involves only C or C++ calls. I guess curses (or ncurses) has something to ease this, but I'd like to avoid its use to keep my dependencies to a minimum.

Rian Sanderson
  • 6,306
  • 4
  • 29
  • 34
ereOn
  • 53,676
  • 39
  • 161
  • 238
  • 8
    Is this the same question? http://stackoverflow.com/questions/2353430/how-can-i-print-to-the-console-in-color-on-mac-os-x-in-a-cross-platform-manner – user1201210 Oct 10 '12 at 19:45
  • You don't want to read the terminfo database by hand. No, you don't. – Ignacio Vazquez-Abrams Oct 10 '12 at 19:46
  • See http://stackoverflow.com/questions/2465425/how-do-i-determine-if-a-terminal-is-color-capable – Yam Marcovic Oct 10 '12 at 19:56
  • 3
    For prospect "exact duplicate" voters: The proposed duplicate *does not* answer the question of determining whether or not `STDOUT` is color capable. – Magnus Hoff Oct 10 '12 at 19:58
  • @tenterhook: Actually, no. It is not. – ereOn Oct 10 '12 at 19:58
  • What if your stdout is going to a file? Files aren't color capable. Printing a file with ANSI color encodings to paper makes a mess. OTOH, using `less -R` to print the file to the screen is very nice. – David Hammen Oct 10 '12 at 20:38
  • 1
    @DavidHammen: Git actually does that: it detects if the output is to be sent to a terminal and if the user wants colors and output them only if both these conditions are matched. – ereOn Oct 10 '12 at 20:40
  • The problem is that I want those colors whether stdout comes straight to me, or is piped, or teed, or is just sent to a log file. I also want colored output, "Test passed" in green, "Test failed" in red, even if I run the tests on a blade where applications need to be run daemonized (no terminal at all). – David Hammen Oct 10 '12 at 21:01
  • @DavidHammen The standard way to go about this is to add a command line option to force color on, for example "ls --color=always" or "hg diff --color always" – Magnus Hoff Oct 11 '12 at 08:37

1 Answers1

34

Probably the easiest way to check is simply:

isatty(fileno(STDOUT))

This will return 1 if your standard output is being sent to any sort of terminal. In practice, any terminal will either support or ignore VT100 color codes; examining terminfo is unnecessary unless you expect to be outputting to certain really unusual hardware terminals. (Most of which haven't been made in decades.)

To output colors, use the (extended) SGR sequence:

"\x1b[%dm"

where %d is one of the following values for commonly supported colors:

0: reset colors/style
1: bold
4: underline
30 - 37: black, red, green, yellow, blue, magenta, cyan, and white text
40 - 47: black, red, green, yellow, blue, magenta, cyan, and white background

There are more values, but these are the most widely supported ones. Again, examining terminfo is largely unnecessary for these control codes, as every software terminal worth its salt will support (or ignore) them.

If you need to change multiple attributes at once, you can specify them all at once, separated by semicolons. For instance, the following sequence will sear your eyeballs with bold magenta text on a green background:

"\x1b[1;35;42m"
  • 3
    It's ANSI, not VT100, codes. Or perhaps ISO/IEC 6429 codes, if you want to be precise. It might be prudent to note that `"\x1b["` == `"\033["` == CSI. http://en.wikipedia.org/wiki/ANSI_escape_code#CSI_codes has a pretty good list of these, as well as portability and other useful info. – Nominal Animal Oct 11 '12 at 04:35
  • 11
    For the record: Xcode's (OSX's standard IDE) built-in console does not support (nor ignore) ANSI color sequences (it tries to print them, resulting in unreadable garbage). I would actually really have liked a snippet that does check for color support. – Dave Nov 30 '13 at 08:10