source: trunk/third/tcsh/tw.color.c @ 12039

Revision 12039, 8.8 KB checked in by danw, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r12038, which included commits to RCS files with non-trunk default branches.
Line 
1/* $Header: /afs/dev.mit.edu/source/repository/third/tcsh/tw.color.c,v 1.1.1.1 1998-10-03 21:10:20 danw Exp $ */
2/*
3 * tw.color.c: builtin color ls-F
4 */
5/*-
6 * Copyright (c) 1998 The Regents of the University of California.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 *    must display the following acknowledgement:
19 *      This product includes software developed by the University of
20 *      California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 *    may be used to endorse or promote products derived from this software
23 *    without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 */
37#include "sh.h"
38
39RCSID("$Id: tw.color.c,v 1.1.1.1 1998-10-03 21:10:20 danw Exp $")
40
41#include "tw.h"
42#include "ed.h"
43#include "tc.h"
44
45#ifdef COLOR_LS_F
46
47typedef struct {
48    char   *s;
49    int     len;
50} Str;
51
52
53#define VAR(suffix,variable,defaultcolor) \
54{ \
55    suffix, variable, { defaultcolor, sizeof(defaultcolor) - 1 }, \
56      { defaultcolor, sizeof(defaultcolor) - 1 } \
57}
58#define NOS '\0' /* no suffix */
59
60typedef struct {
61    const char suffix;
62    const char *variable;
63    Str     color;
64    Str     defaultcolor;
65} Variable;
66
67static Variable variables[] = {
68    VAR('/', "di", "01;34"),    /* Directory */
69    VAR('@', "ln", "01;36"),    /* Symbolic link */
70    VAR('&', "or", ""),         /* Orphanned symbolic link (defaults to ln) */
71    VAR('|', "pi", "33"),       /* Named pipe (FIFO) */
72    VAR('=', "so", "01;35"),    /* Socket */
73    VAR('#', "bd", "01;33"),    /* Block device */
74    VAR('%', "cd", "01;33"),    /* Character device */
75    VAR('*', "ex", "01;32"),    /* Executable file */
76    VAR(NOS, "fi", "0"),        /* Regular file */
77    VAR(NOS, "no", "0"),        /* Normal (non-filename) text */
78    VAR(NOS, "mi", ""),         /* Missing file (defaults to fi) */
79#ifdef _OSD_POSIX
80    VAR(NOS, "lc", "\x27["),    /* Left code (EBCDIC)*/
81#else /* _OSD_POSIX */
82    VAR(NOS, "lc", "\033["),    /* Left code */
83#endif /* _OSD_POSIX */
84    VAR(NOS, "rc", "m"),        /* Right code */
85    VAR(NOS, "ec", ""),         /* End code (replaces lc+no+rc) */
86};
87
88enum FileType {
89    VDir, VSym, VOrph, VPipe, VSock, VBlock, VChr, VExe,
90    VFile, VNormal, VMiss, VLeft, VRight, VEnd
91};
92
93#define nvariables (sizeof(variables)/sizeof(variables[0]))
94
95typedef struct {
96    Str     extension;  /* file extension */
97    Str     color;      /* color string */
98} Extension;
99
100static Extension *extensions = NULL;
101static int nextensions = 0;
102
103static char *colors = NULL;
104bool         color_context_ls = FALSE;  /* do colored ls */
105static bool  color_context_lsmF = FALSE;        /* do colored ls-F */
106
107static bool getstring __P((char **, const Char **, Str *, int));
108static void put_color __P((Str *));
109static void print_color __P((Char *, size_t, int));
110
111/* set_color_context():
112 */
113void
114set_color_context()
115{
116    struct varent *vp = adrof(STRcolor);
117
118    if (!vp) {
119        color_context_ls = FALSE;
120        color_context_lsmF = FALSE;
121    }
122    else if (!vp->vec[0] || vp->vec[0][0] == '\0') {
123        color_context_ls = TRUE;
124        color_context_lsmF = TRUE;
125    }
126    else {
127        size_t i;
128
129        color_context_ls = FALSE;
130        color_context_lsmF = FALSE;
131        for (i = 0; vp->vec[i]; i++)
132            if (Strcmp(vp->vec[i], STRls) == 0)
133                color_context_ls = TRUE;
134            else if (Strcmp(vp->vec[i], STRlsmF) == 0)
135                color_context_lsmF = TRUE;
136    }
137}
138
139
140/* getstring():
141 */
142static  bool
143getstring(dp, sp, pd, f)
144    char        **dp;           /* dest buffer */
145    const Char  **sp;           /* source buffer */
146    Str          *pd;           /* pointer to dest buffer */
147    int           f;            /* final character */
148{
149    const Char *s = *sp;
150    char *d = *dp;
151    int sc;
152
153    while (*s && (*s & CHAR) != f && (*s & CHAR) != ':') {
154        if ((*s & CHAR) == '\\' || (*s & CHAR) == '^') {
155            if ((sc = parseescape(&s)) == -1)
156                return 0;
157            else
158                *d++ = (char) sc;
159        }
160        else
161            *d++ = *s++ & CHAR;
162    }
163
164    pd->s = *dp;
165    pd->len = d - *dp;
166    *sp = s;
167    *dp = d;
168    return *s == f;
169}
170
171
172/* parseLS_COLORS():
173 *      Parse the LS_COLORS environment variable
174 */
175void
176parseLS_COLORS(value)
177    Char   *value;              /* LS_COLOR variable's value */
178{
179    int     i;
180    size_t  len;
181    const Char   *v;            /* pointer in value */
182    char   *c;                  /* pointer in colors */
183    Extension *e;               /* pointer in extensions */
184
185    /* init */
186    if (extensions)
187        xfree((ptr_t) extensions);
188    for (i = 0; i < nvariables; i++)
189        variables[i].color = variables[i].defaultcolor;
190    colors = NULL;
191    extensions = NULL;
192    nextensions = 0;
193
194    if (value == NULL)
195        return;
196
197    len = Strlen(value);
198    /* allocate memory */
199    i = 1;
200    for (v = value; *v; v++)
201        if ((*v & CHAR) == ':')
202            i++;
203    extensions = (Extension *) xmalloc((size_t) (len + i * sizeof(Extension)));
204    colors = i * sizeof(Extension) + (char *)extensions;
205    nextensions = 0;
206
207    /* init pointers */
208    v = value;
209    c = colors;
210    e = &extensions[0];
211
212    /* parse */
213    while (*v) {
214        switch (*v & CHAR) {
215        case ':':
216            v++;
217            continue;
218
219        case '*':               /* :*ext=color: */
220            v++;
221            if (getstring(&c, &v, &e->extension, '=') &&
222                0 < e->extension.len) {
223                v++;
224                getstring(&c, &v, &e->color, ':');
225                e++;
226                continue;
227            }
228            break;
229
230        default:                /* :vl=color: */
231            if (v[0] && v[1] && (v[2] & CHAR) == '=') {
232                for (i = 0; i < nvariables; i++)
233                    if (variables[i].variable[0] == (v[0] & CHAR) &&
234                        variables[i].variable[1] == (v[1] & CHAR))
235                        break;
236                if (i < nvariables) {
237                    v += 3;
238                    getstring(&c, &v, &variables[i].color, ':');
239                    continue;
240                }
241                else
242                    stderror(ERR_BADCOLORVAR, v[0], v[1]);
243            }
244            break;
245        }
246        while (*v && (*v & CHAR) != ':')
247            v++;
248    }
249
250    nextensions = e - extensions;
251}
252
253
254/* put_color():
255 */
256static void
257put_color(color)
258    Str    *color;
259{
260    extern bool output_raw;     /* PWP: in sh.print.c */
261    size_t  i;
262    char   *c = color->s;
263    bool    original_output_raw = output_raw;
264
265    output_raw = TRUE;
266    for (i = color->len; 0 < i; i--)
267        xputchar(*c++);
268    output_raw = original_output_raw;
269}
270
271
272/* print_color():
273 */
274static void
275print_color(fname, len, suffix)
276    Char   *fname;
277    size_t  len;
278    int     suffix;
279{
280    int     i;
281    char   *filename = short2str(fname);
282    char   *last = filename + len;
283    Str    *color = &variables[VFile].color;
284
285    switch (suffix) {
286    case '>':                   /* File is a symbolic link pointing to
287                                 * a directory */
288        color = &variables[VDir].color;
289            break;
290    case '+':                   /* File is a hidden directory [aix] or
291                                 * context dependent [hpux] */
292    case ':':                   /* File is network special [hpux] */
293        break;
294    default:
295        for (i = 0; i < nvariables; i++)
296            if (variables[i].suffix != NOS &&
297                variables[i].suffix == suffix) {
298                color = &variables[i].color;
299                break;
300            }
301        if (i == nvariables) {
302            for (i = 0; i < nextensions; i++)
303                if (strncmp(last - extensions[i].extension.len,
304                            extensions[i].extension.s,
305                            extensions[i].extension.len) == 0) {
306                  color = &extensions[i].color;
307                break;
308            }
309        }
310        break;
311    }
312
313    put_color(&variables[VLeft].color);
314    put_color(color);
315    put_color(&variables[VRight].color);
316}
317
318
319/* print_with_color():
320 */
321void
322print_with_color(filename, len, suffix)
323    Char   *filename;
324    size_t  len;
325    int    suffix;
326{
327    if (color_context_lsmF &&
328        (haderr ? (didfds ? is2atty : isdiagatty) :
329         (didfds ? is1atty : isoutatty))) {
330        print_color(filename, len, suffix);
331        xprintf("%S", filename);
332        if (0 < variables[VEnd].color.len)
333            put_color(&variables[VEnd].color);
334        else {
335            put_color(&variables[VLeft].color);
336            put_color(&variables[VNormal].color);
337            put_color(&variables[VRight].color);
338        }
339        xputchar(suffix);
340    }
341    else
342        xprintf("%S%c", filename, suffix);
343}
344
345
346#endif /* COLOR_LS_F */
Note: See TracBrowser for help on using the repository browser.