-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move color option parsing out of diff.c and into color.[ch]
The intent is to lib-ify colorizing code so it can be reused. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <junkio@cox.net>
- Loading branch information
Jeff King
authored and
Junio C Hamano
committed
Sep 8, 2006
1 parent
0424558
commit 7c92fe0
Showing
4 changed files
with
194 additions
and
133 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
#include "color.h" | ||
#include "cache.h" | ||
#include "git-compat-util.h" | ||
|
||
#include <stdarg.h> | ||
|
||
#define COLOR_RESET "\033[m" | ||
|
||
static int parse_color(const char *name, int len) | ||
{ | ||
static const char * const color_names[] = { | ||
"normal", "black", "red", "green", "yellow", | ||
"blue", "magenta", "cyan", "white" | ||
}; | ||
char *end; | ||
int i; | ||
for (i = 0; i < ARRAY_SIZE(color_names); i++) { | ||
const char *str = color_names[i]; | ||
if (!strncasecmp(name, str, len) && !str[len]) | ||
return i - 1; | ||
} | ||
i = strtol(name, &end, 10); | ||
if (*name && !*end && i >= -1 && i <= 255) | ||
return i; | ||
return -2; | ||
} | ||
|
||
static int parse_attr(const char *name, int len) | ||
{ | ||
static const int attr_values[] = { 1, 2, 4, 5, 7 }; | ||
static const char * const attr_names[] = { | ||
"bold", "dim", "ul", "blink", "reverse" | ||
}; | ||
int i; | ||
for (i = 0; i < ARRAY_SIZE(attr_names); i++) { | ||
const char *str = attr_names[i]; | ||
if (!strncasecmp(name, str, len) && !str[len]) | ||
return attr_values[i]; | ||
} | ||
return -1; | ||
} | ||
|
||
void color_parse(const char *value, const char *var, char *dst) | ||
{ | ||
const char *ptr = value; | ||
int attr = -1; | ||
int fg = -2; | ||
int bg = -2; | ||
|
||
if (!strcasecmp(value, "reset")) { | ||
strcpy(dst, "\033[m"); | ||
return; | ||
} | ||
|
||
/* [fg [bg]] [attr] */ | ||
while (*ptr) { | ||
const char *word = ptr; | ||
int val, len = 0; | ||
|
||
while (word[len] && !isspace(word[len])) | ||
len++; | ||
|
||
ptr = word + len; | ||
while (*ptr && isspace(*ptr)) | ||
ptr++; | ||
|
||
val = parse_color(word, len); | ||
if (val >= -1) { | ||
if (fg == -2) { | ||
fg = val; | ||
continue; | ||
} | ||
if (bg == -2) { | ||
bg = val; | ||
continue; | ||
} | ||
goto bad; | ||
} | ||
val = parse_attr(word, len); | ||
if (val < 0 || attr != -1) | ||
goto bad; | ||
attr = val; | ||
} | ||
|
||
if (attr >= 0 || fg >= 0 || bg >= 0) { | ||
int sep = 0; | ||
|
||
*dst++ = '\033'; | ||
*dst++ = '['; | ||
if (attr >= 0) { | ||
*dst++ = '0' + attr; | ||
sep++; | ||
} | ||
if (fg >= 0) { | ||
if (sep++) | ||
*dst++ = ';'; | ||
if (fg < 8) { | ||
*dst++ = '3'; | ||
*dst++ = '0' + fg; | ||
} else { | ||
dst += sprintf(dst, "38;5;%d", fg); | ||
} | ||
} | ||
if (bg >= 0) { | ||
if (sep++) | ||
*dst++ = ';'; | ||
if (bg < 8) { | ||
*dst++ = '4'; | ||
*dst++ = '0' + bg; | ||
} else { | ||
dst += sprintf(dst, "48;5;%d", bg); | ||
} | ||
} | ||
*dst++ = 'm'; | ||
} | ||
*dst = 0; | ||
return; | ||
bad: | ||
die("bad config value '%s' for variable '%s'", value, var); | ||
} | ||
|
||
int git_config_colorbool(const char *var, const char *value) | ||
{ | ||
if (!value) | ||
return 1; | ||
if (!strcasecmp(value, "auto")) { | ||
if (isatty(1) || (pager_in_use && pager_use_color)) { | ||
char *term = getenv("TERM"); | ||
if (term && strcmp(term, "dumb")) | ||
return 1; | ||
} | ||
return 0; | ||
} | ||
if (!strcasecmp(value, "never")) | ||
return 0; | ||
if (!strcasecmp(value, "always")) | ||
return 1; | ||
return git_config_bool(var, value); | ||
} | ||
|
||
static int color_vprintf(const char *color, const char *fmt, | ||
va_list args, const char *trail) | ||
{ | ||
int r = 0; | ||
|
||
if (*color) | ||
r += printf("%s", color); | ||
r += vprintf(fmt, args); | ||
if (*color) | ||
r += printf("%s", COLOR_RESET); | ||
if (trail) | ||
r += printf("%s", trail); | ||
return r; | ||
} | ||
|
||
|
||
|
||
int color_printf(const char *color, const char *fmt, ...) | ||
{ | ||
va_list args; | ||
int r; | ||
va_start(args, fmt); | ||
r = color_vprintf(color, fmt, args, NULL); | ||
va_end(args); | ||
return r; | ||
} | ||
|
||
int color_printf_ln(const char *color, const char *fmt, ...) | ||
{ | ||
va_list args; | ||
int r; | ||
va_start(args, fmt); | ||
r = color_vprintf(color, fmt, args, "\n"); | ||
va_end(args); | ||
return r; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#ifndef COLOR_H | ||
#define COLOR_H | ||
|
||
/* "\033[1;38;5;2xx;48;5;2xxm\0" is 23 bytes */ | ||
#define COLOR_MAXLEN 24 | ||
|
||
int git_config_colorbool(const char *var, const char *value); | ||
void color_parse(const char *var, const char *value, char *dst); | ||
int color_printf(const char *color, const char *fmt, ...); | ||
int color_printf_ln(const char *color, const char *fmt, ...); | ||
|
||
#endif /* COLOR_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters