File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / readline / colors.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 01:01:01 2021 UTC (3 years, 3 months ago) by misho
Branches: readline, MAIN
CVS tags: v8_2p0, v8_1p0, HEAD
readline 8.1

    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, 2015, 2017, 2019
    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: #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: 
   42: #include <stdio.h>
   43: 
   44: #include "posixstat.h" // stat related macros (S_ISREG, ...)
   45: #include <fcntl.h> // S_ISUID
   46: 
   47: #ifndef S_ISDIR
   48: #  define	S_ISDIR(m)	(((m) & S_IFMT) == S_IFDIR)
   49: #endif
   50: 
   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
   80: _rl_put_indicator (const struct bin_str *ind)
   81: {
   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: 
  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:   
  133: /* Returns whether any color sequence was printed. */
  134: bool
  135: _rl_print_color_indicator (const char *f)
  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;
  143:   struct stat astat, linkstat;
  144:   mode_t mode;
  145:   int linkok;	/* 1 == ok, 0 == dangling symlink, -1 == missing */
  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
  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:     }
  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;
  185:   else if (linkok == 0 && _rl_color_indicator[C_ORPHAN].string != NULL)
  186:     colored_filetype = C_ORPHAN;	/* dangling symlink */
  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: 
  198: #if defined (S_ISUID)
  199:           if ((mode & S_ISUID) != 0 && is_colored (C_SETUID))
  200:             colored_filetype = C_SETUID;
  201:           else
  202: #endif
  203: #if defined (S_ISGID)
  204:           if ((mode & S_ISGID) != 0 && is_colored (C_SETGID))
  205:             colored_filetype = C_SETGID;
  206:           else
  207: #endif
  208:           if (is_colored (C_CAP) && 0) //f->has_capability)
  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:         }
  232: #if defined (S_ISLNK)
  233:       else if (S_ISLNK (mode))
  234:         colored_filetype = C_LINK;
  235: #endif
  236:       else if (S_ISFIFO (mode))
  237:         colored_filetype = C_FIFO;
  238: #if defined (S_ISSOCK)
  239:       else if (S_ISSOCK (mode))
  240:         colored_filetype = C_SOCK;
  241: #endif
  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>