summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/grep/grep.110
-rw-r--r--usr.bin/grep/grep.c14
-rw-r--r--usr.bin/grep/grep.h6
-rw-r--r--usr.bin/grep/queue.c4
-rw-r--r--usr.bin/grep/util.c56
5 files changed, 57 insertions, 33 deletions
diff --git a/usr.bin/grep/grep.1 b/usr.bin/grep/grep.1
index a818c95c272..96569a0ee97 100644
--- a/usr.bin/grep/grep.1
+++ b/usr.bin/grep/grep.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: grep.1,v 1.40 2011/03/04 03:11:22 tedu Exp $
+.\" $OpenBSD: grep.1,v 1.41 2011/07/08 01:20:24 tedu Exp $
.\" Copyright (c) 1980, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
@@ -28,7 +28,7 @@
.\"
.\" @(#)grep.1 8.3 (Berkeley) 4/18/94
.\"
-.Dd $Mdocdate: March 4 2011 $
+.Dd $Mdocdate: July 8 2011 $
.Dt GREP 1
.Os
.Sh NAME
@@ -38,7 +38,7 @@
.Sh SYNOPSIS
.Nm grep
.Bk -words
-.Op Fl abcEFGHhIiLlnqRsUVvwxZ
+.Op Fl abcEFGHhIiLlnoqRsUVvwxZ
.Op Fl A Ar num
.Op Fl B Ar num
.Op Fl C Ns Op Ar num
@@ -228,6 +228,8 @@ or
.Fl q
is
specified.
+.It Fl o
+Print each match, but only the match, not the entire line.
.It Fl q
Quiet mode:
suppress normal output.
@@ -353,7 +355,7 @@ utility is compliant with the
specification.
.Pp
The flags
-.Op Fl AaBbCGHhILRUVwZ
+.Op Fl AaBbCGHhILoRUVwZ
are extensions to that specification, and the behaviour of the
.Fl f
flag when used with an empty pattern file is left undefined.
diff --git a/usr.bin/grep/grep.c b/usr.bin/grep/grep.c
index e477cf97e3a..eb467d7e352 100644
--- a/usr.bin/grep/grep.c
+++ b/usr.bin/grep/grep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: grep.c,v 1.43 2011/03/04 03:11:23 tedu Exp $ */
+/* $OpenBSD: grep.c,v 1.44 2011/07/08 01:20:24 tedu Exp $ */
/*-
* Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
@@ -74,6 +74,7 @@ int hflag; /* -h: don't print filename headers */
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: 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 */
@@ -107,9 +108,9 @@ usage(void)
{
fprintf(stderr,
#ifdef NOZ
- "usage: %s [-abcEFGHhIiLlnqRsUVvwx] [-A num] [-B num] [-C[num]]\n"
+ "usage: %s [-abcEFGHhIiLlnoqRsUVvwx] [-A num] [-B num] [-C[num]]\n"
#else
- "usage: %s [-abcEFGHhIiLlnqRsUVvwxZ] [-A num] [-B num] [-C[num]]\n"
+ "usage: %s [-abcEFGHhIiLlnoqRsUVvwxZ] [-A num] [-B num] [-C[num]]\n"
#endif
"\t[-e pattern] [-f file] [--binary-files=value] [--context[=num]]\n"
"\t[--line-buffered] [pattern] [file ...]\n", __progname);
@@ -117,9 +118,9 @@ usage(void)
}
#ifdef NOZ
-static char *optstr = "0123456789A:B:CEFGHILRUVabce:f:hilnqrsuvwxy";
+static char *optstr = "0123456789A:B:CEFGHILRUVabce:f:hilnoqrsuvwxy";
#else
-static char *optstr = "0123456789A:B:CEFGHILRUVZabce:f:hilnqrsuvwxy";
+static char *optstr = "0123456789A:B:CEFGHILRUVZabce:f:hilnoqrsuvwxy";
#endif
struct option long_options[] =
@@ -383,6 +384,9 @@ main(int argc, char *argv[])
case 'n':
nflag = 1;
break;
+ case 'o':
+ oflag = 1;
+ break;
case 'q':
qflag = 1;
break;
diff --git a/usr.bin/grep/grep.h b/usr.bin/grep/grep.h
index 7d584d40727..3cb3a6b9f60 100644
--- a/usr.bin/grep/grep.h
+++ b/usr.bin/grep/grep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: grep.h,v 1.16 2011/03/04 03:11:23 tedu Exp $ */
+/* $OpenBSD: grep.h,v 1.17 2011/07/08 01:20:24 tedu Exp $ */
/*-
* Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
@@ -65,7 +65,7 @@ extern int cflags, eflags;
/* Command line flags */
extern int Aflag, Bflag, Eflag, Fflag, Gflag, Hflag, Lflag,
Rflag, Zflag,
- bflag, cflag, hflag, iflag, lflag, nflag, qflag, sflag,
+ bflag, cflag, hflag, iflag, lflag, nflag, oflag, qflag, sflag,
vflag, wflag, xflag;
extern int binbehave;
@@ -84,7 +84,7 @@ int grep_tree(char **argv);
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 *);
diff --git a/usr.bin/grep/queue.c b/usr.bin/grep/queue.c
index 0ca6f76a8c5..96de3b2736a 100644
--- a/usr.bin/grep/queue.c
+++ b/usr.bin/grep/queue.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: queue.c,v 1.5 2006/02/09 09:54:47 otto Exp $ */
+/* $OpenBSD: queue.c,v 1.6 2011/07/08 01:20:24 tedu Exp $ */
/*-
* Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
@@ -107,7 +107,7 @@ printqueue(void)
queue_t *item;
while ((item = dequeue()) != NULL) {
- printline(&item->data, '-');
+ printline(&item->data, '-', NULL);
free_item(item);
}
}
diff --git a/usr.bin/grep/util.c b/usr.bin/grep/util.c
index 77755fb70ca..6754cfc02ed 100644
--- a/usr.bin/grep/util.c
+++ b/usr.bin/grep/util.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: util.c,v 1.39 2010/07/02 22:18:03 tedu Exp $ */
+/* $OpenBSD: util.c,v 1.40 2011/07/08 01:20:24 tedu Exp $ */
/*-
* Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
@@ -48,9 +48,9 @@
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_search(fastgrep_t *, char *, size_t, regmatch_t *pmatch);
#ifndef SMALL
-static int grep_cmp(const unsigned char *, const unsigned char *, size_t);
+static int grep_cmp(const char *, const char *, size_t);
static void grep_revstr(unsigned char *, int);
#endif
@@ -169,19 +169,25 @@ procline(str_t *l, int nottext)
{
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) {
@@ -189,14 +195,18 @@ procline(str_t *l, int nottext)
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 */
@@ -210,12 +220,16 @@ print:
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;
}
@@ -424,7 +438,7 @@ fastcomp(fastgrep_t *fg, const char *pattern)
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)
{
#ifdef SMALL
return 0;
@@ -476,7 +490,7 @@ grep_search(fastgrep_t *fg, unsigned char *data, size_t dataLen, regmatch_t *pma
/* 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. */
@@ -497,7 +511,7 @@ grep_search(fastgrep_t *fg, unsigned char *data, size_t dataLen, regmatch_t *pma
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));
}
@@ -540,7 +554,7 @@ grep_realloc(void *ptr, size_t size)
* -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;
@@ -569,7 +583,7 @@ grep_revstr(unsigned char *str, int len)
#endif
void
-printline(str_t *line, int sep)
+printline(str_t *line, int sep, regmatch_t *pmatch)
{
int n;
@@ -592,6 +606,10 @@ printline(str_t *line, int sep)
}
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');
}