Turns out we have an -o option, but it doesn't do what most people 
expect.  That's a problem with nonstandard options, and we were probably 
lax in asserting that we really wanted these options when importing.  
oops.

Anyway, the GNU -o option seems a lot more useful than ours.  They call 
this option -H, and have no equivalent to our -H (which also seems pretty 
useless).

This diff switches over to only printing the part of the line that 
matched, not the whole line, possibly repeating the pattern if the line 
matches twice (that's the tricky part with our code, as is).  The tangly 
gotos can be cleaned up, but I figured I should just toss this out there.

I think it works, but there are so many combinations of options I didn't 
test.

Index: grep.c
===================================================================
RCS file: /home/tedu/cvs/src/usr.bin/grep/grep.c,v
retrieving revision 1.39
diff -u -u -r1.39 grep.c
--- grep.c      2 Sep 2007 15:19:32 -0000       1.39
+++ grep.c      24 Mar 2010 22:56:56 -0000
@@ -76,7 +76,7 @@
 int     iflag;         /* -i: ignore case */
 int     lflag;         /* -l: only show names of files with matches */
 int     nflag;         /* -n: show line numbers in front of matching lines */
-int     oflag;         /* -o: always print file name */
+int     oflag;         /* -o: print each match */
 int     qflag;         /* -q: quiet mode (don't output anything) */
 int     sflag;         /* -s: silent mode (ignore errors) */
 int     vflag;         /* -v: only show non-matching lines */
@@ -336,7 +336,6 @@
                case 'R':
                case 'r':
                        Rflag++;
-                       oflag++;
                        break;
                case 'U':
                        binbehave = BIN_FILE_BIN;
@@ -370,7 +369,6 @@
                        needpattern = 0;
                        break;
                case 'h':
-                       oflag = 0;
                        hflag = 1;
                        break;
                case 'i':
@@ -386,7 +384,6 @@
                        nflag = 1;
                        break;
                case 'o':
-                       hflag = 0;
                        oflag = 1;
                        break;
                case 'q':
@@ -472,7 +469,7 @@
        if (lbflag)
                setlinebuf(stdout);
 
-       if ((argc == 0 || argc == 1) && !oflag)
+       if ((argc == 0 || argc == 1))
                hflag = 1;
 
        if (argc == 0)
Index: grep.h
===================================================================
RCS file: /home/tedu/cvs/src/usr.bin/grep/grep.h,v
retrieving revision 1.14
diff -u -u -r1.14 grep.h
--- grep.h      2 Sep 2007 15:19:32 -0000       1.14
+++ grep.h      24 Mar 2010 22:59:35 -0000
@@ -65,6 +65,7 @@
 /* Command line flags */
 extern int      Aflag, Bflag, Eflag, Fflag, Gflag, Hflag, Lflag, Pflag,
                 Sflag, Rflag, Zflag,
+                oflag,
                 bflag, cflag, hflag, iflag, lflag, nflag, qflag, sflag,
                 vflag, wflag, xflag;
 extern int      binbehave;
@@ -84,7 +85,7 @@
 void           *grep_malloc(size_t size);
 void           *grep_calloc(size_t nmemb, size_t size);
 void           *grep_realloc(void *ptr, size_t size);
-void            printline(str_t *line, int sep);
+void            printline(str_t *line, int sep, regmatch_t *pmatch);
 int             fastcomp(fastgrep_t *, const char *);
 void            fgrepcomp(fastgrep_t *, const char *);
 
Index: queue.c
===================================================================
RCS file: /home/tedu/cvs/src/usr.bin/grep/queue.c,v
retrieving revision 1.5
diff -u -u -r1.5 queue.c
--- queue.c     9 Feb 2006 09:54:47 -0000       1.5
+++ queue.c     24 Mar 2010 23:00:25 -0000
@@ -107,7 +107,7 @@
        queue_t *item;
 
        while ((item = dequeue()) != NULL) {
-               printline(&item->data, '-');
+               printline(&item->data, '-', NULL);
                free_item(item);
        }
 }
Index: util.c
===================================================================
RCS file: /home/tedu/cvs/src/usr.bin/grep/util.c,v
retrieving revision 1.36
diff -u -u -r1.36 util.c
--- util.c      2 Oct 2007 17:59:18 -0000       1.36
+++ util.c      24 Mar 2010 23:06:02 -0000
@@ -48,8 +48,8 @@
 
 static int     linesqueued;
 static int     procline(str_t *l, int);
-static int     grep_search(fastgrep_t *, unsigned char *, size_t, regmatch_t 
*pmatch);
-static int     grep_cmp(const unsigned char *, const unsigned char *, size_t);
+static int     grep_search(fastgrep_t *, char *, size_t, regmatch_t *pmatch);
+static int     grep_cmp(const char *, const char *, size_t);
 static void    grep_revstr(unsigned char *, int);
 
 int
@@ -174,19 +174,25 @@
 {
        regmatch_t      pmatch;
        int             c, i, r;
+       int             offset;
 
+       c = 0;
+       i = 0;
        if (matchall) {
-               c = !vflag;
                goto print;
        }
 
-       for (c = i = 0; i < patterns; i++) {
+       for (i = 0; i < patterns; i++) {
+               offset = 0;
+redo:
                if (fg_pattern[i].pattern) {
-                       r = grep_search(&fg_pattern[i], (unsigned char *)l->dat,
-                           l->len, &pmatch);
+                       r = grep_search(&fg_pattern[i], l->dat + offset,
+                           l->len - offset, &pmatch);
+                       pmatch.rm_so += offset;
+                       pmatch.rm_eo += offset;
                } else {
-                       pmatch.rm_so = 0;
-                       pmatch.rm_eo = l->len;
+                       pmatch.rm_so = offset;
+                       pmatch.rm_eo = l->len - offset;
                        r = regexec(&r_pattern[i], l->dat, 1, &pmatch, eflags);
                }
                if (r == 0 && xflag) {
@@ -194,14 +200,18 @@
                                r = REG_NOMATCH;
                }
                if (r == 0) {
-                       c++;
+                       c = 1;
+                       if (oflag)
+                               goto print;
                        break;
                }
        }
+       if (oflag)
+               return c;
+print:
        if (vflag)
                c = !c;
 
-print:
        if (c && binbehave == BIN_FILE_BIN && nottext)
                return c; /* Binary file */
 
@@ -215,12 +225,17 @@
                        if (Bflag > 0)
                                printqueue();
                        linesqueued = 0;
-                       printline(l, ':');
+                       printline(l, ':', oflag ? &pmatch : NULL);
                } else {
-                       printline(l, '-');
+                       printline(l, '-', oflag ? &pmatch : NULL);
                        tail--;
                }
        }
+       if (oflag && !matchall) {
+
+               offset = pmatch.rm_eo;
+               goto redo;
+       }
        return c;
 }
 
@@ -423,7 +438,7 @@
          e > s && isword(d[s]) && isword(d[e-1]))
 
 static int
-grep_search(fastgrep_t *fg, unsigned char *data, size_t dataLen, regmatch_t 
*pmatch)
+grep_search(fastgrep_t *fg, char *data, size_t dataLen, regmatch_t *pmatch)
 {
        int j;
        int rtrnVal = REG_NOMATCH;
@@ -472,7 +487,7 @@
                        /* Shift if within bounds, otherwise, we are done. */
                        if (j == fg->patternLen)
                                break;
-                       j -= fg->qsBc[data[j - fg->patternLen - 1]];
+                       j -= fg->qsBc[(unsigned char)data[j - fg->patternLen - 
1]];
                } while (j >= fg->patternLen);
        } else {
                /* Quick Search algorithm. */
@@ -493,7 +508,7 @@
                        if (j + fg->patternLen == dataLen)
                                break;
                        else
-                               j += fg->qsBc[data[j + fg->patternLen]];
+                               j += fg->qsBc[(unsigned char)data[j + 
fg->patternLen]];
                } while (j <= (dataLen - fg->patternLen));
        }
 
@@ -534,7 +549,7 @@
  *             -1 on success
  */
 static int
-grep_cmp(const unsigned char *pattern, const unsigned char *data, size_t len)
+grep_cmp(const char *pattern, const char *data, size_t len)
 {
        int i;
 
@@ -562,7 +577,7 @@
 }
 
 void
-printline(str_t *line, int sep)
+printline(str_t *line, int sep, regmatch_t *pmatch)
 {
        int n;
 
@@ -585,6 +600,10 @@
        }
        if (n)
                putchar(sep);
-       fwrite(line->dat, line->len, 1, stdout);
+       if (pmatch)
+               fwrite(line->dat + pmatch->rm_so,
+                   pmatch->rm_eo - pmatch->rm_so, 1, stdout);
+       else
+               fwrite(line->dat, line->len, 1, stdout);
        putchar('\n');
 }

Reply via email to