Annotation of embedaddon/readline/colors.c, revision 1.1.1.2
1.1 misho 1: /* `dir', `vdir' and `ls' directory listing programs for GNU.
2:
3: Modified by Chet Ramey for Readline.
4:
1.1.1.2 ! misho 5: Copyright (C) 1985, 1988, 1990-1991, 1995-2010, 2012, 2015, 2017, 2019
! 6: Free Software Foundation, Inc.
1.1 misho 7:
8: This program is free software: you can redistribute it and/or modify
9: it under the terms of the GNU General Public License as published by
10: the Free Software Foundation, either version 3 of the License, or
11: (at your option) any later version.
12:
13: This program is distributed in the hope that it will be useful,
14: but WITHOUT ANY WARRANTY; without even the implied warranty of
15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16: GNU General Public License for more details.
17:
18: You should have received a copy of the GNU General Public License
19: along with this program. If not, see <http://www.gnu.org/licenses/>. */
20:
21: /* Written by Richard Stallman and David MacKenzie. */
22:
23: /* Color support by Peter Anvin <Peter.Anvin@linux.org> and Dennis
24: Flaherty <dennisf@denix.elk.miles.com> based on original patches by
25: Greg Lee <lee@uhunix.uhcc.hawaii.edu>. */
26:
27: #define READLINE_LIBRARY
28:
29: #if defined (HAVE_CONFIG_H)
30: # include <config.h>
31: #endif
32:
33: #include "rlconf.h"
34:
1.1.1.2 ! misho 35: #if defined __TANDEM
! 36: # define _XOPEN_SOURCE_EXTENDED 1
! 37: # define _TANDEM_SOURCE 1
! 38: # include <sys/types.h>
! 39: # include <sys/stat.h>
! 40: #endif
! 41:
1.1 misho 42: #include <stdio.h>
43:
44: #include "posixstat.h" // stat related macros (S_ISREG, ...)
45: #include <fcntl.h> // S_ISUID
46:
1.1.1.2 ! misho 47: #ifndef S_ISDIR
! 48: # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
! 49: #endif
! 50:
1.1 misho 51: // strlen()
52: #if defined (HAVE_STRING_H)
53: # include <string.h>
54: #else /* !HAVE_STRING_H */
55: # include <strings.h>
56: #endif /* !HAVE_STRING_H */
57:
58: // abort()
59: #if defined (HAVE_STDLIB_H)
60: # include <stdlib.h>
61: #else
62: # include "ansi_stdlib.h"
63: #endif /* HAVE_STDLIB_H */
64:
65: #include "readline.h"
66: #include "rldefs.h"
67:
68: #ifdef COLOR_SUPPORT
69:
70: #include "xmalloc.h"
71: #include "colors.h"
72:
73: static bool is_colored (enum indicator_no type);
74: static void restore_default_color (void);
75:
76: COLOR_EXT_TYPE *_rl_color_ext_list = 0;
77:
78: /* Output a color indicator (which may contain nulls). */
79: void
1.1.1.2 ! misho 80: _rl_put_indicator (const struct bin_str *ind)
! 81: {
1.1 misho 82: fwrite (ind->string, ind->len, 1, rl_outstream);
83: }
84:
85: static bool
86: is_colored (enum indicator_no colored_filetype)
87: {
88: size_t len = _rl_color_indicator[colored_filetype].len;
89: char const *s = _rl_color_indicator[colored_filetype].string;
90: return ! (len == 0
91: || (len == 1 && strncmp (s, "0", 1) == 0)
92: || (len == 2 && strncmp (s, "00", 2) == 0));
93: }
94:
95: static void
96: restore_default_color (void)
97: {
98: _rl_put_indicator (&_rl_color_indicator[C_LEFT]);
99: _rl_put_indicator (&_rl_color_indicator[C_RIGHT]);
100: }
101:
102: void
103: _rl_set_normal_color (void)
104: {
105: if (is_colored (C_NORM))
106: {
107: _rl_put_indicator (&_rl_color_indicator[C_LEFT]);
108: _rl_put_indicator (&_rl_color_indicator[C_NORM]);
109: _rl_put_indicator (&_rl_color_indicator[C_RIGHT]);
110: }
111: }
112:
1.1.1.2 ! misho 113: bool
! 114: _rl_print_prefix_color (void)
! 115: {
! 116: struct bin_str *s;
! 117:
! 118: /* What do we want to use for the prefix? Let's try cyan first, see colors.h */
! 119: s = &_rl_color_indicator[C_PREFIX];
! 120: if (s->string != NULL)
! 121: {
! 122: if (is_colored (C_NORM))
! 123: restore_default_color ();
! 124: _rl_put_indicator (&_rl_color_indicator[C_LEFT]);
! 125: _rl_put_indicator (s);
! 126: _rl_put_indicator (&_rl_color_indicator[C_RIGHT]);
! 127: return 0;
! 128: }
! 129: else
! 130: return 1;
! 131: }
! 132:
1.1 misho 133: /* Returns whether any color sequence was printed. */
134: bool
1.1.1.2 ! misho 135: _rl_print_color_indicator (const char *f)
1.1 misho 136: {
137: enum indicator_no colored_filetype;
138: COLOR_EXT_TYPE *ext; /* Color extension */
139: size_t len; /* Length of name */
140:
141: const char* name;
142: char *filename;
1.1.1.2 ! misho 143: struct stat astat, linkstat;
1.1 misho 144: mode_t mode;
1.1.1.2 ! misho 145: int linkok; /* 1 == ok, 0 == dangling symlink, -1 == missing */
1.1 misho 146: int stat_ok;
147:
148: name = f;
149:
150: /* This should already have undergone tilde expansion */
151: filename = 0;
152: if (rl_filename_stat_hook)
153: {
154: filename = savestring (f);
155: (*rl_filename_stat_hook) (&filename);
156: name = filename;
157: }
158:
159: #if defined (HAVE_LSTAT)
160: stat_ok = lstat(name, &astat);
161: #else
162: stat_ok = stat(name, &astat);
163: #endif
1.1.1.2 ! misho 164: if (stat_ok == 0)
! 165: {
! 166: mode = astat.st_mode;
! 167: #if defined (HAVE_LSTAT)
! 168: if (S_ISLNK (mode))
! 169: {
! 170: linkok = stat (name, &linkstat) == 0;
! 171: if (linkok && strncmp (_rl_color_indicator[C_LINK].string, "target", 6) == 0)
! 172: mode = linkstat.st_mode;
! 173: }
! 174: else
! 175: #endif
! 176: linkok = 1;
! 177: }
1.1 misho 178: else
179: linkok = -1;
180:
181: /* Is this a nonexistent file? If so, linkok == -1. */
182:
183: if (linkok == -1 && _rl_color_indicator[C_MISSING].string != NULL)
184: colored_filetype = C_MISSING;
1.1.1.2 ! misho 185: else if (linkok == 0 && _rl_color_indicator[C_ORPHAN].string != NULL)
! 186: colored_filetype = C_ORPHAN; /* dangling symlink */
1.1 misho 187: else if(stat_ok != 0)
188: {
189: static enum indicator_no filetype_indicator[] = FILETYPE_INDICATORS;
190: colored_filetype = filetype_indicator[normal]; //f->filetype];
191: }
192: else
193: {
194: if (S_ISREG (mode))
195: {
196: colored_filetype = C_FILE;
197:
1.1.1.2 ! misho 198: #if defined (S_ISUID)
1.1 misho 199: if ((mode & S_ISUID) != 0 && is_colored (C_SETUID))
200: colored_filetype = C_SETUID;
1.1.1.2 ! misho 201: else
! 202: #endif
! 203: #if defined (S_ISGID)
! 204: if ((mode & S_ISGID) != 0 && is_colored (C_SETGID))
1.1 misho 205: colored_filetype = C_SETGID;
1.1.1.2 ! misho 206: else
! 207: #endif
! 208: if (is_colored (C_CAP) && 0) //f->has_capability)
1.1 misho 209: colored_filetype = C_CAP;
210: else if ((mode & S_IXUGO) != 0 && is_colored (C_EXEC))
211: colored_filetype = C_EXEC;
212: else if ((1 < astat.st_nlink) && is_colored (C_MULTIHARDLINK))
213: colored_filetype = C_MULTIHARDLINK;
214: }
215: else if (S_ISDIR (mode))
216: {
217: colored_filetype = C_DIR;
218:
219: #if defined (S_ISVTX)
220: if ((mode & S_ISVTX) && (mode & S_IWOTH)
221: && is_colored (C_STICKY_OTHER_WRITABLE))
222: colored_filetype = C_STICKY_OTHER_WRITABLE;
223: else
224: #endif
225: if ((mode & S_IWOTH) != 0 && is_colored (C_OTHER_WRITABLE))
226: colored_filetype = C_OTHER_WRITABLE;
227: #if defined (S_ISVTX)
228: else if ((mode & S_ISVTX) != 0 && is_colored (C_STICKY))
229: colored_filetype = C_STICKY;
230: #endif
231: }
1.1.1.2 ! misho 232: #if defined (S_ISLNK)
1.1 misho 233: else if (S_ISLNK (mode))
1.1.1.2 ! misho 234: colored_filetype = C_LINK;
! 235: #endif
1.1 misho 236: else if (S_ISFIFO (mode))
237: colored_filetype = C_FIFO;
1.1.1.2 ! misho 238: #if defined (S_ISSOCK)
1.1 misho 239: else if (S_ISSOCK (mode))
240: colored_filetype = C_SOCK;
1.1.1.2 ! misho 241: #endif
1.1 misho 242: else if (S_ISBLK (mode))
243: colored_filetype = C_BLK;
244: else if (S_ISCHR (mode))
245: colored_filetype = C_CHR;
246: else
247: {
248: /* Classify a file of some other type as C_ORPHAN. */
249: colored_filetype = C_ORPHAN;
250: }
251: }
252:
253: /* Check the file's suffix only if still classified as C_FILE. */
254: ext = NULL;
255: if (colored_filetype == C_FILE)
256: {
257: /* Test if NAME has a recognized suffix. */
258: len = strlen (name);
259: name += len; /* Pointer to final \0. */
260: for (ext = _rl_color_ext_list; ext != NULL; ext = ext->next)
261: {
262: if (ext->ext.len <= len
263: && strncmp (name - ext->ext.len, ext->ext.string,
264: ext->ext.len) == 0)
265: break;
266: }
267: }
268:
269: free (filename); /* NULL or savestring return value */
270:
271: {
272: const struct bin_str *const s
273: = ext ? &(ext->seq) : &_rl_color_indicator[colored_filetype];
274: if (s->string != NULL)
275: {
276: /* Need to reset so not dealing with attribute combinations */
277: if (is_colored (C_NORM))
278: restore_default_color ();
279: _rl_put_indicator (&_rl_color_indicator[C_LEFT]);
280: _rl_put_indicator (s);
281: _rl_put_indicator (&_rl_color_indicator[C_RIGHT]);
282: return 0;
283: }
284: else
285: return 1;
286: }
287: }
288:
289: void
290: _rl_prep_non_filename_text (void)
291: {
292: if (_rl_color_indicator[C_END].string != NULL)
293: _rl_put_indicator (&_rl_color_indicator[C_END]);
294: else
295: {
296: _rl_put_indicator (&_rl_color_indicator[C_LEFT]);
297: _rl_put_indicator (&_rl_color_indicator[C_RESET]);
298: _rl_put_indicator (&_rl_color_indicator[C_RIGHT]);
299: }
300: }
301: #endif /* COLOR_SUPPORT */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>