/[grep]/grep/src/grep.c
ViewVC logotype

Diff of /grep/src/grep.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.118 by charles_levert, Fri Nov 11 12:17:52 2005 UTC revision 1.119 by charles_levert, Thu Nov 17 23:13:11 2005 UTC
# Line 51  Line 51 
51  #undef MAX  #undef MAX
52  #define MAX(A,B) ((A) > (B) ? (A) : (B))  #define MAX(A,B) ((A) > (B) ? (A) : (B))
53    
54  #define SEP_CHAR_MATCH   ':'  #define SEP_CHAR_SELECTED ':'
55  #define SEP_CHAR_CONTEXT '-'  #define SEP_CHAR_REJECTED '-'
56  #define SEP_STR_CHUNK    "--"  #define SEP_STR_GROUP    "--"
57    
58  struct stats  struct stats
59  {  {
# Line 76  static int suppress_errors; Line 76  static int suppress_errors;
76  /* If nonzero, use mmap if possible.  */  /* If nonzero, use mmap if possible.  */
77  static int mmap_option;  static int mmap_option;
78    
79  /* If nonzero, use grep_color marker.  */  /* If nonzero, use color markers.  */
80  static int color_option;  static int color_option;
81    
82  /* If nonzero, show only the part of a line matching the expression. */  /* If nonzero, show only the part of a line matching the expression. */
# Line 127  static int align_tabs; Line 127  static int align_tabs;
127           terminal with either a black (dark) or white (light) background.           terminal with either a black (dark) or white (light) background.
128           This only leaves red, magenta, green, and cyan (and their bold           This only leaves red, magenta, green, and cyan (and their bold
129           counterparts) and possibly bold blue.  */           counterparts) and possibly bold blue.  */
130  /* The color string used for matched text.  /* The color strings used for matched text.
131     The user can overwrite it using the deprecated     The user can overwrite them using the deprecated
132     environment variable GREP_COLOR or the new GREP_COLORS.  */     environment variable GREP_COLOR or the new GREP_COLORS.  */
133  static const char *grep_color = "01;31";        /* bold red */  static const char *selected_match_color = "01;31";      /* bold red */
134    static const char *context_match_color  = "01;31";      /* bold red */
135    
136  /* Other colors.  Defaults look damn good.  */  /* Other colors.  Defaults look damn good.  */
137  static const char *filename_color = "35";       /* magenta */  static const char *filename_color = "35";       /* magenta */
138  static const char *line_num_color = "32";       /* green */  static const char *line_num_color = "32";       /* green */
139  static const char *byte_num_color = "32";       /* green */  static const char *byte_num_color = "32";       /* green */
140  static const char *sep_color      = "36";       /* cyan */  static const char *sep_color      = "36";       /* cyan */
141  static const char *mlines_color   = "";         /* default color pair */  static const char *selected_line_color = "";    /* default color pair */
142  static const char *context_color  = "";         /* default color pair */  static const char *context_line_color  = "";    /* default color pair */
143    
144  /* Select Graphic Rendition (SGR, "\33[...m") strings.  */  /* Select Graphic Rendition (SGR, "\33[...m") strings.  */
145  /* Also Erase in Line (EL) to Right ("\33[K") by default.  */  /* Also Erase in Line (EL) to Right ("\33[K") by default.  */
# Line 219  struct color_cap Line 220  struct color_cap
220    };    };
221    
222  static const char *  static const char *
223    color_cap_mt_fct(void)
224    {
225      /* Our caller just set selected_match_color.  */
226      context_match_color = selected_match_color;
227    
228      return NULL;
229    }
230    
231    static const char *
232    color_cap_rv_fct(void)
233    {
234      /* By this point, it was 1 (or already -1).  */
235      color_option = -1;  /* That's still != 0.  */
236    
237      return NULL;
238    }
239    
240    static const char *
241  color_cap_ne_fct(void)  color_cap_ne_fct(void)
242  {  {
243    sgr_start = "\33[%sm";    sgr_start = "\33[%sm";
# Line 230  color_cap_ne_fct(void) Line 249  color_cap_ne_fct(void)
249  /* For GREP_COLORS.  */  /* For GREP_COLORS.  */
250  static struct color_cap color_dict[] =  static struct color_cap color_dict[] =
251    {    {
252      { "mt", &grep_color,        NULL },                 /* matched text */      { "mt", &selected_match_color, color_cap_mt_fct }, /* both ms/mc */
253      { "fn", &filename_color,    NULL },                 /* filename */      { "ms", &selected_match_color, NULL }, /* selected matched text */
254      { "ln", &line_num_color,    NULL },                 /* line number */      { "mc", &context_match_color,  NULL }, /* context matched text */
255      { "bn", &byte_num_color,    NULL },                 /* byte (sic) offset */      { "fn", &filename_color,       NULL }, /* filename */
256      { "se", &sep_color,         NULL },                 /* separator */      { "ln", &line_num_color,       NULL }, /* line number */
257      { "ml", &mlines_color,      NULL },                 /* matching lines */      { "bn", &byte_num_color,       NULL }, /* byte (sic) offset */
258      { "cx", &context_color,     NULL },                 /* context lines */      { "se", &sep_color,            NULL }, /* separator */
259      { "ne", NULL,               color_cap_ne_fct },     /* no EL on SGR_* */      { "sl", &selected_line_color,  NULL }, /* selected lines */
260      { NULL, NULL,               NULL }      { "cx", &context_line_color,   NULL }, /* context lines */
261        { "rv", NULL,                  color_cap_rv_fct }, /* -v reverses sl/cx */
262        { "ne", NULL,                  color_cap_ne_fct }, /* no EL on SGR_* */
263        { NULL, NULL,                  NULL }
264    };    };
265    
266  static struct exclude *excluded_patterns;  static struct exclude *excluded_patterns;
# Line 757  print_line_head (char const *beg, char c Line 779  print_line_head (char const *beg, char c
779  }  }
780    
781  static const char *  static const char *
782  print_line_middle (const char *beg, const char *lim)  print_line_middle (const char *beg, const char *lim,
783                       const char *line_color, const char *match_color)
784  {  {
785    size_t match_size;    size_t match_size;
786    size_t match_offset;    size_t match_offset;
# Line 803  print_line_middle (const char *beg, cons Line 826  print_line_middle (const char *beg, cons
826          }          }
827        else        else
828          {          {
829              /* This function is called on a matching line only,
830                 but is it selected or rejected/context?  */
831            if (only_matching)            if (only_matching)
832              print_line_head(b, lim, SEP_CHAR_MATCH);              print_line_head(b, lim, out_invert ? SEP_CHAR_REJECTED
833                                                   : SEP_CHAR_SELECTED);
834            else            else
835              {              {
836                PR_SGR_START(mlines_color);                PR_SGR_START(line_color);
837                if (mid)                if (mid)
838                  {                  {
839                    cur = mid;                    cur = mid;
# Line 816  print_line_middle (const char *beg, cons Line 842  print_line_middle (const char *beg, cons
842                fwrite (cur, sizeof (char), b - cur, stdout);                fwrite (cur, sizeof (char), b - cur, stdout);
843              }              }
844    
845            PR_SGR_START_IF(grep_color);            PR_SGR_START_IF(match_color);
846            fwrite (b, sizeof (char), match_size, stdout);            fwrite (b, sizeof (char), match_size, stdout);
847            PR_SGR_END_IF(grep_color);            PR_SGR_END_IF(match_color);
848            if (only_matching)            if (only_matching)
849              fputs("\n", stdout);              fputs("\n", stdout);
850          }          }
# Line 837  print_line_middle (const char *beg, cons Line 863  print_line_middle (const char *beg, cons
863  }  }
864    
865  static const char *  static const char *
866  print_line_tail (const char *beg, const char *lim, const char *color)  print_line_tail (const char *beg, const char *lim, const char *line_color)
867  {  {
868    size_t  eol_size;    size_t  eol_size;
869    size_t tail_size;    size_t tail_size;
# Line 848  print_line_tail (const char *beg, const Line 874  print_line_tail (const char *beg, const
874    
875    if (tail_size > 0)    if (tail_size > 0)
876      {      {
877        PR_SGR_START(color);        PR_SGR_START(line_color);
878        fwrite(beg, 1, tail_size, stdout);        fwrite(beg, 1, tail_size, stdout);
879        beg += tail_size;        beg += tail_size;
880        PR_SGR_END(color);        PR_SGR_END(line_color);
881      }      }
882    
883    return beg;    return beg;
# Line 860  print_line_tail (const char *beg, const Line 886  print_line_tail (const char *beg, const
886  static void  static void
887  prline (char const *beg, char const *lim, int sep)  prline (char const *beg, char const *lim, int sep)
888  {  {
889      int matching;
890    const char *line_color;    const char *line_color;
891      const char *match_color;
892    
893    if (!only_matching)    if (!only_matching)
894      print_line_head(beg, lim, sep);      print_line_head(beg, lim, sep);
895    
896      matching = (sep == SEP_CHAR_SELECTED) ^ !!out_invert;
897    
898    if (color_option)    if (color_option)
899      line_color = ((sep == SEP_CHAR_MATCH) ? mlines_color : context_color);      {
900          line_color  = (  (sep == SEP_CHAR_SELECTED)
901                         ^ (out_invert && (color_option < 0)))
902                      ? selected_line_color  : context_line_color;
903          match_color = (sep == SEP_CHAR_SELECTED)
904                      ? selected_match_color : context_match_color;
905        }
906      else
907        line_color = match_color = NULL; /* Shouldn't be used.  */
908    
909    if (only_matching || (color_option && (*grep_color || *line_color)))    if (   (only_matching && matching)
910          || (color_option  && (*line_color || *match_color)))
911      {      {
912        /* We already know that context lines have no match (to colorize).  */        /* We already know that non-matching lines have no match (to colorize).  */
913        if (only_matching || (*grep_color && sep == SEP_CHAR_MATCH))        if (matching && (only_matching || *match_color))
914          beg = print_line_middle(beg, lim);          beg = print_line_middle(beg, lim, line_color, match_color);
915    
916        if (!only_matching && *line_color);        if (!only_matching && *line_color);
917          beg = print_line_tail(beg, lim, line_color);          beg = print_line_tail(beg, lim, line_color);
# Line 906  prpending (char const *lim) Line 945  prpending (char const *lim)
945            || ((execute(lastout, nl + 1 - lastout,            || ((execute(lastout, nl + 1 - lastout,
946                         &match_size, NULL) == (size_t) -1)                         &match_size, NULL) == (size_t) -1)
947                == !out_invert))                == !out_invert))
948          prline (lastout, nl + 1, SEP_CHAR_CONTEXT);          prline (lastout, nl + 1, SEP_CHAR_REJECTED);
949        else        else
950          pending = 0;          pending = 0;
951      }      }
# Line 917  prpending (char const *lim) Line 956  prpending (char const *lim)
956  static void  static void
957  prtext (char const *beg, char const *lim, int *nlinesp)  prtext (char const *beg, char const *lim, int *nlinesp)
958  {  {
959    static int used;      /* avoid printing SEP_STR_CHUNK before any output */    static int used;      /* avoid printing SEP_STR_GROUP before any output */
960    char const *bp, *p;    char const *bp, *p;
961    char eol = eolbyte;    char eol = eolbyte;
962    int i, n;    int i, n;
# Line 938  prtext (char const *beg, char const *lim Line 977  prtext (char const *beg, char const *lim
977              --p;              --p;
978            while (p[-1] != eol);            while (p[-1] != eol);
979    
980        /* We print the SEP_STR_CHUNK separator only if our output is        /* We print the SEP_STR_GROUP separator only if our output is
981           discontiguous from the last output in the file. */           discontiguous from the last output in the file. */
982        if ((out_before || out_after) && used && p != lastout)        if ((out_before || out_after) && used && p != lastout)
983          {          {
984            PR_SGR_START_IF(sep_color);            PR_SGR_START_IF(sep_color);
985            fputs (SEP_STR_CHUNK, stdout);            fputs (SEP_STR_GROUP, stdout);
986            PR_SGR_END_IF(sep_color);            PR_SGR_END_IF(sep_color);
987            fputc('\n', stdout);            fputc('\n', stdout);
988          }          }
# Line 952  prtext (char const *beg, char const *lim Line 991  prtext (char const *beg, char const *lim
991          {          {
992            char const *nl = memchr (p, eol, beg - p);            char const *nl = memchr (p, eol, beg - p);
993            nl++;            nl++;
994            prline (p, nl, SEP_CHAR_CONTEXT);            prline (p, nl, SEP_CHAR_REJECTED);
995            p = nl;            p = nl;
996          }          }
997      }      }
# Line 965  prtext (char const *beg, char const *lim Line 1004  prtext (char const *beg, char const *lim
1004            char const *nl = memchr (p, eol, lim - p);            char const *nl = memchr (p, eol, lim - p);
1005            nl++;            nl++;
1006            if (!out_quiet)            if (!out_quiet)
1007              prline (p, nl, SEP_CHAR_MATCH);              prline (p, nl, SEP_CHAR_SELECTED);
1008            p = nl;            p = nl;
1009          }          }
1010        *nlinesp = n;        *nlinesp = n;
# Line 975  prtext (char const *beg, char const *lim Line 1014  prtext (char const *beg, char const *lim
1014      }      }
1015    else    else
1016      if (!out_quiet)      if (!out_quiet)
1017        prline (beg, lim, SEP_CHAR_MATCH);        prline (beg, lim, SEP_CHAR_SELECTED);
1018    
1019    pending = out_quiet ? 0 : out_after;    pending = out_quiet ? 0 : out_after;
1020    used = 1;    used = 1;
# Line 1256  grepfile (char const *file, struct stats Line 1295  grepfile (char const *file, struct stats
1295              {              {
1296                print_filename();                print_filename();
1297                if (filename_mask)                if (filename_mask)
1298                  print_sep(SEP_CHAR_MATCH);                  print_sep(SEP_CHAR_SELECTED);
1299                else                else
1300                  fputc(0, stdout);                  fputc(0, stdout);
1301              }              }
# Line 1620  get_nondigit_option (int argc, char *con Line 1659  get_nondigit_option (int argc, char *con
1659    return opt;    return opt;
1660  }  }
1661    
1662  /* Parse GREP_COLORS.  The  default would look like:  /* Parse GREP_COLORS.  The default would look like:
1663       GREP_COLORS='mt=01;31:ml=:cx=:fn=35:ln=32:bn=32:se=36'       GREP_COLORS='ms=01;31:mc=01;31:sl=:cx=:fn=35:ln=32:bn=32:se=36'
1664       with boolean capabilities (ne and rv) unset (i.e., omitted).
1665     No character escaping is needed or supported.  */     No character escaping is needed or supported.  */
1666  static void  static void
1667  parse_grep_colors (void)  parse_grep_colors (void)
# Line 2120  main (int argc, char **argv) Line 2160  main (int argc, char **argv)
2160        /* Legacy.  */        /* Legacy.  */
2161        char *userval = getenv ("GREP_COLOR");        char *userval = getenv ("GREP_COLOR");
2162        if (userval != NULL && *userval != '\0')        if (userval != NULL && *userval != '\0')
2163          grep_color = userval;          selected_match_color = context_match_color = userval;
2164    
2165        /* New GREP_COLORS has priority.  */        /* New GREP_COLORS has priority.  */
2166        parse_grep_colors();        parse_grep_colors();

Legend:
Removed from v.1.118  
changed lines
  Added in v.1.119

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26