sheesania
sheesania

Reputation: 247

Terminal-agnostic color printing in C without using ncurses

I'm writing a C program that outputs test results, and I'd like it to print them in color so it's easier to scan through the results. I initially just used ANSI color codes (per https://stackoverflow.com/a/23657072/4954731), but a code reviewer wanted it to be more terminal-independent and suggested using ncurses instead.

The problem with using ncurses is that the test results outputted by my C program are interspersed with other test results from bash scripts. Something like this:

Test Name            | Result
------------------------------
1+1 == 2             | PASS     <-- outputted by a C executable
!(!true) == true     | PASS     <-- outputted by a bash script
0+0 == 0             | PASS     <-- outputted by a C executable
...

So I can't use a regular ncurses screen - I have to play nicely with other output.

The bash scripts use tput and setaf to print with color, but I'm not sure if there's a way to use these tools in a C context without directly finding and calling the tput executable...

Is there some way I can do terminal-agnostic color printing in C without using ncurses?

Upvotes: 1

Views: 383

Answers (1)

sheesania
sheesania

Reputation: 247

Guess what, tput is actually part of the underlying ncurses C library!

Here's an example of printing colored text using tput. Don't forget to compile with -lncurses.

#include <stdio.h>
#include <curses.h>
#include <term.h>

int main() 
{
  // first you need to initialize your terminal
  int result = setupterm(0, 1, 0); 
  if (result != 0) {
    return result;
  }
  printf("%-62.62s  ", "1+1 == 2");

  // set color to green. You can pass a different function instead
  // of putchar if you want to, say, set the stderr color
  tputs(tparm(tigetstr("setaf"), COLOR_GREEN), 1, putchar);

  // set text to bold
  tputs(tparm(tigetstr("bold")), 1, putchar);

  // this text will be printed as green and bold
  printf("PASS\n");

  // reset text attributes
  tputs(tparm(tigetstr("sgr0")), 1, putchar);

  // now this text won't be green and bold
  printf("Done\n");
}

As you can see, you can freely mix-and-match tput stuff with regular printf output. There's no need to create a curses screen.

More information about tputs, tparm, etc here: https://invisible-island.net/ncurses/man/curs_terminfo.3x.html

Here's a list of what tigetstr capabilities your terminal may have available: https://invisible-island.net/ncurses/man/terminfo.5.html#h3-Predefined-Capabilities

Upvotes: 2

Related Questions