summaryrefslogtreecommitdiff
path: root/tw.color.c
diff options
context:
space:
mode:
Diffstat (limited to 'tw.color.c')
-rw-r--r--tw.color.c252
1 files changed, 197 insertions, 55 deletions
diff --git a/tw.color.c b/tw.color.c
index 31a1d2dca3fdc..c0567b2a76931 100644
--- a/tw.color.c
+++ b/tw.color.c
@@ -1,4 +1,4 @@
-/* $Header: /p/tcsh/cvsroot/tcsh/tw.color.c,v 1.27 2010/08/19 05:52:19 christos Exp $ */
+/* $Header: /p/tcsh/cvsroot/tcsh/tw.color.c,v 1.33 2015/05/28 11:53:49 christos Exp $ */
/*
* tw.color.c: builtin color ls-F
*/
@@ -32,7 +32,7 @@
*/
#include "sh.h"
-RCSID("$tcsh: tw.color.c,v 1.27 2010/08/19 05:52:19 christos Exp $")
+RCSID("$tcsh: tw.color.c,v 1.33 2015/05/28 11:53:49 christos Exp $")
#include "tw.h"
#include "ed.h"
@@ -91,13 +91,66 @@ static Variable variables[] = {
VAR(NOS, "ca", "30;41"), /* File with capability */
};
+#define nvariables (sizeof(variables)/sizeof(variables[0]))
+
enum FileType {
VDir, VSym, VOrph, VPipe, VSock, VDoor, VBlock, VChr, VExe,
- VFile, VNormal, VMiss, VLeft, VRight, VEnd
+ VFile, VNormal, VMiss, VLeft, VRight, VEnd, VSuid, VSgid, VSticky,
+ VOther, Vstird, VReset, Vhard, Vhard2, VCap
+};
+
+/*
+ * Map from LSCOLORS entry index to Variable array index
+ */
+static const uint8_t map[] = {
+ VDir, /* Directory */
+ VSym, /* Symbolic Link */
+ VSock, /* Socket */
+ VPipe, /* Named Pipe */
+ VExe, /* Executable */
+ VBlock, /* Block Special */
+ VChr, /* Character Special */
+ VSuid, /* Setuid Executable */
+ VSgid, /* Setgid Executable */
+ VSticky, /* Directory writable to others and sticky */
+ VOther, /* Directory writable to others but not sticky */
};
-#define nvariables (sizeof(variables)/sizeof(variables[0]))
+
+enum ansi {
+ ANSI_RESET_ON = 0, /* reset colors/styles (white on black) */
+ ANSI_BOLD_ON = 1, /* bold on */
+ ANSI_ITALICS_ON = 3, /* italics on */
+ ANSI_UNDERLINE_ON = 4, /* underline on */
+ ANSI_INVERSE_ON = 7, /* inverse on */
+ ANSI_STRIKETHROUGH_ON = 9, /* strikethrough on */
+ ANSI_BOLD_OFF = 21, /* bold off */
+ ANSI_ITALICS_OFF = 23, /* italics off */
+ ANSI_UNDERLINE_OFF = 24, /* underline off */
+ ANSI_INVERSE_OFF = 27, /* inverse off */
+ ANSI_STRIKETHROUGH_OFF = 29,/* strikethrough off */
+ ANSI_FG_BLACK = 30, /* fg black */
+ ANSI_FG_RED = 31, /* fg red */
+ ANSI_FG_GREEN = 32, /* fg green */
+ ANSI_FG_YELLOW = 33, /* fg yellow */
+ ANSI_FG_BLUE = 34, /* fg blue */
+ ANSI_FG_MAGENTA = 35, /* fg magenta */
+ ANSI_FG_CYAN = 36, /* fg cyan */
+ ANSI_FG_WHITE = 37, /* fg white */
+ ANSI_FG_DEFAULT = 39, /* fg default (white) */
+ ANSI_BG_BLACK = 40, /* bg black */
+ ANSI_BG_RED = 41, /* bg red */
+ ANSI_BG_GREEN = 42, /* bg green */
+ ANSI_BG_YELLOW = 43, /* bg yellow */
+ ANSI_BG_BLUE = 44, /* bg blue */
+ ANSI_BG_MAGENTA = 45, /* bg magenta */
+ ANSI_BG_CYAN = 46, /* bg cyan */
+ ANSI_BG_WHITE = 47, /* bg white */
+ ANSI_BG_DEFAULT = 49, /* bg default (black) */
+};
+#define TCSH_BOLD 0x80
+
typedef struct {
Str extension; /* file extension */
Str color; /* color string */
@@ -167,6 +220,101 @@ getstring(char **dp, const Char **sp, Str *pd, int f)
return *s == (Char)f;
}
+static void
+init(size_t colorlen, size_t extnum)
+{
+ size_t i;
+
+ xfree(extensions);
+ for (i = 0; i < nvariables; i++)
+ variables[i].color = variables[i].defaultcolor;
+ if (colorlen == 0 && extnum == 0) {
+ extensions = NULL;
+ colors = NULL;
+ } else {
+ extensions = xmalloc(colorlen + extnum * sizeof(*extensions));
+ colors = extnum * sizeof(*extensions) + (char *)extensions;
+ }
+ nextensions = 0;
+}
+
+static int
+color(Char x)
+{
+ static const char ccolors[] = "abcdefghx";
+ char *p;
+ if (Isupper(x)) {
+ x = Tolower(x);
+ }
+
+ if (x == '\0' || (p = strchr(ccolors, x)) == NULL)
+ return -1;
+ return 30 + (p - ccolors);
+}
+
+static void
+makecolor(char **c, int fg, int bg, Str *v)
+{
+ int l;
+ if (fg & 0x80)
+ l = xsnprintf(*c, 12, "%.2d;%.2d;%.2d;%.2d", ANSI_BOLD_ON,
+ fg & ~TCSH_BOLD, (10 + bg) & ~TCSH_BOLD, ANSI_BOLD_OFF);
+ l = xsnprintf(*c, 6, "%.2d;%.2d",
+ fg & ~TCSH_BOLD, (10 + bg) & ~TCSH_BOLD);
+
+ v->s = *c;
+ v->len = l;
+ *c += l + 1;
+}
+
+/* parseLSCOLORS():
+ * Parse the LSCOLORS environment variable
+ */
+static const Char *xv; /* setjmp clobbering */
+void
+parseLSCOLORS(const Char *value)
+{
+ size_t i, len, clen;
+ jmp_buf_t osetexit;
+ size_t omark;
+ xv = value;
+
+ if (xv == NULL) {
+ init(0, 0);
+ return;
+ }
+
+ len = Strlen(xv);
+ len >>= 1;
+ clen = len * 12; /* "??;??;??;??\0" */
+ init(clen, 0);
+
+ /* Prevent from crashing if unknown parameters are given. */
+ omark = cleanup_push_mark();
+ getexit(osetexit);
+
+ /* init pointers */
+
+ if (setexit() == 0) {
+ const Char *v = xv;
+ char *c = colors;
+
+ int fg, bg;
+ for (i = 0; i < len; i++) {
+ fg = color(*v++);
+ if (fg == -1)
+ stderror(ERR_BADCOLORVAR, v[-1], '?');
+
+ bg = color(*v++);
+ if (bg == -1)
+ stderror(ERR_BADCOLORVAR, '?', v[-1]);
+ makecolor(&c, fg, bg, &variables[map[i]].color);
+ }
+
+ }
+ cleanup_pop_mark(omark);
+ resexit(osetexit);
+}
/* parseLS_COLORS():
* Parse the LS_COLORS environment variable
@@ -183,16 +331,11 @@ parseLS_COLORS(const Char *value)
(void) &e;
- /* init */
- xfree(extensions);
- for (i = 0; i < nvariables; i++)
- variables[i].color = variables[i].defaultcolor;
- colors = NULL;
- extensions = NULL;
- nextensions = 0;
- if (value == NULL)
+ if (value == NULL) {
+ init(0, 0);
return;
+ }
len = Strlen(value);
/* allocate memory */
@@ -200,14 +343,13 @@ parseLS_COLORS(const Char *value)
for (v = value; *v; v++)
if ((*v & CHAR) == ':')
i++;
- extensions = xmalloc(len + i * sizeof(Extension));
- colors = i * sizeof(Extension) + (char *)extensions;
- nextensions = 0;
+
+ init(len, i);
/* init pointers */
v = value;
c = colors;
- e = &extensions[0];
+ e = extensions;
/* Prevent from crashing if unknown parameters are given. */
@@ -216,43 +358,43 @@ parseLS_COLORS(const Char *value)
if (setexit() == 0) {
- /* parse */
- while (*v) {
- switch (*v & CHAR) {
- case ':':
- v++;
- continue;
-
- case '*': /* :*ext=color: */
- v++;
- if (getstring(&c, &v, &e->extension, '=') &&
- 0 < e->extension.len) {
+ /* parse */
+ while (*v) {
+ switch (*v & CHAR) {
+ case ':':
v++;
- getstring(&c, &v, &e->color, ':');
- e++;
continue;
- }
- break;
-
- default: /* :vl=color: */
- if (v[0] && v[1] && (v[2] & CHAR) == '=') {
- for (i = 0; i < nvariables; i++)
- if ((Char)variables[i].variable[0] == (v[0] & CHAR) &&
- (Char)variables[i].variable[1] == (v[1] & CHAR))
- break;
- if (i < nvariables) {
- v += 3;
- getstring(&c, &v, &variables[i].color, ':');
+
+ case '*': /* :*ext=color: */
+ v++;
+ if (getstring(&c, &v, &e->extension, '=') &&
+ 0 < e->extension.len) {
+ v++;
+ getstring(&c, &v, &e->color, ':');
+ e++;
continue;
}
- else
- stderror(ERR_BADCOLORVAR, v[0], v[1]);
+ break;
+
+ default: /* :vl=color: */
+ if (v[0] && v[1] && (v[2] & CHAR) == '=') {
+ for (i = 0; i < nvariables; i++)
+ if ((Char)variables[i].variable[0] == (v[0] & CHAR) &&
+ (Char)variables[i].variable[1] == (v[1] & CHAR))
+ break;
+ if (i < nvariables) {
+ v += 3;
+ getstring(&c, &v, &variables[i].color, ':');
+ continue;
+ }
+ else
+ stderror(ERR_BADCOLORVAR, v[0], v[1]);
+ }
+ break;
}
- break;
+ while (*v && (*v & CHAR) != ':')
+ v++;
}
- while (*v && (*v & CHAR) != ':')
- v++;
- }
}
cleanup_pop_mark(omark);
@@ -264,15 +406,15 @@ parseLS_COLORS(const Char *value)
/* put_color():
*/
static void
-put_color(const Str *color)
+put_color(const Str *colorp)
{
size_t i;
- const char *c = color->s;
+ const char *c = colorp->s;
int original_output_raw = output_raw;
output_raw = TRUE;
cleanup_push(&original_output_raw, output_raw_restore);
- for (i = color->len; 0 < i; i--)
+ for (i = colorp->len; 0 < i; i--)
xputchar(*c++);
cleanup_until(&original_output_raw);
}
@@ -286,12 +428,12 @@ print_color(const Char *fname, size_t len, Char suffix)
size_t i;
char *filename = short2str(fname);
char *last = filename + len;
- Str *color = &variables[VFile].color;
+ Str *colorp = &variables[VFile].color;
switch (suffix) {
case '>': /* File is a symbolic link pointing to
* a directory */
- color = &variables[VDir].color;
+ colorp = &variables[VDir].color;
break;
case '+': /* File is a hidden directory [aix] or
* context dependent [hpux] */
@@ -301,7 +443,7 @@ print_color(const Char *fname, size_t len, Char suffix)
for (i = 0; i < nvariables; i++)
if (variables[i].suffix != NOS &&
(Char)variables[i].suffix == suffix) {
- color = &variables[i].color;
+ colorp = &variables[i].color;
break;
}
if (i == nvariables) {
@@ -310,7 +452,7 @@ print_color(const Char *fname, size_t len, Char suffix)
&& strncmp(last - extensions[i].extension.len,
extensions[i].extension.s,
extensions[i].extension.len) == 0) {
- color = &extensions[i].color;
+ colorp = &extensions[i].color;
break;
}
}
@@ -318,7 +460,7 @@ print_color(const Char *fname, size_t len, Char suffix)
}
put_color(&variables[VLeft].color);
- put_color(color);
+ put_color(colorp);
put_color(&variables[VRight].color);
}