Import readline 8.0
[deliverable/binutils-gdb.git] / 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
cb41b9e7 5 Copyright (C) 1985, 1988, 1990-1991, 1995-2010, 2012, 2015, 2017
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
35#include <stdio.h>
36
37#include "posixstat.h" // stat related macros (S_ISREG, ...)
38#include <fcntl.h> // S_ISUID
39
cb41b9e7
TT
40#ifndef S_ISDIR
41# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
42#endif
43
775e241e
TT
44// strlen()
45#if defined (HAVE_STRING_H)
46# include <string.h>
47#else /* !HAVE_STRING_H */
48# include <strings.h>
49#endif /* !HAVE_STRING_H */
50
51// abort()
52#if defined (HAVE_STDLIB_H)
53# include <stdlib.h>
54#else
55# include "ansi_stdlib.h"
56#endif /* HAVE_STDLIB_H */
57
58#include "readline.h"
59#include "rldefs.h"
60
61#ifdef COLOR_SUPPORT
62
63#include "xmalloc.h"
64#include "colors.h"
65
66static bool is_colored (enum indicator_no type);
67static void restore_default_color (void);
68
69COLOR_EXT_TYPE *_rl_color_ext_list = 0;
70
71/* Output a color indicator (which may contain nulls). */
72void
cb41b9e7
TT
73_rl_put_indicator (const struct bin_str *ind)
74{
775e241e
TT
75 fwrite (ind->string, ind->len, 1, rl_outstream);
76}
77
78static bool
79is_colored (enum indicator_no colored_filetype)
80{
81 size_t len = _rl_color_indicator[colored_filetype].len;
82 char const *s = _rl_color_indicator[colored_filetype].string;
83 return ! (len == 0
84 || (len == 1 && strncmp (s, "0", 1) == 0)
85 || (len == 2 && strncmp (s, "00", 2) == 0));
86}
87
88static void
89restore_default_color (void)
90{
91 _rl_put_indicator (&_rl_color_indicator[C_LEFT]);
92 _rl_put_indicator (&_rl_color_indicator[C_RIGHT]);
93}
94
95void
96_rl_set_normal_color (void)
97{
98 if (is_colored (C_NORM))
99 {
100 _rl_put_indicator (&_rl_color_indicator[C_LEFT]);
101 _rl_put_indicator (&_rl_color_indicator[C_NORM]);
102 _rl_put_indicator (&_rl_color_indicator[C_RIGHT]);
103 }
104}
105
106bool
107_rl_print_prefix_color (void)
108{
109 struct bin_str *s;
110
111 /* What do we want to use for the prefix? Let's try cyan first, see colors.h */
112 s = &_rl_color_indicator[C_PREFIX];
113 if (s->string != NULL)
114 {
115 if (is_colored (C_NORM))
116 restore_default_color ();
117 _rl_put_indicator (&_rl_color_indicator[C_LEFT]);
118 _rl_put_indicator (s);
119 _rl_put_indicator (&_rl_color_indicator[C_RIGHT]);
120 return 0;
121 }
122 else
123 return 1;
124}
125
126/* Returns whether any color sequence was printed. */
127bool
128_rl_print_color_indicator (const char *f)
129{
130 enum indicator_no colored_filetype;
131 COLOR_EXT_TYPE *ext; /* Color extension */
132 size_t len; /* Length of name */
133
134 const char* name;
135 char *filename;
136 struct stat astat, linkstat;
137 mode_t mode;
138 int linkok; /* 1 == ok, 0 == dangling symlink, -1 == missing */
139 int stat_ok;
140
141 name = f;
142
143 /* This should already have undergone tilde expansion */
144 filename = 0;
145 if (rl_filename_stat_hook)
146 {
147 filename = savestring (f);
148 (*rl_filename_stat_hook) (&filename);
149 name = filename;
150 }
151
152#if defined (HAVE_LSTAT)
153 stat_ok = lstat(name, &astat);
154#else
155 stat_ok = stat(name, &astat);
156#endif
157 if (stat_ok == 0)
158 {
159 mode = astat.st_mode;
160#if defined (HAVE_LSTAT)
161 if (S_ISLNK (mode))
162 {
163 linkok = stat (name, &linkstat) == 0;
164 if (linkok && strncmp (_rl_color_indicator[C_LINK].string, "target", 6) == 0)
165 mode = linkstat.st_mode;
166 }
167 else
168#endif
169 linkok = 1;
170 }
171 else
172 linkok = -1;
173
174 /* Is this a nonexistent file? If so, linkok == -1. */
175
176 if (linkok == -1 && _rl_color_indicator[C_MISSING].string != NULL)
177 colored_filetype = C_MISSING;
178 else if (linkok == 0 && S_ISLNK(mode) && _rl_color_indicator[C_ORPHAN].string != NULL)
179 colored_filetype = C_ORPHAN; /* dangling symlink */
180 else if(stat_ok != 0)
181 {
182 static enum indicator_no filetype_indicator[] = FILETYPE_INDICATORS;
183 colored_filetype = filetype_indicator[normal]; //f->filetype];
184 }
185 else
186 {
187 if (S_ISREG (mode))
188 {
189 colored_filetype = C_FILE;
190
cb41b9e7 191#if defined (S_ISUID)
775e241e
TT
192 if ((mode & S_ISUID) != 0 && is_colored (C_SETUID))
193 colored_filetype = C_SETUID;
cb41b9e7
TT
194 else
195#endif
196#if defined (S_ISGID)
197 if ((mode & S_ISGID) != 0 && is_colored (C_SETGID))
775e241e 198 colored_filetype = C_SETGID;
cb41b9e7
TT
199 else
200#endif
201 if (is_colored (C_CAP) && 0) //f->has_capability)
775e241e
TT
202 colored_filetype = C_CAP;
203 else if ((mode & S_IXUGO) != 0 && is_colored (C_EXEC))
204 colored_filetype = C_EXEC;
205 else if ((1 < astat.st_nlink) && is_colored (C_MULTIHARDLINK))
206 colored_filetype = C_MULTIHARDLINK;
207 }
208 else if (S_ISDIR (mode))
209 {
210 colored_filetype = C_DIR;
211
212#if defined (S_ISVTX)
213 if ((mode & S_ISVTX) && (mode & S_IWOTH)
214 && is_colored (C_STICKY_OTHER_WRITABLE))
215 colored_filetype = C_STICKY_OTHER_WRITABLE;
216 else
217#endif
218 if ((mode & S_IWOTH) != 0 && is_colored (C_OTHER_WRITABLE))
219 colored_filetype = C_OTHER_WRITABLE;
220#if defined (S_ISVTX)
221 else if ((mode & S_ISVTX) != 0 && is_colored (C_STICKY))
222 colored_filetype = C_STICKY;
223#endif
224 }
cb41b9e7 225#if defined (S_ISLNK)
775e241e
TT
226 else if (S_ISLNK (mode))
227 colored_filetype = C_LINK;
cb41b9e7 228#endif
775e241e
TT
229 else if (S_ISFIFO (mode))
230 colored_filetype = C_FIFO;
cb41b9e7 231#if defined (S_ISSOCK)
775e241e
TT
232 else if (S_ISSOCK (mode))
233 colored_filetype = C_SOCK;
cb41b9e7 234#endif
775e241e
TT
235 else if (S_ISBLK (mode))
236 colored_filetype = C_BLK;
237 else if (S_ISCHR (mode))
238 colored_filetype = C_CHR;
239 else
240 {
241 /* Classify a file of some other type as C_ORPHAN. */
242 colored_filetype = C_ORPHAN;
243 }
244 }
245
246 /* Check the file's suffix only if still classified as C_FILE. */
247 ext = NULL;
248 if (colored_filetype == C_FILE)
249 {
250 /* Test if NAME has a recognized suffix. */
251 len = strlen (name);
252 name += len; /* Pointer to final \0. */
253 for (ext = _rl_color_ext_list; ext != NULL; ext = ext->next)
254 {
255 if (ext->ext.len <= len
256 && strncmp (name - ext->ext.len, ext->ext.string,
257 ext->ext.len) == 0)
258 break;
259 }
260 }
261
262 free (filename); /* NULL or savestring return value */
263
264 {
265 const struct bin_str *const s
266 = ext ? &(ext->seq) : &_rl_color_indicator[colored_filetype];
267 if (s->string != NULL)
268 {
269 /* Need to reset so not dealing with attribute combinations */
270 if (is_colored (C_NORM))
271 restore_default_color ();
272 _rl_put_indicator (&_rl_color_indicator[C_LEFT]);
273 _rl_put_indicator (s);
274 _rl_put_indicator (&_rl_color_indicator[C_RIGHT]);
275 return 0;
276 }
277 else
278 return 1;
279 }
280}
281
282void
283_rl_prep_non_filename_text (void)
284{
285 if (_rl_color_indicator[C_END].string != NULL)
286 _rl_put_indicator (&_rl_color_indicator[C_END]);
287 else
288 {
289 _rl_put_indicator (&_rl_color_indicator[C_LEFT]);
290 _rl_put_indicator (&_rl_color_indicator[C_RESET]);
291 _rl_put_indicator (&_rl_color_indicator[C_RIGHT]);
292 }
293}
294#endif /* COLOR_SUPPORT */
This page took 0.054419 seconds and 4 git commands to generate.