diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2019-01-02 22:12:36 -0500 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2019-01-02 22:17:08 -0500 |
commit | 28c787b0dcbae9e6c7dfc0013bdaff25d0a2f009 (patch) | |
tree | d8c49d80fe896aff24af78db7530f67aa245eb2b | |
parent | 29a49f5d150911428a35943be8d9fc226865eb1b (diff) | |
download | bfs-28c787b0dcbae9e6c7dfc0013bdaff25d0a2f009.tar.xz |
color: Fix more incompatibilities with GNU ls
-rw-r--r-- | RELEASES.md | 7 | ||||
-rw-r--r-- | color.c | 31 | ||||
-rwxr-xr-x | tests.sh | 83 | ||||
-rw-r--r-- | tests/test_color.out | 15 | ||||
-rw-r--r-- | tests/test_color_ext.out | 15 | ||||
-rw-r--r-- | tests/test_color_ext0.out | 15 | ||||
-rw-r--r-- | tests/test_color_mh.out | 15 | ||||
-rw-r--r-- | tests/test_color_mh0.out | 15 | ||||
-rw-r--r-- | tests/test_color_mi.out | 15 | ||||
-rw-r--r-- | tests/test_color_missing_colon.out | 15 | ||||
-rw-r--r-- | tests/test_color_or.out | 15 | ||||
-rw-r--r-- | tests/test_color_or0_mi.out | 15 | ||||
-rw-r--r-- | tests/test_color_or_mi.out | 15 | ||||
-rw-r--r-- | tests/test_color_or_mi0.out | 15 | ||||
-rw-r--r-- | tests/test_colors.out | 12 |
15 files changed, 267 insertions, 31 deletions
diff --git a/RELEASES.md b/RELEASES.md index 2275cf8..f8f3c3c 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -15,7 +15,12 @@ New features: Fixes: -- Extension colors from `LS_COLORS` are now case-insensitive like GNU `ls` +- `LS_COLORS` handling has been improved: + - Extension colors are now case-insensitive like GNU `ls` + - `or` (orphan) and `mi` (missing) files are now treated differently + - Default colors can be unset with `di=00` or similar + - Specific colors fall back to more general colors when unspecified in more places + - `LS_COLORS` no longer needs a trailing colon - `-ls`/`-fls` now prints the major/minor numbers for device nodes - `-exec ;` is rejected rather than segfaulting - `bfs` now builds on old Linux versions that require `-lrt` for POSIX timers @@ -184,25 +184,20 @@ struct colors *parse_colors(const char *ls_colors) { } char *start = colors->data; - char *end; + size_t colon; struct ext_color *ext; - for (end = strchr(start, ':'); *start && end; start = end + 1, end = strchr(start, ':')) { + for (colon = strcspn(start, ":"); *start; start += colon + 1, colon = strcspn(start, ":")) { + start[colon] = '\0'; + char *equals = strchr(start, '='); if (!equals) { continue; } - *equals = '\0'; - *end = '\0'; const char *key = start; const char *value = equals + 1; - // Ignore all-zero values - if (strspn(value, "0") == strlen(value)) { - continue; - } - if (key[0] == '*') { ext = malloc(sizeof(struct ext_color)); if (ext) { @@ -213,6 +208,11 @@ struct colors *parse_colors(const char *ls_colors) { colors->ext_list = ext; } } else { + // All-zero values should be treated like NULL, to fall + // back on any other relevant coloring for that file + if (strcmp(key, "rs") != 0 && strspn(value, "0") == strlen(value)) { + value = NULL; + } set_color(colors, key, value); } } @@ -307,7 +307,11 @@ static const char *ext_color(const struct colors *colors, const char *filename) static const char *file_color(const struct colors *colors, const char *filename, const struct BFTW *ftwbuf) { const struct bfs_stat *sb = ftwbuf->statbuf; if (!sb) { - return colors->orphan; + if (colors->missing) { + return colors->missing; + } else { + return colors->orphan; + } } const char *color = NULL; @@ -318,7 +322,7 @@ static const char *file_color(const struct colors *colors, const char *filename, color = colors->setuid; } else if (sb->mode & S_ISGID) { color = colors->setgid; - } else if (bfs_check_capabilities(ftwbuf)) { + } else if (colors->capable && bfs_check_capabilities(ftwbuf)) { color = colors->capable; } else if (sb->mode & 0111) { color = colors->exec; @@ -356,9 +360,8 @@ static const char *file_color(const struct colors *colors, const char *filename, break; case S_IFLNK: - if (xfaccessat(ftwbuf->at_fd, ftwbuf->at_path, F_OK) == 0) { - color = colors->link; - } else { + color = colors->link; + if (colors->orphan && xfaccessat(ftwbuf->at_fd, ftwbuf->at_path, F_OK) != 0) { color = colors->orphan; } break; @@ -53,7 +53,9 @@ function installp() { # Like a mythical touch -p function touchp() { - installp -m644 /dev/null "$1" + for arg; do + installp -m644 /dev/null "$arg" + done } # Creates a simple file+directory structure for tests @@ -164,6 +166,29 @@ function make_deep() { } make_deep "$TMP/deep" +# Creates a directory structure with many different types, and therefore colors +function make_rainbow() { + touchp "$1/file.txt" + touchp "$1/file.dat" + ln -s file.txt "$1/link.txt" + touchp "$1/mh1" + ln "$1/mh1" "$1/mh2" + mkfifo "$1/pipe" + # XXX: block + # XXX: chardev + ln -s nowhere "$1/broken" + # XXX: socket + touchp "$1"/s{u,g,ug}id + chmod u+s "$1"/su{,g}id + chmod g+s "$1"/s{u,}gid + mkdir "$1/ow" "$1"/sticky{,_ow} + chmod o+w "$1"/*ow + chmod +t "$1"/sticky* + touchp "$1"/exec.sh + chmod +x "$1"/exec.sh +} +make_rainbow "$TMP/rainbow" + # Creates a scratch directory that tests can modify function make_scratch() { mkdir -p "$1" @@ -582,7 +607,17 @@ bfs_tests=( # Primaries - test_colors + test_color + test_color_mh + test_color_mh0 + test_color_or + test_color_mi + test_color_or_mi + test_color_or0_mi + test_color_or_mi0 + test_color_ext + test_color_ext0 + test_color_missing_colon test_execdir_plus @@ -1741,8 +1776,48 @@ function test_precedence() { bfs_diff basic \( -name foo -type d -o -name bar -a -type f \) -print , \! -empty -type f -print } -function test_colors() { - LS_COLORS= bfs_diff links -color +function test_color() { + LS_COLORS= bfs_diff rainbow -color +} + +function test_color_mh() { + LS_COLORS="mh=01:" bfs_diff rainbow -color +} + +function test_color_mh0() { + LS_COLORS="mh=00:" bfs_diff rainbow -color +} + +function test_color_or() { + LS_COLORS="or=01:" bfs_diff rainbow -color +} + +function test_color_mi() { + LS_COLORS="mi=01:" bfs_diff rainbow -color +} + +function test_color_or_mi() { + LS_COLORS="or=01;31:mi=01;33:" bfs_diff rainbow -color +} + +function test_color_or0_mi() { + LS_COLORS="or=00:mi=01;33:" bfs_diff rainbow -color +} + +function test_color_or_mi0() { + LS_COLORS="or=01;31:mi=00:" bfs_diff rainbow -color +} + +function test_color_ext() { + LS_COLORS="*.txt=01:" bfs_diff rainbow -color +} + +function test_color_ext0() { + LS_COLORS="*.txt=00:" bfs_diff rainbow -color +} + +function test_color_missing_colon() { + LS_COLORS="*.txt=01" bfs_diff rainbow -color } function test_deep() { diff --git a/tests/test_color.out b/tests/test_color.out new file mode 100644 index 0000000..e267da8 --- /dev/null +++ b/tests/test_color.out @@ -0,0 +1,15 @@ +[01;34mrainbow[0m +[01;34mrainbow/[0m[01;32mexec.sh[0m +[01;34mrainbow/[0m[01;36mlink.txt[0m +[01;34mrainbow/[0m[30;42msticky_ow[0m +[01;34mrainbow/[0m[30;43msgid[0m +[01;34mrainbow/[0m[34;42mow[0m +[01;34mrainbow/[0m[37;41msugid[0m +[01;34mrainbow/[0m[37;41msuid[0m +[01;34mrainbow/[0m[37;44msticky[0m +[01;34mrainbow/[0m[40;31;01mbroken[0m +[01;34mrainbow/[0m[40;33mpipe[0m +[01;34mrainbow/[0mfile.dat +[01;34mrainbow/[0mfile.txt +[01;34mrainbow/[0mmh1 +[01;34mrainbow/[0mmh2 diff --git a/tests/test_color_ext.out b/tests/test_color_ext.out new file mode 100644 index 0000000..d2e2a70 --- /dev/null +++ b/tests/test_color_ext.out @@ -0,0 +1,15 @@ +[01;34mrainbow[0m +[01;34mrainbow/[0m[01;32mexec.sh[0m +[01;34mrainbow/[0m[01;36mlink.txt[0m +[01;34mrainbow/[0m[01mfile.txt[0m +[01;34mrainbow/[0m[30;42msticky_ow[0m +[01;34mrainbow/[0m[30;43msgid[0m +[01;34mrainbow/[0m[34;42mow[0m +[01;34mrainbow/[0m[37;41msugid[0m +[01;34mrainbow/[0m[37;41msuid[0m +[01;34mrainbow/[0m[37;44msticky[0m +[01;34mrainbow/[0m[40;31;01mbroken[0m +[01;34mrainbow/[0m[40;33mpipe[0m +[01;34mrainbow/[0mfile.dat +[01;34mrainbow/[0mmh1 +[01;34mrainbow/[0mmh2 diff --git a/tests/test_color_ext0.out b/tests/test_color_ext0.out new file mode 100644 index 0000000..3bc8dc1 --- /dev/null +++ b/tests/test_color_ext0.out @@ -0,0 +1,15 @@ +[01;34mrainbow[0m +[01;34mrainbow/[0m[00mfile.txt[0m +[01;34mrainbow/[0m[01;32mexec.sh[0m +[01;34mrainbow/[0m[01;36mlink.txt[0m +[01;34mrainbow/[0m[30;42msticky_ow[0m +[01;34mrainbow/[0m[30;43msgid[0m +[01;34mrainbow/[0m[34;42mow[0m +[01;34mrainbow/[0m[37;41msugid[0m +[01;34mrainbow/[0m[37;41msuid[0m +[01;34mrainbow/[0m[37;44msticky[0m +[01;34mrainbow/[0m[40;31;01mbroken[0m +[01;34mrainbow/[0m[40;33mpipe[0m +[01;34mrainbow/[0mfile.dat +[01;34mrainbow/[0mmh1 +[01;34mrainbow/[0mmh2 diff --git a/tests/test_color_mh.out b/tests/test_color_mh.out new file mode 100644 index 0000000..600451e --- /dev/null +++ b/tests/test_color_mh.out @@ -0,0 +1,15 @@ +[01;34mrainbow[0m +[01;34mrainbow/[0m[01;32mexec.sh[0m +[01;34mrainbow/[0m[01;36mlink.txt[0m +[01;34mrainbow/[0m[01mmh1[0m +[01;34mrainbow/[0m[01mmh2[0m +[01;34mrainbow/[0m[30;42msticky_ow[0m +[01;34mrainbow/[0m[30;43msgid[0m +[01;34mrainbow/[0m[34;42mow[0m +[01;34mrainbow/[0m[37;41msugid[0m +[01;34mrainbow/[0m[37;41msuid[0m +[01;34mrainbow/[0m[37;44msticky[0m +[01;34mrainbow/[0m[40;31;01mbroken[0m +[01;34mrainbow/[0m[40;33mpipe[0m +[01;34mrainbow/[0mfile.dat +[01;34mrainbow/[0mfile.txt diff --git a/tests/test_color_mh0.out b/tests/test_color_mh0.out new file mode 100644 index 0000000..e267da8 --- /dev/null +++ b/tests/test_color_mh0.out @@ -0,0 +1,15 @@ +[01;34mrainbow[0m +[01;34mrainbow/[0m[01;32mexec.sh[0m +[01;34mrainbow/[0m[01;36mlink.txt[0m +[01;34mrainbow/[0m[30;42msticky_ow[0m +[01;34mrainbow/[0m[30;43msgid[0m +[01;34mrainbow/[0m[34;42mow[0m +[01;34mrainbow/[0m[37;41msugid[0m +[01;34mrainbow/[0m[37;41msuid[0m +[01;34mrainbow/[0m[37;44msticky[0m +[01;34mrainbow/[0m[40;31;01mbroken[0m +[01;34mrainbow/[0m[40;33mpipe[0m +[01;34mrainbow/[0mfile.dat +[01;34mrainbow/[0mfile.txt +[01;34mrainbow/[0mmh1 +[01;34mrainbow/[0mmh2 diff --git a/tests/test_color_mi.out b/tests/test_color_mi.out new file mode 100644 index 0000000..e267da8 --- /dev/null +++ b/tests/test_color_mi.out @@ -0,0 +1,15 @@ +[01;34mrainbow[0m +[01;34mrainbow/[0m[01;32mexec.sh[0m +[01;34mrainbow/[0m[01;36mlink.txt[0m +[01;34mrainbow/[0m[30;42msticky_ow[0m +[01;34mrainbow/[0m[30;43msgid[0m +[01;34mrainbow/[0m[34;42mow[0m +[01;34mrainbow/[0m[37;41msugid[0m +[01;34mrainbow/[0m[37;41msuid[0m +[01;34mrainbow/[0m[37;44msticky[0m +[01;34mrainbow/[0m[40;31;01mbroken[0m +[01;34mrainbow/[0m[40;33mpipe[0m +[01;34mrainbow/[0mfile.dat +[01;34mrainbow/[0mfile.txt +[01;34mrainbow/[0mmh1 +[01;34mrainbow/[0mmh2 diff --git a/tests/test_color_missing_colon.out b/tests/test_color_missing_colon.out new file mode 100644 index 0000000..d2e2a70 --- /dev/null +++ b/tests/test_color_missing_colon.out @@ -0,0 +1,15 @@ +[01;34mrainbow[0m +[01;34mrainbow/[0m[01;32mexec.sh[0m +[01;34mrainbow/[0m[01;36mlink.txt[0m +[01;34mrainbow/[0m[01mfile.txt[0m +[01;34mrainbow/[0m[30;42msticky_ow[0m +[01;34mrainbow/[0m[30;43msgid[0m +[01;34mrainbow/[0m[34;42mow[0m +[01;34mrainbow/[0m[37;41msugid[0m +[01;34mrainbow/[0m[37;41msuid[0m +[01;34mrainbow/[0m[37;44msticky[0m +[01;34mrainbow/[0m[40;31;01mbroken[0m +[01;34mrainbow/[0m[40;33mpipe[0m +[01;34mrainbow/[0mfile.dat +[01;34mrainbow/[0mmh1 +[01;34mrainbow/[0mmh2 diff --git a/tests/test_color_or.out b/tests/test_color_or.out new file mode 100644 index 0000000..6e94bc6 --- /dev/null +++ b/tests/test_color_or.out @@ -0,0 +1,15 @@ +[01;34mrainbow[0m +[01;34mrainbow/[0m[01;32mexec.sh[0m +[01;34mrainbow/[0m[01;36mlink.txt[0m +[01;34mrainbow/[0m[01mbroken[0m +[01;34mrainbow/[0m[30;42msticky_ow[0m +[01;34mrainbow/[0m[30;43msgid[0m +[01;34mrainbow/[0m[34;42mow[0m +[01;34mrainbow/[0m[37;41msugid[0m +[01;34mrainbow/[0m[37;41msuid[0m +[01;34mrainbow/[0m[37;44msticky[0m +[01;34mrainbow/[0m[40;33mpipe[0m +[01;34mrainbow/[0mfile.dat +[01;34mrainbow/[0mfile.txt +[01;34mrainbow/[0mmh1 +[01;34mrainbow/[0mmh2 diff --git a/tests/test_color_or0_mi.out b/tests/test_color_or0_mi.out new file mode 100644 index 0000000..cafa798 --- /dev/null +++ b/tests/test_color_or0_mi.out @@ -0,0 +1,15 @@ +[01;34mrainbow[0m +[01;34mrainbow/[0m[01;32mexec.sh[0m +[01;34mrainbow/[0m[01;36mbroken[0m +[01;34mrainbow/[0m[01;36mlink.txt[0m +[01;34mrainbow/[0m[30;42msticky_ow[0m +[01;34mrainbow/[0m[30;43msgid[0m +[01;34mrainbow/[0m[34;42mow[0m +[01;34mrainbow/[0m[37;41msugid[0m +[01;34mrainbow/[0m[37;41msuid[0m +[01;34mrainbow/[0m[37;44msticky[0m +[01;34mrainbow/[0m[40;33mpipe[0m +[01;34mrainbow/[0mfile.dat +[01;34mrainbow/[0mfile.txt +[01;34mrainbow/[0mmh1 +[01;34mrainbow/[0mmh2 diff --git a/tests/test_color_or_mi.out b/tests/test_color_or_mi.out new file mode 100644 index 0000000..7e57688 --- /dev/null +++ b/tests/test_color_or_mi.out @@ -0,0 +1,15 @@ +[01;34mrainbow[0m +[01;34mrainbow/[0m[01;31mbroken[0m +[01;34mrainbow/[0m[01;32mexec.sh[0m +[01;34mrainbow/[0m[01;36mlink.txt[0m +[01;34mrainbow/[0m[30;42msticky_ow[0m +[01;34mrainbow/[0m[30;43msgid[0m +[01;34mrainbow/[0m[34;42mow[0m +[01;34mrainbow/[0m[37;41msugid[0m +[01;34mrainbow/[0m[37;41msuid[0m +[01;34mrainbow/[0m[37;44msticky[0m +[01;34mrainbow/[0m[40;33mpipe[0m +[01;34mrainbow/[0mfile.dat +[01;34mrainbow/[0mfile.txt +[01;34mrainbow/[0mmh1 +[01;34mrainbow/[0mmh2 diff --git a/tests/test_color_or_mi0.out b/tests/test_color_or_mi0.out new file mode 100644 index 0000000..7e57688 --- /dev/null +++ b/tests/test_color_or_mi0.out @@ -0,0 +1,15 @@ +[01;34mrainbow[0m +[01;34mrainbow/[0m[01;31mbroken[0m +[01;34mrainbow/[0m[01;32mexec.sh[0m +[01;34mrainbow/[0m[01;36mlink.txt[0m +[01;34mrainbow/[0m[30;42msticky_ow[0m +[01;34mrainbow/[0m[30;43msgid[0m +[01;34mrainbow/[0m[34;42mow[0m +[01;34mrainbow/[0m[37;41msugid[0m +[01;34mrainbow/[0m[37;41msuid[0m +[01;34mrainbow/[0m[37;44msticky[0m +[01;34mrainbow/[0m[40;33mpipe[0m +[01;34mrainbow/[0mfile.dat +[01;34mrainbow/[0mfile.txt +[01;34mrainbow/[0mmh1 +[01;34mrainbow/[0mmh2 diff --git a/tests/test_colors.out b/tests/test_colors.out deleted file mode 100644 index dbdeafa..0000000 --- a/tests/test_colors.out +++ /dev/null @@ -1,12 +0,0 @@ -[01;34mlinks[0m -[01;34mlinks/[0m[01;34mdeeply[0m -[01;34mlinks/[0m[01;36mskip[0m -[01;34mlinks/[0m[01;36msymlink[0m -[01;34mlinks/[0m[40;31;01mbroken[0m -[01;34mlinks/[0m[40;31;01mnotdir[0m -[01;34mlinks/[0mfile -[01;34mlinks/[0mhardlink -[01;34mlinks/deeply/[0m[01;34mnested[0m -[01;34mlinks/deeply/nested/[0m[01;34mdir[0m -[01;34mlinks/deeply/nested/[0m[01;36mlink[0m -[01;34mlinks/deeply/nested/[0mfile |