#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[] = {
}
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;
}
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++)
*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)
goto auto_color;
}
+ if (!var)
+ return -1;
+
/* Missing or explicit false to turn off colorization */
if (!git_config_bool(var, value))
return 0;
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)
{
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;
va_end(args);
return r;
}
+
+int color_is_nil(const char *c)
+{
+ return !strcmp(c, "NIL");
+}