What does this do?
This mr adds color to ctinfo message headers and the source. Even though I used the new color system this was not as simple as I would have hoped. Here are some important things to know:
- Colorize the source code print out, for this I added a new color for the called
linenumber
- Add color option to sac4c and sac2tex
- color support detection
- I did not like abort also being red so I used the
name
color. This is also what gcc does. We could add a separate abort color if there are strong opinions about this we can add a new color for it. - Further improve and fix
color.c
- Use normal global initialization for
global.colors
andglobal.named_colors
Fixing tests
Adding this broke some of the ctinfo tests. To fix this I initially added -cti-no-color
and for the more complicated test-compile-time-formatting.cpp
I just set global.cti_no_color
to false on global and then called COLORparse
.
These tests also exposed a problem where global.colors
has to be set as early as possible otherwise you de-reference a null pointer when you use colors.
To fix this I split out the functionality of COLORparse
that sets pointers to the static color arrays from color.c
to global.colors
and instead we now just have getters to the static color arrays. With these getters we can just use the normal global initialization functionality and the colors do not have to be special while also being set early enough, because nothing uses colors before GLOBinitializeGlobal
is called.
Except for test-compile-time-formatting.cpp
because that never calls GLOBinitializeGlobal
there you have to set the parts of global that you actually need so there I set global.colors
manually using the getter.
Color support detection
But there was one test for which -cti-no-colors
and the getters did not work which was test-warning-generic.sac
.
Here adding -cti-no-color
actually did not work! Colors where printed none the less. After puzzling me for a bit I realized this exposed a deeper issue where you always get colors with messages that happen before COLORparse
is called.
To resolve this I added detection for if colors are supported and I use that as the initial value of global.cti_no_color
instead of global.cti_no_color
always being false by default.
Then I added that if global.cti_no_color
is already true at the end of GLOBinitializeGlobal
then we immediately parse colors so that the colors will be disabled right away.
This way you will never get colors when you probably don't want it.
For instance, you will not get colors if it is not supported or if your output is not a terminal.
This is a great feature to have anyway because if the compiler is not outputting for humans you probably do not want colors.
If you do want colors always you can set the FORCE_COLOR
env var. This is a standard env var often used.
I also brought up automatic error detection in issue #2486 (closed).
Adding the automatic color support detection fixed the final failing test and also fixed the test it previously broke without needing the -cti-no-color
flag, so I removed that flag again from those tests.
Adding automatic color detection support like this should also protect any future test and also error message parsing from colors so it is just a good thing to have.
A final problem remains where if you specify -cti-no-colors
, and you get a warning or error before the command line arguments are parsed and global.cti_no_color
is initialized to false then you will get colors until OPTcheckPostSetupOptions
is called which calls COLORparse
.
A workaround for this problem is setting the NO_COLOR
env var because this forces global.cti_no_color
to be initialized as true.
This is also a standard name which is used more often.
Resolving this fully is challenging because currently there is already a call to CTFinitialize
right between GLOBinitializeGlobal
and OPTanalyseCommandline
in SetupCompiler
.
Why is that CTFinitialize
call there? It can generate warnings.
To resolve this issue of always having colors for some early messages if you output to a terminal we already need to know if we need to disable colors before we call that CTFinitialize
. Does that call HAVE to be there? Especially because we call it again at the end of OPTanalyseCommandline
?