diff options
Diffstat (limited to 'color.c')
-rw-r--r-- | color.c | 100 |
1 files changed, 78 insertions, 22 deletions
@@ -1,10 +1,30 @@ #include "cache.h" #include "color.h" -#define COLOR_RESET "\033[m" - int git_use_color_default = 0; +/* + * The list of available column colors. + */ +const char *column_colors_ansi[] = { + GIT_COLOR_RED, + GIT_COLOR_GREEN, + GIT_COLOR_YELLOW, + GIT_COLOR_BLUE, + GIT_COLOR_MAGENTA, + GIT_COLOR_CYAN, + GIT_COLOR_BOLD_RED, + GIT_COLOR_BOLD_GREEN, + GIT_COLOR_BOLD_YELLOW, + GIT_COLOR_BOLD_BLUE, + GIT_COLOR_BOLD_MAGENTA, + GIT_COLOR_BOLD_CYAN, + GIT_COLOR_RESET, +}; + +/* Ignore the RESET at the end when giving the size */ +const int column_colors_ansi_max = ARRAY_SIZE(column_colors_ansi) - 1; + static int parse_color(const char *name, int len) { static const char * const color_names[] = { @@ -41,29 +61,40 @@ static int parse_attr(const char *name, int len) void color_parse(const char *value, const char *var, char *dst) { + color_parse_mem(value, strlen(value), var, dst); +} + +void color_parse_mem(const char *value, int value_len, const char *var, + char *dst) +{ const char *ptr = value; - int attr = -1; + int len = value_len; + unsigned int attr = 0; int fg = -2; int bg = -2; - if (!strcasecmp(value, "reset")) { - strcpy(dst, "\033[m"); + if (!strncasecmp(value, "reset", len)) { + strcpy(dst, GIT_COLOR_RESET); return; } - /* [fg [bg]] [attr] */ - while (*ptr) { + /* [fg [bg]] [attr]... */ + while (len > 0) { const char *word = ptr; - int val, len = 0; + int val, wordlen = 0; - while (word[len] && !isspace(word[len])) - len++; + while (len > 0 && !isspace(word[wordlen])) { + wordlen++; + len--; + } - ptr = word + len; - while (*ptr && isspace(*ptr)) + ptr = word + wordlen; + while (len > 0 && isspace(*ptr)) { ptr++; + len--; + } - val = parse_color(word, len); + val = parse_color(word, wordlen); if (val >= -1) { if (fg == -2) { fg = val; @@ -75,20 +106,28 @@ void color_parse(const char *value, const char *var, char *dst) } goto bad; } - val = parse_attr(word, len); - if (val < 0 || attr != -1) + val = parse_attr(word, wordlen); + if (0 <= val) + attr |= (1 << val); + else goto bad; - attr = val; } - if (attr >= 0 || fg >= 0 || bg >= 0) { + if (attr || fg >= 0 || bg >= 0) { int sep = 0; + int i; *dst++ = '\033'; *dst++ = '['; - if (attr >= 0) { - *dst++ = '0' + attr; - sep++; + + for (i = 0; attr; i++) { + unsigned bit = (1 << i); + if (!(attr & bit)) + continue; + attr &= ~bit; + if (sep++) + *dst++ = ';'; + *dst++ = '0' + i; } if (fg >= 0) { if (sep++) @@ -115,7 +154,7 @@ void color_parse(const char *value, const char *var, char *dst) *dst = 0; return; bad: - die("bad config value '%s' for variable '%s'", value, var); + die("bad color value '%.*s' for variable '%s'", value_len, value, var); } int git_config_colorbool(const char *var, const char *value, int stdout_is_tty) @@ -129,6 +168,9 @@ int git_config_colorbool(const char *var, const char *value, int stdout_is_tty) goto auto_color; } + if (!var) + return -1; + /* Missing or explicit false to turn off colorization */ if (!git_config_bool(var, value)) return 0; @@ -155,6 +197,15 @@ int git_color_default_config(const char *var, const char *value, void *cb) return git_default_config(var, value, cb); } +void color_print_strbuf(FILE *fp, const char *color, const struct strbuf *sb) +{ + if (*color) + fprintf(fp, "%s", color); + fprintf(fp, "%s", sb->buf); + if (*color) + fprintf(fp, "%s", GIT_COLOR_RESET); +} + static int color_vfprintf(FILE *fp, const char *color, const char *fmt, va_list args, const char *trail) { @@ -164,7 +215,7 @@ static int color_vfprintf(FILE *fp, const char *color, const char *fmt, r += fprintf(fp, "%s", color); r += vfprintf(fp, fmt, args); if (*color) - r += fprintf(fp, "%s", COLOR_RESET); + r += fprintf(fp, "%s", GIT_COLOR_RESET); if (trail) r += fprintf(fp, "%s", trail); return r; @@ -191,3 +242,8 @@ int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...) va_end(args); return r; } + +int color_is_nil(const char *c) +{ + return !strcmp(c, "NIL"); +} |