color.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. #include "cache.h"
  2. #include "config.h"
  3. #include "color.h"
  4. static int git_use_color_default = GIT_COLOR_AUTO;
  5. int color_stdout_is_tty = -1;
  6. /*
  7. * The list of available column colors.
  8. */
  9. const char *column_colors_ansi[] = {
  10. GIT_COLOR_RED,
  11. GIT_COLOR_GREEN,
  12. GIT_COLOR_YELLOW,
  13. GIT_COLOR_BLUE,
  14. GIT_COLOR_MAGENTA,
  15. GIT_COLOR_CYAN,
  16. GIT_COLOR_BOLD_RED,
  17. GIT_COLOR_BOLD_GREEN,
  18. GIT_COLOR_BOLD_YELLOW,
  19. GIT_COLOR_BOLD_BLUE,
  20. GIT_COLOR_BOLD_MAGENTA,
  21. GIT_COLOR_BOLD_CYAN,
  22. GIT_COLOR_RESET,
  23. };
  24. enum {
  25. COLOR_BACKGROUND_OFFSET = 10,
  26. COLOR_FOREGROUND_ANSI = 30,
  27. COLOR_FOREGROUND_RGB = 38,
  28. COLOR_FOREGROUND_256 = 38,
  29. COLOR_FOREGROUND_BRIGHT_ANSI = 90,
  30. };
  31. /* Ignore the RESET at the end when giving the size */
  32. const int column_colors_ansi_max = ARRAY_SIZE(column_colors_ansi) - 1;
  33. /* An individual foreground or background color. */
  34. struct color {
  35. enum {
  36. COLOR_UNSPECIFIED = 0,
  37. COLOR_NORMAL,
  38. COLOR_ANSI, /* basic 0-7 ANSI colors */
  39. COLOR_256,
  40. COLOR_RGB
  41. } type;
  42. /* The numeric value for ANSI and 256-color modes */
  43. unsigned char value;
  44. /* 24-bit RGB color values */
  45. unsigned char red, green, blue;
  46. };
  47. /*
  48. * "word" is a buffer of length "len"; does it match the NUL-terminated
  49. * "match" exactly?
  50. */
  51. static int match_word(const char *word, int len, const char *match)
  52. {
  53. return !strncasecmp(word, match, len) && !match[len];
  54. }
  55. static int get_hex_color(const char *in, unsigned char *out)
  56. {
  57. unsigned int val;
  58. val = (hexval(in[0]) << 4) | hexval(in[1]);
  59. if (val & ~0xff)
  60. return -1;
  61. *out = val;
  62. return 0;
  63. }
  64. /*
  65. * If an ANSI color is recognized in "name", fill "out" and return 0.
  66. * Otherwise, leave out unchanged and return -1.
  67. */
  68. static int parse_ansi_color(struct color *out, const char *name, int len)
  69. {
  70. /* Positions in array must match ANSI color codes */
  71. static const char * const color_names[] = {
  72. "black", "red", "green", "yellow",
  73. "blue", "magenta", "cyan", "white"
  74. };
  75. int i;
  76. int color_offset = COLOR_FOREGROUND_ANSI;
  77. if (strncasecmp(name, "bright", 6) == 0) {
  78. color_offset = COLOR_FOREGROUND_BRIGHT_ANSI;
  79. name += 6;
  80. len -= 6;
  81. }
  82. for (i = 0; i < ARRAY_SIZE(color_names); i++) {
  83. if (match_word(name, len, color_names[i])) {
  84. out->type = COLOR_ANSI;
  85. out->value = i + color_offset;
  86. return 0;
  87. }
  88. }
  89. return -1;
  90. }
  91. static int parse_color(struct color *out, const char *name, int len)
  92. {
  93. char *end;
  94. long val;
  95. /* First try the special word "normal"... */
  96. if (match_word(name, len, "normal")) {
  97. out->type = COLOR_NORMAL;
  98. return 0;
  99. }
  100. /* Try a 24-bit RGB value */
  101. if (len == 7 && name[0] == '#') {
  102. if (!get_hex_color(name + 1, &out->red) &&
  103. !get_hex_color(name + 3, &out->green) &&
  104. !get_hex_color(name + 5, &out->blue)) {
  105. out->type = COLOR_RGB;
  106. return 0;
  107. }
  108. }
  109. /* Then pick from our human-readable color names... */
  110. if (parse_ansi_color(out, name, len) == 0) {
  111. return 0;
  112. }
  113. /* And finally try a literal 256-color-mode number */
  114. val = strtol(name, &end, 10);
  115. if (end - name == len) {
  116. /*
  117. * Allow "-1" as an alias for "normal", but other negative
  118. * numbers are bogus.
  119. */
  120. if (val < -1)
  121. ; /* fall through to error */
  122. else if (val < 0) {
  123. out->type = COLOR_NORMAL;
  124. return 0;
  125. /* Rewrite 0-7 as more-portable standard colors. */
  126. } else if (val < 8) {
  127. out->type = COLOR_ANSI;
  128. out->value = val + COLOR_FOREGROUND_ANSI;
  129. return 0;
  130. /* Rewrite 8-15 as more-portable aixterm colors. */
  131. } else if (val < 16) {
  132. out->type = COLOR_ANSI;
  133. out->value = val - 8 + COLOR_FOREGROUND_BRIGHT_ANSI;
  134. return 0;
  135. } else if (val < 256) {
  136. out->type = COLOR_256;
  137. out->value = val;
  138. return 0;
  139. }
  140. }
  141. return -1;
  142. }
  143. static int parse_attr(const char *name, size_t len)
  144. {
  145. static const struct {
  146. const char *name;
  147. size_t len;
  148. int val, neg;
  149. } attrs[] = {
  150. #define ATTR(x, val, neg) { (x), sizeof(x)-1, (val), (neg) }
  151. ATTR("bold", 1, 22),
  152. ATTR("dim", 2, 22),
  153. ATTR("italic", 3, 23),
  154. ATTR("ul", 4, 24),
  155. ATTR("blink", 5, 25),
  156. ATTR("reverse", 7, 27),
  157. ATTR("strike", 9, 29)
  158. #undef ATTR
  159. };
  160. int negate = 0;
  161. int i;
  162. if (skip_prefix_mem(name, len, "no", &name, &len)) {
  163. skip_prefix_mem(name, len, "-", &name, &len);
  164. negate = 1;
  165. }
  166. for (i = 0; i < ARRAY_SIZE(attrs); i++) {
  167. if (attrs[i].len == len && !memcmp(attrs[i].name, name, len))
  168. return negate ? attrs[i].neg : attrs[i].val;
  169. }
  170. return -1;
  171. }
  172. int color_parse(const char *value, char *dst)
  173. {
  174. return color_parse_mem(value, strlen(value), dst);
  175. }
  176. /*
  177. * Write the ANSI color codes for "c" to "out"; the string should
  178. * already have the ANSI escape code in it. "out" should have enough
  179. * space in it to fit any color.
  180. */
  181. static char *color_output(char *out, int len, const struct color *c, int background)
  182. {
  183. int offset = 0;
  184. if (background)
  185. offset = COLOR_BACKGROUND_OFFSET;
  186. switch (c->type) {
  187. case COLOR_UNSPECIFIED:
  188. case COLOR_NORMAL:
  189. break;
  190. case COLOR_ANSI:
  191. out += xsnprintf(out, len, "%d", c->value + offset);
  192. break;
  193. case COLOR_256:
  194. out += xsnprintf(out, len, "%d;5;%d", COLOR_FOREGROUND_256 + offset,
  195. c->value);
  196. break;
  197. case COLOR_RGB:
  198. out += xsnprintf(out, len, "%d;2;%d;%d;%d",
  199. COLOR_FOREGROUND_RGB + offset,
  200. c->red, c->green, c->blue);
  201. break;
  202. }
  203. return out;
  204. }
  205. static int color_empty(const struct color *c)
  206. {
  207. return c->type <= COLOR_NORMAL;
  208. }
  209. int color_parse_mem(const char *value, int value_len, char *dst)
  210. {
  211. const char *ptr = value;
  212. int len = value_len;
  213. char *end = dst + COLOR_MAXLEN;
  214. unsigned int attr = 0;
  215. struct color fg = { COLOR_UNSPECIFIED };
  216. struct color bg = { COLOR_UNSPECIFIED };
  217. while (len > 0 && isspace(*ptr)) {
  218. ptr++;
  219. len--;
  220. }
  221. if (!len) {
  222. dst[0] = '\0';
  223. return 0;
  224. }
  225. if (!strncasecmp(ptr, "reset", len)) {
  226. xsnprintf(dst, end - dst, GIT_COLOR_RESET);
  227. return 0;
  228. }
  229. /* [fg [bg]] [attr]... */
  230. while (len > 0) {
  231. const char *word = ptr;
  232. struct color c = { COLOR_UNSPECIFIED };
  233. int val, wordlen = 0;
  234. while (len > 0 && !isspace(word[wordlen])) {
  235. wordlen++;
  236. len--;
  237. }
  238. ptr = word + wordlen;
  239. while (len > 0 && isspace(*ptr)) {
  240. ptr++;
  241. len--;
  242. }
  243. if (!parse_color(&c, word, wordlen)) {
  244. if (fg.type == COLOR_UNSPECIFIED) {
  245. fg = c;
  246. continue;
  247. }
  248. if (bg.type == COLOR_UNSPECIFIED) {
  249. bg = c;
  250. continue;
  251. }
  252. goto bad;
  253. }
  254. val = parse_attr(word, wordlen);
  255. if (0 <= val)
  256. attr |= (1 << val);
  257. else
  258. goto bad;
  259. }
  260. #undef OUT
  261. #define OUT(x) do { \
  262. if (dst == end) \
  263. BUG("color parsing ran out of space"); \
  264. *dst++ = (x); \
  265. } while(0)
  266. if (attr || !color_empty(&fg) || !color_empty(&bg)) {
  267. int sep = 0;
  268. int i;
  269. OUT('\033');
  270. OUT('[');
  271. for (i = 0; attr; i++) {
  272. unsigned bit = (1 << i);
  273. if (!(attr & bit))
  274. continue;
  275. attr &= ~bit;
  276. if (sep++)
  277. OUT(';');
  278. dst += xsnprintf(dst, end - dst, "%d", i);
  279. }
  280. if (!color_empty(&fg)) {
  281. if (sep++)
  282. OUT(';');
  283. dst = color_output(dst, end - dst, &fg, 0);
  284. }
  285. if (!color_empty(&bg)) {
  286. if (sep++)
  287. OUT(';');
  288. dst = color_output(dst, end - dst, &bg, 1);
  289. }
  290. OUT('m');
  291. }
  292. OUT(0);
  293. return 0;
  294. bad:
  295. return error(_("invalid color value: %.*s"), value_len, value);
  296. #undef OUT
  297. }
  298. int git_config_colorbool(const char *var, const char *value)
  299. {
  300. if (value) {
  301. if (!strcasecmp(value, "never"))
  302. return 0;
  303. if (!strcasecmp(value, "always"))
  304. return 1;
  305. if (!strcasecmp(value, "auto"))
  306. return GIT_COLOR_AUTO;
  307. }
  308. if (!var)
  309. return -1;
  310. /* Missing or explicit false to turn off colorization */
  311. if (!git_config_bool(var, value))
  312. return 0;
  313. /* any normal truth value defaults to 'auto' */
  314. return GIT_COLOR_AUTO;
  315. }
  316. static int check_auto_color(int fd)
  317. {
  318. static int color_stderr_is_tty = -1;
  319. int *is_tty_p = fd == 1 ? &color_stdout_is_tty : &color_stderr_is_tty;
  320. if (*is_tty_p < 0)
  321. *is_tty_p = isatty(fd);
  322. if (*is_tty_p || (fd == 1 && pager_in_use() && pager_use_color)) {
  323. if (!is_terminal_dumb())
  324. return 1;
  325. }
  326. return 0;
  327. }
  328. int want_color_fd(int fd, int var)
  329. {
  330. /*
  331. * NEEDSWORK: This function is sometimes used from multiple threads, and
  332. * we end up using want_auto racily. That "should not matter" since
  333. * we always write the same value, but it's still wrong. This function
  334. * is listed in .tsan-suppressions for the time being.
  335. */
  336. static int want_auto[3] = { -1, -1, -1 };
  337. if (fd < 1 || fd >= ARRAY_SIZE(want_auto))
  338. BUG("file descriptor out of range: %d", fd);
  339. if (var < 0)
  340. var = git_use_color_default;
  341. if (var == GIT_COLOR_AUTO) {
  342. if (want_auto[fd] < 0)
  343. want_auto[fd] = check_auto_color(fd);
  344. return want_auto[fd];
  345. }
  346. return var;
  347. }
  348. int git_color_config(const char *var, const char *value, void *cb)
  349. {
  350. if (!strcmp(var, "color.ui")) {
  351. git_use_color_default = git_config_colorbool(var, value);
  352. return 0;
  353. }
  354. return 0;
  355. }
  356. int git_color_default_config(const char *var, const char *value, void *cb)
  357. {
  358. if (git_color_config(var, value, cb) < 0)
  359. return -1;
  360. return git_default_config(var, value, cb);
  361. }
  362. void color_print_strbuf(FILE *fp, const char *color, const struct strbuf *sb)
  363. {
  364. if (*color)
  365. fprintf(fp, "%s", color);
  366. fprintf(fp, "%s", sb->buf);
  367. if (*color)
  368. fprintf(fp, "%s", GIT_COLOR_RESET);
  369. }
  370. static int color_vfprintf(FILE *fp, const char *color, const char *fmt,
  371. va_list args, const char *trail)
  372. {
  373. int r = 0;
  374. if (*color)
  375. r += fprintf(fp, "%s", color);
  376. r += vfprintf(fp, fmt, args);
  377. if (*color)
  378. r += fprintf(fp, "%s", GIT_COLOR_RESET);
  379. if (trail)
  380. r += fprintf(fp, "%s", trail);
  381. return r;
  382. }
  383. int color_fprintf(FILE *fp, const char *color, const char *fmt, ...)
  384. {
  385. va_list args;
  386. int r;
  387. va_start(args, fmt);
  388. r = color_vfprintf(fp, color, fmt, args, NULL);
  389. va_end(args);
  390. return r;
  391. }
  392. int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...)
  393. {
  394. va_list args;
  395. int r;
  396. va_start(args, fmt);
  397. r = color_vfprintf(fp, color, fmt, args, "\n");
  398. va_end(args);
  399. return r;
  400. }
  401. int color_is_nil(const char *c)
  402. {
  403. return !strcmp(c, "NIL");
  404. }