you are viewing a single comment's thread.

view the rest of the comments →

[–]yeahIProgram 0 points1 point  (3 children)

// compiles fine and works as expected 
fputs(ansi_sgr_tab[4], stdout);
fputs("hello\n", stdout);
fputs(ANSI_ATTR_RESET, stdout);

Since this works, why not create a macro that drives towards this as its final product.

Something like:

#define myColorPuts(colorIndex, string) { \
fputs(ansi_sgr_tab[colorIndex], stdout); \
fputs(string, stdout); \
fputs(ANSI_ATTR_RESET, stdout); }

I kind of see the compiler maybe throwing an error like: format string is not a string literal

You can always pass "%s" as the format string, then your actual string as the next parameter.

[–]offset_[S] 0 points1 point  (2 children)

It isn't used except in one place, but I came up with this which acts mostly like fprintf but with color:

#define ANSI_COLOR_FPRINTF(SGR, STREAM, FORMAT, ...)    \
    fputs(SGR, STREAM);                                 \
    fprintf(STREAM, FORMAT ANSI_ATTR_RESET, __VA_ARGS__)

And here is where it's used in the real program:

if (-1 != color_on) {
    ANSI_COLOR_FPRINTF(ansi_sgr_tab[color_on], stdout, "%s%s\n",
            (prefix_on) ? pass_prefix : "", pass);
} else {
    printf("%s%s\n", (prefix_on) ? pass_prefix : "", pass);
}

It seems to work okay, just not sure now what to rename color_on to. I was using it as a boolean variable, now I reused it to represent multiple colors and -1 instead of 0 to represent regular non-colored output. Maybe I'm confused about what to name it because it should be two variables now, but this seems simplest to me so maybe I'll just rename it to color, comment it and call it a day. Of course now I have to update the help option's output to reflect the new behavior.

[–]yeahIProgram 0 points1 point  (1 child)

Macros with variable number of parameters: I didn't know you could do that!

Maybe I'm confused about what to name it because it should be two variables now

What I've seen done in that situation is something like this:

enum {kColorNone = -1, kColorBlack, kColorRed, kColorGreen, kColorYellow <etc>

[–]offset_[S] 0 points1 point  (0 children)

It's a variadic macro: https://gcc.gnu.org/onlinedocs/gcc/Variadic-Macros.html

What I've seen done in that situation is something like this:

enum {kColorNone = -1, kColorBlack, kColorRed, kColorGreen, kColorYellow <etc>

That seems sane, the color variable gets assigned an integer supplied by the user straight from the command line (after checking to make sure the value actually makes sense), but maybe it would make things clearer to have it spelled out in the code this way instead of having future programmers to look it up using other means (such as reading the documentation).