From c1969f69b11dca4fdd8916684daea8b2abf63017 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Wed, 18 Mar 2009 22:39:34 +0000 Subject: ls: make color-related code more readable. Fix a case when it was working non-deterministically. function old new delta bold - 34 +34 showfiles 1508 1495 -13 fgcolor 50 34 -16 bgcolor 34 - -34 ------------------------------------------------------------------------------ (add/remove: 1/1 grow/shrink: 0/2 up/down: 34/-63) Total: -29 bytes --- coreutils/ls.c | 62 ++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/coreutils/ls.c b/coreutils/ls.c index a461b154f..8007f2a2e 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c @@ -127,14 +127,6 @@ SPLIT_SUBDIR = 2, }; -#define TYPEINDEX(mode) (((mode) >> 12) & 0x0f) -#define TYPECHAR(mode) ("0pcCd?bB-?l?s???" [TYPEINDEX(mode)]) -#define APPCHAR(mode) ("\0|\0\0/\0\0\0\0\0@\0=\0\0\0" [TYPEINDEX(mode)]) -#define COLOR(mode) ("\000\043\043\043\042\000\043\043"\ - "\000\000\044\000\043\000\000\040" [TYPEINDEX(mode)]) -#define ATTR(mode) ("\00\00\01\00\01\00\01\00"\ - "\00\00\01\00\01\00\00\01" [TYPEINDEX(mode)]) - /* "[-]Cadil1", POSIX mandated options, busybox always supports */ /* "[-]gnsx", POSIX non-mandated options, busybox always supports */ /* "[-]Q" GNU option? busybox always supports */ @@ -344,18 +336,46 @@ static struct dnode *my_stat(const char *fullname, const char *name, int force_f return cur; } + +/* FYI type values: 1:fifo 2:char 4:dir 6:blk 8:file 10:link 12:socket + * (various wacky OSes: 13:Sun door 14:BSD whiteout 5:XENIX named file + * 3/7:multiplexed char/block device) + * and we use 0 for unknown and 15 for executables (see below) */ +#define TYPEINDEX(mode) (((mode) >> 12) & 0x0f) +#define TYPECHAR(mode) ("0pcCd?bB-?l?s???" [TYPEINDEX(mode)]) +#define APPCHAR(mode) ("\0|\0\0/\0\0\0\0\0@\0=\0\0\0" [TYPEINDEX(mode)]) +/* 036 black foreground 050 black background + 037 red foreground 051 red background + 040 green foreground 052 green background + 041 brown foreground 053 brown background + 042 blue foreground 054 blue background + 043 magenta (purple) foreground 055 magenta background + 044 cyan (light blue) foreground 056 cyan background + 045 gray foreground 057 white background +*/ +#define COLOR(mode) ( \ + /*un fi chr dir blk file link sock exe */ \ + "\037\043\043\045\042\045\043\043\000\045\044\045\043\045\045\040" \ + [TYPEINDEX(mode)]) +/* Select normal (0) [actually "reset all"] or bold (1) + * (other attributes are 2:dim 4:underline 5:blink 7:reverse, + * let's use 7 for "impossible" types, just for fun) + * Note: coreutils 6.9 uses inverted red for setuid binaries. + */ +#define ATTR(mode) ( \ + /*un fi chr dir blk file link sock exe */ \ + "\01\00\01\07\01\07\01\07\00\07\01\07\01\07\07\01" \ + [TYPEINDEX(mode)]) + #if ENABLE_FEATURE_LS_COLOR +/* mode of zero is interpreted as "unknown" (stat failed) */ static char fgcolor(mode_t mode) { - /* Check wheter the file is existing (if so, color it red!) */ - if (errno == ENOENT) - return '\037'; if (S_ISREG(mode) && (mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return COLOR(0xF000); /* File is executable ... */ return COLOR(mode); } - -static char bgcolor(mode_t mode) +static char bold(mode_t mode) { if (S_ISREG(mode) && (mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return ATTR(0xF000); /* File is executable ... */ @@ -378,6 +398,7 @@ static char append_char(mode_t mode) } #endif + #define countdirs(A, B) count_dirs((A), (B), 1) #define countsubdirs(A, B) count_dirs((A), (B), 0) static int count_dirs(struct dnode **dn, int nfiles, int notsubdirs) @@ -818,10 +839,11 @@ static int list_single(const struct dnode *dn) break; #endif case LIST_FILENAME: - errno = 0; #if ENABLE_FEATURE_LS_COLOR - if (show_color && !lstat(dn->fullname, &info)) { - printf("\033[%u;%um", bgcolor(info.st_mode), + if (show_color) { + info.st_mode = 0; /* for fgcolor() */ + lstat(dn->fullname, &info); + printf("\033[%u;%um", bold(info.st_mode), fgcolor(info.st_mode)); } #endif @@ -836,14 +858,16 @@ static int list_single(const struct dnode *dn) if (!lpath) break; printf(" -> "); #if ENABLE_FEATURE_LS_FILETYPES || ENABLE_FEATURE_LS_COLOR - if (!stat(dn->fullname, &info)) { +#if ENABLE_FEATURE_LS_COLOR + info.st_mode = 0; /* for fgcolor() */ +#endif + if (stat(dn->fullname, &info) == 0) { append = append_char(info.st_mode); } #endif #if ENABLE_FEATURE_LS_COLOR if (show_color) { - errno = 0; - printf("\033[%u;%um", bgcolor(info.st_mode), + printf("\033[%u;%um", bold(info.st_mode), fgcolor(info.st_mode)); } #endif -- cgit v1.2.3