Print this page
4701 would like grep context options (-A, -B, -C)
*** 62,71 ****
--- 62,75 ----
#define BSIZE 512 /* Size of block for -b */
#define BUFSIZE 8192 /* Input buffer size */
#define MAX_DEPTH 1000 /* how deep to recurse */
+ #define AFTER 1 /* 'After' Context */
+ #define BEFORE 2 /* 'Before' Context */
+ #define CONTEXT (AFTER|BEFORE) /* Full Context */
+
#define M_CSETSIZE 256 /* singlebyte chars */
static int bmglen; /* length of BMG pattern */
static char *bmgpat; /* BMG pattern */
static int bmgtab[M_CSETSIZE]; /* BMG delta1 table */
*** 98,113 ****
static uchar_t xflag; /* Anchoring */
static uchar_t Eflag; /* Egrep or -E flag */
static uchar_t Fflag; /* Fgrep or -F flag */
static uchar_t Rflag; /* Like rflag, but follow symlinks */
static uchar_t outfn; /* Put out file name */
static char *cmdname;
static int use_wchar, use_bmg, mblocale;
! static size_t outbuflen, prntbuflen;
! static char *prntbuf;
static wchar_t *outline;
static void addfile(const char *fn);
static void addpattern(char *s);
static void fixpatterns(void);
--- 102,119 ----
static uchar_t xflag; /* Anchoring */
static uchar_t Eflag; /* Egrep or -E flag */
static uchar_t Fflag; /* Fgrep or -F flag */
static uchar_t Rflag; /* Like rflag, but follow symlinks */
static uchar_t outfn; /* Put out file name */
+ static uchar_t conflag; /* show context of matches */
static char *cmdname;
static int use_wchar, use_bmg, mblocale;
! static size_t outbuflen, prntbuflen, conbuflen;
! static unsigned long conalen, conblen, conmatches;
! static char *prntbuf, *conbuf;
static wchar_t *outline;
static void addfile(const char *fn);
static void addpattern(char *s);
static void fixpatterns(void);
*** 123,133 ****
* mainline for grep
*/
int
main(int argc, char **argv)
{
! char *ap;
int c;
int fflag = 0;
int i, n_pattern = 0, n_file = 0;
char **pattern_list = NULL;
char **file_list = NULL;
--- 129,139 ----
* mainline for grep
*/
int
main(int argc, char **argv)
{
! char *ap, *test;
int c;
int fflag = 0;
int i, n_pattern = 0, n_file = 0;
char **pattern_list = NULL;
char **file_list = NULL;
*** 160,170 ****
if (*ap == 'f' || *ap == 'F') {
fgrep++;
}
}
! while ((c = getopt(argc, argv, "vwchHilnrbse:f:qxEFIR")) != EOF) {
switch (c) {
case 'v': /* POSIX: negate matches */
nvflag = 0;
break;
--- 166,210 ----
if (*ap == 'f' || *ap == 'F') {
fgrep++;
}
}
! /* check for non-standard "-line-count" option */
! for (i = 1; i < argc; i++) {
! if (strcmp(argv[i], "--") == 0)
! break;
!
! if ((argv[i][0] == '-') && isdigit(argv[i][1])) {
! if (strlen(&argv[i][1]) !=
! strspn(&argv[i][1], "0123456789")) {
! (void) fprintf(stderr, gettext(
! "%s: Bad number flag\n"), argv[0]);
! usage();
! }
!
! conalen = conblen = strtoul(&argv[i][1], (char **)NULL,
! 10);
!
! /* isdigit() check prevents negative arguments */
! if (conalen >= ULONG_MAX) {
! (void) fprintf(stderr, gettext(
! "%s: Bad context argument\n"), argv[0]);
! }
!
! if (conalen)
! conflag = CONTEXT;
!
! while (i < argc) {
! argv[i] = argv[i + 1];
! i++;
! }
! argc--;
! }
! }
!
! while ((c = getopt(argc, argv, "vwchHilnrbse:f:qxEFIRA:B:C:")) != EOF) {
! unsigned long tval;
switch (c) {
case 'v': /* POSIX: negate matches */
nvflag = 0;
break;
*** 260,269 ****
--- 300,352 ----
case 'R': /* Solaris: like rflag, but follow symlinks */
Rflag++;
rflag++;
break;
+ case 'A': /* print N lines after each match */
+ conalen = strtoul(optarg, &test, 10);
+ /* *test will be non-null if optarg is negative */
+ if (*test != '\0' || conalen >= ULONG_MAX) {
+ (void) fprintf(stderr, gettext(
+ "%s: Bad context argument\n"), argv[0]);
+ exit(2);
+ }
+ if (conalen)
+ conflag |= AFTER;
+ else
+ conflag &= ~AFTER;
+ break;
+ case 'B': /* print N lines before each match */
+ conblen = strtoul(optarg, &test, 10);
+ /* *test will be non-null if optarg is negative */
+ if (*test != '\0' || conblen >= ULONG_MAX) {
+ (void) fprintf(stderr, gettext(
+ "%s: Bad context argument\n"), argv[0]);
+ exit(2);
+ }
+ if (conblen)
+ conflag |= BEFORE;
+ else
+ conflag &= ~BEFORE;
+ break;
+ case 'C': /* print N lines around each match */
+ tval = strtoul(optarg, &test, 10);
+ /* *test will be non-null if optarg is negative */
+ if (*test != '\0' || tval >= ULONG_MAX) {
+ (void) fprintf(stderr, gettext(
+ "%s: Bad context argument\n"), argv[0]);
+ exit(2);
+ }
+ if (tval) {
+ if (!(conflag & BEFORE))
+ conblen = tval;
+ if (!(conflag & AFTER))
+ conalen = tval;
+ conflag = CONTEXT;
+ }
+ break;
+
default:
usage();
}
}
/*
*** 540,549 ****
--- 623,634 ----
bufp = inbuf;
bufused = 0;
}
free(inbuf);
+ free(prntbuf);
+ free(conbuf);
(void) fclose(fp);
}
/*
* Add a string to the pattern list.
*** 716,731 ****
* - no ignoring case (!iflag)
* - no printing line numbers (!nflag)
* - no negating the output (nvflag)
* - only one pattern (npatterns == 1)
* - non zero length pattern (strlen(patterns->pattern) != 0)
*
* It's guaranteed patterns->pattern is still alive
* when Fflag && !mblocale.
*/
use_bmg = Fflag && !mblocale && !iflag && !nflag && nvflag &&
! (npatterns == 1) && (strlen(patterns->pattern) != 0);
}
/*
* Search a newline from the beginning of the string
*/
--- 801,817 ----
* - no ignoring case (!iflag)
* - no printing line numbers (!nflag)
* - no negating the output (nvflag)
* - only one pattern (npatterns == 1)
* - non zero length pattern (strlen(patterns->pattern) != 0)
+ * - no context required (!conflag)
*
* It's guaranteed patterns->pattern is still alive
* when Fflag && !mblocale.
*/
use_bmg = Fflag && !mblocale && !iflag && !nflag && nvflag &&
! (npatterns == 1) && (strlen(patterns->pattern) != 0) && !conflag;
}
/*
* Search a newline from the beginning of the string
*/
*** 802,817 ****
{
PATTERN *pp;
off_t data_len; /* length of the data chunk */
off_t line_len; /* length of the current line */
off_t line_offset; /* current line's offset from the beginning */
! long long lineno;
long long matches = 0; /* Number of matching lines */
int newlinep; /* 0 if the last line of file has no newline */
! char *ptr, *ptrend;
-
if (patterns == NULL)
return (0); /* no patterns to match -- just return */
pp = patterns;
--- 888,910 ----
{
PATTERN *pp;
off_t data_len; /* length of the data chunk */
off_t line_len; /* length of the current line */
off_t line_offset; /* current line's offset from the beginning */
! off_t blkoffset; /* line_offset but context-compatible */
! long long lineno, linenum;
long long matches = 0; /* Number of matching lines */
+ long long conacnt = 0, conbcnt = 0; /* context line count */
int newlinep; /* 0 if the last line of file has no newline */
! char *ptr, *ptrend, *prntptr, *prntptrend;
! char *nextptr = NULL, *nextend = NULL;
! char *conptr = NULL, *conptrend = NULL;
! char *matchptr = NULL;
! int conaprnt = 0, conbprnt = 0, lastmatch = 0;
! int nearmatch = conmatches ? 1 : 0; /* w/in N+1 of last match */
! size_t prntlen;
if (patterns == NULL)
return (0); /* no patterns to match -- just return */
pp = patterns;
*** 836,858 ****
cmdname);
exit(2);
}
}
! line_offset = 0;
lineno = 0;
newlinep = 1;
data_len = 0;
for (; ; ) {
long count;
off_t offset = 0;
if (data_len == 0) {
/*
* If no data in the buffer, reset ptr
*/
ptr = prntbuf;
}
if (ptr == prntbuf) {
/*
* The current data chunk starts from prntbuf.
* This means either the buffer has no data
--- 929,965 ----
cmdname);
exit(2);
}
}
! if (conflag && (conbuf == NULL)) {
! conbuflen = BUFSIZE;
! if ((conbuf = malloc(BUFSIZE+1)) == NULL) {
! (void) fprintf(stderr, gettext("%s: out of memory\n"),
! cmdname);
! exit(2);
! }
! }
!
! blkoffset = line_offset = 0;
lineno = 0;
+ linenum = 1;
newlinep = 1;
data_len = 0;
for (; ; ) {
long count;
off_t offset = 0;
+ int eof = 0, rv = REG_NOMATCH;
+ char separate;
if (data_len == 0) {
/*
* If no data in the buffer, reset ptr
*/
ptr = prntbuf;
+ if (conptr == NULL)
+ conptrend = conptr = conbuf;
}
if (ptr == prntbuf) {
/*
* The current data chunk starts from prntbuf.
* This means either the buffer has no data
*** 873,886 ****
}
}
return (0);
} else if (count == 0) {
/* no new data */
if (data_len == 0) {
/* end of file already reached */
! break;
}
/* last line of file has no newline */
ptrend = ptr + data_len;
newlinep = 0;
goto L_start_process;
}
--- 980,1003 ----
}
}
return (0);
} else if (count == 0) {
/* no new data */
+ eof = 1;
+
+ /* we never want to match EOF */
+ pp = (PATTERN *) !nvflag;
+
if (data_len == 0) {
/* end of file already reached */
! if (conflag) {
! *conptrend = '\n';
! goto L_next_line;
! } else {
! goto out;
}
+ }
/* last line of file has no newline */
ptrend = ptr + data_len;
newlinep = 0;
goto L_start_process;
}
*** 904,914 ****
*/
(void) memmove(prntbuf, ptr, data_len);
}
if (data_len == prntbuflen) {
/*
! * No enough room in the buffer
*/
prntbuflen += BUFSIZE;
prntbuf = realloc(prntbuf, prntbuflen + 1);
if (prntbuf == NULL) {
(void) fprintf(stderr,
--- 1021,1031 ----
*/
(void) memmove(prntbuf, ptr, data_len);
}
if (data_len == prntbuflen) {
/*
! * Not enough room in the buffer
*/
prntbuflen += BUFSIZE;
prntbuf = realloc(prntbuf, prntbuflen + 1);
if (prntbuf == NULL) {
(void) fprintf(stderr,
*** 1038,1055 ****
--- 1155,1174 ----
for (pp = patterns; pp; pp = pp->next) {
if (outline[0] == pp->wpattern[0] &&
wcscmp(outline,
pp->wpattern) == 0) {
/* matched */
+ rv = REG_OK;
break;
}
}
} else {
for (pp = patterns; pp; pp = pp->next) {
if (wcswcs(outline, pp->wpattern)
!= NULL) {
/* matched */
+ rv = REG_OK;
break;
}
}
}
} else if (Fflag) {
*** 1064,1089 ****
/* fgrep -x */
for (pp = patterns; pp; pp = pp->next) {
if (fptr[0] == pp->pattern[0] &&
strcmp(fptr, pp->pattern) == 0) {
/* matched */
break;
}
}
} else {
for (pp = patterns; pp; pp = pp->next) {
if (strstr(fptr, pp->pattern) != NULL) {
/* matched */
break;
}
}
}
} else {
/* grep or egrep */
for (pp = patterns; pp; pp = pp->next) {
- int rv;
-
rv = regexec(&pp->re, ptr, 0, NULL, 0);
if (rv == REG_OK) {
/* matched */
break;
}
--- 1183,1208 ----
/* fgrep -x */
for (pp = patterns; pp; pp = pp->next) {
if (fptr[0] == pp->pattern[0] &&
strcmp(fptr, pp->pattern) == 0) {
/* matched */
+ rv = REG_OK;
break;
}
}
} else {
for (pp = patterns; pp; pp = pp->next) {
if (strstr(fptr, pp->pattern) != NULL) {
/* matched */
+ rv = REG_OK;
break;
}
}
}
} else {
/* grep or egrep */
for (pp = patterns; pp; pp = pp->next) {
rv = regexec(&pp->re, ptr, 0, NULL, 0);
if (rv == REG_OK) {
/* matched */
break;
}
*** 1105,1122 ****
--- 1224,1406 ----
exit(2);
}
}
}
+ /*
+ * Context is set up as follows:
+ * For a 'Before' context, we maintain a set of pointers
+ * containing 'N' lines of context. If the current number of
+ * lines contained is greater than N, and N isn't a match, the
+ * start pointer is moved forward to the next newline.
+ *
+ * If we ever find a match, we print out immediately.
+ * 'nearmatch' tells us if we're within N+1 lines of the last
+ * match ; if we are, and we find another match, we don't
+ * separate the matches. 'nearmatch' becomes false when
+ * a line gets rotated out of the context.
+ *
+ * For an 'After' context, we simply wait until we've found a
+ * match, then create a context N+1 lines big. If we don't find
+ * a match within the context, we print out the current context.
+ * Otherwise, we save a reference to the new matching line,
+ * print out the other context, and reset our context pointers
+ * to the new matching line.
+ *
+ * 'nearmatch' becomes false when we find a non-matching line
+ * that isn't a part of any context.
+ *
+ * A full-context is implemented as a combination of the
+ * 'Before' and 'After' context logic. Before we find a match,
+ * we follow the Before logic. When we find a match, we
+ * follow the After logic. 'nearmatch' is handled by the Before
+ * logic.
+ */
+
+ if (!conflag)
+ goto L_next_line;
+
+ if (line_len + (conptrend - conbuf) > conbuflen) {
+ char *oldconbuf = conbuf;
+ char *oldconptr = conptr;
+ long tmp = matchptr - conptr;
+
+ conbuflen += BUFSIZE;
+ conbuf = realloc(conbuf, conbuflen + 1);
+ if (conbuf == NULL) {
+ (void) fprintf(stderr,
+ gettext("%s: out of memory\n"),
+ cmdname);
+ exit(2);
+ }
+
+ conptr = conbuf + (conptr - oldconbuf);
+ conptrend = conptr + (conptrend - oldconptr);
+ if (matchptr)
+ matchptr = conptr + tmp;
+ }
+ (void) memcpy((conptrend > conptr) ?
+ conptrend + 1 : conptrend, ptr, line_len);
+ conptrend += line_len + (conptrend > conptr);
+ *conptrend = '\n';
+
+ if (!nvflag == rv) {
+ /* matched */
+ if (lastmatch) {
+ if (conflag & AFTER) {
+ conaprnt = 1;
+ nextend = conptrend;
+ conptrend = conptr + lastmatch;
+ nextptr = conptrend + 1;
+ *nextend = '\n';
+ }
+ } else {
+ if (conflag == AFTER) {
+ conptr = conptrend - (line_len);
+ linenum = lineno;
+ blkoffset = line_offset;
+ }
+ blkoffset = line_offset -
+ (conptrend - conptr - line_len);
+ }
+
+ if (conflag == BEFORE)
+ conbprnt = 1;
+
+ lastmatch = conptrend - conptr;
+ goto L_next_line;
+ }
+
+ if (!lastmatch) {
+ if (conflag & BEFORE) {
+ if (conbcnt >= conblen) {
+ char *tmp = conptr;
+ conptr = find_nl(conptr,
+ conptrend - conptr) + 1;
+ if (bflag)
+ blkoffset += conptr - tmp;
+ linenum++;
+ nearmatch = 1;
+ } else {
+ conbcnt++;
+ }
+ }
+ if (conflag == AFTER)
+ nearmatch = 1;
+ } else {
+ if (++conacnt >= conalen && !conaprnt && conalen)
+ conaprnt = 1;
+ else
+ lastmatch = conptrend - conptr;
+ }
+
L_next_line:
/*
* Here, if pp points to non-NULL, something has been matched
* to the pattern.
*/
if (nvflag == (pp != NULL)) {
matches++;
+ if (!nextend)
+ matchptr = conflag ? conptrend : ptrend;
+ }
+
/*
+ * Set up some print context so that we can treat
+ * single-line matches as a zero-N context.
+ * Apply CLI flags to each line of the context.
+ *
+ * For context, we only print if we both have a match and are
+ * either at the end of the data stream, or we've previously
+ * declared that we want to print for a particular context.
+ */
+ if (lastmatch && (eof || conaprnt || conbprnt)) {
+
+ /*
+ * We'd normally do this earlier, but we had to
+ * escape early because we reached the end of the data.
+ */
+ if (eof && nextptr)
+ conptrend = nextend;
+
+ prntlen = conptrend - conptr + 1;
+ prntptrend = prntptr = conptr;
+ if (conmatches++ && nearmatch && !cflag)
+ (void) fwrite("--\n", 1, 3, stdout);
+ } else if (!conflag && nvflag == (pp != NULL)) {
+ *ptrend = '\n';
+ prntlen = line_len + 1;
+ prntptrend = prntptr = ptr;
+ linenum = lineno;
+ blkoffset = line_offset;
+ } else if (eof) {
+ /* No match and no more data */
+ goto out;
+ } else {
+ /* No match, or we're not done building context */
+ goto L_skip_line;
+ }
+
+ while ((prntptrend = find_nl(prntptrend+1, prntlen)) != NULL) {
+
+ /*
+ * GNU grep uses '-' for context lines and ':' for
+ * matching lines, so replicate that here.
+ */
+ if (prntptrend == matchptr) {
+ if (eof && nextptr) {
+ matchptr = nextend;
+ nextptr = NULL;
+ } else {
+ matchptr = NULL;
+ }
+ separate = ':';
+ } else {
+ separate = '-';
+ }
+
+ /*
* Handle q, l, and c flags.
*/
if (qflag) {
/* no need to continue */
/*
*** 1128,1166 ****
(void) lseek(fd, -pos, SEEK_CUR);
exit(0);
}
if (lflag) {
(void) printf("%s\n", fn);
! break;
}
if (!cflag) {
if (Hflag || outfn) {
! (void) printf("%s:", fn);
}
if (bflag) {
! (void) printf("%lld:", (offset_t)
! (line_offset / BSIZE));
}
if (nflag) {
! (void) printf("%lld:", lineno);
}
! *ptrend = '\n';
! (void) fwrite(ptr, 1, line_len + 1, stdout);
}
if (ferror(stdout)) {
return (0);
}
}
L_skip_line:
if (!newlinep)
break;
data_len -= line_len + 1;
line_offset += line_len + 1;
ptr = ptrend + 1;
}
if (cflag) {
if (Hflag || outfn) {
(void) printf("%s:", fn);
}
if (!qflag) {
--- 1412,1485 ----
(void) lseek(fd, -pos, SEEK_CUR);
exit(0);
}
if (lflag) {
(void) printf("%s\n", fn);
! goto out;
}
if (!cflag) {
if (Hflag || outfn) {
! (void) printf("%s%c", fn, separate);
}
if (bflag) {
! (void) printf("%lld%c", (offset_t)
! (blkoffset / BSIZE), separate);
}
if (nflag) {
! (void) printf("%lld%c", linenum,
! separate);
}
! (void) fwrite(prntptr, 1,
! prntptrend - prntptr + 1, stdout);
}
if (ferror(stdout)) {
return (0);
}
+ linenum++;
+ prntlen -= prntptrend - prntptr + 1;
+ blkoffset += prntptrend - prntptr + 1;
+ prntptr = prntptrend + 1;
}
+
+ if (eof)
+ goto out;
+
+ /*
+ * Update context buffer and variables post-print
+ */
+ if (conflag) {
+ conptr = conbuf;
+ conaprnt = conbprnt = 0;
+ nearmatch = 0;
+ conacnt = conbcnt = 0;
+
+ if (nextptr) {
+ (void) memmove(conbuf, nextptr,
+ nextend - nextptr + 1);
+ blkoffset += nextptr - conptrend - 1;
+ conptrend = conptr + (nextend - nextptr);
+ matchptr = conptrend;
+ linenum = lineno;
+ lastmatch = conptrend - conptr;
+ } else {
+ conptrend = conptr;
+ conacnt = 0;
+ lastmatch = 0;
+ }
+ nextptr = nextend = NULL;
+ }
+
L_skip_line:
if (!newlinep)
break;
data_len -= line_len + 1;
line_offset += line_len + 1;
ptr = ptrend + 1;
}
+ out:
if (cflag) {
if (Hflag || outfn) {
(void) printf("%s:", fn);
}
if (!qflag) {
*** 1177,1225 ****
usage(void)
{
if (egrep || fgrep) {
(void) fprintf(stderr, gettext("Usage:\t%s"), cmdname);
(void) fprintf(stderr,
! gettext(" [-c|-l|-q] [-r|-R] [-bhHinsvx] "
! "pattern_list [file ...]\n"));
(void) fprintf(stderr, "\t%s", cmdname);
(void) fprintf(stderr,
! gettext(" [-c|-l|-q] [-r|-R] [-bhHinsvx] "
! "[-e pattern_list]... "
"[-f pattern_file]... [file...]\n"));
} else {
(void) fprintf(stderr, gettext("Usage:\t%s"), cmdname);
(void) fprintf(stderr,
! gettext(" [-c|-l|-q] [-r|-R] [-bhHinsvwx] "
! "pattern_list [file ...]\n"));
(void) fprintf(stderr, "\t%s", cmdname);
(void) fprintf(stderr,
! gettext(" [-c|-l|-q] [-r|-R] [-bhHinsvwx] "
! "[-e pattern_list]... "
"[-f pattern_file]... [file...]\n"));
(void) fprintf(stderr, "\t%s", cmdname);
(void) fprintf(stderr,
! gettext(" -E [-c|-l|-q] [-r|-R] [-bhHinsvx] "
! "pattern_list [file ...]\n"));
(void) fprintf(stderr, "\t%s", cmdname);
(void) fprintf(stderr,
! gettext(" -E [-c|-l|-q] [-r|-R] [-bhHinsvx] "
! "[-e pattern_list]... "
"[-f pattern_file]... [file...]\n"));
(void) fprintf(stderr, "\t%s", cmdname);
(void) fprintf(stderr,
! gettext(" -F [-c|-l|-q] [-r|-R] [-bhHinsvx] "
! "pattern_list [file ...]\n"));
(void) fprintf(stderr, "\t%s", cmdname);
(void) fprintf(stderr,
! gettext(" -F [-c|-l|-q] [-bhHinsvx] [-e pattern_list]... "
"[-f pattern_file]... [file...]\n"));
}
exit(2);
/* NOTREACHED */
}
--- 1496,1545 ----
usage(void)
{
if (egrep || fgrep) {
(void) fprintf(stderr, gettext("Usage:\t%s"), cmdname);
(void) fprintf(stderr,
! gettext(" [-c|-l|-q] [-r|-R] [-A #|-B #|-C #|-#] "
! "[-bhHinsvx] pattern_list [file ...]\n"));
(void) fprintf(stderr, "\t%s", cmdname);
(void) fprintf(stderr,
! gettext(" [-c|-l|-q] [-r|-R] [-A #|-B #|-C #|-#] "
! "[-bhHinsvx] [-e pattern_list]... "
"[-f pattern_file]... [file...]\n"));
} else {
(void) fprintf(stderr, gettext("Usage:\t%s"), cmdname);
(void) fprintf(stderr,
! gettext(" [-c|-l|-q] [-r|-R] [-A #|-B #|-C #|-#] "
! "[-bhHinsvx] pattern_list [file ...]\n"));
(void) fprintf(stderr, "\t%s", cmdname);
(void) fprintf(stderr,
! gettext(" [-c|-l|-q] [-r|-R] [-A #|-B #|-C #|-#] "
! "[-bhHinsvx] [-e pattern_list]... "
"[-f pattern_file]... [file...]\n"));
(void) fprintf(stderr, "\t%s", cmdname);
(void) fprintf(stderr,
! gettext(" -E [-c|-l|-q] [-r|-R] [-A #|-B #|-C #|-#] "
! "[-bhHinsvx] pattern_list [file ...]\n"));
(void) fprintf(stderr, "\t%s", cmdname);
(void) fprintf(stderr,
! gettext(" -E [-c|-l|-q] [-r|-R] [-A #|-B #|-C #|-#] "
! "[-bhHinsvx] [-e pattern_list]... "
"[-f pattern_file]... [file...]\n"));
(void) fprintf(stderr, "\t%s", cmdname);
(void) fprintf(stderr,
! gettext(" -F [-c|-l|-q] [-r|-R] [-A #|-B #|-C #|-#] "
! "[-bhHinsvx] pattern_list [file ...]\n"));
(void) fprintf(stderr, "\t%s", cmdname);
(void) fprintf(stderr,
! gettext(" -F [-c|-l|-q] [-A #|-B #|-C #|-#] "
! "[-bhHinsvx] [-e pattern_list]... "
"[-f pattern_file]... [file...]\n"));
}
exit(2);
/* NOTREACHED */
}