Annotation of embedaddon/readline/colors.c, revision 1.1.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>