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>


  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  28 /*        All Rights Reserved   */
  29 
  30 /*      Copyright (c) 1987, 1988 Microsoft Corporation  */
  31 /*        All Rights Reserved   */
  32 
  33 #pragma ident   "%Z%%M% %I%     %E% SMI"


  34 
  35 /*
  36  * fgrep -- print all lines containing any of a set of keywords
  37  *
  38  *      status returns:
  39  *              0 - ok, and some matches
  40  *              1 - ok, but no matches
  41  *              2 - some error
  42  */
  43 
  44 #include <stdio.h>
  45 #include <ctype.h>
  46 #include <sys/types.h>
  47 #include <stdlib.h>
  48 #include <string.h>
  49 #include <locale.h>
  50 #include <libintl.h>
  51 #include <euc.h>
  52 #include <sys/stat.h>
  53 #include <fcntl.h>


  90                             &buf[fw_lBufsiz + BUFSIZ] - p, fptr))\
  91                                 <= 0) break;                         \
  92                 } else if ((ccount = fread(p,                \
  93                         sizeof (char),  BUFSIZ, fptr)) <= 0)     \
  94                         break;                                   \
  95                 blkno += (long long)ccount;                  \
  96         }                                                \
  97         ccount -= cw;                                    \
  98         while (cw--)                                     \
  99                 lc = (lc << 7) | ((*p++) & 0177)
 100 
 101 /*
 102  * The same() macro and letter() function were inserted to allow for
 103  * the -i option work for the multi-byte environment.
 104  */
 105 wchar_t letter();
 106 #define same(a, b) \
 107         (a == b || iflag && (!MULTI_BYTE || ISASCII(a)) && (a ^ b) == ' ' && \
 108         letter(a) == letter(b))
 109 

 110 
 111 #define QSIZE 400
 112 struct words {
 113         wchar_t inp;
 114         char    out;
 115         struct  words *nst;
 116         struct  words *link;
 117         struct  words *fail;
 118 } *w = NULL, *smax, *q;
 119 
 120 FILE *fptr;
 121 long long lnum;
 122 int     bflag, cflag, lflag, fflag, nflag, vflag, xflag, eflag, sflag;
 123 int     hflag, iflag;
 124 int     retcode = 0;
 125 int     nfile;
 126 long long blkno;
 127 int     nsucc;
 128 long long tln;
 129 FILE    *wordf;
 130 char    *argptr;
 131 off_t input_size = 0;
 132 
 133 void    execute(char *);
 134 void    cgotofn(void);
 135 void    overflo(void);
 136 void    cfail(void);
 137 
 138 static long fw_lBufsiz = 0;
 139 
 140 int
 141 main(int argc, char **argv)
 142 {
 143         int c;
 144         int errflg = 0;
 145         struct stat file_stat;
 146 
 147         (void) setlocale(LC_ALL, "");
 148 #if !defined(TEXT_DOMAIN)       /* Should be defined by cc -D */
 149 #define TEXT_DOMAIN "SYS_TEST"  /* Use this only if it weren't */
 150 #endif
 151         (void) textdomain(TEXT_DOMAIN);
 152 
 153         while ((c = getopt(argc, argv, "hybcie:f:lnvxs")) != EOF)
 154                 switch (c) {
 155 
 156                 case 's':
 157                         sflag++;

 158                         continue;




 159                 case 'h':
 160                         hflag++;

 161                         continue;
 162                 case 'b':
 163                         bflag++;
 164                         continue;
 165 
 166                 case 'i':
 167                 case 'y':
 168                         iflag++;
 169                         continue;
 170 
 171                 case 'c':
 172                         cflag++;
 173                         continue;
 174 
 175                 case 'e':
 176                         eflag++;
 177                         argptr = optarg;
 178                         input_size = strlen(argptr);
 179                         continue;
 180 


 204                         continue;
 205 
 206                 case 'n':
 207                         nflag++;
 208                         continue;
 209 
 210                 case 'v':
 211                         vflag++;
 212                         continue;
 213 
 214                 case 'x':
 215                         xflag++;
 216                         continue;
 217 
 218                 case '?':
 219                         errflg++;
 220         }
 221 
 222         argc -= optind;
 223         if (errflg || ((argc <= 0) && !fflag && !eflag)) {
 224                 (void) printf(gettext("usage: fgrep [ -bchilnsvx ] "
 225                         "[ -e exp ] [ -f file ] [ strings ] [ file ] ...\n"));
 226                 exit(2);
 227         }
 228         if (!eflag && !fflag) {
 229                 argptr = argv[optind];
 230                 input_size = strlen(argptr);
 231                 input_size++;
 232                 optind++;
 233                 argc--;
 234         }
 235 
 236 /*
 237  * Normally we need one struct words for each letter in the pattern
 238  * plus one terminating struct words with outp = 1, but when -x option
 239  * is specified we require one more struct words for `\n` character so we
 240  * calculate the input_size as below. We add extra 1 because
 241  * (input_size/2) rounds off odd numbers
 242  */
 243 
 244         if (xflag) {


 296         int failed;
 297         char *nlp;
 298         wchar_t lc;
 299         int cw;
 300 
 301         if (buf == NULL) {
 302                 fw_lBufsiz = BUFSIZ;
 303                 if ((buf = malloc(fw_lBufsiz + BUFSIZ)) == NULL) {
 304                         exit(2); /* out of memory */
 305                 }
 306         }
 307 
 308         if (file) {
 309                 if ((fptr = fopen(file, "r")) == NULL) {
 310                         (void) fprintf(stderr,
 311                                 gettext("fgrep: can't open %s\n"), file);
 312                         retcode = 2;
 313                         return;
 314                 }
 315         } else {
 316                 file = "<stdin>";
 317                 fptr = stdin;

 318         }
 319         ccount = 0;
 320         failed = 0;
 321         lnum = 1;
 322         tln = 0;
 323         blkno = 0;
 324         p = buf;
 325         nlp = p;
 326         c = w;
 327         for (;;) {
 328                 if (c == 0)
 329                         break;
 330                 if (ccount <= 0) {
 331                         if (p >= &buf[fw_lBufsiz + BUFSIZ]) {
 332                                 if (nlp == buf) {
 333                                         /* increase the buffer size */
 334                                         fw_lBufsiz += BUFSIZ;
 335                                         if ((buf = realloc(buf,
 336                                                 fw_lBufsiz + BUFSIZ)) == NULL) {
 337                                                 exit(2); /* out of memory */


 400                 /* shift buffer down */
 401                 (void) memmove(buf, nlp, &buf[fw_lBufsiz + BUFSIZ] - nlp);
 402                 p -= nlp - buf;
 403                 nlp = buf;
 404         }
 405 }
 406 if (p > &buf[fw_lBufsiz]) {
 407         if ((ccount = fread(p, sizeof (char),
 408                 &buf[fw_lBufsiz + BUFSIZ] - p, fptr)) <= 0) break;
 409         } else if ((ccount = fread(p, sizeof (char), BUFSIZ,
 410                 fptr)) <= 0) break;
 411                 blkno += (long long)ccount;
 412         }
 413         GETONE(lc, p);
 414 }
 415                         if ((vflag && (failed == 0 || xflag == 0)) ||
 416                                 (vflag == 0 && xflag && failed))
 417                                 goto nomatch;
 418 succeed:
 419                         nsucc = 1;
 420                         if (cflag)
 421                                 tln++;
 422                         else if (lflag && !sflag) {
 423                                 (void) printf("%s\n", file);
 424                                 (void) fclose(fptr);
 425                                 return;
 426                         } else if (!sflag) {
 427                                 if (nfile > 1 && !hflag)



 428                                         (void) printf("%s:", file);
 429                                 if (bflag)
 430                                         (void) printf("%lld:",
 431                                                 (blkno - (long long)(ccount-1))
 432                                                 / BUFSIZ);
 433                                 if (nflag)
 434                                         (void) printf("%lld:", lnum);
 435                                 if (p <= nlp) {
 436                                         while (nlp < &buf[fw_lBufsiz + BUFSIZ])
 437                                                 (void) putchar(*nlp++);
 438                                         nlp = buf;
 439                                 }
 440                                 while (nlp < p)
 441                                         (void) putchar(*nlp++);
 442                         }
 443 nomatch:
 444                         lnum++;
 445                         nlp = p;
 446                         c = w;
 447                         failed = 0;
 448                         continue;
 449                 }
 450                 if (lc == '\n')
 451                         if (vflag)
 452                                 goto succeed;
 453                         else {
 454                                 lnum++;
 455                                 nlp = p;
 456                                 c = w;
 457                                 failed = 0;
 458                         }
 459         }
 460         (void) fclose(fptr);
 461         if (cflag) {
 462                 if ((nfile > 1) && !hflag)
 463                         (void) printf("%s:", file);
 464                 (void) printf("%lld\n", tln);
 465         }
 466 }
 467 
 468 
 469 wchar_t
 470 getargc(void)
 471 {
 472         /* appends a newline to shell quoted argument list so */
 473         /* the list looks like it came from an ed style file  */
 474         wchar_t c;
 475         int cw;
 476         int b;
 477         static int endflg;
 478 
 479 
 480         if (wordf) {
 481                 if ((b = getc(wordf)) == EOF)
 482                         return (EOF);




  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  28 /*        All Rights Reserved   */
  29 
  30 /*      Copyright (c) 1987, 1988 Microsoft Corporation  */
  31 /*        All Rights Reserved   */
  32 
  33 /*
  34  * Copyright 2013 Damian Bogel. All rights reserved.
  35  */
  36 
  37 /*
  38  * fgrep -- print all lines containing any of a set of keywords
  39  *
  40  *      status returns:
  41  *              0 - ok, and some matches
  42  *              1 - ok, but no matches
  43  *              2 - some error
  44  */
  45 
  46 #include <stdio.h>
  47 #include <ctype.h>
  48 #include <sys/types.h>
  49 #include <stdlib.h>
  50 #include <string.h>
  51 #include <locale.h>
  52 #include <libintl.h>
  53 #include <euc.h>
  54 #include <sys/stat.h>
  55 #include <fcntl.h>


  92                             &buf[fw_lBufsiz + BUFSIZ] - p, fptr))\
  93                                 <= 0) break;                         \
  94                 } else if ((ccount = fread(p,                \
  95                         sizeof (char),  BUFSIZ, fptr)) <= 0)     \
  96                         break;                                   \
  97                 blkno += (long long)ccount;                  \
  98         }                                                \
  99         ccount -= cw;                                    \
 100         while (cw--)                                     \
 101                 lc = (lc << 7) | ((*p++) & 0177)
 102 
 103 /*
 104  * The same() macro and letter() function were inserted to allow for
 105  * the -i option work for the multi-byte environment.
 106  */
 107 wchar_t letter();
 108 #define same(a, b) \
 109         (a == b || iflag && (!MULTI_BYTE || ISASCII(a)) && (a ^ b) == ' ' && \
 110         letter(a) == letter(b))
 111 
 112 #define STDIN_FILENAME gettext("(standard input)")
 113 
 114 #define QSIZE 400
 115 struct words {
 116         wchar_t inp;
 117         char    out;
 118         struct  words *nst;
 119         struct  words *link;
 120         struct  words *fail;
 121 } *w = NULL, *smax, *q;
 122 
 123 FILE *fptr;
 124 long long lnum;
 125 int     bflag, cflag, lflag, fflag, nflag, vflag, xflag, eflag, qflag;
 126 int     Hflag, hflag, iflag;
 127 int     retcode = 0;
 128 int     nfile;
 129 long long blkno;
 130 int     nsucc;
 131 long long tln;
 132 FILE    *wordf;
 133 char    *argptr;
 134 off_t input_size = 0;
 135 
 136 void    execute(char *);
 137 void    cgotofn(void);
 138 void    overflo(void);
 139 void    cfail(void);
 140 
 141 static long fw_lBufsiz = 0;
 142 
 143 int
 144 main(int argc, char **argv)
 145 {
 146         int c;
 147         int errflg = 0;
 148         struct stat file_stat;
 149 
 150         (void) setlocale(LC_ALL, "");
 151 #if !defined(TEXT_DOMAIN)       /* Should be defined by cc -D */
 152 #define TEXT_DOMAIN "SYS_TEST"  /* Use this only if it weren't */
 153 #endif
 154         (void) textdomain(TEXT_DOMAIN);
 155 
 156         while ((c = getopt(argc, argv, "Hhybcie:f:lnvxqs")) != EOF)
 157                 switch (c) {
 158 
 159                 case 'q':
 160                 case 's': /* Solaris: legacy option */
 161                         qflag++;
 162                         continue;
 163                 case 'H':
 164                         Hflag++;
 165                         hflag = 0;
 166                         continue;
 167                 case 'h':
 168                         hflag++;
 169                         Hflag = 0;
 170                         continue;
 171                 case 'b':
 172                         bflag++;
 173                         continue;
 174 
 175                 case 'i':
 176                 case 'y':
 177                         iflag++;
 178                         continue;
 179 
 180                 case 'c':
 181                         cflag++;
 182                         continue;
 183 
 184                 case 'e':
 185                         eflag++;
 186                         argptr = optarg;
 187                         input_size = strlen(argptr);
 188                         continue;
 189 


 213                         continue;
 214 
 215                 case 'n':
 216                         nflag++;
 217                         continue;
 218 
 219                 case 'v':
 220                         vflag++;
 221                         continue;
 222 
 223                 case 'x':
 224                         xflag++;
 225                         continue;
 226 
 227                 case '?':
 228                         errflg++;
 229         }
 230 
 231         argc -= optind;
 232         if (errflg || ((argc <= 0) && !fflag && !eflag)) {
 233                 (void) printf(gettext("usage: fgrep [ -bcHhilnqsvx ] "
 234                     "[ -e exp ] [ -f file ] [ strings ] [ file ] ...\n"));
 235                 exit(2);
 236         }
 237         if (!eflag && !fflag) {
 238                 argptr = argv[optind];
 239                 input_size = strlen(argptr);
 240                 input_size++;
 241                 optind++;
 242                 argc--;
 243         }
 244 
 245 /*
 246  * Normally we need one struct words for each letter in the pattern
 247  * plus one terminating struct words with outp = 1, but when -x option
 248  * is specified we require one more struct words for `\n` character so we
 249  * calculate the input_size as below. We add extra 1 because
 250  * (input_size/2) rounds off odd numbers
 251  */
 252 
 253         if (xflag) {


 305         int failed;
 306         char *nlp;
 307         wchar_t lc;
 308         int cw;
 309 
 310         if (buf == NULL) {
 311                 fw_lBufsiz = BUFSIZ;
 312                 if ((buf = malloc(fw_lBufsiz + BUFSIZ)) == NULL) {
 313                         exit(2); /* out of memory */
 314                 }
 315         }
 316 
 317         if (file) {
 318                 if ((fptr = fopen(file, "r")) == NULL) {
 319                         (void) fprintf(stderr,
 320                             gettext("fgrep: can't open %s\n"), file);
 321                         retcode = 2;
 322                         return;
 323                 }
 324         } else {

 325                 fptr = stdin;
 326                 file = STDIN_FILENAME;
 327         }
 328         ccount = 0;
 329         failed = 0;
 330         lnum = 1;
 331         tln = 0;
 332         blkno = 0;
 333         p = buf;
 334         nlp = p;
 335         c = w;
 336         for (;;) {
 337                 if (c == 0)
 338                         break;
 339                 if (ccount <= 0) {
 340                         if (p >= &buf[fw_lBufsiz + BUFSIZ]) {
 341                                 if (nlp == buf) {
 342                                         /* increase the buffer size */
 343                                         fw_lBufsiz += BUFSIZ;
 344                                         if ((buf = realloc(buf,
 345                                             fw_lBufsiz + BUFSIZ)) == NULL) {
 346                                                 exit(2); /* out of memory */


 409                 /* shift buffer down */
 410                 (void) memmove(buf, nlp, &buf[fw_lBufsiz + BUFSIZ] - nlp);
 411                 p -= nlp - buf;
 412                 nlp = buf;
 413         }
 414 }
 415 if (p > &buf[fw_lBufsiz]) {
 416         if ((ccount = fread(p, sizeof (char),
 417                 &buf[fw_lBufsiz + BUFSIZ] - p, fptr)) <= 0) break;
 418         } else if ((ccount = fread(p, sizeof (char), BUFSIZ,
 419                 fptr)) <= 0) break;
 420                 blkno += (long long)ccount;
 421         }
 422         GETONE(lc, p);
 423 }
 424                         if ((vflag && (failed == 0 || xflag == 0)) ||
 425                                 (vflag == 0 && xflag && failed))
 426                                 goto nomatch;
 427 succeed:
 428                         nsucc = 1;
 429                         if (lflag || qflag) {
 430                                 if (!qflag)

 431                                         (void) printf("%s\n", file);
 432                                 (void) fclose(fptr);
 433                                 return;
 434                         }
 435                         if (cflag) {
 436                                 tln++;
 437                         } else {
 438                                 if (Hflag || (nfile > 1 && !hflag))
 439                                         (void) printf("%s:", file);
 440                                 if (bflag)
 441                                         (void) printf("%lld:",
 442                                                 (blkno - (long long)(ccount-1))
 443                                                 / BUFSIZ);
 444                                 if (nflag)
 445                                         (void) printf("%lld:", lnum);
 446                                 if (p <= nlp) {
 447                                         while (nlp < &buf[fw_lBufsiz + BUFSIZ])
 448                                                 (void) putchar(*nlp++);
 449                                         nlp = buf;
 450                                 }
 451                                 while (nlp < p)
 452                                         (void) putchar(*nlp++);
 453                         }
 454 nomatch:
 455                         lnum++;
 456                         nlp = p;
 457                         c = w;
 458                         failed = 0;
 459                         continue;
 460                 }
 461                 if (lc == '\n')
 462                         if (vflag)
 463                                 goto succeed;
 464                         else {
 465                                 lnum++;
 466                                 nlp = p;
 467                                 c = w;
 468                                 failed = 0;
 469                         }
 470         }
 471         (void) fclose(fptr);
 472         if (cflag && !qflag) {
 473                 if (Hflag || (nfile > 1 && !hflag))
 474                         (void) printf("%s:", file);
 475                 (void) printf("%lld\n", tln);
 476         }
 477 }
 478 
 479 
 480 wchar_t
 481 getargc(void)
 482 {
 483         /* appends a newline to shell quoted argument list so */
 484         /* the list looks like it came from an ed style file  */
 485         wchar_t c;
 486         int cw;
 487         int b;
 488         static int endflg;
 489 
 490 
 491         if (wordf) {
 492                 if ((b = getc(wordf)) == EOF)
 493                         return (EOF);