* Re-implement colour support using termcap's AF and AB capabilities

to manage the ANSI colour sequences.  Colour support is disabled
  unless the TERM environment variable references a valid termcap.

* Allow optional compilation of the colour support in the Makefile,
  defaulting to yes.  This allows us to switch it off for fixit
  floppies and other mediums where space is an issue and the extra
  bloat of statically linking with ncurses isn't acceptable.

* Display a warning if colour is requested with '-G' but support
  for it isn't compiled in.
This commit is contained in:
Josef Karthauser 2000-06-05 02:14:01 +00:00
parent 8db63bde5b
commit 74985094ef
5 changed files with 74 additions and 12 deletions

View File

@ -6,4 +6,7 @@ PROG= ls
SRCS= cmp.c setflags.c ls.c print.c util.c SRCS= cmp.c setflags.c ls.c print.c util.c
.PATH: ${.CURDIR}/../../lib/libc/gen .PATH: ${.CURDIR}/../../lib/libc/gen
CFLAGS+= -DCOLORLS
LDADD= -lncurses
.include <bsd.prog.mk> .include <bsd.prog.mk>

View File

@ -51,5 +51,8 @@ void printscol __P((DISPLAY *));
void usage __P((void)); void usage __P((void));
int len_octal __P((char *, int)); int len_octal __P((char *, int));
int prn_octal __P((char *)); int prn_octal __P((char *));
#ifdef COLORLS
void parsecolors __P((char *cs)); void parsecolors __P((char *cs));
int colortype __P((mode_t mode)); int colortype __P((mode_t mode));
void endcolor __P((void));
#endif

View File

@ -53,6 +53,9 @@ static const char rcsid[] =
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#ifdef COLORLS
#include <curses.h>
#endif
#include <dirent.h> #include <dirent.h>
#include <err.h> #include <err.h>
#include <errno.h> #include <errno.h>
@ -62,6 +65,9 @@ static const char rcsid[] =
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#ifdef COLORLS
#include <term.h>
#endif
#include <unistd.h> #include <unistd.h>
#include "ls.h" #include "ls.h"
@ -111,7 +117,9 @@ int f_statustime; /* use time of last mode change */
int f_timesort; /* sort by time vice name */ int f_timesort; /* sort by time vice name */
int f_type; /* add type character for non-regular files */ int f_type; /* add type character for non-regular files */
int f_whiteout; /* show whiteout entries */ int f_whiteout; /* show whiteout entries */
#ifdef COLORLS
int f_color; /* add type in color for non-regular files */ int f_color; /* add type in color for non-regular files */
#endif
int rval; int rval;
@ -189,7 +197,12 @@ main(argc, argv)
break; break;
case 'G': case 'G':
if (isatty(STDOUT_FILENO)) if (isatty(STDOUT_FILENO))
f_color = 1; #ifdef COLORLS
if (tgetent(NULL, getenv("TERM")) == 1)
f_color = 1;
#else
(void)fprintf(stderr, "Color support not compiled in.\n");
#endif
break; break;
case 'L': case 'L':
fts_options &= ~FTS_PHYSICAL; fts_options &= ~FTS_PHYSICAL;
@ -264,8 +277,10 @@ main(argc, argv)
argc -= optind; argc -= optind;
argv += optind; argv += optind;
#ifdef COLORLS
if (f_color) if (f_color)
parsecolors(getenv("LSCOLORS")); parsecolors(getenv("LSCOLORS"));
#endif
/* /*
* If not -F, -i, -l, -s or -t options, don't require stat * If not -F, -i, -l, -s or -t options, don't require stat
@ -273,7 +288,10 @@ main(argc, argv)
* need this to determine which colors to display. * need this to determine which colors to display.
*/ */
if (!f_inode && !f_longform && !f_size && !f_timesort && !f_type if (!f_inode && !f_longform && !f_size && !f_timesort && !f_type
&& !f_color) #ifdef COLORLS
&& !f_color
#endif
)
fts_options |= FTS_NOSTAT; fts_options |= FTS_NOSTAT;
/* /*

View File

@ -53,7 +53,9 @@ extern int f_size; /* list size in short listing */
extern int f_statustime; /* use time of last mode change */ extern int f_statustime; /* use time of last mode change */
extern int f_notabs; /* don't use tab-separated multi-col output */ extern int f_notabs; /* don't use tab-separated multi-col output */
extern int f_type; /* add type character for non-regular files */ extern int f_type; /* add type character for non-regular files */
#ifdef COLORLS
extern int f_color; /* add type in color for non-regular files */ extern int f_color; /* add type in color for non-regular files */
#endif
typedef struct { typedef struct {
FTSENT *list; FTSENT *list;

View File

@ -46,6 +46,10 @@ static const char rcsid[] =
#include <sys/param.h> #include <sys/param.h>
#include <sys/stat.h> #include <sys/stat.h>
#ifdef COLORLS
#include <ctype.h>
#include <curses.h>
#endif
#include <err.h> #include <err.h>
#include <errno.h> #include <errno.h>
#include <fts.h> #include <fts.h>
@ -54,9 +58,11 @@ static const char rcsid[] =
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#ifdef COLORLS
#include <term.h>
#endif
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include <ctype.h>
#include "ls.h" #include "ls.h"
#include "extern.h" #include "extern.h"
@ -68,6 +74,7 @@ static int printtype __P((u_int));
#define IS_NOPRINT(p) ((p)->fts_number == NO_PRINT) #define IS_NOPRINT(p) ((p)->fts_number == NO_PRINT)
#ifdef COLORLS
/* Most of these are taken from <sys/stat.h> */ /* Most of these are taken from <sys/stat.h> */
typedef enum Colors { typedef enum Colors {
C_DIR, /* directory */ C_DIR, /* directory */
@ -87,6 +94,7 @@ typedef enum Colors {
char *defcolors = "4x5x2x3x1x464301060203"; char *defcolors = "4x5x2x3x1x464301060203";
static int colors[C_NUMCOLORS][2]; static int colors[C_NUMCOLORS][2];
#endif
void void
printscol(dp) printscol(dp)
@ -149,12 +157,16 @@ printlong(dp)
printtime(sp->st_ctime); printtime(sp->st_ctime);
else else
printtime(sp->st_mtime); printtime(sp->st_mtime);
#ifdef COLORLS
if (f_color) if (f_color)
(void)colortype(sp->st_mode); (void)colortype(sp->st_mode);
#endif
if (f_octal || f_octal_escape) (void)prn_octal(p->fts_name); if (f_octal || f_octal_escape) (void)prn_octal(p->fts_name);
else (void)printf("%s", p->fts_name); else (void)printf("%s", p->fts_name);
#ifdef COLORLS
if (f_color) if (f_color)
(void)printf("\033[m"); endcolor();
#endif
if (f_type) if (f_type)
(void)printtype(sp->st_mode); (void)printtype(sp->st_mode);
if (S_ISLNK(sp->st_mode)) if (S_ISLNK(sp->st_mode))
@ -224,6 +236,7 @@ printcol(dp)
dp->s_block); dp->s_block);
if ((base += numrows) >= num) if ((base += numrows) >= num)
break; break;
#ifdef COLORLS
/* /*
* some terminals get confused if we mix tabs * some terminals get confused if we mix tabs
* with color sequences * with color sequences
@ -234,6 +247,7 @@ printcol(dp)
chcnt = cnt; chcnt = cnt;
} }
else else
#endif
while ((cnt = ((chcnt + tabwidth) & ~(tabwidth - 1))) while ((cnt = ((chcnt + tabwidth) & ~(tabwidth - 1)))
<= endcol){ <= endcol){
(void)putchar(f_notabs ? ' ' : '\t'); (void)putchar(f_notabs ? ' ' : '\t');
@ -264,12 +278,16 @@ printaname(p, inodefield, sizefield)
if (f_size) if (f_size)
chcnt += printf("%*qd ", chcnt += printf("%*qd ",
(int)sizefield, howmany(sp->st_blocks, blocksize)); (int)sizefield, howmany(sp->st_blocks, blocksize));
#ifdef COLORLS
if (f_color) if (f_color)
(void)colortype(sp->st_mode); (void)colortype(sp->st_mode);
#endif
chcnt += (f_octal || f_octal_escape) ? prn_octal(p->fts_name) chcnt += (f_octal || f_octal_escape) ? prn_octal(p->fts_name)
: printf("%s", p->fts_name); : printf("%s", p->fts_name);
#ifdef COLORLS
if (f_color) if (f_color)
printf("\033[m"); endcolor();
#endif
if (f_type) if (f_type)
chcnt += printtype(sp->st_mode); chcnt += printtype(sp->st_mode);
return (chcnt); return (chcnt);
@ -333,19 +351,36 @@ printtype(mode)
return (0); return (0);
} }
#ifdef COLORLS
static char tcapbuf[512];
void void
printcolor(c) printcolor(c)
Colors c; Colors c;
{ {
printf("\033["); char *bp = tcapbuf;
char *ansiseq;
if (colors[c][0] != -1) { if (colors[c][0] != -1) {
printf("3%d", colors[c][0]); ansiseq = tparm(tgetstr("AF", &bp), colors[c][0]);
if (colors[c][1] != -1) if (ansiseq)
printf(";"); putp(ansiseq);
} }
if (colors[c][1] != -1)
printf("4%d", colors[c][1]); if (colors[c][1] != -1) {
printf("m"); ansiseq = tparm(tgetstr("AB", &bp), colors[c][1]);
if (ansiseq)
putp(ansiseq);
}
}
void
endcolor()
{
char *bp = tcapbuf;
char *ansiseq;
ansiseq = tgetstr("se", &bp);
if (ansiseq)
putp(ansiseq);
} }
int int
@ -422,6 +457,7 @@ char *cs;
} }
} }
} }
#endif /*COLORLS*/
static void static void
printlink(p) printlink(p)