2

When I ran this command on linux $ gcc, it gave me an output like this:

gcc: fatal error: no input files
compilation terminated.

Where, gcc was in bold white color and fatal error: was in bold red color.

And then I ran this command $ gcc &> err.txt and the content of err.txt was:

gcc: fatal error: no input files
compilation terminated.

With no ANSI color codes, just the plain text.

But with my program written in C++, the text file's content was:

[1;91merr:[0m no arguments were passed, try using '--help'

Where err: was in bold red color with showed up in terminal but the file too contains those characters.

My sample code is:

if (argc == 1)
{
    std::fprintf(stderr, "\033[1;91merr:\033[0m no arguments were passed, try using '--help'\n");
    return EXIT_FAILURE;
}

My Question:

  1. How does gcc and other linux programs prints colored text on terminal without using ANSI color codes?
  2. Are there any other methods to print colored output on terminal except ANSI color codes?
  3. Are there any cross-platform libraries todo so?
Darth-CodeX
  • 2,166
  • 1
  • 6
  • 23
  • 2
    gcc *is* using ANSI escape sequences; it's just omitting them when it thinks its output is being redirected into a file instead of to an interactive terminal. – ecatmur Aug 01 '23 at 06:30
  • How can I achieve that simply in my program? – Darth-CodeX Aug 01 '23 at 06:31
  • 3
    For POSIX systems it probably checks [`isatty`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/isatty.html) to check if the standard output is connected to a terminal or something else (redirected, pipe, etc). – Some programmer dude Aug 01 '23 at 06:32
  • @Someprogrammerdude On Windows CMD, gcc was able to print colored text while my program just printed `[1;91merr:[0m` – Darth-CodeX Aug 01 '23 at 06:33
  • @Someprogrammerdude Thanks for that function, which is quite new to me, as I generally opt for solution which are cross-platform. – Darth-CodeX Aug 01 '23 at 06:38
  • 1
    Unfortunately it's not really possible to check in a cross-platform way, unless you're using a library or emulation layer (e.g. Cygwin) that handles it for you. As for what GCC does on Windows and CMD I don't know, but the good news is that the source for GCC is freely available. The bad news is that the source is rather messy and it could be hard to find. – Some programmer dude Aug 01 '23 at 06:42
  • 1
    I think on Windows you need to use `SetConsoleMode(... ENABLE_VIRTUAL_TERMINAL_PROCESSING)`. See https://stackoverflow.com/a/51777740/567292 – ecatmur Aug 01 '23 at 06:42
  • 2
    The equivalent of `isatty` on Windows is `GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE))` or similar. See https://github.com/gcc-mirror/gcc/blob/01b0c36ba0c3bbe6ce0b0c77297e16d9531aac69/gcc/diagnostic-color.cc#L206 for how gcc does it. – ecatmur Aug 01 '23 at 06:43
  • Hence, I can make a single function merging both `isatty` and windows api and deciding what to do, using preprocessor. – Darth-CodeX Aug 01 '23 at 06:45

0 Answers0