Annotation of embedaddon/readline/colors.c, revision 1.1
1.1 ! misho 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 Free Software Foundation,
! 6: 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:
! 40: // strlen()
! 41: #if defined (HAVE_STRING_H)
! 42: # include <string.h>
! 43: #else /* !HAVE_STRING_H */
! 44: # include <strings.h>
! 45: #endif /* !HAVE_STRING_H */
! 46:
! 47: // abort()
! 48: #if defined (HAVE_STDLIB_H)
! 49: # include <stdlib.h>
! 50: #else
! 51: # include "ansi_stdlib.h"
! 52: #endif /* HAVE_STDLIB_H */
! 53:
! 54: #include "readline.h"
! 55: #include "rldefs.h"
! 56:
! 57: #ifdef COLOR_SUPPORT
! 58:
! 59: #include "xmalloc.h"
! 60: #include "colors.h"
! 61:
! 62: static bool is_colored (enum indicator_no type);
! 63: static void restore_default_color (void);
! 64:
! 65: COLOR_EXT_TYPE *_rl_color_ext_list = 0;
! 66:
! 67: /* Output a color indicator (which may contain nulls). */
! 68: void
! 69: _rl_put_indicator (const struct bin_str *ind) {
! 70: fwrite (ind->string, ind->len, 1, rl_outstream);
! 71: }
! 72:
! 73: static bool
! 74: is_colored (enum indicator_no colored_filetype)
! 75: {
! 76: size_t len = _rl_color_indicator[colored_filetype].len;
! 77: char const *s = _rl_color_indicator[colored_filetype].string;
! 78: return ! (len == 0
! 79: || (len == 1 && strncmp (s, "0", 1) == 0)
! 80: || (len == 2 && strncmp (s, "00", 2) == 0));
! 81: }
! 82:
! 83: static void
! 84: restore_default_color (void)
! 85: {
! 86: _rl_put_indicator (&_rl_color_indicator[C_LEFT]);
! 87: _rl_put_indicator (&_rl_color_indicator[C_RIGHT]);
! 88: }
! 89:
! 90: void
! 91: _rl_set_normal_color (void)
! 92: {
! 93: if (is_colored (C_NORM))
! 94: {
! 95: _rl_put_indicator (&_rl_color_indicator[C_LEFT]);
! 96: _rl_put_indicator (&_rl_color_indicator[C_NORM]);
! 97: _rl_put_indicator (&_rl_color_indicator[C_RIGHT]);
! 98: }
! 99: }
! 100:
! 101: /* Returns whether any color sequence was printed. */
! 102: bool
! 103: _rl_print_color_indicator (char *f)
! 104: {
! 105: enum indicator_no colored_filetype;
! 106: COLOR_EXT_TYPE *ext; /* Color extension */
! 107: size_t len; /* Length of name */
! 108:
! 109: const char* name;
! 110: char *filename;
! 111: struct stat astat;
! 112: mode_t mode;
! 113: int linkok;
! 114:
! 115: int stat_ok;
! 116:
! 117: name = f;
! 118:
! 119: /* This should already have undergone tilde expansion */
! 120: filename = 0;
! 121: if (rl_filename_stat_hook)
! 122: {
! 123: filename = savestring (f);
! 124: (*rl_filename_stat_hook) (&filename);
! 125: name = filename;
! 126: }
! 127:
! 128: #if defined (HAVE_LSTAT)
! 129: stat_ok = lstat(name, &astat);
! 130: #else
! 131: stat_ok = stat(name, &astat);
! 132: #endif
! 133: if( stat_ok == 0 ) {
! 134: mode = astat.st_mode;
! 135: linkok = 1; //f->linkok;
! 136: }
! 137: else
! 138: linkok = -1;
! 139:
! 140: /* Is this a nonexistent file? If so, linkok == -1. */
! 141:
! 142: if (linkok == -1 && _rl_color_indicator[C_MISSING].string != NULL)
! 143: colored_filetype = C_MISSING;
! 144: else if(stat_ok != 0)
! 145: {
! 146: static enum indicator_no filetype_indicator[] = FILETYPE_INDICATORS;
! 147: colored_filetype = filetype_indicator[normal]; //f->filetype];
! 148: }
! 149: else
! 150: {
! 151: if (S_ISREG (mode))
! 152: {
! 153: colored_filetype = C_FILE;
! 154:
! 155: if ((mode & S_ISUID) != 0 && is_colored (C_SETUID))
! 156: colored_filetype = C_SETUID;
! 157: else if ((mode & S_ISGID) != 0 && is_colored (C_SETGID))
! 158: colored_filetype = C_SETGID;
! 159: else if (is_colored (C_CAP) && 0) //f->has_capability)
! 160: colored_filetype = C_CAP;
! 161: else if ((mode & S_IXUGO) != 0 && is_colored (C_EXEC))
! 162: colored_filetype = C_EXEC;
! 163: else if ((1 < astat.st_nlink) && is_colored (C_MULTIHARDLINK))
! 164: colored_filetype = C_MULTIHARDLINK;
! 165: }
! 166: else if (S_ISDIR (mode))
! 167: {
! 168: colored_filetype = C_DIR;
! 169:
! 170: #if defined (S_ISVTX)
! 171: if ((mode & S_ISVTX) && (mode & S_IWOTH)
! 172: && is_colored (C_STICKY_OTHER_WRITABLE))
! 173: colored_filetype = C_STICKY_OTHER_WRITABLE;
! 174: else
! 175: #endif
! 176: if ((mode & S_IWOTH) != 0 && is_colored (C_OTHER_WRITABLE))
! 177: colored_filetype = C_OTHER_WRITABLE;
! 178: #if defined (S_ISVTX)
! 179: else if ((mode & S_ISVTX) != 0 && is_colored (C_STICKY))
! 180: colored_filetype = C_STICKY;
! 181: #endif
! 182: }
! 183: else if (S_ISLNK (mode))
! 184: colored_filetype = ((linkok == 0
! 185: && (!strncmp (_rl_color_indicator[C_LINK].string, "target", 6)
! 186: || _rl_color_indicator[C_ORPHAN].string))
! 187: ? C_ORPHAN : C_LINK);
! 188: else if (S_ISFIFO (mode))
! 189: colored_filetype = C_FIFO;
! 190: else if (S_ISSOCK (mode))
! 191: colored_filetype = C_SOCK;
! 192: else if (S_ISBLK (mode))
! 193: colored_filetype = C_BLK;
! 194: else if (S_ISCHR (mode))
! 195: colored_filetype = C_CHR;
! 196: else
! 197: {
! 198: /* Classify a file of some other type as C_ORPHAN. */
! 199: colored_filetype = C_ORPHAN;
! 200: }
! 201: }
! 202:
! 203: /* Check the file's suffix only if still classified as C_FILE. */
! 204: ext = NULL;
! 205: if (colored_filetype == C_FILE)
! 206: {
! 207: /* Test if NAME has a recognized suffix. */
! 208: len = strlen (name);
! 209: name += len; /* Pointer to final \0. */
! 210: for (ext = _rl_color_ext_list; ext != NULL; ext = ext->next)
! 211: {
! 212: if (ext->ext.len <= len
! 213: && strncmp (name - ext->ext.len, ext->ext.string,
! 214: ext->ext.len) == 0)
! 215: break;
! 216: }
! 217: }
! 218:
! 219: free (filename); /* NULL or savestring return value */
! 220:
! 221: {
! 222: const struct bin_str *const s
! 223: = ext ? &(ext->seq) : &_rl_color_indicator[colored_filetype];
! 224: if (s->string != NULL)
! 225: {
! 226: /* Need to reset so not dealing with attribute combinations */
! 227: if (is_colored (C_NORM))
! 228: restore_default_color ();
! 229: _rl_put_indicator (&_rl_color_indicator[C_LEFT]);
! 230: _rl_put_indicator (s);
! 231: _rl_put_indicator (&_rl_color_indicator[C_RIGHT]);
! 232: return 0;
! 233: }
! 234: else
! 235: return 1;
! 236: }
! 237: }
! 238:
! 239: void
! 240: _rl_prep_non_filename_text (void)
! 241: {
! 242: if (_rl_color_indicator[C_END].string != NULL)
! 243: _rl_put_indicator (&_rl_color_indicator[C_END]);
! 244: else
! 245: {
! 246: _rl_put_indicator (&_rl_color_indicator[C_LEFT]);
! 247: _rl_put_indicator (&_rl_color_indicator[C_RESET]);
! 248: _rl_put_indicator (&_rl_color_indicator[C_RIGHT]);
! 249: }
! 250: }
! 251: #endif /* COLOR_SUPPORT */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>