Annotation of embedaddon/readline/colors.c, revision 1.1.1.2

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>