Import GNU Readline 8.1
[deliverable/binutils-gdb.git] / readline / readline / colors.c
CommitLineData
775e241e
TT
1/* `dir', `vdir' and `ls' directory listing programs for GNU.
2
3 Modified by Chet Ramey for Readline.
4
b4f26d54 5 Copyright (C) 1985, 1988, 1990-1991, 1995-2010, 2012, 2015, 2017, 2019
775e241e
TT
6 Free Software Foundation, Inc.
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
b4f26d54
TT
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
775e241e
TT
42#include <stdio.h>
43
44#include "posixstat.h" // stat related macros (S_ISREG, ...)
45#include <fcntl.h> // S_ISUID
46
cb41b9e7
TT
47#ifndef S_ISDIR
48# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
49#endif
50
775e241e
TT
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
73static bool is_colored (enum indicator_no type);
74static void restore_default_color (void);
75
76COLOR_EXT_TYPE *_rl_color_ext_list = 0;
77
78/* Output a color indicator (which may contain nulls). */
79void
cb41b9e7
TT
80_rl_put_indicator (const struct bin_str *ind)
81{
775e241e
TT
82 fwrite (ind->string, ind->len, 1, rl_outstream);
83}
84
85static bool
86is_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
95static void
96restore_default_color (void)
97{
98 _rl_put_indicator (&_rl_color_indicator[C_LEFT]);
99 _rl_put_indicator (&_rl_color_indicator[C_RIGHT]);
100}
101
102void
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
113bool
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
133/* Returns whether any color sequence was printed. */
134bool
135_rl_print_color_indicator (const char *f)
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;
143 struct stat astat, linkstat;
144 mode_t mode;
145 int linkok; /* 1 == ok, 0 == dangling symlink, -1 == missing */
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
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 }
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;
01116842 185 else if (linkok == 0 && _rl_color_indicator[C_ORPHAN].string != NULL)
775e241e
TT
186 colored_filetype = C_ORPHAN; /* dangling symlink */
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
cb41b9e7 198#if defined (S_ISUID)
775e241e
TT
199 if ((mode & S_ISUID) != 0 && is_colored (C_SETUID))
200 colored_filetype = C_SETUID;
cb41b9e7
TT
201 else
202#endif
203#if defined (S_ISGID)
204 if ((mode & S_ISGID) != 0 && is_colored (C_SETGID))
775e241e 205 colored_filetype = C_SETGID;
cb41b9e7
TT
206 else
207#endif
208 if (is_colored (C_CAP) && 0) //f->has_capability)
775e241e
TT
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 }
cb41b9e7 232#if defined (S_ISLNK)
775e241e
TT
233 else if (S_ISLNK (mode))
234 colored_filetype = C_LINK;
cb41b9e7 235#endif
775e241e
TT
236 else if (S_ISFIFO (mode))
237 colored_filetype = C_FIFO;
cb41b9e7 238#if defined (S_ISSOCK)
775e241e
TT
239 else if (S_ISSOCK (mode))
240 colored_filetype = C_SOCK;
cb41b9e7 241#endif
775e241e
TT
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
289void
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 */
This page took 0.136376 seconds and 4 git commands to generate.