File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / readline / colors.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Wed Jul 30 08:16:45 2014 UTC (9 years, 11 months ago) by misho
CVS tags: MAIN, HEAD
Initial revision

    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>