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/fgrep/fgrep.c
          +++ new/usr/src/cmd/fgrep/fgrep.c
↓ open down ↓ 22 lines elided ↑ open up ↑
  23   23   * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
  25   25   */
  26   26  
  27   27  /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
  28   28  /*        All Rights Reserved   */
  29   29  
  30   30  /*      Copyright (c) 1987, 1988 Microsoft Corporation  */
  31   31  /*        All Rights Reserved   */
  32   32  
  33      -#pragma ident   "%Z%%M% %I%     %E% SMI"
       33 +/*
       34 + * Copyright 2013 Damian Bogel. All rights reserved.
       35 + */
  34   36  
  35   37  /*
  36   38   * fgrep -- print all lines containing any of a set of keywords
  37   39   *
  38   40   *      status returns:
  39   41   *              0 - ok, and some matches
  40   42   *              1 - ok, but no matches
  41   43   *              2 - some error
  42   44   */
  43   45  
↓ open down ↓ 56 lines elided ↑ open up ↑
 100  102  
 101  103  /*
 102  104   * The same() macro and letter() function were inserted to allow for
 103  105   * the -i option work for the multi-byte environment.
 104  106   */
 105  107  wchar_t letter();
 106  108  #define same(a, b) \
 107  109          (a == b || iflag && (!MULTI_BYTE || ISASCII(a)) && (a ^ b) == ' ' && \
 108  110          letter(a) == letter(b))
 109  111  
      112 +#define STDIN_FILENAME gettext("(standard input)")
 110  113  
 111  114  #define QSIZE 400
 112  115  struct words {
 113  116          wchar_t inp;
 114  117          char    out;
 115  118          struct  words *nst;
 116  119          struct  words *link;
 117  120          struct  words *fail;
 118  121  } *w = NULL, *smax, *q;
 119  122  
 120  123  FILE *fptr;
 121  124  long long lnum;
 122      -int     bflag, cflag, lflag, fflag, nflag, vflag, xflag, eflag, sflag;
 123      -int     hflag, iflag;
      125 +int     bflag, cflag, lflag, fflag, nflag, vflag, xflag, eflag, qflag;
      126 +int     Hflag, hflag, iflag;
 124  127  int     retcode = 0;
 125  128  int     nfile;
 126  129  long long blkno;
 127  130  int     nsucc;
 128  131  long long tln;
 129  132  FILE    *wordf;
 130  133  char    *argptr;
 131  134  off_t input_size = 0;
 132  135  
 133  136  void    execute(char *);
↓ open down ↓ 9 lines elided ↑ open up ↑
 143  146          int c;
 144  147          int errflg = 0;
 145  148          struct stat file_stat;
 146  149  
 147  150          (void) setlocale(LC_ALL, "");
 148  151  #if !defined(TEXT_DOMAIN)       /* Should be defined by cc -D */
 149  152  #define TEXT_DOMAIN "SYS_TEST"  /* Use this only if it weren't */
 150  153  #endif
 151  154          (void) textdomain(TEXT_DOMAIN);
 152  155  
 153      -        while ((c = getopt(argc, argv, "hybcie:f:lnvxs")) != EOF)
      156 +        while ((c = getopt(argc, argv, "Hhybcie:f:lnvxqs")) != EOF)
 154  157                  switch (c) {
 155  158  
 156      -                case 's':
 157      -                        sflag++;
      159 +                case 'q':
      160 +                case 's': /* Solaris: legacy option */
      161 +                        qflag++;
 158  162                          continue;
      163 +                case 'H':
      164 +                        Hflag++;
      165 +                        hflag = 0;
      166 +                        continue;
 159  167                  case 'h':
 160  168                          hflag++;
      169 +                        Hflag = 0;
 161  170                          continue;
 162  171                  case 'b':
 163  172                          bflag++;
 164  173                          continue;
 165  174  
 166  175                  case 'i':
 167  176                  case 'y':
 168  177                          iflag++;
 169  178                          continue;
 170  179  
↓ open down ↓ 5 lines elided ↑ open up ↑
 176  185                          eflag++;
 177  186                          argptr = optarg;
 178  187                          input_size = strlen(argptr);
 179  188                          continue;
 180  189  
 181  190                  case 'f':
 182  191                          fflag++;
 183  192                          wordf = fopen(optarg, "r");
 184  193                          if (wordf == NULL) {
 185  194                                  (void) fprintf(stderr,
 186      -                                        gettext("fgrep: can't open %s\n"),
 187      -                                        optarg);
      195 +                                    gettext("fgrep: can't open %s\n"),
      196 +                                    optarg);
 188  197                                  exit(2);
 189  198                          }
 190  199  
 191  200                          if (fstat(fileno(wordf), &file_stat) == 0) {
 192      -                            input_size = file_stat.st_size;
      201 +                                input_size = file_stat.st_size;
 193  202                          } else {
 194  203                                  (void) fprintf(stderr,
 195      -                                        gettext("fgrep: can't fstat %s\n"),
 196      -                                        optarg);
      204 +                                    gettext("fgrep: can't fstat %s\n"),
      205 +                                    optarg);
 197  206                                  exit(2);
 198  207                          }
 199  208  
 200  209                          continue;
 201  210  
 202  211                  case 'l':
 203  212                          lflag++;
 204  213                          continue;
 205  214  
 206  215                  case 'n':
↓ open down ↓ 7 lines elided ↑ open up ↑
 214  223                  case 'x':
 215  224                          xflag++;
 216  225                          continue;
 217  226  
 218  227                  case '?':
 219  228                          errflg++;
 220  229          }
 221  230  
 222  231          argc -= optind;
 223  232          if (errflg || ((argc <= 0) && !fflag && !eflag)) {
 224      -                (void) printf(gettext("usage: fgrep [ -bchilnsvx ] "
 225      -                        "[ -e exp ] [ -f file ] [ strings ] [ file ] ...\n"));
      233 +                (void) printf(gettext("usage: fgrep [ -bcHhilnqsvx ] "
      234 +                    "[ -e exp ] [ -f file ] [ strings ] [ file ] ...\n"));
 226  235                  exit(2);
 227  236          }
 228  237          if (!eflag && !fflag) {
 229  238                  argptr = argv[optind];
 230  239                  input_size = strlen(argptr);
 231  240                  input_size++;
 232  241                  optind++;
 233  242                  argc--;
 234  243          }
 235  244  
↓ open down ↓ 7 lines elided ↑ open up ↑
 243  252  
 244  253          if (xflag) {
 245  254                  input_size = input_size + (input_size/2) + 1;
 246  255          }
 247  256  
 248  257          input_size++;
 249  258  
 250  259          w = (struct words *)calloc(input_size, sizeof (struct words));
 251  260          if (w == NULL) {
 252  261                  (void) fprintf(stderr,
 253      -                        gettext("fgrep: could not allocate "
 254      -                                "memory for wordlist\n"));
      262 +                    gettext("fgrep: could not allocate "
      263 +                    "memory for wordlist\n"));
 255  264                  exit(2);
 256  265          }
 257  266  
 258  267          getwidth(&WW);
 259  268          if ((WIDTH1 == 0) && (WIDTH2 == 0) &&
 260      -                (WIDTH3 == 0)) {
      269 +            (WIDTH3 == 0)) {
 261  270                  /*
 262  271                   * If non EUC-based locale,
 263  272                   * assume WIDTH1 is 1.
 264  273                   */
 265  274                  WIDTH1 = 1;
 266  275          }
 267  276          WIDTH2++;
 268  277          WIDTH3++;
 269  278  
 270  279          cgotofn();
↓ open down ↓ 30 lines elided ↑ open up ↑
 301  310          if (buf == NULL) {
 302  311                  fw_lBufsiz = BUFSIZ;
 303  312                  if ((buf = malloc(fw_lBufsiz + BUFSIZ)) == NULL) {
 304  313                          exit(2); /* out of memory */
 305  314                  }
 306  315          }
 307  316  
 308  317          if (file) {
 309  318                  if ((fptr = fopen(file, "r")) == NULL) {
 310  319                          (void) fprintf(stderr,
 311      -                                gettext("fgrep: can't open %s\n"), file);
      320 +                            gettext("fgrep: can't open %s\n"), file);
 312  321                          retcode = 2;
 313  322                          return;
 314  323                  }
 315  324          } else {
 316      -                file = "<stdin>";
 317  325                  fptr = stdin;
      326 +                file = STDIN_FILENAME;
 318  327          }
 319  328          ccount = 0;
 320  329          failed = 0;
 321  330          lnum = 1;
 322  331          tln = 0;
 323  332          blkno = 0;
 324  333          p = buf;
 325  334          nlp = p;
 326  335          c = w;
 327  336          for (;;) {
 328  337                  if (c == 0)
 329  338                          break;
 330  339                  if (ccount <= 0) {
 331  340                          if (p >= &buf[fw_lBufsiz + BUFSIZ]) {
 332  341                                  if (nlp == buf) {
 333  342                                          /* increase the buffer size */
 334  343                                          fw_lBufsiz += BUFSIZ;
 335  344                                          if ((buf = realloc(buf,
 336      -                                                fw_lBufsiz + BUFSIZ)) == NULL) {
      345 +                                            fw_lBufsiz + BUFSIZ)) == NULL) {
 337  346                                                  exit(2); /* out of memory */
 338  347                                          }
 339  348                                          nlp = buf;
 340  349                                          p = &buf[fw_lBufsiz];
 341  350                                  } else {
 342  351                                          /* shift the buffer down */
 343  352                                          (void) memmove(buf, nlp,
 344      -                                                &buf[fw_lBufsiz + BUFSIZ]
 345      -                                                - nlp);
      353 +                                            &buf[fw_lBufsiz + BUFSIZ]
      354 +                                            - nlp);
 346  355                                          p -= nlp - buf;
 347  356                                          nlp = buf;
 348  357                                  }
 349  358  
 350  359                          }
 351  360                          if (p > &buf[fw_lBufsiz]) {
 352  361                                  if ((ccount = fread(p, sizeof (char),
 353      -                                        &buf[fw_lBufsiz + BUFSIZ] - p, fptr))
 354      -                                        <= 0)
      362 +                                    &buf[fw_lBufsiz + BUFSIZ] - p, fptr))
      363 +                                    <= 0)
 355  364                                          break;
 356  365                          } else if ((ccount = fread(p, sizeof (char),
 357      -                                BUFSIZ, fptr)) <= 0)
      366 +                            BUFSIZ, fptr)) <= 0)
 358  367                                  break;
 359  368                          blkno += (long long)ccount;
 360  369                  }
 361  370                  GETONE(lc, p);
 362  371  nstate:
 363  372                  if (same(c->inp, lc)) {
 364  373                          c = c->nst;
 365  374                  } else if (c->link != 0) {
 366  375                          c = c->link;
 367  376                          goto nstate;
↓ open down ↓ 42 lines elided ↑ open up ↑
 410  419                  fptr)) <= 0) break;
 411  420                  blkno += (long long)ccount;
 412  421          }
 413  422          GETONE(lc, p);
 414  423  }
 415  424                          if ((vflag && (failed == 0 || xflag == 0)) ||
 416  425                                  (vflag == 0 && xflag && failed))
 417  426                                  goto nomatch;
 418  427  succeed:
 419  428                          nsucc = 1;
 420      -                        if (cflag)
 421      -                                tln++;
 422      -                        else if (lflag && !sflag) {
 423      -                                (void) printf("%s\n", file);
      429 +                        if (lflag || qflag) {
      430 +                                if (!qflag)
      431 +                                        (void) printf("%s\n", file);
 424  432                                  (void) fclose(fptr);
 425  433                                  return;
 426      -                        } else if (!sflag) {
 427      -                                if (nfile > 1 && !hflag)
      434 +                        }
      435 +                        if (cflag) {
      436 +                                tln++;
      437 +                        } else {
      438 +                                if (Hflag || (nfile > 1 && !hflag))
 428  439                                          (void) printf("%s:", file);
 429  440                                  if (bflag)
 430  441                                          (void) printf("%lld:",
 431  442                                                  (blkno - (long long)(ccount-1))
 432  443                                                  / BUFSIZ);
 433  444                                  if (nflag)
 434  445                                          (void) printf("%lld:", lnum);
 435  446                                  if (p <= nlp) {
 436  447                                          while (nlp < &buf[fw_lBufsiz + BUFSIZ])
 437  448                                                  (void) putchar(*nlp++);
↓ open down ↓ 13 lines elided ↑ open up ↑
 451  462                          if (vflag)
 452  463                                  goto succeed;
 453  464                          else {
 454  465                                  lnum++;
 455  466                                  nlp = p;
 456  467                                  c = w;
 457  468                                  failed = 0;
 458  469                          }
 459  470          }
 460  471          (void) fclose(fptr);
 461      -        if (cflag) {
 462      -                if ((nfile > 1) && !hflag)
      472 +        if (cflag && !qflag) {
      473 +                if (Hflag || (nfile > 1 && !hflag))
 463  474                          (void) printf("%s:", file);
 464  475                  (void) printf("%lld\n", tln);
 465  476          }
 466  477  }
 467  478  
 468  479  
 469  480  wchar_t
 470  481  getargc(void)
 471  482  {
 472  483          /* appends a newline to shell quoted argument list so */
↓ open down ↓ 1 lines elided ↑ open up ↑
 474  485          wchar_t c;
 475  486          int cw;
 476  487          int b;
 477  488          static int endflg;
 478  489  
 479  490  
 480  491          if (wordf) {
 481  492                  if ((b = getc(wordf)) == EOF)
 482  493                          return (EOF);
 483  494                  cw = ISASCII(c = (wchar_t)b) ? 1 :
 484      -                        (ISSET2(c) ? WIDTH2 : (ISSET3(c) ? WIDTH3 : WIDTH1));
      495 +                    (ISSET2(c) ? WIDTH2 : (ISSET3(c) ? WIDTH3 : WIDTH1));
 485  496                  while (--cw) {
 486  497                          if ((b = getc(wordf)) == EOF)
 487  498                                  return (EOF);
 488  499                          c = (c << 7) | (b & 0177);
 489  500                  }
 490  501                  return (iflag ? letter(c) : c);
 491  502          }
 492  503  
 493  504          if (endflg)
 494  505                  return (EOF);
 495  506  
 496  507          {
 497  508                  cw = ISASCII(c = (unsigned char)*argptr++) ? 1 :
 498      -                        (ISSET2(c) ? WIDTH2 : (ISSET3(c) ? WIDTH3 : WIDTH1));
      509 +                    (ISSET2(c) ? WIDTH2 : (ISSET3(c) ? WIDTH3 : WIDTH1));
 499  510  
 500  511                  while (--cw)
 501  512                          c = (c << 7) | ((*argptr++) & 0177);
 502  513                  if (c == '\0') {
 503  514                          endflg++;
 504  515                          return ('\n');
 505  516                  }
 506  517          }
 507  518          return (iflag ? letter(c) : c);
 508  519  
↓ open down ↓ 98 lines elided ↑ open up ↑
 607  618           * front and rear are pointers used to traverse the global words
 608  619           * structure "w" which contains the data of input pattern file
 609  620           */
 610  621          struct words **front, **rear;
 611  622          struct words *state;
 612  623          unsigned long frontoffset = 0, rearoffset = 0;
 613  624          char c;
 614  625          struct words *s;
 615  626          s = w;
 616  627          if ((queue = (struct words **)calloc(qsize, sizeof (struct words *)))
 617      -                                == NULL) {
      628 +            == NULL) {
 618  629                  perror("fgrep");
 619  630                  exit(2);
 620  631          }
 621  632          front = rear = queue;
 622  633  init:
 623  634          if ((s->inp) != 0) {
 624  635                  *rear++ = s->nst;
 625  636          /*
 626  637           * Reallocates the queue if the number of distinct starting
 627  638           * character of patterns exceeds the qsize value
↓ open down ↓ 67 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX