Print this page
3737 grep does not support -H option
3759 egrep(1) and fgrep(1) -s flag does not hide -c output
Reviewed by: Albert Lee <trisk@nexenta.com>
Reviewed by: Andy Stormont <andyjstormont@gmail.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/grep_xpg4/grep.c
          +++ new/usr/src/cmd/grep_xpg4/grep.c
↓ open down ↓ 28 lines elided ↑ open up ↑
  29   29   *      Based on MKS grep command, with XCU & Solaris mods.
  30   30   */
  31   31  
  32   32  /*
  33   33   * Copyright 1985, 1992 by Mortice Kern Systems Inc.  All rights reserved.
  34   34   *
  35   35   */
  36   36  
  37   37  /* Copyright 2012 Nexenta Systems, Inc.  All rights reserved. */
  38   38  
       39 +/*
       40 + * Copyright 2013 Damian Bogel. All rights reserved.
       41 + */
       42 +
  39   43  #include <string.h>
  40   44  #include <stdlib.h>
  41   45  #include <ctype.h>
  42   46  #include <stdarg.h>
  43   47  #include <regex.h>
  44   48  #include <limits.h>
  45   49  #include <sys/types.h>
  46   50  #include <sys/stat.h>
  47   51  #include <fcntl.h>
  48   52  #include <stdio.h>
  49   53  #include <locale.h>
  50   54  #include <wchar.h>
  51   55  #include <errno.h>
  52   56  #include <unistd.h>
  53   57  #include <wctype.h>
  54   58  #include <ftw.h>
  55   59  #include <sys/param.h>
  56   60  
       61 +#define STDIN_FILENAME gettext("(standard input)")
       62 +
  57   63  #define BSIZE           512             /* Size of block for -b */
  58   64  #define BUFSIZE         8192            /* Input buffer size */
  59   65  #define MAX_DEPTH       1000            /* how deep to recurse */
  60   66  
  61   67  #define M_CSETSIZE      256             /* singlebyte chars */
  62   68  static int      bmglen;                 /* length of BMG pattern */
  63   69  static char     *bmgpat;                /* BMG pattern */
  64   70  static int      bmgtab[M_CSETSIZE];     /* BMG delta1 table */
  65   71  
  66   72  typedef struct  _PATTERN        {
↓ open down ↓ 6 lines elided ↑ open up ↑
  73   79  static PATTERN  *patterns;
  74   80  static char     errstr[128];            /* regerror string buffer */
  75   81  static int      regflags = 0;           /* regcomp options */
  76   82  static int      matched = 0;            /* return of the grep() */
  77   83  static int      errors = 0;             /* count of errors */
  78   84  static uchar_t  fgrep = 0;              /* Invoked as fgrep */
  79   85  static uchar_t  egrep = 0;              /* Invoked as egrep */
  80   86  static uchar_t  nvflag = 1;             /* Print matching lines */
  81   87  static uchar_t  cflag;                  /* Count of matches */
  82   88  static uchar_t  iflag;                  /* Case insensitve matching */
       89 +static uchar_t  Hflag;                  /* Precede lines by file name */
  83   90  static uchar_t  hflag;                  /* Supress printing of filename */
  84   91  static uchar_t  lflag;                  /* Print file names of matches */
  85   92  static uchar_t  nflag;                  /* Precede lines by line number */
  86   93  static uchar_t  rflag;                  /* Search directories recursively */
  87   94  static uchar_t  bflag;                  /* Preccede matches by block number */
  88   95  static uchar_t  sflag;                  /* Suppress file error messages */
  89   96  static uchar_t  qflag;                  /* Suppress standard output */
  90   97  static uchar_t  wflag;                  /* Search for expression as a word */
  91   98  static uchar_t  xflag;                  /* Anchoring */
  92   99  static uchar_t  Eflag;                  /* Egrep or -E flag */
↓ open down ↓ 55 lines elided ↑ open up ↑
 148  155           */
 149  156          if (*ap == 'e' || *ap == 'E') {
 150  157                  regflags |= REG_EXTENDED;
 151  158                  egrep++;
 152  159          } else {
 153  160                  if (*ap == 'f' || *ap == 'F') {
 154  161                          fgrep++;
 155  162                  }
 156  163          }
 157  164  
 158      -        while ((c = getopt(argc, argv, "vwchilnrbse:f:qxEFIR")) != EOF) {
      165 +        while ((c = getopt(argc, argv, "vwchHilnrbse:f:qxEFIR")) != EOF) {
 159  166                  switch (c) {
 160  167                  case 'v':       /* POSIX: negate matches */
 161  168                          nvflag = 0;
 162  169                          break;
 163  170  
 164  171                  case 'c':       /* POSIX: write count */
 165  172                          cflag++;
 166  173                          break;
 167  174  
 168  175                  case 'i':       /* POSIX: ignore case */
↓ open down ↓ 40 lines elided ↑ open up ↑
 209  216                          file_list = realloc(file_list,
 210  217                              sizeof (char *) * n_file);
 211  218                          if (file_list == NULL) {
 212  219                                  (void) fprintf(stderr,
 213  220                                      gettext("%s: out of memory\n"),
 214  221                                      cmdname);
 215  222                                  exit(2);
 216  223                          }
 217  224                          *(file_list + n_file - 1) = optarg;
 218  225                          break;
      226 +
      227 +                /* based on options order h or H is set as in GNU grep */
 219  228                  case 'h':       /* Solaris: supress printing of file name */
 220  229                          hflag = 1;
      230 +                        Hflag = 0;
 221  231                          break;
      232 +                /* Solaris: precede every matching with file name */
      233 +                case 'H':
      234 +                        Hflag = 1;
      235 +                        hflag = 0;
      236 +                        break;
 222  237  
 223  238                  case 'q':       /* POSIX: quiet: status only */
 224  239                          qflag++;
 225  240                          break;
 226  241  
 227  242                  case 'w':       /* Solaris: treat pattern as word */
 228  243                          wflag++;
 229  244                          break;
 230  245  
 231  246                  case 'x':       /* POSIX: full line matches */
↓ open down ↓ 55 lines elided ↑ open up ↑
 287  302                  usage();
 288  303          }
 289  304  
 290  305          /*
 291  306           * -E and -F flags are mutually exclusive - check for this
 292  307           */
 293  308          if (Eflag && Fflag)
 294  309                  usage();
 295  310  
 296  311          /*
      312 +         * -l overrides -H like in GNU grep
      313 +         */
      314 +        if (lflag)
      315 +                Hflag = 0;
      316 +
      317 +        /*
 297  318           * -c, -l and -q flags are mutually exclusive
 298  319           * We have -c override -l like in Solaris.
 299  320           * -q overrides -l & -c programmatically in grep() function.
 300  321           */
 301  322          if (cflag && lflag)
 302  323                  lflag = 0;
 303  324  
 304  325          argv += optind - 1;
 305  326          argc -= optind - 1;
 306  327  
↓ open down ↓ 32 lines elided ↑ open up ↑
 339  360           */
 340  361          use_wchar = Fflag && mblocale && (!xflag || iflag);
 341  362  
 342  363          /*
 343  364           * Compile Patterns and also decide if BMG can be used
 344  365           */
 345  366          fixpatterns();
 346  367  
 347  368          /* Process all files: stdin, or rest of arg list */
 348  369          if (argc < 2) {
 349      -                matched = grep(0, gettext("(standard input)"));
      370 +                matched = grep(0, STDIN_FILENAME);
 350  371          } else {
 351      -                if (argc > 2 && hflag == 0)
      372 +                if (Hflag || (argc > 2 && hflag == 0))
 352  373                          outfn = 1;      /* Print filename on match line */
 353  374                  for (argv++; *argv != NULL; argv++) {
 354  375                          process_path(*argv);
 355  376                  }
 356  377          }
 357  378          /*
 358  379           * Return() here is used instead of exit
 359  380           */
 360  381  
 361  382          (void) fflush(stdout);
↓ open down ↓ 743 lines elided ↑ open up ↑
1105 1126                                  off_t   pos;
1106 1127                                  pos = ptr + data_len - (ptrend + 1);
1107 1128                                  (void) lseek(fd, -pos, SEEK_CUR);
1108 1129                                  exit(0);
1109 1130                          }
1110 1131                          if (lflag) {
1111 1132                                  (void) printf("%s\n", fn);
1112 1133                                  break;
1113 1134                          }
1114 1135                          if (!cflag) {
1115      -                                if (outfn) {
     1136 +                                if (Hflag || outfn) {
1116 1137                                          (void) printf("%s:", fn);
1117 1138                                  }
1118 1139                                  if (bflag) {
1119 1140                                          (void) printf("%lld:", (offset_t)
1120 1141                                              (line_offset / BSIZE));
1121 1142                                  }
1122 1143                                  if (nflag) {
1123 1144                                          (void) printf("%lld:", lineno);
1124 1145                                  }
1125 1146                                  *ptrend = '\n';
↓ open down ↓ 6 lines elided ↑ open up ↑
1132 1153  L_skip_line:
1133 1154                  if (!newlinep)
1134 1155                          break;
1135 1156  
1136 1157                  data_len -= line_len + 1;
1137 1158                  line_offset += line_len + 1;
1138 1159                  ptr = ptrend + 1;
1139 1160          }
1140 1161  
1141 1162          if (cflag) {
1142      -                if (outfn) {
     1163 +                if (Hflag || outfn) {
1143 1164                          (void) printf("%s:", fn);
1144 1165                  }
1145 1166                  if (!qflag) {
1146 1167                          (void) printf("%lld\n", matches);
1147 1168                  }
1148 1169          }
1149 1170          return (matches != 0);
1150 1171  }
1151 1172  
1152 1173  /*
1153 1174   * usage message for grep
1154 1175   */
1155 1176  static void
1156 1177  usage(void)
1157 1178  {
1158 1179          if (egrep || fgrep) {
1159 1180                  (void) fprintf(stderr, gettext("Usage:\t%s"), cmdname);
1160 1181                  (void) fprintf(stderr,
1161      -                    gettext(" [-c|-l|-q] [-r|-R] [-bhinsvx] "
     1182 +                    gettext(" [-c|-l|-q] [-r|-R] [-bhHinsvx] "
1162 1183                      "pattern_list [file ...]\n"));
1163 1184  
1164 1185                  (void) fprintf(stderr, "\t%s", cmdname);
1165 1186                  (void) fprintf(stderr,
1166      -                    gettext(" [-c|-l|-q] [-r|-R] [-bhinsvx] "
     1187 +                    gettext(" [-c|-l|-q] [-r|-R] [-bhHinsvx] "
1167 1188                      "[-e pattern_list]... "
1168 1189                      "[-f pattern_file]... [file...]\n"));
1169 1190          } else {
1170 1191                  (void) fprintf(stderr, gettext("Usage:\t%s"), cmdname);
1171 1192                  (void) fprintf(stderr,
1172      -                    gettext(" [-c|-l|-q] [-r|-R] [-bhinsvwx] "
     1193 +                    gettext(" [-c|-l|-q] [-r|-R] [-bhHinsvwx] "
1173 1194                      "pattern_list [file ...]\n"));
1174 1195  
1175 1196                  (void) fprintf(stderr, "\t%s", cmdname);
1176 1197                  (void) fprintf(stderr,
1177      -                    gettext(" [-c|-l|-q] [-r|-R] [-bhinsvwx] "
     1198 +                    gettext(" [-c|-l|-q] [-r|-R] [-bhHinsvwx] "
1178 1199                      "[-e pattern_list]... "
1179 1200                      "[-f pattern_file]... [file...]\n"));
1180 1201  
1181 1202                  (void) fprintf(stderr, "\t%s", cmdname);
1182 1203                  (void) fprintf(stderr,
1183      -                    gettext(" -E [-c|-l|-q] [-r|-R] [-bhinsvx] "
     1204 +                    gettext(" -E [-c|-l|-q] [-r|-R] [-bhHinsvx] "
1184 1205                      "pattern_list [file ...]\n"));
1185 1206  
1186 1207                  (void) fprintf(stderr, "\t%s", cmdname);
1187 1208                  (void) fprintf(stderr,
1188      -                    gettext(" -E [-c|-l|-q] [-r|-R] [-bhinsvx] "
     1209 +                    gettext(" -E [-c|-l|-q] [-r|-R] [-bhHinsvx] "
1189 1210                      "[-e pattern_list]... "
1190 1211                      "[-f pattern_file]... [file...]\n"));
1191 1212  
1192 1213                  (void) fprintf(stderr, "\t%s", cmdname);
1193 1214                  (void) fprintf(stderr,
1194      -                    gettext(" -F [-c|-l|-q] [-r|-R] [-bhinsvx] "
     1215 +                    gettext(" -F [-c|-l|-q] [-r|-R] [-bhHinsvx] "
1195 1216                      "pattern_list [file ...]\n"));
1196 1217  
1197 1218                  (void) fprintf(stderr, "\t%s", cmdname);
1198 1219                  (void) fprintf(stderr,
1199      -                    gettext(" -F [-c|-l|-q] [-bhinsvx] [-e pattern_list]... "
     1220 +                    gettext(" -F [-c|-l|-q] [-bhHinsvx] [-e pattern_list]... "
1200 1221                      "[-f pattern_file]... [file...]\n"));
1201 1222          }
1202 1223          exit(2);
1203 1224          /* NOTREACHED */
1204 1225  }
1205 1226  
1206 1227  /*
1207 1228   * Compile literal pattern into BMG tables
1208 1229   */
1209 1230  static void
↓ open down ↓ 49 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX