OpenCoverage

parse-colors.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/bash/src/lib/readline/parse-colors.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* `dir', `vdir' and `ls' directory listing programs for GNU.-
2-
3 Modified by Chet Ramey for Readline.-
4-
5 Copyright (C) 1985, 1988, 1990-1991, 1995-2010, 2012, 2017-
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 <stdio.h>-
34-
35// strdup() / strcpy()-
36#if defined (HAVE_STRING_H)-
37# include <string.h>-
38#else /* !HAVE_STRING_H */-
39# include <strings.h>-
40#endif /* !HAVE_STRING_H */-
41-
42// abort()-
43#if defined (HAVE_STDLIB_H)-
44# include <stdlib.h>-
45#else-
46# include "ansi_stdlib.h"-
47#endif /* HAVE_STDLIB_H */-
48-
49#include "rldefs.h" // STREQ, savestring-
50#include "readline.h"-
51#include "rlprivate.h"-
52#include "rlshell.h"-
53#include "xmalloc.h"-
54-
55#include "colors.h"-
56#include "parse-colors.h"-
57-
58#if defined (COLOR_SUPPORT)-
59-
60static bool get_funky_string (char **dest, const char **src, bool equals_end, size_t *output_count);-
61-
62struct bin_str _rl_color_indicator[] =-
63 {-
64 { LEN_STR_PAIR ("\033[") }, // lc: Left of color sequence-
65 { LEN_STR_PAIR ("m") }, // rc: Right of color sequence-
66 { 0, NULL }, // ec: End color (replaces lc+no+rc)-
67 { LEN_STR_PAIR ("0") }, // rs: Reset to ordinary colors-
68 { 0, NULL }, // no: Normal-
69 { 0, NULL }, // fi: File: default-
70 { LEN_STR_PAIR ("01;34") }, // di: Directory: bright blue-
71 { LEN_STR_PAIR ("01;36") }, // ln: Symlink: bright cyan-
72 { LEN_STR_PAIR ("33") }, // pi: Pipe: yellow/brown-
73 { LEN_STR_PAIR ("01;35") }, // so: Socket: bright magenta-
74 { LEN_STR_PAIR ("01;33") }, // bd: Block device: bright yellow-
75 { LEN_STR_PAIR ("01;33") }, // cd: Char device: bright yellow-
76 { 0, NULL }, // mi: Missing file: undefined-
77 { 0, NULL }, // or: Orphaned symlink: undefined-
78 { LEN_STR_PAIR ("01;32") }, // ex: Executable: bright green-
79 { LEN_STR_PAIR ("01;35") }, // do: Door: bright magenta-
80 { LEN_STR_PAIR ("37;41") }, // su: setuid: white on red-
81 { LEN_STR_PAIR ("30;43") }, // sg: setgid: black on yellow-
82 { LEN_STR_PAIR ("37;44") }, // st: sticky: black on blue-
83 { LEN_STR_PAIR ("34;42") }, // ow: other-writable: blue on green-
84 { LEN_STR_PAIR ("30;42") }, // tw: ow w/ sticky: black on green-
85 { LEN_STR_PAIR ("30;41") }, // ca: black on red-
86 { 0, NULL }, // mh: disabled by default-
87 { LEN_STR_PAIR ("\033[K") }, // cl: clear to end of line-
88 };-
89-
90/* Parse a string as part of the LS_COLORS variable; this may involve-
91 decoding all kinds of escape characters. If equals_end is set an-
92 unescaped equal sign ends the string, otherwise only a : or \0-
93 does. Set *OUTPUT_COUNT to the number of bytes output. Return-
94 true if successful.-
95-
96 The resulting string is *not* null-terminated, but may contain-
97 embedded nulls.-
98-
99 Note that both dest and src are char **; on return they point to-
100 the first free byte after the array and the character that ended-
101 the input string, respectively. */-
102-
103static bool-
104get_funky_string (char **dest, const char **src, bool equals_end, size_t *output_count) {-
105 char num; /* For numerical codes */-
106 size_t count; /* Something to count with */-
107 enum {-
108 ST_GND, ST_BACKSLASH, ST_OCTAL, ST_HEX, ST_CARET, ST_END, ST_ERROR-
109 } state;-
110 const char *p;-
111 char *q;-
112-
113 p = *src; /* We don't want to double-indirect */-
114 q = *dest; /* the whole darn time. */-
115-
116 count = 0; /* No characters counted in yet. */-
117 num = 0;-
118-
119 state = ST_GND; /* Start in ground state. */-
120 while (state < ST_END)
state < ST_ENDDescription
TRUEnever evaluated
FALSEnever evaluated
0
121 {-
122 switch (state)-
123 {-
124 case ST_GND: /* Ground state (no escapes) */
never executed: case ST_GND:
0
125 switch (*p)-
126 {-
127 case ':':
never executed: case ':':
0
128 case '\0':
never executed: case '\0':
0
129 state = ST_END; /* End of string */-
130 break;
never executed: break;
0
131 case '\\':
never executed: case '\\':
0
132 state = ST_BACKSLASH; /* Backslash scape sequence */-
133 ++p;-
134 break;
never executed: break;
0
135 case '^':
never executed: case '^':
0
136 state = ST_CARET; /* Caret escape */-
137 ++p;-
138 break;
never executed: break;
0
139 case '=':
never executed: case '=':
0
140 if (equals_end)
equals_endDescription
TRUEnever evaluated
FALSEnever evaluated
0
141 {-
142 state = ST_END; /* End */-
143 break;
never executed: break;
0
144 }-
145 /* else fall through */-
146 default:
code before this statement never executed: default:
never executed: default:
0
147 *(q++) = *(p++);-
148 ++count;-
149 break;
never executed: break;
0
150 }-
151 break;
never executed: break;
0
152-
153 case ST_BACKSLASH: /* Backslash escaped character */
never executed: case ST_BACKSLASH:
0
154 switch (*p)-
155 {-
156 case '0':
never executed: case '0':
0
157 case '1':
never executed: case '1':
0
158 case '2':
never executed: case '2':
0
159 case '3':
never executed: case '3':
0
160 case '4':
never executed: case '4':
0
161 case '5':
never executed: case '5':
0
162 case '6':
never executed: case '6':
0
163 case '7':
never executed: case '7':
0
164 state = ST_OCTAL; /* Octal sequence */-
165 num = *p - '0';-
166 break;
never executed: break;
0
167 case 'x':
never executed: case 'x':
0
168 case 'X':
never executed: case 'X':
0
169 state = ST_HEX; /* Hex sequence */-
170 num = 0;-
171 break;
never executed: break;
0
172 case 'a': /* Bell */
never executed: case 'a':
0
173 num = '\a';-
174 break;
never executed: break;
0
175 case 'b': /* Backspace */
never executed: case 'b':
0
176 num = '\b';-
177 break;
never executed: break;
0
178 case 'e': /* Escape */
never executed: case 'e':
0
179 num = 27;-
180 break;
never executed: break;
0
181 case 'f': /* Form feed */
never executed: case 'f':
0
182 num = '\f';-
183 break;
never executed: break;
0
184 case 'n': /* Newline */
never executed: case 'n':
0
185 num = '\n';-
186 break;
never executed: break;
0
187 case 'r': /* Carriage return */
never executed: case 'r':
0
188 num = '\r';-
189 break;
never executed: break;
0
190 case 't': /* Tab */
never executed: case 't':
0
191 num = '\t';-
192 break;
never executed: break;
0
193 case 'v': /* Vtab */
never executed: case 'v':
0
194 num = '\v';-
195 break;
never executed: break;
0
196 case '?': /* Delete */
never executed: case '?':
0
197 num = 127;-
198 break;
never executed: break;
0
199 case '_': /* Space */
never executed: case '_':
0
200 num = ' ';-
201 break;
never executed: break;
0
202 case '\0': /* End of string */
never executed: case '\0':
0
203 state = ST_ERROR; /* Error! */-
204 break;
never executed: break;
0
205 default: /* Escaped character like \ ^ : = */
never executed: default:
0
206 num = *p;-
207 break;
never executed: break;
0
208 }-
209 if (state == ST_BACKSLASH)
state == ST_BACKSLASHDescription
TRUEnever evaluated
FALSEnever evaluated
0
210 {-
211 *(q++) = num;-
212 ++count;-
213 state = ST_GND;-
214 }
never executed: end of block
0
215 ++p;-
216 break;
never executed: break;
0
217-
218 case ST_OCTAL: /* Octal sequence */
never executed: case ST_OCTAL:
0
219 if (*p < '0' || *p > '7')
*p < '0'Description
TRUEnever evaluated
FALSEnever evaluated
*p > '7'Description
TRUEnever evaluated
FALSEnever evaluated
0
220 {-
221 *(q++) = num;-
222 ++count;-
223 state = ST_GND;-
224 }
never executed: end of block
0
225 else-
226 num = (num << 3) + (*(p++) - '0');
never executed: num = (num << 3) + (*(p++) - '0');
0
227 break;
never executed: break;
0
228-
229 case ST_HEX: /* Hex sequence */
never executed: case ST_HEX:
0
230 switch (*p)-
231 {-
232 case '0':
never executed: case '0':
0
233 case '1':
never executed: case '1':
0
234 case '2':
never executed: case '2':
0
235 case '3':
never executed: case '3':
0
236 case '4':
never executed: case '4':
0
237 case '5':
never executed: case '5':
0
238 case '6':
never executed: case '6':
0
239 case '7':
never executed: case '7':
0
240 case '8':
never executed: case '8':
0
241 case '9':
never executed: case '9':
0
242 num = (num << 4) + (*(p++) - '0');-
243 break;
never executed: break;
0
244 case 'a':
never executed: case 'a':
0
245 case 'b':
never executed: case 'b':
0
246 case 'c':
never executed: case 'c':
0
247 case 'd':
never executed: case 'd':
0
248 case 'e':
never executed: case 'e':
0
249 case 'f':
never executed: case 'f':
0
250 num = (num << 4) + (*(p++) - 'a') + 10;-
251 break;
never executed: break;
0
252 case 'A':
never executed: case 'A':
0
253 case 'B':
never executed: case 'B':
0
254 case 'C':
never executed: case 'C':
0
255 case 'D':
never executed: case 'D':
0
256 case 'E':
never executed: case 'E':
0
257 case 'F':
never executed: case 'F':
0
258 num = (num << 4) + (*(p++) - 'A') + 10;-
259 break;
never executed: break;
0
260 default:
never executed: default:
0
261 *(q++) = num;-
262 ++count;-
263 state = ST_GND;-
264 break;
never executed: break;
0
265 }-
266 break;
never executed: break;
0
267-
268 case ST_CARET: /* Caret escape */
never executed: case ST_CARET:
0
269 state = ST_GND; /* Should be the next state... */-
270 if (*p >= '@' && *p <= '~')
*p >= '@'Description
TRUEnever evaluated
FALSEnever evaluated
*p <= '~'Description
TRUEnever evaluated
FALSEnever evaluated
0
271 {-
272 *(q++) = *(p++) & 037;-
273 ++count;-
274 }
never executed: end of block
0
275 else if (*p == '?')
*p == '?'Description
TRUEnever evaluated
FALSEnever evaluated
0
276 {-
277 *(q++) = 127;-
278 ++count;-
279 }
never executed: end of block
0
280 else-
281 state = ST_ERROR;
never executed: state = ST_ERROR;
0
282 break;
never executed: break;
0
283-
284 default:
never executed: default:
0
285 /* should we ? */-
286 /* abort (); no, we should not */-
287 state = ST_ERROR;-
288 break;
never executed: break;
0
289 }-
290 }-
291-
292 *dest = q;-
293 *src = p;-
294 *output_count = count;-
295-
296 return state != ST_ERROR;
never executed: return state != ST_ERROR;
0
297}-
298#endif /* COLOR_SUPPORT */-
299-
300void _rl_parse_colors(void)-
301{-
302#if defined (COLOR_SUPPORT)-
303 const char *p; /* Pointer to character being parsed */-
304 char *buf; /* color_buf buffer pointer */-
305 int state; /* State of parser */-
306 int ind_no; /* Indicator number */-
307 char label[3]; /* Indicator label */-
308 COLOR_EXT_TYPE *ext; /* Extension we are working on */-
309-
310 p = sh_get_env_value ("LS_COLORS");-
311 if (p == 0 || *p == '\0')
p == 0Description
TRUEnever evaluated
FALSEnever evaluated
*p == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
312 {-
313 _rl_color_ext_list = NULL;-
314 return;
never executed: return;
0
315 }-
316-
317 ext = NULL;-
318 strcpy (label, "??");-
319-
320 /* This is an overly conservative estimate, but any possible-
321 LS_COLORS string will *not* generate a color_buf longer than-
322 itself, so it is a safe way of allocating a buffer in-
323 advance. */-
324 buf = color_buf = savestring (p);-
325-
326 state = 1;-
327 while (state > 0)
state > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
328 {-
329 switch (state)-
330 {-
331 case 1: /* First label character */
never executed: case 1:
0
332 switch (*p)-
333 {-
334 case ':':
never executed: case ':':
0
335 ++p;-
336 break;
never executed: break;
0
337-
338 case '*':
never executed: case '*':
0
339 /* Allocate new extension block and add to head of-
340 linked list (this way a later definition will-
341 override an earlier one, which can be useful for-
342 having terminal-specific defs override global). */-
343-
344 ext = (COLOR_EXT_TYPE *)xmalloc (sizeof *ext);-
345 ext->next = _rl_color_ext_list;-
346 _rl_color_ext_list = ext;-
347-
348 ++p;-
349 ext->ext.string = buf;-
350-
351 state = (get_funky_string (&buf, &p, true, &ext->ext.len)
get_funky_stri...&ext->ext.len)Description
TRUEnever evaluated
FALSEnever evaluated
0
352 ? 4 : -1);-
353 break;
never executed: break;
0
354-
355 case '\0':
never executed: case '\0':
0
356 state = 0; /* Done! */-
357 break;
never executed: break;
0
358-
359 default: /* Assume it is file type label */
never executed: default:
0
360 label[0] = *(p++);-
361 state = 2;-
362 break;
never executed: break;
0
363 }-
364 break;
never executed: break;
0
365-
366 case 2: /* Second label character */
never executed: case 2:
0
367 if (*p)
*pDescription
TRUEnever evaluated
FALSEnever evaluated
0
368 {-
369 label[1] = *(p++);-
370 state = 3;-
371 }
never executed: end of block
0
372 else-
373 state = -1; /* Error */
never executed: state = -1;
0
374 break;
never executed: break;
0
375-
376 case 3: /* Equal sign after indicator label */
never executed: case 3:
0
377 state = -1; /* Assume failure... */-
378 if (*(p++) == '=')/* It *should* be... */
*(p++) == '='Description
TRUEnever evaluated
FALSEnever evaluated
0
379 {-
380 for (ind_no = 0; indicator_name[ind_no] != NULL; ++ind_no)
indicator_name...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
381 {-
382 if (STREQ (label, indicator_name[ind_no]))
never executed: __result = (((const unsigned char *) (const char *) ( (label) ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( (indicator_name[ind_no]) ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
((label)[0] ==...e[ind_no])[0])Description
TRUEnever evaluated
FALSEnever evaluated
( __extension_...)))); }) == 0)Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
383 {-
384 _rl_color_indicator[ind_no].string = buf;-
385 state = (get_funky_string (&buf, &p, false,
get_funky_stri...r[ind_no].len)Description
TRUEnever evaluated
FALSEnever evaluated
0
386 &_rl_color_indicator[ind_no].len)
get_funky_stri...r[ind_no].len)Description
TRUEnever evaluated
FALSEnever evaluated
0
387 ? 1 : -1);-
388 break;
never executed: break;
0
389 }-
390 }
never executed: end of block
0
391 if (state == -1)
state == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
392 {-
393 _rl_errmsg ("LS_COLORS: unrecognized prefix: %s", label);-
394 /* recover from an unrecognized prefix */-
395 while (p && *p && *p != ':')
pDescription
TRUEnever evaluated
FALSEnever evaluated
*pDescription
TRUEnever evaluated
FALSEnever evaluated
*p != ':'Description
TRUEnever evaluated
FALSEnever evaluated
0
396 p++;
never executed: p++;
0
397 if (p && *p == ':')
pDescription
TRUEnever evaluated
FALSEnever evaluated
*p == ':'Description
TRUEnever evaluated
FALSEnever evaluated
0
398 state = 1;
never executed: state = 1;
0
399 else if (p && *p == 0)
pDescription
TRUEnever evaluated
FALSEnever evaluated
*p == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
400 state = 0;
never executed: state = 0;
0
401 }
never executed: end of block
0
402 }
never executed: end of block
0
403 break;
never executed: break;
0
404-
405 case 4: /* Equal sign after *.ext */
never executed: case 4:
0
406 if (*(p++) == '=')
*(p++) == '='Description
TRUEnever evaluated
FALSEnever evaluated
0
407 {-
408 ext->seq.string = buf;-
409 state = (get_funky_string (&buf, &p, false, &ext->seq.len)
get_funky_stri...&ext->seq.len)Description
TRUEnever evaluated
FALSEnever evaluated
0
410 ? 1 : -1);-
411 }
never executed: end of block
0
412 else-
413 state = -1;
never executed: state = -1;
0
414 /* XXX - recover here as with an unrecognized prefix? */-
415 if (state == -1 && ext->ext.string)
state == -1Description
TRUEnever evaluated
FALSEnever evaluated
ext->ext.stringDescription
TRUEnever evaluated
FALSEnever evaluated
0
416 _rl_errmsg ("LS_COLORS: syntax error: %s", ext->ext.string);
never executed: _rl_errmsg ("LS_COLORS: syntax error: %s", ext->ext.string);
0
417 break;
never executed: break;
0
418 }-
419 }
never executed: end of block
0
420-
421 if (state < 0)
state < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
422 {-
423 COLOR_EXT_TYPE *e;-
424 COLOR_EXT_TYPE *e2;-
425-
426 _rl_errmsg ("unparsable value for LS_COLORS environment variable");-
427 free (color_buf);-
428 for (e = _rl_color_ext_list; e != NULL; /* empty */)
e != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
429 {-
430 e2 = e;-
431 e = e->next;-
432 free (e2);-
433 }
never executed: end of block
0
434 _rl_color_ext_list = NULL;-
435 _rl_colored_stats = 0; /* can't have colored stats without colors */-
436 }
never executed: end of block
0
437#else /* !COLOR_SUPPORT */-
438 ;-
439#endif /* !COLOR_SUPPORT */-
440}
never executed: end of block
0
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.1.2