summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/color.c67
-rw-r--r--tests/bfs/color_bsd.out54
-rw-r--r--tests/bfs/color_bsd.sh2
-rw-r--r--tests/bfs/color_bsd_fail.sh2
4 files changed, 74 insertions, 51 deletions
diff --git a/src/color.c b/src/color.c
index 11dff2a..926cf2b 100644
--- a/src/color.c
+++ b/src/color.c
@@ -618,28 +618,43 @@ fail:
/** Parse the FreeBSD $LSCOLORS format. */
static int parse_bsd_ls_colors(struct colors *colors, const char *lscolors) {
static const char *fg_codes[256] = {
- ['a'] = "30", ['b'] = "31", ['c'] = "32", ['d'] = "33",
- ['e'] = "34", ['f'] = "35", ['g'] = "36", ['h'] = "37", ['x'] = "39",
+ // 0-7: deprecated aliases for a-h
+ ['0'] = "30", ['1'] = "31", ['2'] = "32", ['3'] = "33",
+ ['4'] = "34", ['5'] = "35", ['6'] = "36", ['7'] = "37",
+ // a-h: first 8 ANSI foreground colors
+ ['a'] = "30", ['b'] = "31", ['c'] = "32", ['d'] = "33",
+ ['e'] = "34", ['f'] = "35", ['g'] = "36", ['h'] = "37",
+ // x: default foreground
+ ['x'] = "39",
+ // A-H: bold foreground colors
['A'] = "1;30", ['B'] = "1;31", ['C'] = "1;32", ['D'] = "1;33",
- ['E'] = "1;34", ['F'] = "1;35", ['G'] = "1;36", ['H'] = "1;37", ['X'] = "1"
+ ['E'] = "1;34", ['F'] = "1;35", ['G'] = "1;36", ['H'] = "1;37",
+ // X: bold default foreground
+ ['X'] = "1;39",
};
static const char *bg_codes[256] = {
- ['a'] = "40", ['b'] = "41", ['c'] = "42", ['d'] = "43",
- ['e'] = "44", ['f'] = "45", ['g'] = "46", ['h'] = "47", ['x'] = "49",
- ['A'] = "4;100", ['B'] = "4;101", ['C'] = "4;102", ['D'] = "4;103",
- ['E'] = "4;104", ['F'] = "4;105", ['G'] = "4;106", ['H'] = "4;107", ['X'] = "4;49"
+ // 0-7: deprecated aliases for a-h
+ ['0'] = "40", ['1'] = "41", ['2'] = "42", ['3'] = "43",
+ ['4'] = "44", ['5'] = "45", ['6'] = "46", ['7'] = "47",
+ // a-h: first 8 ANSI background colors
+ ['a'] = "40", ['b'] = "41", ['c'] = "42", ['d'] = "43",
+ ['e'] = "44", ['f'] = "45", ['g'] = "46", ['h'] = "47",
+ // x: default background
+ ['x'] = "49",
+ // A-H: background colors + underline
+ ['A'] = "4;40", ['B'] = "4;41", ['C'] = "4;42", ['D'] = "4;43",
+ ['E'] = "4;44", ['F'] = "4;45", ['G'] = "4;46", ['H'] = "4;47",
+ // X: default background + underline
+ ['X'] = "4;49",
};
// Please refer to https://man.freebsd.org/cgi/man.cgi?ls(1)#ENVIRONMENT
char complete_colors[] = "exfxcxdxbxegedabagacadah";
+ // For short $LSCOLORS, use the default colors for the rest
size_t max = strlen(complete_colors);
- size_t len = strnlen(lscolors, max + 1);
- if (len == 0 || len % 2 != 0 || len > max) {
- errno = EINVAL;
- return -1;
- }
+ size_t len = strnlen(lscolors, max);
memcpy(complete_colors, lscolors, len);
struct esc_seq **keys[] = {
@@ -657,8 +672,8 @@ static int parse_bsd_ls_colors(struct colors *colors, const char *lscolors) {
&colors->dataless,
};
- dchar *value = dstralloc(0);
- if (!value) {
+ dchar *buf = dstralloc(8);
+ if (!buf) {
return -1;
}
@@ -669,15 +684,25 @@ static int parse_bsd_ls_colors(struct colors *colors, const char *lscolors) {
const char *fg_code = fg_codes[fg];
const char *bg_code = bg_codes[bg];
- if (!fg_code || !bg_code) {
- continue;
- }
- dstrshrink(value, 0);
- if (dstrcatf(&value, "%s;%s", fg_code, bg_code) != 0) {
- goto fail;
+ dstrshrink(buf, 0);
+ if (fg_code) {
+ if (dstrcat(&buf, fg_code) != 0) {
+ goto fail;
+ }
+ }
+ if (fg_code && bg_code) {
+ if (dstrcat(&buf, ";") != 0) {
+ goto fail;
+ }
+ }
+ if (bg_code) {
+ if (dstrcat(&buf, bg_code) != 0) {
+ goto fail;
+ }
}
+ const dchar *value = dstrlen(buf) > 0 ? buf : NULL;
if (set_esc_field(colors, keys[i], value) != 0) {
goto fail;
}
@@ -685,7 +710,7 @@ static int parse_bsd_ls_colors(struct colors *colors, const char *lscolors) {
ret = 0;
fail:
- dstrfree(value);
+ dstrfree(buf);
return ret;
}
diff --git a/tests/bfs/color_bsd.out b/tests/bfs/color_bsd.out
index f7c577c..2ad656f 100644
--- a/tests/bfs/color_bsd.out
+++ b/tests/bfs/color_bsd.out
@@ -1,27 +1,27 @@
-$'rainbow/\e[1m'
-$'rainbow/\e[1m/'$'\e[0m'
-rainbow
-rainbow/sugid
-rainbow/suid
-rainbow/sticky_ow
-rainbow/ow
-rainbow/sgid
-rainbow/exec.sh
-rainbow/socket
-rainbow/pipe
-rainbow/broken
-rainbow/chardev_link
-rainbow/link.txt
-rainbow/sticky
-rainbow/file.dat
-rainbow/file.txt
-rainbow/lower.gz
-rainbow/lower.tar
-rainbow/lower.tar.gz
-rainbow/lu.tar.GZ
-rainbow/mh1
-rainbow/mh2
-rainbow/ul.TAR.gz
-rainbow/upper.GZ
-rainbow/upper.TAR
-rainbow/upper.TAR.GZ
+$'rainbow/\e[1m'
+$'rainbow/\e[1m/'$'\e[0m'
+rainbow
+rainbow/pipe
+rainbow/broken
+rainbow/chardev_link
+rainbow/link.txt
+rainbow/sugid
+rainbow/suid
+rainbow/sticky_ow
+rainbow/ow
+rainbow/sgid
+rainbow/exec.sh
+rainbow/socket
+rainbow/sticky
+rainbow/file.dat
+rainbow/file.txt
+rainbow/lower.gz
+rainbow/lower.tar
+rainbow/lower.tar.gz
+rainbow/lu.tar.GZ
+rainbow/mh1
+rainbow/mh2
+rainbow/ul.TAR.gz
+rainbow/upper.GZ
+rainbow/upper.TAR
+rainbow/upper.TAR.GZ
diff --git a/tests/bfs/color_bsd.sh b/tests/bfs/color_bsd.sh
index f8a777f..2e99f0b 100644
--- a/tests/bfs/color_bsd.sh
+++ b/tests/bfs/color_bsd.sh
@@ -1 +1 @@
-LSCOLORS="eB" bfs_diff rainbow -color
+LSCOLORS="exFxcXDXbxeGxdXb" bfs_diff rainbow -color
diff --git a/tests/bfs/color_bsd_fail.sh b/tests/bfs/color_bsd_fail.sh
deleted file mode 100644
index 541190c..0000000
--- a/tests/bfs/color_bsd_fail.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-# LSCOLORS can be at most 24 characters long (12 color pairs); this one has 25.
-! LSCOLORS="exfxcxdxbxegedabagacadeahB" invoke_bfs rainbow -color