summary refs log tree commit diff
path: root/color.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2016-07-11 10:31:05 -0700
committerJunio C Hamano <gitster@pobox.com>2016-07-11 10:31:05 -0700
commit3c5de5c77b0718b47010b146160ecff6309f86b5 (patch)
tree10dfe3c6e701fab8fee60d0059a07b72cfd34c59 /color.c
parentbb2d8a817df91c68742e10ace2a791de176f7247 (diff)
parent9dc3515cf005639317fb95492b3157aadf056923 (diff)
Merge branch 'jk/ansi-color'
The output coloring scheme learned two new attributes, italic and
strike, in addition to existing bold, reverse, etc.

* jk/ansi-color:
  color: support strike-through attribute
  color: support "italic" attribute
  color: allow "no-" for negating attributes
  color: refactor parse_attr
  add skip_prefix_mem helper
  doc: refactor description of color format
  color: fix max-size comment
Diffstat (limited to 'color.c')
-rw-r--r--color.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/color.c b/color.c
index 8f85153d0d..81c2676723 100644
--- a/color.c
+++ b/color.c
@@ -123,19 +123,34 @@ static int parse_color(struct color *out, const char *name, int len)
 	return -1;
 }
 
-static int parse_attr(const char *name, int len)
+static int parse_attr(const char *name, size_t len)
 {
-	static const int attr_values[] = { 1, 2, 4, 5, 7,
-					   22, 22, 24, 25, 27 };
-	static const char * const attr_names[] = {
-		"bold", "dim", "ul", "blink", "reverse",
-		"nobold", "nodim", "noul", "noblink", "noreverse"
+	static const struct {
+		const char *name;
+		size_t len;
+		int val, neg;
+	} attrs[] = {
+#define ATTR(x, val, neg) { (x), sizeof(x)-1, (val), (neg) }
+		ATTR("bold",      1, 22),
+		ATTR("dim",       2, 22),
+		ATTR("italic",    3, 23),
+		ATTR("ul",        4, 24),
+		ATTR("blink",     5, 25),
+		ATTR("reverse",   7, 27),
+		ATTR("strike",    9, 29)
+#undef ATTR
 	};
+	int negate = 0;
 	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];
+
+	if (skip_prefix_mem(name, len, "no", &name, &len)) {
+		skip_prefix_mem(name, len, "-", &name, &len);
+		negate = 1;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(attrs); i++) {
+		if (attrs[i].len == len && !memcmp(attrs[i].name, name, len))
+			return negate ? attrs[i].neg : attrs[i].val;
 	}
 	return -1;
 }