Print this page
3546 add support for grep -o option


  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 /* Copyright 2012 Nexenta Systems, Inc.  All rights reserved. */
  34 
  35 /*
  36  * Copyright 2013 Damian Bogel. All rights reserved.

  37  */
  38 
  39 /*
  40  * grep -- print lines matching (or not matching) a pattern
  41  *
  42  *      status returns:
  43  *              0 - ok, and some matches
  44  *              1 - ok, but no matches
  45  *              2 - some error
  46  */
  47 
  48 #include <sys/types.h>
  49 
  50 #include <ctype.h>
  51 #include <fcntl.h>
  52 #include <locale.h>
  53 #include <memory.h>
  54 #include <regexpr.h>
  55 #include <stdio.h>
  56 #include <stdlib.h>


  85 #define MAX_DEPTH       1000
  86 
  87 static int      temp;
  88 static long long        lnum;
  89 static char     *linebuf;
  90 static char     *prntbuf = NULL;
  91 static long     fw_lPrntBufLen = 0;
  92 static int      nflag;
  93 static int      bflag;
  94 static int      lflag;
  95 static int      cflag;
  96 static int      rflag;
  97 static int      Rflag;
  98 static int      vflag;
  99 static int      sflag;
 100 static int      iflag;
 101 static int      wflag;
 102 static int      hflag;
 103 static int      Hflag;
 104 static int      qflag;

 105 static int      errflg;
 106 static int      nfile;
 107 static long long        tln;
 108 static int      nsucc;
 109 static int      outfn = 0;
 110 static int      nlflag;
 111 static char     *ptr, *ptrend;
 112 static char     *expbuf;
 113 
 114 static void     execute(const char *, int);
 115 static void     regerr(int);
 116 static void     prepare(const char *);
 117 static int      recursive(const char *, const struct stat *, int, struct FTW *);
 118 static int      succeed(const char *);
 119 
 120 int
 121 main(int argc, char **argv)
 122 {
 123         int     c;
 124         char    *arg;
 125         extern int      optind;
 126 
 127         (void) setlocale(LC_ALL, "");
 128 #if !defined(TEXT_DOMAIN)       /* Should be defined by cc -D */
 129 #define TEXT_DOMAIN "SYS_TEST"  /* Use this only if it weren't */
 130 #endif
 131         (void) textdomain(TEXT_DOMAIN);
 132 
 133         while ((c = getopt(argc, argv, "hHqblcnRrsviyw")) != -1)
 134                 switch (c) {
 135                 /* based on options order h or H is set as in GNU grep */
 136                 case 'h':
 137                         hflag++;
 138                         Hflag = 0; /* h excludes H */
 139                         break;
 140                 case 'H':
 141                         if (!lflag) /* H is excluded by l */
 142                                 Hflag++;
 143                         hflag = 0; /* H excludes h */
 144                         break;
 145                 case 'q':       /* POSIX: quiet: status only */
 146                         qflag++;
 147                         break;
 148                 case 'v':
 149                         vflag++;
 150                         break;
 151                 case 'c':
 152                         cflag++;
 153                         break;
 154                 case 'n':
 155                         nflag++;
 156                         break;



 157                 case 'R':
 158                         Rflag++;
 159                         /* FALLTHROUGH */
 160                 case 'r':
 161                         rflag++;
 162                         break;
 163                 case 'b':
 164                         bflag++;
 165                         break;
 166                 case 's':
 167                         sflag++;
 168                         break;
 169                 case 'l':
 170                         lflag++;
 171                         Hflag = 0; /* l excludes H */
 172                         break;
 173                 case 'y':
 174                 case 'i':
 175                         iflag++;
 176                         break;
 177                 case 'w':
 178                         wflag++;
 179                         break;
 180                 case '?':
 181                         errflg++;
 182                 }
 183 
 184         if (errflg || (optind >= argc)) {
 185                 errmsg("Usage: grep [-c|-l|-q] [-r|-R] -hHbnsviw "
 186                     "pattern file . . .\n",
 187                     (char *)NULL);
 188                 exit(2);
 189         }
 190 
 191         argv = &argv[optind];
 192         argc -= optind;
 193         nfile = argc - 1;
 194 
 195         if (strrchr(*argv, '\n') != NULL)
 196                 regerr(41);
 197 
 198         if (iflag) {
 199                 for (arg = *argv; *arg != NULL; ++arg)
 200                         *arg = (char)tolower((int)((unsigned char)*arg));
 201         }
 202 
 203         if (wflag) {
 204                 unsigned int    wordlen;
 205                 char            *wordbuf;


 396                 lnum++;
 397                 *ptrend = '\0';
 398 
 399                 if (iflag) {
 400                         /*
 401                          * Make a lower case copy of the record
 402                          */
 403                         p = ptr;
 404                         for (lbuf = linebuf; p < ptrend; )
 405                                 *lbuf++ = (char)tolower((int)
 406                                     (unsigned char)*p++);
 407                         *lbuf = '\0';
 408                         lbuf = linebuf;
 409                 } else
 410                         /*
 411                          * Use record as is
 412                          */
 413                         lbuf = ptr;
 414 
 415                 /* lflag only once */
 416                 if ((step(lbuf, expbuf) ^ vflag) && succeed(file) == 1)








 417                         break;

 418 
 419                 if (!nlflag)
 420                         break;
 421 
 422                 ptr = next_ptr;
 423                 count = next_count;
 424                 offset = 0;
 425         }
 426         (void) close(temp);
 427 
 428         if (cflag && !qflag) {
 429                 if (Hflag || (!hflag && ((nfile > 1) ||
 430                     (rflag && outfn))))
 431                         (void) fprintf(stdout, "%s:", file);
 432                 (void) fprintf(stdout, "%lld\n", tln);
 433         }
 434 }
 435 
 436 static int
 437 succeed(const char *f)




  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 /* Copyright 2012 Nexenta Systems, Inc.  All rights reserved. */
  34 
  35 /*
  36  * Copyright 2013 Damian Bogel. All rights reserved.
  37  * Copyright (c) 2013 Andrew Stormont.  All rights reserved.
  38  */
  39 
  40 /*
  41  * grep -- print lines matching (or not matching) a pattern
  42  *
  43  *      status returns:
  44  *              0 - ok, and some matches
  45  *              1 - ok, but no matches
  46  *              2 - some error
  47  */
  48 
  49 #include <sys/types.h>
  50 
  51 #include <ctype.h>
  52 #include <fcntl.h>
  53 #include <locale.h>
  54 #include <memory.h>
  55 #include <regexpr.h>
  56 #include <stdio.h>
  57 #include <stdlib.h>


  86 #define MAX_DEPTH       1000
  87 
  88 static int      temp;
  89 static long long        lnum;
  90 static char     *linebuf;
  91 static char     *prntbuf = NULL;
  92 static long     fw_lPrntBufLen = 0;
  93 static int      nflag;
  94 static int      bflag;
  95 static int      lflag;
  96 static int      cflag;
  97 static int      rflag;
  98 static int      Rflag;
  99 static int      vflag;
 100 static int      sflag;
 101 static int      iflag;
 102 static int      wflag;
 103 static int      hflag;
 104 static int      Hflag;
 105 static int      qflag;
 106 static int      oflag;
 107 static int      errflg;
 108 static int      nfile;
 109 static long long        tln;
 110 static int      nsucc;
 111 static int      outfn = 0;
 112 static int      nlflag;
 113 static char     *ptr, *ptrend;
 114 static char     *expbuf;
 115 
 116 static void     execute(const char *, int);
 117 static void     regerr(int);
 118 static void     prepare(const char *);
 119 static int      recursive(const char *, const struct stat *, int, struct FTW *);
 120 static int      succeed(const char *);
 121 
 122 int
 123 main(int argc, char **argv)
 124 {
 125         int     c;
 126         char    *arg;
 127         extern int      optind;
 128 
 129         (void) setlocale(LC_ALL, "");
 130 #if !defined(TEXT_DOMAIN)       /* Should be defined by cc -D */
 131 #define TEXT_DOMAIN "SYS_TEST"  /* Use this only if it weren't */
 132 #endif
 133         (void) textdomain(TEXT_DOMAIN);
 134 
 135         while ((c = getopt(argc, argv, "hHqblcnoRrsviyw")) != -1)
 136                 switch (c) {
 137                 /* based on options order h or H is set as in GNU grep */
 138                 case 'h':
 139                         hflag++;
 140                         Hflag = 0; /* h excludes H */
 141                         break;
 142                 case 'H':
 143                         if (!lflag) /* H is excluded by l */
 144                                 Hflag++;
 145                         hflag = 0; /* H excludes h */
 146                         break;
 147                 case 'q':       /* POSIX: quiet: status only */
 148                         qflag++;
 149                         break;
 150                 case 'v':
 151                         vflag++;
 152                         break;
 153                 case 'c':
 154                         cflag++;
 155                         break;
 156                 case 'n':
 157                         nflag++;
 158                         break;
 159                 case 'o':
 160                         oflag++;
 161                         break;
 162                 case 'R':
 163                         Rflag++;
 164                         /* FALLTHROUGH */
 165                 case 'r':
 166                         rflag++;
 167                         break;
 168                 case 'b':
 169                         bflag++;
 170                         break;
 171                 case 's':
 172                         sflag++;
 173                         break;
 174                 case 'l':
 175                         lflag++;
 176                         Hflag = 0; /* l excludes H */
 177                         break;
 178                 case 'y':
 179                 case 'i':
 180                         iflag++;
 181                         break;
 182                 case 'w':
 183                         wflag++;
 184                         break;
 185                 case '?':
 186                         errflg++;
 187                 }
 188 
 189         if (errflg || (optind >= argc)) {
 190                 errmsg("Usage: grep [-c|-l|-q|-o] [-r|-R] -hHbnsviw "
 191                     "pattern file . . .\n",
 192                     (char *)NULL);
 193                 exit(2);
 194         }
 195 
 196         argv = &argv[optind];
 197         argc -= optind;
 198         nfile = argc - 1;
 199 
 200         if (strrchr(*argv, '\n') != NULL)
 201                 regerr(41);
 202 
 203         if (iflag) {
 204                 for (arg = *argv; *arg != NULL; ++arg)
 205                         *arg = (char)tolower((int)((unsigned char)*arg));
 206         }
 207 
 208         if (wflag) {
 209                 unsigned int    wordlen;
 210                 char            *wordbuf;


 401                 lnum++;
 402                 *ptrend = '\0';
 403 
 404                 if (iflag) {
 405                         /*
 406                          * Make a lower case copy of the record
 407                          */
 408                         p = ptr;
 409                         for (lbuf = linebuf; p < ptrend; )
 410                                 *lbuf++ = (char)tolower((int)
 411                                     (unsigned char)*p++);
 412                         *lbuf = '\0';
 413                         lbuf = linebuf;
 414                 } else
 415                         /*
 416                          * Use record as is
 417                          */
 418                         lbuf = ptr;
 419 
 420                 /* lflag only once */
 421                 if (step(lbuf, expbuf) ^ vflag) {
 422                         if (oflag) {
 423                                 /*
 424                                  * Only store the matching bits
 425                                  */
 426                                 ptr = loc1;
 427                                 ptrend = loc2;
 428                         }
 429                         if (succeed(file) == 1)
 430                                 break;
 431                 }
 432 
 433                 if (!nlflag)
 434                         break;
 435 
 436                 ptr = next_ptr;
 437                 count = next_count;
 438                 offset = 0;
 439         }
 440         (void) close(temp);
 441 
 442         if (cflag && !qflag) {
 443                 if (Hflag || (!hflag && ((nfile > 1) ||
 444                     (rflag && outfn))))
 445                         (void) fprintf(stdout, "%s:", file);
 446                 (void) fprintf(stdout, "%lld\n", tln);
 447         }
 448 }
 449 
 450 static int
 451 succeed(const char *f)