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
This commit is contained in:
Denis Vlasenko 2009-03-18 22:39:34 +00:00
parent cbb4e61dd5
commit c1969f69b1

View File

@ -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