summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorAlexander Pyhalov <apyhalov@gmail.com>2017-12-19 08:48:38 +0300
committerDan McDonald <danmcd@joyent.com>2018-01-09 14:12:32 -0500
commitd2d52addd50254d1b7c318c6784172d8d7de20c6 (patch)
tree0c378517379e7cd6076434359ca24fc303fbb66b /usr/src
parentda61ddb06d5ac64f86b2dfb126769267c1ebcd67 (diff)
downloadillumos-joyent-d2d52addd50254d1b7c318c6784172d8d7de20c6.tar.gz
8858 /usr/bin/grep doesn't support -E option
4580 /usr/bin/grep can't handle multibyte characters 8929 8868 tests are not delivered with system/test/utiltest 8860 Example in grep(1) is incorrect Reviewed by: Peter Tribble <peter.tribble@gmail.com> Reviewed by: Toomas Soome <tsoome@me.com> Reviewed by: Yuri Pankov <yuripv@gmx.com> Approved by: Robert Mustacchi <rm@joyent.com>
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/Makefile.lint2
-rw-r--r--usr/src/cmd/Makefile5
-rw-r--r--usr/src/cmd/diff3/diff3.sh6
-rw-r--r--usr/src/cmd/egrep/Makefile55
-rw-r--r--usr/src/cmd/egrep/egrep.y1318
-rw-r--r--usr/src/cmd/fgrep/Makefile44
-rw-r--r--usr/src/cmd/fgrep/fgrep.c705
-rw-r--r--usr/src/cmd/grep/Makefile46
-rw-r--r--usr/src/cmd/grep/grep.c1768
-rw-r--r--usr/src/cmd/grep/grep.xcl28
-rw-r--r--usr/src/cmd/grep_xpg4/Makefile72
-rw-r--r--usr/src/cmd/grep_xpg4/grep.c1640
-rw-r--r--usr/src/cmd/ldap/ns_ldap/idsconfig.sh2
-rw-r--r--usr/src/cmd/sgs/test/ld/x64/tls/ie/x64-ie-test.sh2
-rw-r--r--usr/src/cmd/tsol/misc/txzonemgr.sh2
-rw-r--r--usr/src/lib/libsaveargs/tests/functional/test.sh2
-rw-r--r--usr/src/lib/libshell/common/tests/sun_solaris_cr_6887363_shell_sometimes_mishandles_return_value_of_its_child_process.sh2
-rw-r--r--usr/src/lib/libshell/misc/shell_styleguide.docbook6
-rw-r--r--usr/src/man/man1/egrep.1142
-rw-r--r--usr/src/man/man1/fgrep.188
-rw-r--r--usr/src/man/man1/grep.1302
-rw-r--r--usr/src/man/man1/locale.112
-rw-r--r--usr/src/pkg/manifests/SUNWcs.mf4
-rw-r--r--usr/src/pkg/manifests/system-test-utiltest.mf5
-rw-r--r--usr/src/pkg/manifests/system-xopen-xcu4.mf6
-rw-r--r--usr/src/test/util-tests/tests/grep_xpg4/files/Makefile7
-rw-r--r--usr/src/test/util-tests/tests/grep_xpg4/grep_test.ksh2
-rw-r--r--usr/src/test/zfs-tests/tests/functional/acl/acl_common.kshlib2
-rw-r--r--usr/src/tools/scripts/elfcmp.sh4
29 files changed, 1690 insertions, 4589 deletions
diff --git a/usr/src/Makefile.lint b/usr/src/Makefile.lint
index cb1805e5c4..18d2f2398a 100644
--- a/usr/src/Makefile.lint
+++ b/usr/src/Makefile.lint
@@ -128,7 +128,6 @@ COMMON_SUBDIRS = \
cmd/fdetach \
cmd/fdformat \
cmd/fdisk \
- cmd/fgrep \
cmd/file \
cmd/find \
cmd/fmthard \
@@ -156,7 +155,6 @@ COMMON_SUBDIRS = \
cmd/getopt \
cmd/gettext \
cmd/grep \
- cmd/grep_xpg4 \
cmd/groups \
cmd/halt \
cmd/head \
diff --git a/usr/src/cmd/Makefile b/usr/src/cmd/Makefile
index 0903d63b7b..7249f43cb1 100644
--- a/usr/src/cmd/Makefile
+++ b/usr/src/cmd/Makefile
@@ -141,7 +141,6 @@ COMMON_SUBDIRS= \
echo \
ed \
eeprom \
- egrep \
eject \
emul64ioctl \
enhance \
@@ -159,7 +158,6 @@ COMMON_SUBDIRS= \
fdisk \
ficl \
filesync \
- fgrep \
file \
find \
flowadm \
@@ -187,7 +185,6 @@ COMMON_SUBDIRS= \
gettext \
gettxt \
grep \
- grep_xpg4 \
groups \
growfs \
grpck \
@@ -574,7 +571,6 @@ MSGSUBDIRS= \
expand \
expr \
fcinfo \
- fgrep \
file \
filesync \
find \
@@ -591,7 +587,6 @@ MSGSUBDIRS= \
gettext \
gettxt \
grep \
- grep_xpg4 \
grpck \
gss \
halt \
diff --git a/usr/src/cmd/diff3/diff3.sh b/usr/src/cmd/diff3/diff3.sh
index fe115c517e..f29059a587 100644
--- a/usr/src/cmd/diff3/diff3.sh
+++ b/usr/src/cmd/diff3/diff3.sh
@@ -27,8 +27,6 @@
# Copyright (c) 1999, 2001 by Sun Microsystems, Inc.
# All rights reserved.
-#ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.4 */
-
usage="usage: diff3 file1 file2 file3"
# mktmpdir - Create a private (mode 0700) temporary directory inside of /tmp
@@ -80,7 +78,7 @@ fi
STATUS=$?
if [ $STATUS -eq 1 ]
then
- /usr/xpg4/bin/grep -q "^[<>]" $tmpdir/d3a$$
+ /usr/bin/grep -q "^[<>]" $tmpdir/d3a$$
RET=$?
if [ $RET -eq 1 ]
then
@@ -105,7 +103,7 @@ fi
STATUS=$?
if [ $STATUS -eq 1 ]
then
- /usr/xpg4/bin/grep -q "^[<>]" $tmpdir/d3b$$
+ /usr/bin/grep -q "^[<>]" $tmpdir/d3b$$
RET=$?
if [ $RET -eq 1 ]
then
diff --git a/usr/src/cmd/egrep/Makefile b/usr/src/cmd/egrep/Makefile
deleted file mode 100644
index fde0fabcbe..0000000000
--- a/usr/src/cmd/egrep/Makefile
+++ /dev/null
@@ -1,55 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-PROG= egrep
-
-include ../Makefile.cmd
-
-CPPFLAGS += -D_FILE_OFFSET_BITS=64
-CERRWARN += -_gcc=-Wno-parentheses
-CERRWARN += -_gcc=-Wno-implicit-function-declaration
-CERRWARN += -_gcc=-Wno-unused-variable
-CERRWARN += -_gcc=-Wno-unused-label
-
-.KEEP_STATE:
-
-all: $(PROG)
-
-install: all $(ROOTPROG)
-
-$(PROG).c: $(PROG).y
- $(YACC.y) $<
- $(SED) '-e 1 a\
- \#define yyerror_gettext(x) yyerror(gettext(x))' y.tab.c > y1.c
- $(SED) '-e /syntax/ s/yyerror/yyerror_gettext/' y1.c > $@
- $(RM) y1.c y.tab.c
-
-clean:
- $(RM) $(PROG).c
-
-lint: lint_PROG
-
-include ../Makefile.targ
diff --git a/usr/src/cmd/egrep/egrep.y b/usr/src/cmd/egrep/egrep.y
deleted file mode 100644
index 8068dc447e..0000000000
--- a/usr/src/cmd/egrep/egrep.y
+++ /dev/null
@@ -1,1318 +0,0 @@
-%{
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-%}
-/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-/* Copyright (c) 1987, 1988 Microsoft Corporation */
-/* All Rights Reserved */
-
-/*
- * Copyright 2013 Damian Bogel. All rights reserved.
- */
-
-/*
- * egrep -- print lines containing (or not containing) a regular expression
- *
- * status returns:
- * 0 - ok, and some matches
- * 1 - ok, but no matches
- * 2 - some error; matches irrelevant
- */
-%token CHAR MCHAR DOT MDOT CCL NCCL MCCL NMCCL OR CAT STAR PLUS QUEST
-%left OR
-%left CHAR MCHAR DOT CCL NCCL MCCL NMCCL '('
-%left CAT
-%left STAR PLUS QUEST
-
-%{
-#include <stdio.h>
-#include <ctype.h>
-#include <memory.h>
-#include <wchar.h>
-#include <wctype.h>
-#include <widec.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <locale.h>
-
-#define STDIN_FILENAME gettext("(standard input)")
-
-#define BLKSIZE 512 /* size of reported disk blocks */
-#define EBUFSIZ 8192
-#define MAXLIN 350
-#define NCHARS 256
-#define MAXPOS 4000
-#define NSTATES 64
-#define FINAL -1
-#define RIGHT '\n' /* serves as record separator and as $ */
-#define LEFT '\n' /* beginning of line */
-int gotofn[NSTATES][NCHARS];
-int state[NSTATES];
-int out[NSTATES];
-int line = 1;
-int *name;
-int *left;
-int *right;
-int *parent;
-int *foll;
-int *positions;
-char *chars;
-wchar_t *lower;
-wchar_t *upper;
-int maxlin, maxclin, maxwclin, maxpos;
-int nxtpos = 0;
-int inxtpos;
-int nxtchar = 0;
-int *tmpstat;
-int *initstat;
-int istat;
-int nstate = 1;
-int xstate;
-int count;
-int icount;
-char *input;
-
-
-wchar_t lyylval;
-wchar_t nextch();
-wchar_t maxmin();
-int compare();
-void overflo();
-
-char reinit = 0;
-
-long long lnum;
-int bflag;
-int cflag;
-int eflag;
-int fflag;
-int Hflag;
-int hflag;
-int iflag;
-int lflag;
-int nflag;
-int qflag;
-int vflag;
-int nfile;
-long long blkno;
-long long tln;
-int nsucc;
-int badbotch;
-extern char *optarg;
-extern int optind;
-
-int f;
-FILE *expfile;
-%}
-
-%%
-s: t
- {
- unary(FINAL, $1);
- line--;
- }
- ;
-t: b r
- { $$ = node(CAT, $1, $2); }
- | OR b r OR
- { $$ = node(CAT, $2, $3); }
- | OR b r
- { $$ = node(CAT, $2, $3); }
- | b r OR
- { $$ = node(CAT, $1, $2); }
- ;
-b:
- { /* if(multibyte)
- $$ = mdotenter();
- else */
- $$ = enter(DOT);
- $$ = unary(STAR, $$);
- }
- ;
-r: CHAR
- { $$ = iflag && isalpha($1) ?
- node(OR, enter(tolower($1)), enter(toupper($1))) : enter($1); }
- | MCHAR
- { $$ = (iflag && iswalpha(lyylval)) ?
- node(OR, mchar(towlower(lyylval)), mchar(towupper(lyylval))) :
- mchar(lyylval); }
- | DOT
- { if(multibyte)
- $$ = mdotenter();
- else
- $$ = enter(DOT);
- }
- | CCL
- { $$ = cclenter(CCL); }
- | NCCL
- { $$ = cclenter(NCCL); }
- | MCCL
- { $$ = ccl(CCL); }
- | NMCCL
- { $$ = ccl(NCCL); }
- ;
-
-r: r OR r
- { $$ = node(OR, $1, $3); }
- | r r %prec CAT
- { $$ = node(CAT, $1, $2); }
- | r STAR
- { $$ = unary(STAR, $1); }
- | r PLUS
- { $$ = unary(PLUS, $1); }
- | r QUEST
- { $$ = unary(QUEST, $1); }
- | '(' r ')'
- { $$ = $2; }
- | error
- ;
-
-%%
-void add(int *, int);
-void clearg(void);
-void execute(char *);
-void follow(int);
-int mgetc(void);
-void synerror(void);
-
-
-void
-yyerror(char *s)
-{
- fprintf(stderr, "egrep: %s\n", s);
- exit(2);
-}
-
-int
-yylex(void)
-{
- extern int yylval;
- int cclcnt, x, ccount, oldccount;
- wchar_t c, lc;
-
- c = nextch();
- switch(c) {
- case '^':
- yylval = LEFT;
- return(CHAR);
- case '$':
- c = RIGHT;
- goto defchar;
- case '|': return (OR);
- case '*': return (STAR);
- case '+': return (PLUS);
- case '?': return (QUEST);
- case '(': return (c);
- case ')': return (c);
- case '.': return(DOT);
- case '\0': return (0);
- case RIGHT: return (OR);
- case '[':
- x = (multibyte ? MCCL : CCL);
- cclcnt = 0;
- count = nxtchar++;
- if ((c = nextch()) == '^') {
- x = (multibyte ? NMCCL : NCCL);
- c = nextch();
- }
- lc = 0;
- do {
- if (iflag && iswalpha(c))
- c = towlower(c);
- if (c == '\0') synerror();
- if (c == '-' && cclcnt > 0 && lc != 0) {
- if ((c = nextch()) != 0) {
- if(c == ']') {
- chars[nxtchar++] = '-';
- cclcnt++;
- break;
- }
- if (iflag && iswalpha(c))
- c = towlower(c);
- if (!multibyte ||
- (c & WCHAR_CSMASK) == (lc & WCHAR_CSMASK) &&
- lc < c &&
- !iswcntrl(c) && !iswcntrl(lc)) {
- if (nxtchar >= maxclin)
- if (allocchars() == 0)
- overflo();
- chars[nxtchar++] = '-';
- cclcnt++;
- }
- }
- }
- ccount = oldccount = nxtchar;
- if(ccount + MB_LEN_MAX >= maxclin)
- if(allocchars() == 0)
- overflo();
- ccount += wctomb(&chars[ccount], c);
- cclcnt += ccount - oldccount;
- nxtchar += ccount - oldccount;
- lc = c;
- } while ((c = nextch()) != ']');
- chars[count] = cclcnt;
- return(x);
-
- case '\\':
- if ((c = nextch()) == '\0') synerror();
- defchar:
- default:
- if (c <= 0177) {
- yylval = c;
- return (CHAR);
- } else {
- lyylval = c;
- return (MCHAR);
- }
- }
-}
-
-wchar_t
-nextch(void)
-{
- wchar_t lc;
- char multic[MB_LEN_MAX];
- int length, d;
- if (fflag) {
- if ((length = _mbftowc(multic, &lc, mgetc, &d)) < 0)
- synerror();
- if(length == 0)
- lc = '\0';
- }
- else {
- if((length = mbtowc(&lc, input, MB_LEN_MAX)) == -1)
- synerror();
- if(length == 0)
- return(0);
- input += length;
- }
- return(lc);
-}
-
-int
-mgetc(void)
-{
- return(getc(expfile));
-}
-
-void
-synerror(void)
-{
- fprintf(stderr, gettext("egrep: syntax error\n"));
- exit(2);
-}
-
-int
-enter(int x)
-{
- if(line >= maxlin)
- if(alloctree() == 0)
- overflo();
- name[line] = x;
- left[line] = 0;
- right[line] = 0;
- return(line++);
-}
-
-int
-cclenter(int x)
-{
- int linno;
- linno = enter(x);
- right[linno] = count;
- return (linno);
-}
-
-int
-node(int x, int l, int r)
-{
- if(line >= maxlin)
- if(alloctree() == 0)
- overflo();
- name[line] = x;
- left[line] = l;
- right[line] = r;
- parent[l] = line;
- parent[r] = line;
- return(line++);
-}
-
-int
-unary(int x, int d)
-{
- if(line >= maxlin)
- if(alloctree() == 0)
- overflo();
- name[line] = x;
- left[line] = d;
- right[line] = 0;
- parent[d] = line;
- return(line++);
-}
-
-int
-allocchars(void)
-{
- maxclin += MAXLIN;
- if((chars = realloc(chars, maxclin)) == (char *)0)
- return 0;
- return 1;
-}
-
-int
-alloctree(void)
-{
- maxlin += MAXLIN;
- if((name = (int *)realloc(name, maxlin*sizeof(int))) == (int *)0)
- return 0;
- if((left = (int *)realloc(left, maxlin*sizeof(int))) == (int *)0)
- return 0;
- if((right = (int *)realloc(right, maxlin*sizeof(int))) == (int *)0)
- return 0;
- if((parent = (int *)realloc(parent, maxlin*sizeof(int))) == (int *)0)
- return 0;
- if((foll = (int *)realloc(foll, maxlin*sizeof(int))) == (int *)0)
- return 0;
- if((tmpstat = (int *)realloc(tmpstat, maxlin*sizeof(int))) == (int *)0)
- return 0;
- if((initstat = (int *)realloc(initstat, maxlin*sizeof(int))) == (int *)0)
- return 0;
- return 1;
-}
-
-void
-overflo(void)
-{
- fprintf(stderr, gettext("egrep: regular expression too long\n"));
- exit(2);
-}
-
-void
-cfoll(int v)
-{
- int i;
- if (left[v] == 0) {
- count = 0;
- for (i=1; i<=line; i++) tmpstat[i] = 0;
- follow(v);
- add(foll, v);
- }
- else if (right[v] == 0) cfoll(left[v]);
- else {
- cfoll(left[v]);
- cfoll(right[v]);
- }
-}
-
-void
-cgotofn(void)
-{
- int i;
- count = 0;
- inxtpos = nxtpos;
- for (i=3; i<=line; i++) tmpstat[i] = 0;
- if (cstate(line-1)==0) {
- tmpstat[line] = 1;
- count++;
- out[1] = 1;
- }
- for (i=3; i<=line; i++) initstat[i] = tmpstat[i];
- count--; /*leave out position 1 */
- icount = count;
- tmpstat[1] = 0;
- add(state, 1);
- istat = nxtst(1, LEFT);
-}
-
-int
-nxtst(int s, int c)
-{
- int i, num, k;
- int pos, curpos, number, newpos;
- num = positions[state[s]];
- count = icount;
- for (i=3; i<=line; i++) tmpstat[i] = initstat[i];
- pos = state[s] + 1;
- for (i=0; i<num; i++) {
- curpos = positions[pos];
- k = name[curpos];
- if (k >= 0)
- if (
- (k == c)
- || (k == DOT && dot(c))
- || (k == MDOT && mdot(c))
- || (k == CCL && dot(c) && member(c, right[curpos], 1))
- || (k == NCCL && dot(c) && member(c, right[curpos], 0))
- || (k == MCCL && mdot(c) && member(c, right[curpos], 1))
- ) {
- number = positions[foll[curpos]];
- newpos = foll[curpos] + 1;
- for (k=0; k<number; k++) {
- if (tmpstat[positions[newpos]] != 1) {
- tmpstat[positions[newpos]] = 1;
- count++;
- }
- newpos++;
- }
- }
- pos++;
- }
- if (notin(nstate)) {
- if (++nstate >= NSTATES) {
- for (i=1; i<NSTATES; i++)
- out[i] = 0;
- for (i=1; i<NSTATES; i++)
- for (k=0; k<NCHARS; k++)
- gotofn[i][k] = 0;
- nstate = 1;
- nxtpos = inxtpos;
- reinit = 1;
- add(state, nstate);
- if (tmpstat[line] == 1) out[nstate] = 1;
- return nstate;
- }
- add(state, nstate);
- if (tmpstat[line] == 1) out[nstate] = 1;
- gotofn[s][c] = nstate;
- return nstate;
- }
- else {
- gotofn[s][c] = xstate;
- return xstate;
- }
-}
-
-
-int
-cstate(int v)
-{
- int b;
- if (left[v] == 0) {
- if (tmpstat[v] != 1) {
- tmpstat[v] = 1;
- count++;
- }
- return(1);
- }
- else if (right[v] == 0) {
- if (cstate(left[v]) == 0) return (0);
- else if (name[v] == PLUS) return (1);
- else return (0);
- }
- else if (name[v] == CAT) {
- if (cstate(left[v]) == 0 && cstate(right[v]) == 0) return (0);
- else return (1);
- }
- else { /* name[v] == OR */
- b = cstate(right[v]);
- if (cstate(left[v]) == 0 || b == 0) return (0);
- else return (1);
- }
-}
-
-
-int
-dot(int c)
-{
- if(multibyte && c >= 0200 && (!iscntrl(c) || c == SS2 && eucw2 || c == SS3 && eucw3))
- return(0);
- if(c == RIGHT || c == LEFT)
- return(0);
- return(1);
-}
-
-int
-mdot(int c)
-{
- if(c >= 0200 && !iscntrl(c))
- return(1);
- return(0);
-}
-
-int
-member(int symb, int set, int torf)
-{
- int i, num, pos, c, lc;
- if(symb == RIGHT || symb == LEFT)
- return(0);
- num = chars[set];
- pos = set + 1;
- lc = 0;
- if(iflag)
- symb = tolower(symb);
- for (i=0; i<num; i++) {
- c = (unsigned char)chars[pos++];
- if(c == '-' && lc != 0 && ++i < num) {
- c = (unsigned char)chars[pos++];
- if(lc <= symb && symb <= c)
- return(torf);
- }
- if (symb == c)
- return (torf);
- lc = c;
- }
- return(!torf);
-}
-
-int
-notin(int n)
-{
- int i, j, pos;
- for (i=1; i<=n; i++) {
- if (positions[state[i]] == count) {
- pos = state[i] + 1;
- for (j=0; j < count; j++)
- if (tmpstat[positions[pos++]] != 1) goto nxt;
- xstate = i;
- return (0);
- }
- nxt: ;
- }
- return (1);
-}
-
-void
-add(int *array, int n)
-{
- int i;
- if (nxtpos + count >= maxpos) {
- maxpos += MAXPOS + count;
- if((positions = (int *)realloc(positions, maxpos *sizeof(int))) == (int *)0)
- overflo();
- }
- array[n] = nxtpos;
- positions[nxtpos++] = count;
- for (i=3; i <= line; i++) {
- if (tmpstat[i] == 1) {
- positions[nxtpos++] = i;
- }
- }
-}
-
-void
-follow(int v)
-{
- int p;
- if (v == line) return;
- p = parent[v];
- switch(name[p]) {
- case STAR:
- case PLUS: cstate(v);
- follow(p);
- return;
-
- case OR:
- case QUEST: follow(p);
- return;
-
- case CAT: if (v == left[p]) {
- if (cstate(right[p]) == 0) {
- follow(p);
- return;
- }
- }
- else follow(p);
- return;
- case FINAL: if (tmpstat[line] != 1) {
- tmpstat[line] = 1;
- count++;
- }
- return;
- }
-}
-
-#define USAGE "[ -bchHilnsqv ] [ -e exp ] [ -f file ] [ strings ] [ file ] ..."
-
-int
-main(int argc, char **argv)
-{
- char c;
- char nl = '\n';
- int errflag = 0;
-
- (void)setlocale(LC_ALL, "");
-
-#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
- #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't. */
-#endif
- (void) textdomain(TEXT_DOMAIN);
-
- while((c = getopt(argc, argv, "ybcie:f:Hhlnvsq")) != -1)
- switch(c) {
-
- case 'b':
- bflag++;
- continue;
-
- case 'c':
- cflag++;
- continue;
-
- case 'e':
- eflag++;
- input = optarg;
- continue;
-
- case 'f':
- fflag++;
- expfile = fopen(optarg, "r");
- if(expfile == NULL) {
- fprintf(stderr,
- gettext("egrep: can't open %s\n"), optarg);
- exit(2);
- }
- continue;
-
- case 'H':
- if (!lflag) /* H is excluded by l as in GNU grep */
- Hflag++;
- hflag = 0; /* H excludes h */
- continue;
-
- case 'h':
- hflag++;
- Hflag = 0; /* h excludes H */
- continue;
-
- case 'y':
- case 'i':
- iflag++;
- continue;
-
- case 'l':
- lflag++;
- Hflag = 0; /* l excludes H */
- continue;
-
- case 'n':
- nflag++;
- continue;
-
- case 'q':
- case 's': /* Solaris: legacy option */
- qflag++;
- continue;
-
- case 'v':
- vflag++;
- continue;
-
- case '?':
- errflag++;
- }
- if (errflag || ((argc <= 0) && !fflag && !eflag)) {
- fprintf(stderr, gettext("usage: egrep %s\n"), gettext(USAGE));
- exit(2);
- }
- if(!eflag && !fflag) {
- input = argv[optind];
- optind++;
- }
-
- argc -= optind;
- argv = &argv[optind];
-
- /* allocate initial space for arrays */
- if((name = (int *)malloc(MAXLIN*sizeof(int))) == (int *)0)
- overflo();
- if((left = (int *)malloc(MAXLIN*sizeof(int))) == (int *)0)
- overflo();
- if((right = (int *)malloc(MAXLIN*sizeof(int))) == (int *)0)
- overflo();
- if((parent = (int *)malloc(MAXLIN*sizeof(int))) == (int *)0)
- overflo();
- if((foll = (int *)malloc(MAXLIN*sizeof(int))) == (int *)0)
- overflo();
- if((tmpstat = (int *)malloc(MAXLIN*sizeof(int))) == (int *)0)
- overflo();
- if((initstat = (int *)malloc(MAXLIN*sizeof(int))) == (int *)0)
- overflo();
- if((chars = (char *)malloc(MAXLIN)) == (char *)0)
- overflo();
- if((lower = (wchar_t *)malloc(MAXLIN*sizeof(wchar_t))) == (wchar_t *)0)
- overflo();
- if((upper = (wchar_t *)malloc(MAXLIN*sizeof(wchar_t))) == (wchar_t *)0)
- overflo();
- if((positions = (int *)malloc(MAXPOS*sizeof(int))) == (int *)0)
- overflo();
- maxlin = MAXLIN;
- maxclin = MAXLIN;
- maxwclin = MAXLIN;
- maxpos = MAXPOS;
-
- yyparse();
-
- cfoll(line-1);
- cgotofn();
- nfile = argc;
- if (argc<=0) {
- execute(0);
- }
- else while (--argc >= 0) {
- if (reinit == 1) clearg();
- execute(*argv++);
- }
- return (badbotch ? 2 : nsucc==0);
-}
-
-void
-execute(char *file)
-{
- char *p;
- int cstat;
- wchar_t c;
- int t;
- long count;
- long count1, count2;
- long nchars;
- int succ;
- char *ptr, *ptrend, *lastptr;
- char *buf;
- long lBufSiz;
- FILE *f;
- int nlflag;
-
- lBufSiz = EBUFSIZ;
- if ((buf = malloc (lBufSiz + EBUFSIZ)) == NULL) {
- exit (2); /* out of memory - BAIL */
- }
-
- if (file) {
- if ((f = fopen(file, "r")) == NULL) {
- fprintf(stderr,
- gettext("egrep: can't open %s\n"), file);
- badbotch=1;
- return;
- }
- } else {
- f = stdin;
- file = STDIN_FILENAME;
- }
- lnum = 1;
- tln = 0;
- if((count = read(fileno(f), buf, EBUFSIZ)) <= 0) {
- fclose(f);
-
- if (cflag && !qflag) {
- if (Hflag || (nfile > 1 && !hflag))
- fprintf(stdout, "%s:", file);
- fprintf(stdout, "%lld\n", tln);
- }
- return;
- }
-
- blkno = count;
- ptr = buf;
- for(;;) {
- if((ptrend = memchr(ptr, '\n', buf + count - ptr)) == NULL) {
- /*
- move the unused partial record to the head of the buffer
- */
- if (ptr > buf) {
- count = buf + count - ptr;
- memmove (buf, ptr, count);
- ptr = buf;
- }
-
- /*
- Get a bigger buffer if this one is full
- */
- if(count > lBufSiz) {
- /*
- expand the buffer
- */
- lBufSiz += EBUFSIZ;
- if ((buf = realloc (buf, lBufSiz + EBUFSIZ)) == NULL) {
- exit (2); /* out of memory - BAIL */
- }
-
- ptr = buf;
- }
-
- p = buf + count;
- if((count1 = read(fileno(f), p, EBUFSIZ)) > 0) {
- count += count1;
- blkno += count1;
- continue;
- }
- ptrend = ptr + count;
- nlflag = 0;
- } else
- nlflag = 1;
- *ptrend = '\n';
- p = ptr;
- lastptr = ptr;
- cstat = istat;
- succ = 0;
- for(;;) {
- if(out[cstat]) {
- if(multibyte && p > ptr) {
- wchar_t wchar;
- int length;
- char *endptr = p;
- p = lastptr;
- while(p < endptr) {
- length = mbtowc(&wchar, p, MB_LEN_MAX);
- if(length <= 1)
- p++;
- else
- p += length;
- }
- if(p == endptr) {
- succ = !vflag;
- break;
- }
- cstat = 1;
- length = mbtowc(&wchar, lastptr, MB_LEN_MAX);
- if(length <= 1)
- lastptr++;
- else
- lastptr += length;
- p = lastptr;
- continue;
- }
- succ = !vflag;
- break;
- }
- c = (unsigned char)*p++;
- if ((t = gotofn[cstat][c]) == 0)
- cstat = nxtst(cstat, c);
- else
- cstat = t;
- if(c == RIGHT) {
- if(out[cstat]) {
- succ = !vflag;
- break;
- }
- succ = vflag;
- break;
- }
- }
- if (succ) {
- nsucc = 1;
- if (lflag || qflag) {
- if (!qflag)
- (void) printf("%s\n", file);
- fclose(f);
- return;
- }
- if (cflag) {
- tln++;
- } else {
- if (Hflag || (nfile > 1 && !hflag))
- printf("%s:", file);
- if (bflag) {
- nchars = blkno - (buf + count - ptrend) - 2;
- if(nlflag)
- nchars++;
- printf("%lld:", nchars/BLKSIZE);
- }
- if (nflag)
- printf("%lld:", lnum);
- if(nlflag)
- nchars = ptrend - ptr + 1;
- else
- nchars = ptrend - ptr;
- fwrite(ptr, (size_t)1, (size_t)nchars, stdout);
- }
- }
- if(!nlflag)
- break;
- ptr = ptrend + 1;
- if(ptr >= buf + count) {
- ptr = buf;
- if((count = read(fileno(f), buf, EBUFSIZ)) <= 0)
- break;
- blkno += count;
- }
- lnum++;
- if (reinit == 1)
- clearg();
- }
- fclose(f);
- if (cflag && !qflag) {
- if (Hflag || (nfile > 1 && !hflag))
- printf("%s:", file);
- printf("%lld\n", tln);
- }
-}
-
-void
-clearg(void)
-{
- int i, k;
- for (i=1; i<=nstate; i++)
- out[i] = 0;
- for (i=1; i<=nstate; i++)
- for (k=0; k<NCHARS; k++)
- gotofn[i][k] = 0;
- nstate = 1;
- nxtpos = inxtpos;
- reinit = 0;
- count = 0;
- for (i=3; i<=line; i++) tmpstat[i] = 0;
- if (cstate(line-1)==0) {
- tmpstat[line] = 1;
- count++;
- out[1] = 1;
- }
- for (i=3; i<=line; i++) initstat[i] = tmpstat[i];
- count--; /*leave out position 1 */
- icount = count;
- tmpstat[1] = 0;
- add(state, 1);
- istat = nxtst(1, LEFT);
-}
-
-int
-mdotenter(void)
-{
- int i, x1, x2;
- x1 = enter(DOT);
- x2 = enter(MDOT);
- for(i = 1; i < (int) eucw1; i++)
- x2 = node(CAT, x2, enter(MDOT));
- x1 = node(OR, x1, x2);
- if(eucw2) {
- x2 = enter('\216');
- for(i = 1; i <= (int) eucw2; i++)
- x2 = node(CAT, x2, enter(MDOT));
- x1 = node(OR, x1, x2);
- }
- if(eucw3) {
- x2 = enter('\217');
- for(i = 1; i <= (int) eucw3; i++)
- x2 = node(CAT, x2, enter(MDOT));
- x1 = node(OR, x1, x2);
- }
- return(x1);
-}
-
-int
-mchar(wchar_t c)
-{
- char multichar[MB_LEN_MAX+1];
- char *p;
- int x1, lc, length;
-
- length = wctomb(multichar, c);
- p = multichar;
- *(p + length) = '\0';
- x1 = enter((unsigned char)*p++);
- while(lc = (unsigned char)*p++)
- x1 = node(CAT, x1, enter(lc));
- return(x1);
-}
-
-int
-ccl(int type)
-{
- wchar_t c, lc;
- char multic1[MB_LEN_MAX];
- char multic2[MB_LEN_MAX];
- int x1, x2, length, current, last, cclcnt;
- x2 = 0;
- current = 0;
- last = genrange(type);
- nxtchar = count + 1;
- cclcnt = 0;
- /* create usual character class for single byte characters */
- while(current <= last && (isascii(c = lower[current]) || c <= 0377 && iscntrl(c))) {
- cclcnt++;
- chars[nxtchar++] = c;
- if(lower[current] != upper[current]) {
- chars[nxtchar++] = '-';
- chars[nxtchar++] = upper[current];
- cclcnt += 2;
- }
- current++;
- }
-
- if(cclcnt)
- chars[count] = cclcnt;
- else
- nxtchar = count;
- if(current > 0)
- /* single byte part of character class */
- x2 = cclenter(type);
- else if(type == NCCL)
- /* all single byte characters match */
- x2 = enter(DOT);
- while(current <= last) {
- if(upper[current] == lower[current])
- x1 = mchar(lower[current]);
- else {
- length = wctomb(multic1, lower[current]);
- wctomb(multic2, upper[current]);
- x1 = range((unsigned char *)multic1,
- (unsigned char *)multic2, length);
- }
- if(x2)
- x2 = node(OR, x2, x1);
- else
- x2 = x1;
- current++;
- }
- return x2;
-}
-
-int
-range(unsigned char *p1, unsigned char *p2, int length)
-{
- char multic[MB_LEN_MAX+1];
- char *p;
- int i, x1, x2;
- if(length == 1)
- return(classenter(*p1, *p2));
- if(p1[0] == p2[0])
- return(node(CAT, enter(p1[0]), range(p1+1, p2+1, length - 1)));
- p = multic;
- for(i = 1; i < length; i++)
- *p++ = 0377;
- x1 = node(CAT, enter(p1[0]),
- range(p1+1, (unsigned char *)multic, length - 1));
- if((unsigned char)(p1[0] + 1) < p2[0]) {
- x2 = classenter(p1[0] + 1, p2[0] - 1);
- for(i = 1; i < length; i++)
- x2 = node(CAT, x2, enter(MDOT));
- x1 = node(OR, x1, x2);
- }
- p = multic;
- for(i = 1; i < length; i++)
- *p++ = 0200;
- x2 = node(CAT, enter(p2[0]),
- range((unsigned char *)multic, p2+1, length - 1));
- return node(OR, x1, x2);
-}
-
-int
-classenter(int x1, int x2)
-{
- static int max, min;
- if(!max) {
- int i;
- for(i = 0200; i <= 0377; i++)
- if(!iscntrl(i))
- break;
- min = i;
- for(i = 0377; i >= 0200; i--)
- if(!iscntrl(i))
- break;
- max = i;
- }
- if(x1 <= min && x2 >= max)
- return enter(MDOT);
- if(nxtchar + 4 >= maxclin)
- if(allocchars() == 0)
- overflo();
- count = nxtchar++;
- chars[nxtchar++] = x1;
- chars[nxtchar++] = '-';
- chars[nxtchar++] = x2;
- chars[count] = 3;
- return cclenter(MCCL);
-}
-
-int
-genrange(int type)
-{
- char *p, *endp;
- int current, nel, i, last, length;
- wchar_t c, lc;
-
- current = 0;
- p = &chars[count+1];
- endp = &chars[count+1] + chars[count];
- lc = 0;
-
- /* convert character class into union of ranges */
- while(p < endp) {
- length = mbtowc(&c, p, MB_LEN_MAX);
- p += length;
- if(c == '-' && lc != 0) {
- length = mbtowc(&c, p, MB_LEN_MAX);
- upper[current-1] = c;
- p += length;
- } else {
- lower[current] = c;
- upper[current++] = c;
- }
- lc = c;
- }
- nel = current;
- /* sort lower and upper bounds of ranges */
- qsort((char *)lower, nel, sizeof(wchar_t), compare);
- qsort((char *)upper, nel, sizeof(wchar_t), compare);
- last = current - 1;
- current = 0;
- /* combine overlapping or adjacent ranges */
- for(i = 0; i < last; i++)
- if(upper[i] >= lower[i+1] - 1)
- upper[current] = upper[i+1];
- else {
- lower[++current] = lower[i+1];
- upper[current] = upper[i+1];
- }
- if(type == NCCL) {
- /* find complement of character class */
- int j, next;
- i = 0;
- while(i <= current && isascii(c=lower[i]) || c <= 0377 && iscntrl(c))
- i++;
- if(i > current) {
- /* match all multibyte characters */
- if(eucw2) {
- lower[i] = maxmin(WCHAR_CS2, 0);
- upper[i++] = maxmin(WCHAR_CS2, 1);
- }
- if(eucw3) {
- lower[i] = maxmin(WCHAR_CS3, 0);
- upper[i++] = maxmin(WCHAR_CS3, 1);
- }
- lower[i] = maxmin(WCHAR_CS1, 0);
- upper[i++] = maxmin(WCHAR_CS1, 1);
- return i - 1;
- }
- next = current + 1;
- if(next + current + 2 >= maxwclin) {
- maxwclin += MAXLIN + next + current + 2;
- if((lower = (wchar_t *)realloc(lower, maxwclin *sizeof(wchar_t))) == (wchar_t *)0 ||
- (upper = (wchar_t *)realloc(upper, maxwclin * sizeof(wchar_t))) == (wchar_t *)0)
- overflo();
- }
- if(eucw2 && lower[i] > maxmin(WCHAR_CS2, 0)) {
- lower[next] = maxmin(WCHAR_CS2, 0);
- if((lower[i] & WCHAR_CSMASK) != WCHAR_CS2) {
- upper[next++] = maxmin(WCHAR_CS2, 1);
- if((lower[i] & WCHAR_CSMASK) == WCHAR_CS1 && eucw3) {
- lower[next] = maxmin(WCHAR_CS3, 0);
- upper[next++] = maxmin(WCHAR_CS3, 1);
- }
- if(lower[i] > maxmin(lower[i] & WCHAR_CSMASK, 0)) {
- lower[next] = maxmin(lower[i] & WCHAR_CSMASK, 0);
- upper[next++] = lower[i] - 1;
- }
- } else
- upper[next++] = lower[i] - 1;
- } else if(lower[i] > maxmin(lower[i] & WCHAR_CSMASK, 0)) {
- lower[next] = maxmin(lower[i] & WCHAR_CSMASK, 0);
- upper[next++] = lower[i] - 1;
- }
- for(j = i; j < current; j++) {
- if(upper[j] < maxmin(upper[j] & WCHAR_CSMASK, 1)) {
- lower[next] = upper[j] + 1;
- if((upper[j] & WCHAR_CSMASK) != (lower[j+1] & WCHAR_CSMASK)) {
- upper[next++] = maxmin(upper[j] & WCHAR_CSMASK, 1);
- if(eucw3 && (upper[j] & WCHAR_CSMASK) == WCHAR_CS2 && (lower[j+1] & WCHAR_CSMASK) == WCHAR_CS1) {
- lower[next] = maxmin(WCHAR_CS3, 0);
- upper[next++] = maxmin(WCHAR_CS3, 1);
- }
- if(lower[j+1] > maxmin(lower[j+1] & WCHAR_CSMASK, 0)) {
- lower[next] = maxmin(lower[j+1] & WCHAR_CSMASK, 0);
- upper[next++] = lower[j+1] - 1;
- }
- } else
- upper[next++] = lower[j+1] - 1;
- } else if(lower[j+1] > maxmin(lower[j+1], 0)) {
- lower[next] = maxmin(lower[j+1], 0);
- upper[next++] = lower[j+1] - 1;
- }
- }
- if(upper[current] < maxmin(upper[current] & WCHAR_CSMASK, 1)) {
- lower[next] = upper[current] + 1;
- upper[next++] = maxmin(upper[current] & WCHAR_CSMASK, 1);
- }
- if((upper[current] & WCHAR_CSMASK) != WCHAR_CS1) {
- if((upper[current] & WCHAR_CSMASK) == WCHAR_CS2 && eucw3) {
- lower[next] = maxmin(WCHAR_CS3, 0);
- upper[next++] = maxmin(WCHAR_CS3, 1);
- }
- lower[next] = maxmin(WCHAR_CS1, 0);
- upper[next++] = maxmin(WCHAR_CS1, 1);
- }
- for(j = current + 1; j < next; j++) {
- lower[i] = lower[j];
- upper[i++] = upper[j];
- }
- current = i - 1;
- }
- return(current);
-}
-
-int
-compare(wchar_t *c, wchar_t *d)
-{
- if(*c < *d)
- return -1;
- if(*c == *d)
- return 0;
- return 1;
-}
-
-wchar_t
-maxmin(wchar_t c, int flag)
-{
- static wchar_t minmax1[2], minmax2[2], minmax3[2];
-
- if(!minmax1[0]) {
- /* compute min and max process codes for all code sets */
- int length, i;
- char multic[MB_LEN_MAX], minmax[2];
- for(i = 0377; i >= 0200; i--)
- if(!iscntrl(i))
- break;
- minmax[1] = i;
- for(i = 0240; i <= 0377; i++)
- if(!iscntrl(i))
- break;
- minmax[0] = i;
- for(i = 0; i <= 1; i++) {
- length = MB_LEN_MAX;
- while(length--)
- multic[length] = minmax[i];
- mbtowc(&minmax1[i], multic, MB_LEN_MAX);
- if(eucw2) {
- multic[0] = SS2;
- mbtowc(&minmax2[i], multic, MB_LEN_MAX);
- }
- if(eucw3) {
- multic[0] = SS3;
- mbtowc(&minmax3[i], multic, MB_LEN_MAX);
- }
- }
- }
- switch(c) {
- case WCHAR_CS1: return minmax1[flag];
- case WCHAR_CS2: return minmax2[flag];
- case WCHAR_CS3: return minmax3[flag];
- }
-
- /* NOTREACHED */
- return (0);
-}
diff --git a/usr/src/cmd/fgrep/Makefile b/usr/src/cmd/fgrep/Makefile
deleted file mode 100644
index 26d8ef046c..0000000000
--- a/usr/src/cmd/fgrep/Makefile
+++ /dev/null
@@ -1,44 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright (c) 1989,1996 by Sun Microsystems, Inc.
-# All rights reserved.
-#
-
-PROG= fgrep
-
-include ../Makefile.cmd
-
-CPPFLAGS += -D_FILE_OFFSET_BITS=64
-CERRWARN += -_gcc=-Wno-parentheses
-
-.KEEP_STATE:
-
-all: $(PROG)
-
-install: all $(ROOTPROG)
-
-clean:
-
-lint: lint_PROG
-
-include ../Makefile.targ
diff --git a/usr/src/cmd/fgrep/fgrep.c b/usr/src/cmd/fgrep/fgrep.c
deleted file mode 100644
index 31724cda40..0000000000
--- a/usr/src/cmd/fgrep/fgrep.c
+++ /dev/null
@@ -1,705 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-/* Copyright (c) 1987, 1988 Microsoft Corporation */
-/* All Rights Reserved */
-
-/*
- * Copyright 2013 Damian Bogel. All rights reserved.
- */
-
-/*
- * fgrep -- print all lines containing any of a set of keywords
- *
- * status returns:
- * 0 - ok, and some matches
- * 1 - ok, but no matches
- * 2 - some error
- */
-
-#include <stdio.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <stdlib.h>
-#include <string.h>
-#include <locale.h>
-#include <libintl.h>
-#include <euc.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <getwidth.h>
-
-eucwidth_t WW;
-#define WIDTH1 WW._eucw1
-#define WIDTH2 WW._eucw2
-#define WIDTH3 WW._eucw3
-#define MULTI_BYTE WW._multibyte
-#define GETONE(lc, p) \
- cw = ISASCII(lc = (unsigned char)*p++) ? 1 : \
- (ISSET2(lc) ? WIDTH2 : \
- (ISSET3(lc) ? WIDTH3 : WIDTH1)); \
- if (--cw > --ccount) { \
- cw -= ccount; \
- while (ccount--) \
- lc = (lc << 7) | ((*p++) & 0177); \
- if (p >= &buf[fw_lBufsiz + BUFSIZ]) { \
- if (nlp == buf) { \
- /* Increase the buffer size */ \
- fw_lBufsiz += BUFSIZ; \
- if ((buf = realloc(buf, \
- fw_lBufsiz + BUFSIZ)) == NULL) { \
- exit(2); /* out of memory */ \
- } \
- nlp = buf; \
- p = &buf[fw_lBufsiz]; \
- } else { \
- /* shift the buffer contents down */ \
- (void) memmove(buf, nlp, \
- &buf[fw_lBufsiz + BUFSIZ] - nlp);\
- p -= nlp - buf; \
- nlp = buf; \
- } \
- } \
- if (p > &buf[fw_lBufsiz]) { \
- if ((ccount = fread(p, sizeof (char), \
- &buf[fw_lBufsiz + BUFSIZ] - p, fptr))\
- <= 0) break; \
- } else if ((ccount = fread(p, \
- sizeof (char), BUFSIZ, fptr)) <= 0) \
- break; \
- blkno += (long long)ccount; \
- } \
- ccount -= cw; \
- while (cw--) \
- lc = (lc << 7) | ((*p++) & 0177)
-
-/*
- * The same() macro and letter() function were inserted to allow for
- * the -i option work for the multi-byte environment.
- */
-wchar_t letter();
-#define same(a, b) \
- (a == b || iflag && (!MULTI_BYTE || ISASCII(a)) && (a ^ b) == ' ' && \
- letter(a) == letter(b))
-
-#define STDIN_FILENAME gettext("(standard input)")
-
-#define QSIZE 400
-struct words {
- wchar_t inp;
- char out;
- struct words *nst;
- struct words *link;
- struct words *fail;
-} *w = NULL, *smax, *q;
-
-FILE *fptr;
-long long lnum;
-int bflag, cflag, lflag, fflag, nflag, vflag, xflag, eflag, qflag;
-int Hflag, hflag, iflag;
-int retcode = 0;
-int nfile;
-long long blkno;
-int nsucc;
-long long tln;
-FILE *wordf;
-char *argptr;
-off_t input_size = 0;
-
-void execute(char *);
-void cgotofn(void);
-void overflo(void);
-void cfail(void);
-
-static long fw_lBufsiz = 0;
-
-int
-main(int argc, char **argv)
-{
- int c;
- int errflg = 0;
- struct stat file_stat;
-
- (void) setlocale(LC_ALL, "");
-#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
-#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
-#endif
- (void) textdomain(TEXT_DOMAIN);
-
- while ((c = getopt(argc, argv, "Hhybcie:f:lnvxqs")) != EOF)
- switch (c) {
-
- case 'q':
- case 's': /* Solaris: legacy option */
- qflag++;
- continue;
- case 'H':
- Hflag++;
- hflag = 0;
- continue;
- case 'h':
- hflag++;
- Hflag = 0;
- continue;
- case 'b':
- bflag++;
- continue;
-
- case 'i':
- case 'y':
- iflag++;
- continue;
-
- case 'c':
- cflag++;
- continue;
-
- case 'e':
- eflag++;
- argptr = optarg;
- input_size = strlen(argptr);
- continue;
-
- case 'f':
- fflag++;
- wordf = fopen(optarg, "r");
- if (wordf == NULL) {
- (void) fprintf(stderr,
- gettext("fgrep: can't open %s\n"),
- optarg);
- exit(2);
- }
-
- if (fstat(fileno(wordf), &file_stat) == 0) {
- input_size = file_stat.st_size;
- } else {
- (void) fprintf(stderr,
- gettext("fgrep: can't fstat %s\n"),
- optarg);
- exit(2);
- }
-
- continue;
-
- case 'l':
- lflag++;
- continue;
-
- case 'n':
- nflag++;
- continue;
-
- case 'v':
- vflag++;
- continue;
-
- case 'x':
- xflag++;
- continue;
-
- case '?':
- errflg++;
- }
-
- argc -= optind;
- if (errflg || ((argc <= 0) && !fflag && !eflag)) {
- (void) printf(gettext("usage: fgrep [ -bcHhilnqsvx ] "
- "[ -e exp ] [ -f file ] [ strings ] [ file ] ...\n"));
- exit(2);
- }
- if (!eflag && !fflag) {
- argptr = argv[optind];
- input_size = strlen(argptr);
- input_size++;
- optind++;
- argc--;
- }
-
-/*
- * Normally we need one struct words for each letter in the pattern
- * plus one terminating struct words with outp = 1, but when -x option
- * is specified we require one more struct words for `\n` character so we
- * calculate the input_size as below. We add extra 1 because
- * (input_size/2) rounds off odd numbers
- */
-
- if (xflag) {
- input_size = input_size + (input_size/2) + 1;
- }
-
- input_size++;
-
- w = (struct words *)calloc(input_size, sizeof (struct words));
- if (w == NULL) {
- (void) fprintf(stderr,
- gettext("fgrep: could not allocate "
- "memory for wordlist\n"));
- exit(2);
- }
-
- getwidth(&WW);
- if ((WIDTH1 == 0) && (WIDTH2 == 0) &&
- (WIDTH3 == 0)) {
- /*
- * If non EUC-based locale,
- * assume WIDTH1 is 1.
- */
- WIDTH1 = 1;
- }
- WIDTH2++;
- WIDTH3++;
-
- cgotofn();
- cfail();
- nfile = argc;
- argv = &argv[optind];
- if (argc <= 0) {
- execute((char *)NULL);
- } else
- while (--argc >= 0) {
- execute(*argv);
- argv++;
- }
-
- if (w != NULL) {
- free(w);
- }
-
- return (retcode != 0 ? retcode : nsucc == 0);
-}
-
-void
-execute(char *file)
-{
- char *p;
- struct words *c;
- int ccount;
- static char *buf = NULL;
- int failed;
- char *nlp;
- wchar_t lc;
- int cw;
-
- if (buf == NULL) {
- fw_lBufsiz = BUFSIZ;
- if ((buf = malloc(fw_lBufsiz + BUFSIZ)) == NULL) {
- exit(2); /* out of memory */
- }
- }
-
- if (file) {
- if ((fptr = fopen(file, "r")) == NULL) {
- (void) fprintf(stderr,
- gettext("fgrep: can't open %s\n"), file);
- retcode = 2;
- return;
- }
- } else {
- fptr = stdin;
- file = STDIN_FILENAME;
- }
- ccount = 0;
- failed = 0;
- lnum = 1;
- tln = 0;
- blkno = 0;
- p = buf;
- nlp = p;
- c = w;
- for (;;) {
- if (c == 0)
- break;
- if (ccount <= 0) {
- if (p >= &buf[fw_lBufsiz + BUFSIZ]) {
- if (nlp == buf) {
- /* increase the buffer size */
- fw_lBufsiz += BUFSIZ;
- if ((buf = realloc(buf,
- fw_lBufsiz + BUFSIZ)) == NULL) {
- exit(2); /* out of memory */
- }
- nlp = buf;
- p = &buf[fw_lBufsiz];
- } else {
- /* shift the buffer down */
- (void) memmove(buf, nlp,
- &buf[fw_lBufsiz + BUFSIZ]
- - nlp);
- p -= nlp - buf;
- nlp = buf;
- }
-
- }
- if (p > &buf[fw_lBufsiz]) {
- if ((ccount = fread(p, sizeof (char),
- &buf[fw_lBufsiz + BUFSIZ] - p, fptr))
- <= 0)
- break;
- } else if ((ccount = fread(p, sizeof (char),
- BUFSIZ, fptr)) <= 0)
- break;
- blkno += (long long)ccount;
- }
- GETONE(lc, p);
-nstate:
- if (same(c->inp, lc)) {
- c = c->nst;
- } else if (c->link != 0) {
- c = c->link;
- goto nstate;
- } else {
- c = c->fail;
- failed = 1;
- if (c == 0) {
- c = w;
-istate:
- if (same(c->inp, lc)) {
- c = c->nst;
- } else if (c->link != 0) {
- c = c->link;
- goto istate;
- }
- } else
- goto nstate;
- }
-
- if (c == 0)
- break;
-
- if (c->out) {
- while (lc != '\n') {
- if (ccount <= 0) {
-if (p == &buf[fw_lBufsiz + BUFSIZ]) {
- if (nlp == buf) {
- /* increase buffer size */
- fw_lBufsiz += BUFSIZ;
- if ((buf = realloc(buf, fw_lBufsiz + BUFSIZ)) == NULL) {
- exit(2); /* out of memory */
- }
- nlp = buf;
- p = &buf[fw_lBufsiz];
- } else {
- /* shift buffer down */
- (void) memmove(buf, nlp, &buf[fw_lBufsiz + BUFSIZ] - nlp);
- p -= nlp - buf;
- nlp = buf;
- }
-}
-if (p > &buf[fw_lBufsiz]) {
- if ((ccount = fread(p, sizeof (char),
- &buf[fw_lBufsiz + BUFSIZ] - p, fptr)) <= 0) break;
- } else if ((ccount = fread(p, sizeof (char), BUFSIZ,
- fptr)) <= 0) break;
- blkno += (long long)ccount;
- }
- GETONE(lc, p);
-}
- if ((vflag && (failed == 0 || xflag == 0)) ||
- (vflag == 0 && xflag && failed))
- goto nomatch;
-succeed:
- nsucc = 1;
- if (lflag || qflag) {
- if (!qflag)
- (void) printf("%s\n", file);
- (void) fclose(fptr);
- return;
- }
- if (cflag) {
- tln++;
- } else {
- if (Hflag || (nfile > 1 && !hflag))
- (void) printf("%s:", file);
- if (bflag)
- (void) printf("%lld:",
- (blkno - (long long)(ccount-1))
- / BUFSIZ);
- if (nflag)
- (void) printf("%lld:", lnum);
- if (p <= nlp) {
- while (nlp < &buf[fw_lBufsiz + BUFSIZ])
- (void) putchar(*nlp++);
- nlp = buf;
- }
- while (nlp < p)
- (void) putchar(*nlp++);
- }
-nomatch:
- lnum++;
- nlp = p;
- c = w;
- failed = 0;
- continue;
- }
- if (lc == '\n')
- if (vflag)
- goto succeed;
- else {
- lnum++;
- nlp = p;
- c = w;
- failed = 0;
- }
- }
- (void) fclose(fptr);
- if (cflag && !qflag) {
- if (Hflag || (nfile > 1 && !hflag))
- (void) printf("%s:", file);
- (void) printf("%lld\n", tln);
- }
-}
-
-
-wchar_t
-getargc(void)
-{
- /* appends a newline to shell quoted argument list so */
- /* the list looks like it came from an ed style file */
- wchar_t c;
- int cw;
- int b;
- static int endflg;
-
-
- if (wordf) {
- if ((b = getc(wordf)) == EOF)
- return (EOF);
- cw = ISASCII(c = (wchar_t)b) ? 1 :
- (ISSET2(c) ? WIDTH2 : (ISSET3(c) ? WIDTH3 : WIDTH1));
- while (--cw) {
- if ((b = getc(wordf)) == EOF)
- return (EOF);
- c = (c << 7) | (b & 0177);
- }
- return (iflag ? letter(c) : c);
- }
-
- if (endflg)
- return (EOF);
-
- {
- cw = ISASCII(c = (unsigned char)*argptr++) ? 1 :
- (ISSET2(c) ? WIDTH2 : (ISSET3(c) ? WIDTH3 : WIDTH1));
-
- while (--cw)
- c = (c << 7) | ((*argptr++) & 0177);
- if (c == '\0') {
- endflg++;
- return ('\n');
- }
- }
- return (iflag ? letter(c) : c);
-
-
-}
-
-void
-cgotofn(void)
-{
- int c;
- struct words *s;
-
- s = smax = w;
-nword:
- for (;;) {
- c = getargc();
- if (c == EOF)
- return;
- if (c == 0)
- goto enter;
- if (c == '\n') {
- if (xflag) {
- for (;;) {
- if (s->inp == c) {
- s = s->nst;
- break;
- }
- if (s->inp == 0)
- goto nenter;
- if (s->link == 0) {
- if (smax >= &w[input_size -1])
- overflo();
- s->link = ++smax;
- s = smax;
- goto nenter;
- }
- s = s->link;
- }
- }
- s->out = 1;
- s = w;
- } else {
-loop:
- if (s->inp == c) {
- s = s->nst;
- continue;
- }
- if (s->inp == 0)
- goto enter;
- if (s->link == 0) {
- if (smax >= &w[input_size -1])
- overflo();
- s->link = ++smax;
- s = smax;
- goto enter;
- }
- s = s->link;
- goto loop;
- }
- }
-
-enter:
- do {
- s->inp = c;
- if (smax >= &w[input_size -1])
- overflo();
- s->nst = ++smax;
- s = smax;
- } while ((c = getargc()) != '\n' && c != EOF);
- if (xflag) {
-nenter:
- s->inp = '\n';
- if (smax >= &w[input_size -1])
- overflo();
- s->nst = ++smax;
- }
- smax->out = 1;
- s = w;
- if (c != EOF)
- goto nword;
-}
-
-/*
- * This function is an unexpected condition, since input_size should have been
- * calculated correctly before hand.
- */
-
-void
-overflo(void)
-{
- (void) fprintf(stderr, gettext("fgrep: wordlist too large\n"));
- exit(2);
-}
-
-void
-cfail(void)
-{
- int qsize = QSIZE;
- struct words **queue = NULL;
-
- /*
- * front and rear are pointers used to traverse the global words
- * structure "w" which contains the data of input pattern file
- */
- struct words **front, **rear;
- struct words *state;
- unsigned long frontoffset = 0, rearoffset = 0;
- char c;
- struct words *s;
- s = w;
- if ((queue = (struct words **)calloc(qsize, sizeof (struct words *)))
- == NULL) {
- perror("fgrep");
- exit(2);
- }
- front = rear = queue;
-init:
- if ((s->inp) != 0) {
- *rear++ = s->nst;
- /*
- * Reallocates the queue if the number of distinct starting
- * character of patterns exceeds the qsize value
- */
- if (rear >= &queue[qsize - 1]) {
- frontoffset = front - queue;
- rearoffset = rear - queue;
- qsize += QSIZE;
- if ((queue = (struct words **)realloc(queue,
- qsize * sizeof (struct words *))) == NULL) {
- perror("fgrep");
- exit(2);
- }
- front = queue + frontoffset;
- rear = queue + rearoffset;
- }
- }
- if ((s = s->link) != 0) {
- goto init;
- }
-
- while (rear != front) {
- s = *front++;
-cloop:
- if ((c = s->inp) != 0) {
- *rear++ = (q = s->nst);
- /*
- * Reallocate the queue if the rear pointer reaches the end
- * queue
- */
- if (rear >= &queue[qsize - 1]) {
- frontoffset = front - queue;
- rearoffset = rear - queue;
- qsize += QSIZE;
- if ((queue = (struct words **)realloc(queue,
- qsize * sizeof (struct words *))) == NULL) {
- perror("fgrep");
- exit(2);
- }
- front = queue + frontoffset;
- rear = queue + rearoffset;
- }
- state = s->fail;
-floop:
- if (state == 0)
- state = w;
- if (state->inp == c) {
-qloop:
- q->fail = state->nst;
- if ((state->nst)->out == 1)
- q->out = 1;
- if ((q = q->link) != 0)
- goto qloop;
- } else if ((state = state->link) != 0)
- goto floop;
- }
- if ((s = s->link) != 0)
- goto cloop;
- }
-}
-
-wchar_t
-letter(wchar_t c)
-{
- if (c >= 'a' && c <= 'z')
- return (c);
- if (c >= 'A' && c <= 'Z')
- return (c + 'a' - 'A');
- return (c);
-}
diff --git a/usr/src/cmd/grep/Makefile b/usr/src/cmd/grep/Makefile
index fe8ace2cf8..85d00f57fe 100644
--- a/usr/src/cmd/grep/Makefile
+++ b/usr/src/cmd/grep/Makefile
@@ -20,26 +20,54 @@
# CDDL HEADER END
#
#
-#ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright (c) 1989,1996, by Sun Microsystems, Inc.
-# All rights reserved.
+# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
#
-PROG= grep
+PROG= grep
+FFILE= fgrep
+EFILE= egrep
include ../Makefile.cmd
+CERRWARN += -_gcc=-Wno-parentheses
+CERRWARN += -_gcc=-Wno-uninitialized
+
+ROOTXPG4LINKS = $(ROOTXPG4BIN)/$(FFILE) $(ROOTXPG4BIN)/$(EFILE) $(ROOTXPG4BIN)/$(PROG)
+ROOTLINKS = $(ROOTBIN)/$(FFILE) $(ROOTBIN)/$(EFILE)
+
+CFLAGS += $(CCVERBOSE)
CPPFLAGS += -D_FILE_OFFSET_BITS=64
-LDLIBS += -lgen
-XGETFLAGS += -a -x grep.xcl
+POFILE= grep_xpg4.po
+POFILES= grep.po
.KEEP_STATE:
-all: $(PROG)
+all: $(PROG)
+
+install: all $(ROOTPROG) $(ROOTLINKS) $(ROOTXPG4LINKS)
+
+$(ROOTLINKS): $(ROOTPROG)
+ -$(RM) $@
+ -$(LN) $(ROOTPROG) $@
+
+$(ROOTXPG4LINKS): $(ROOTPROG)
+ -$(RM) $@
+ -$(SYMLINK) ../../bin/grep $@
+
+$(POFILE): $(POFILES)
+ $(RM) $@
+ $(CP) $(POFILES) $@
+
+# Make the links locally for test purposes
+test: $(FFILE) $(EFILE)
+
+$(FFILE): $(PROG)
+ @$(RM) $(FFILE); $(LN) $(PROG) $(FFILE)
-install: all $(ROOTPROG)
+$(EFILE): $(PROG)
+ @$(RM) $(EFILE); $(LN) $(PROG) $(EFILE)
clean:
diff --git a/usr/src/cmd/grep/grep.c b/usr/src/cmd/grep/grep.c
index 44c91f8271..cb49a807c9 100644
--- a/usr/src/cmd/grep/grep.c
+++ b/usr/src/cmd/grep/grep.c
@@ -20,217 +20,464 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-/* Copyright (c) 1987, 1988 Microsoft Corporation */
-/* All Rights Reserved */
-
-/* Copyright 2012 Nexenta Systems, Inc. All rights reserved. */
-
/*
- * Copyright 2013 Damian Bogel. All rights reserved.
+ * grep - pattern matching program - combined grep, egrep, and fgrep.
+ * Based on MKS grep command, with XCU & Solaris mods.
*/
/*
- * grep -- print lines matching (or not matching) a pattern
+ * Copyright 1985, 1992 by Mortice Kern Systems Inc. All rights reserved.
*
- * status returns:
- * 0 - ok, and some matches
- * 1 - ok, but no matches
- * 2 - some error
*/
-#include <sys/types.h>
+/* Copyright 2017 Nexenta Systems, Inc. All rights reserved. */
+/*
+ * Copyright 2013 Damian Bogel. All rights reserved.
+ */
+
+#include <string.h>
+#include <stdlib.h>
#include <ctype.h>
+#include <stdarg.h>
+#include <regex.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include <fcntl.h>
-#include <locale.h>
-#include <memory.h>
-#include <regexpr.h>
#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#include <locale.h>
+#include <wchar.h>
+#include <errno.h>
#include <unistd.h>
+#include <wctype.h>
#include <ftw.h>
-#include <limits.h>
#include <sys/param.h>
-static const char *errstr[] = {
- "Range endpoint too large.",
- "Bad number.",
- "``\\digit'' out of range.",
- "No remembered search string.",
- "\\( \\) imbalance.",
- "Too many \\(.",
- "More than 2 numbers given in \\{ \\}.",
- "} expected after \\.",
- "First number exceeds second in \\{ \\}.",
- "[ ] imbalance.",
- "Regular expression overflow.",
- "Illegal byte sequence.",
- "Unknown regexp error code!!",
- NULL
-};
-
-#define STDIN_FILENAME gettext("(standard input)")
-
-#define errmsg(msg, arg) (void) fprintf(stderr, gettext(msg), arg)
-#define BLKSIZE 512
-#define GBUFSIZ 8192
-#define MAX_DEPTH 1000
-
-static int temp;
-static long long lnum;
-static char *linebuf;
-static char *prntbuf = NULL;
-static long fw_lPrntBufLen = 0;
-static int nflag;
-static int bflag;
-static int lflag;
-static int cflag;
-static int rflag;
-static int Rflag;
-static int vflag;
-static int sflag;
-static int iflag;
-static int wflag;
-static int hflag;
-static int Hflag;
-static int qflag;
-static int errflg;
-static int nfile;
-static long long tln;
-static int nsucc;
-static int outfn = 0;
-static int nlflag;
-static char *ptr, *ptrend;
-static char *expbuf;
-
-static void execute(const char *, int);
-static void regerr(int);
-static void prepare(const char *);
+#define STDIN_FILENAME gettext("(standard input)")
+
+#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 */
+
+typedef struct _PATTERN {
+ char *pattern; /* original pattern */
+ wchar_t *wpattern; /* wide, lowercased pattern */
+ struct _PATTERN *next;
+ regex_t re; /* compiled pattern */
+} PATTERN;
+
+static PATTERN *patterns;
+static char errstr[128]; /* regerror string buffer */
+static int regflags = 0; /* regcomp options */
+static int matched = 0; /* return of the grep() */
+static int errors = 0; /* count of errors */
+static uchar_t fgrep = 0; /* Invoked as fgrep */
+static uchar_t egrep = 0; /* Invoked as egrep */
+static boolean_t nvflag = B_TRUE; /* Print matching lines */
+static uchar_t cflag; /* Count of matches */
+static uchar_t iflag; /* Case insensitve matching */
+static uchar_t Hflag; /* Precede lines by file name */
+static uchar_t hflag; /* Supress printing of filename */
+static uchar_t lflag; /* Print file names of matches */
+static uchar_t nflag; /* Precede lines by line number */
+static uchar_t rflag; /* Search directories recursively */
+static uchar_t bflag; /* Preccede matches by block number */
+static uchar_t sflag; /* Suppress file error messages */
+static uchar_t qflag; /* Suppress standard output */
+static uchar_t wflag; /* Search for expression as a word */
+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);
+static void usage(void);
+static int grep(int, const char *);
+static void bmgcomp(char *, int);
+static char *bmgexec(char *, char *);
static int recursive(const char *, const struct stat *, int, struct FTW *);
-static int succeed(const char *);
+static void process_path(const char *);
+static void process_file(const char *, int);
+/*
+ * mainline for grep
+ */
int
main(int argc, char **argv)
{
+ char *ap, *test;
int c;
- char *arg;
- extern int optind;
+ int fflag = 0;
+ int i, n_pattern = 0, n_file = 0;
+ char **pattern_list = NULL;
+ char **file_list = NULL;
(void) setlocale(LC_ALL, "");
#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
-#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
+#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
#endif
(void) textdomain(TEXT_DOMAIN);
- while ((c = getopt(argc, argv, "hHqblcnRrsviyw")) != -1)
- switch (c) {
- /* based on options order h or H is set as in GNU grep */
- case 'h':
- hflag++;
- Hflag = 0; /* h excludes H */
+ /*
+ * true if this is running on the multibyte locale
+ */
+ mblocale = (MB_CUR_MAX > 1);
+ /*
+ * Skip leading slashes
+ */
+ cmdname = argv[0];
+ if (ap = strrchr(cmdname, '/'))
+ cmdname = ap + 1;
+
+ ap = cmdname;
+ /*
+ * Detect egrep/fgrep via command name, map to -E and -F options.
+ */
+ if (*ap == 'e' || *ap == 'E') {
+ regflags |= REG_EXTENDED;
+ egrep++;
+ } else {
+ 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;
- case 'H':
- if (!lflag) /* H is excluded by l */
- Hflag++;
- hflag = 0; /* H excludes h */
+
+ /* isdigit() check prevents negative arguments */
+ 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();
+ }
+
+ errno = 0;
+ conalen = conblen = strtoul(&argv[i][1], (char **)NULL,
+ 10);
+
+ if (errno != 0 || conalen >= ULONG_MAX) {
+ (void) fprintf(stderr, gettext(
+ "%s: Bad context argument\n"), argv[0]);
+ } else 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 = B_FALSE;
break;
- case 'q': /* POSIX: quiet: status only */
- qflag++;
+
+ case 'c': /* POSIX: write count */
+ cflag++;
break;
- case 'v':
- vflag++;
+
+ case 'i': /* POSIX: ignore case */
+ iflag++;
+ regflags |= REG_ICASE;
break;
- case 'c':
- cflag++;
+
+ case 'l': /* POSIX: Write filenames only */
+ lflag++;
break;
- case 'n':
+
+ case 'n': /* POSIX: Write line numbers */
nflag++;
break;
- case 'R':
- Rflag++;
- /* FALLTHROUGH */
- case 'r':
+
+ case 'r': /* Solaris: search recursively */
rflag++;
break;
- case 'b':
+
+ case 'b': /* Solaris: Write file block numbers */
bflag++;
break;
- case 's':
+
+ case 's': /* POSIX: No error msgs for files */
sflag++;
break;
- case 'l':
- lflag++;
- Hflag = 0; /* l excludes H */
+
+ case 'e': /* POSIX: pattern list */
+ n_pattern++;
+ pattern_list = realloc(pattern_list,
+ sizeof (char *) * n_pattern);
+ if (pattern_list == NULL) {
+ (void) fprintf(stderr,
+ gettext("%s: out of memory\n"),
+ cmdname);
+ exit(2);
+ }
+ *(pattern_list + n_pattern - 1) = optarg;
break;
- case 'y':
- case 'i':
- iflag++;
+
+ case 'f': /* POSIX: pattern file */
+ fflag = 1;
+ n_file++;
+ file_list = realloc(file_list,
+ sizeof (char *) * n_file);
+ if (file_list == NULL) {
+ (void) fprintf(stderr,
+ gettext("%s: out of memory\n"),
+ cmdname);
+ exit(2);
+ }
+ *(file_list + n_file - 1) = optarg;
break;
- case 'w':
+
+ /* based on options order h or H is set as in GNU grep */
+ case 'h': /* Solaris: supress printing of file name */
+ hflag = 1;
+ Hflag = 0;
+ break;
+ /* Solaris: precede every matching with file name */
+ case 'H':
+ Hflag = 1;
+ hflag = 0;
+ break;
+
+ case 'q': /* POSIX: quiet: status only */
+ qflag++;
+ break;
+
+ case 'w': /* Solaris: treat pattern as word */
wflag++;
break;
- case '?':
- errflg++;
+
+ case 'x': /* POSIX: full line matches */
+ xflag++;
+ regflags |= REG_ANCHOR;
+ break;
+
+ case 'E': /* POSIX: Extended RE's */
+ regflags |= REG_EXTENDED;
+ Eflag++;
+ break;
+
+ case 'F': /* POSIX: strings, not RE's */
+ Fflag++;
+ break;
+
+ case 'R': /* Solaris: like rflag, but follow symlinks */
+ Rflag++;
+ rflag++;
+ break;
+
+ case 'A': /* print N lines after each match */
+ errno = 0;
+ conalen = strtoul(optarg, &test, 10);
+ /* *test will be non-null if optarg is negative */
+ if (errno != 0 || *test != '\0' ||
+ conalen >= ULONG_MAX) {
+ (void) fprintf(stderr, gettext(
+ "%s: Bad context argument: %s\n"),
+ argv[0], optarg);
+ exit(2);
+ }
+ if (conalen)
+ conflag |= AFTER;
+ else
+ conflag &= ~AFTER;
+ break;
+ case 'B': /* print N lines before each match */
+ errno = 0;
+ conblen = strtoul(optarg, &test, 10);
+ /* *test will be non-null if optarg is negative */
+ if (errno != 0 || *test != '\0' ||
+ conblen >= ULONG_MAX) {
+ (void) fprintf(stderr, gettext(
+ "%s: Bad context argument: %s\n"),
+ argv[0], optarg);
+ exit(2);
+ }
+ if (conblen)
+ conflag |= BEFORE;
+ else
+ conflag &= ~BEFORE;
+ break;
+ case 'C': /* print N lines around each match */
+ errno = 0;
+ tval = strtoul(optarg, &test, 10);
+ /* *test will be non-null if optarg is negative */
+ if (errno != 0 || *test != '\0' || tval >= ULONG_MAX) {
+ (void) fprintf(stderr, gettext(
+ "%s: Bad context argument: %s\n"),
+ argv[0], optarg);
+ exit(2);
+ }
+ if (tval) {
+ if ((conflag & BEFORE) == 0)
+ conblen = tval;
+ if ((conflag & AFTER) == 0)
+ conalen = tval;
+ conflag = CONTEXT;
+ }
+ break;
+
+ default:
+ usage();
}
+ }
+ /*
+ * If we're invoked as egrep or fgrep we need to do some checks
+ */
- if (errflg || (optind >= argc)) {
- errmsg("Usage: grep [-c|-l|-q] [-r|-R] -hHbnsviw "
- "pattern file . . .\n",
- (char *)NULL);
- exit(2);
+ if (egrep || fgrep) {
+ /*
+ * Use of -E or -F with egrep or fgrep is illegal
+ */
+ if (Eflag || Fflag)
+ usage();
+ /*
+ * Don't allow use of wflag with egrep / fgrep
+ */
+ if (wflag)
+ usage();
+ /*
+ * For Solaris the -s flag is equivalent to XCU -q
+ */
+ if (sflag)
+ qflag++;
+ /*
+ * done with above checks - set the appropriate flags
+ */
+ if (egrep)
+ Eflag++;
+ else /* Else fgrep */
+ Fflag++;
}
- argv = &argv[optind];
- argc -= optind;
- nfile = argc - 1;
+ if (wflag && (Eflag || Fflag)) {
+ /*
+ * -w cannot be specified with grep -F
+ */
+ usage();
+ }
- if (strrchr(*argv, '\n') != NULL)
- regerr(41);
+ /*
+ * -E and -F flags are mutually exclusive - check for this
+ */
+ if (Eflag && Fflag)
+ usage();
- if (iflag) {
- for (arg = *argv; *arg != NULL; ++arg)
- *arg = (char)tolower((int)((unsigned char)*arg));
- }
+ /*
+ * -l overrides -H like in GNU grep
+ */
+ if (lflag)
+ Hflag = 0;
+
+ /*
+ * -c, -l and -q flags are mutually exclusive
+ * We have -c override -l like in Solaris.
+ * -q overrides -l & -c programmatically in grep() function.
+ */
+ if (cflag && lflag)
+ lflag = 0;
- if (wflag) {
- unsigned int wordlen;
- char *wordbuf;
+ argv += optind - 1;
+ argc -= optind - 1;
- wordlen = strlen(*argv) + 5; /* '\\' '<' *argv '\\' '>' '\0' */
- if ((wordbuf = malloc(wordlen)) == NULL) {
- errmsg("grep: Out of memory for word\n", (char *)NULL);
- exit(2);
+ /*
+ * Now handling -e and -f option
+ */
+ if (pattern_list) {
+ for (i = 0; i < n_pattern; i++) {
+ addpattern(pattern_list[i]);
+ }
+ free(pattern_list);
+ }
+ if (file_list) {
+ for (i = 0; i < n_file; i++) {
+ addfile(file_list[i]);
}
+ free(file_list);
+ }
- (void) strcpy(wordbuf, "\\<");
- (void) strcat(wordbuf, *argv);
- (void) strcat(wordbuf, "\\>");
- *argv = wordbuf;
+ /*
+ * No -e or -f? Make sure there is one more arg, use it as the pattern.
+ */
+ if (patterns == NULL && !fflag) {
+ if (argc < 2)
+ usage();
+ addpattern(argv[1]);
+ argc--;
+ argv++;
}
- expbuf = compile(*argv, (char *)0, (char *)0);
- if (regerrno)
- regerr(regerrno);
+ /*
+ * If -x flag is not specified or -i flag is specified
+ * with fgrep in a multibyte locale, need to use
+ * the wide character APIs. Otherwise, byte-oriented
+ * process will be done.
+ */
+ use_wchar = Fflag && mblocale && (!xflag || iflag);
+
+ /*
+ * Compile Patterns and also decide if BMG can be used
+ */
+ fixpatterns();
+
+ /* Process all files: stdin, or rest of arg list */
+ if (argc < 2) {
+ matched = grep(0, STDIN_FILENAME);
+ } else {
+ if (Hflag || (argc > 2 && hflag == 0))
+ outfn = 1; /* Print filename on match line */
+ for (argv++; *argv != NULL; argv++) {
+ process_path(*argv);
+ }
+ }
+ /*
+ * Return() here is used instead of exit
+ */
- if (--argc == 0)
- execute(NULL, 0);
- else
- while (argc-- > 0)
- prepare(*++argv);
+ (void) fflush(stdout);
- return (nsucc == 2 ? 2 : (nsucc == 0 ? 1 : 0));
+ if (errors)
+ return (2);
+ return (matched ? 0 : 1);
}
static void
-prepare(const char *path)
+process_path(const char *path)
{
struct stat st;
int walkflags = FTW_CHDIR;
@@ -239,7 +486,7 @@ prepare(const char *path)
if (rflag) {
if (stat(path, &st) != -1 &&
(st.st_mode & S_IFMT) == S_IFDIR) {
- outfn = 1;
+ outfn = 1; /* Print filename */
/*
* Add trailing slash if arg
@@ -260,273 +507,1134 @@ prepare(const char *path)
if (nftw(path, recursive, MAX_DEPTH, walkflags) != 0) {
if (!sflag)
- errmsg("grep: can't open %s\n", path);
- nsucc = 2;
+ (void) fprintf(stderr,
+ gettext("%s: can't open \"%s\"\n"),
+ cmdname, path);
+ errors = 1;
}
return;
}
}
- execute(path, 0);
+ process_file(path, 0);
}
+/*
+ * Read and process all files in directory recursively.
+ */
static int
recursive(const char *name, const struct stat *statp, int info, struct FTW *ftw)
{
/*
- * process files and follow symlinks if Rflag set.
+ * Process files and follow symlinks if Rflag set.
*/
if (info != FTW_F) {
+ /* Report broken symlinks and unreadable files */
if (!sflag &&
(info == FTW_SLN || info == FTW_DNR || info == FTW_NS)) {
- /* report broken symlinks and unreadable files */
- errmsg("grep: can't open %s\n", name);
+ (void) fprintf(stderr,
+ gettext("%s: can't open \"%s\"\n"), cmdname, name);
}
return (0);
}
- /* skip devices and pipes if Rflag is not set */
+
+ /* Skip devices and pipes if Rflag is not set */
if (!Rflag && !S_ISREG(statp->st_mode))
return (0);
-
- /* pass offset to relative name from FTW_CHDIR */
- execute(name, ftw->base);
+ /* Pass offset to relative name from FTW_CHDIR */
+ process_file(name, ftw->base);
return (0);
}
+/*
+ * Opens file and call grep function.
+ */
static void
-execute(const char *file, int base)
+process_file(const char *name, int base)
{
- char *lbuf, *p;
- long count;
- long offset = 0;
- char *next_ptr = NULL;
- long next_count = 0;
+ int fd;
- tln = 0;
+ if ((fd = open(name + base, O_RDONLY)) == -1) {
+ errors = 1;
+ if (!sflag) /* Silent mode */
+ (void) fprintf(stderr, gettext(
+ "%s: can't open \"%s\"\n"),
+ cmdname, name);
+ return;
+ }
+ matched |= grep(fd, name);
+ (void) close(fd);
- if (prntbuf == NULL) {
- fw_lPrntBufLen = GBUFSIZ + 1;
- if ((prntbuf = malloc(fw_lPrntBufLen)) == NULL) {
- exit(2); /* out of memory - BAIL */
+ if (ferror(stdout)) {
+ (void) fprintf(stderr, gettext(
+ "%s: error writing to stdout\n"),
+ cmdname);
+ (void) fflush(stdout);
+ exit(2);
+ }
+
+}
+
+/*
+ * Add a file of strings to the pattern list.
+ */
+static void
+addfile(const char *fn)
+{
+ FILE *fp;
+ char *inbuf;
+ char *bufp;
+ size_t bufsiz, buflen, bufused;
+
+ /*
+ * Open the pattern file
+ */
+ if ((fp = fopen(fn, "r")) == NULL) {
+ (void) fprintf(stderr, gettext("%s: can't open \"%s\"\n"),
+ cmdname, fn);
+ exit(2);
+ }
+ bufsiz = BUFSIZE;
+ if ((inbuf = malloc(bufsiz)) == NULL) {
+ (void) fprintf(stderr,
+ gettext("%s: out of memory\n"), cmdname);
+ exit(2);
+ }
+ bufp = inbuf;
+ bufused = 0;
+ /*
+ * Read in the file, reallocing as we need more memory
+ */
+ while (fgets(bufp, bufsiz - bufused, fp) != NULL) {
+ buflen = strlen(bufp);
+ bufused += buflen;
+ if (bufused + 1 == bufsiz && bufp[buflen - 1] != '\n') {
+ /*
+ * if this line does not fit to the buffer,
+ * realloc larger buffer
+ */
+ bufsiz += BUFSIZE;
+ if ((inbuf = realloc(inbuf, bufsiz)) == NULL) {
+ (void) fprintf(stderr,
+ gettext("%s: out of memory\n"),
+ cmdname);
+ exit(2);
+ }
+ bufp = inbuf + bufused;
+ continue;
}
- if ((linebuf = malloc(fw_lPrntBufLen)) == NULL) {
- exit(2); /* out of memory - BAIL */
+ if (bufp[buflen - 1] == '\n') {
+ bufp[--buflen] = '\0';
}
+ addpattern(inbuf);
+
+ bufp = inbuf;
+ bufused = 0;
}
+ free(inbuf);
+ free(prntbuf);
+ free(conbuf);
+ (void) fclose(fp);
+}
- if (file == NULL) {
- temp = 0;
- file = STDIN_FILENAME;
- } else if ((temp = open(file + base, O_RDONLY)) == -1) {
- if (!sflag)
- errmsg("grep: can't open %s\n", file);
- nsucc = 2;
- return;
+/*
+ * Add a string to the pattern list.
+ */
+static void
+addpattern(char *s)
+{
+ PATTERN *pp;
+ char *wordbuf;
+ char *np;
+
+ for (; ; ) {
+ np = strchr(s, '\n');
+ if (np != NULL)
+ *np = '\0';
+ if ((pp = malloc(sizeof (PATTERN))) == NULL) {
+ (void) fprintf(stderr, gettext(
+ "%s: out of memory\n"),
+ cmdname);
+ exit(2);
+ }
+ if (wflag) {
+ /*
+ * Solaris wflag support: Add '<' '>' to pattern to
+ * select it as a word. Doesn't make sense with -F
+ * but we're Libertarian.
+ */
+ size_t slen, wordlen;
+
+ slen = strlen(s);
+ wordlen = slen + 5; /* '\\' '<' s '\\' '>' '\0' */
+ if ((wordbuf = malloc(wordlen)) == NULL) {
+ (void) fprintf(stderr,
+ gettext("%s: out of memory\n"),
+ cmdname);
+ exit(2);
+ }
+ (void) strcpy(wordbuf, "\\<");
+ (void) strcpy(wordbuf + 2, s);
+ (void) strcpy(wordbuf + 2 + slen, "\\>");
+ } else {
+ if ((wordbuf = strdup(s)) == NULL) {
+ (void) fprintf(stderr,
+ gettext("%s: out of memory\n"),
+ cmdname);
+ exit(2);
+ }
+ }
+ pp->pattern = wordbuf;
+ pp->next = patterns;
+ patterns = pp;
+ if (np == NULL)
+ break;
+ s = np + 1;
}
+}
+
+/*
+ * Fix patterns.
+ * Must do after all arguments read, in case later -i option.
+ */
+static void
+fixpatterns(void)
+{
+ PATTERN *pp;
+ int rv, fix_pattern, npatterns;
- /* read in first block of bytes */
- if ((count = read(temp, prntbuf, GBUFSIZ)) <= 0) {
- (void) close(temp);
+ /*
+ * As REG_ANCHOR flag is not supported in the current Solaris,
+ * need to fix the specified pattern if -x is specified with
+ * grep or egrep
+ */
+ fix_pattern = !Fflag && xflag;
+
+ for (npatterns = 0, pp = patterns; pp != NULL; pp = pp->next) {
+ npatterns++;
+ if (fix_pattern) {
+ char *cp, *cq;
+ size_t plen, nplen;
- if (cflag && !qflag) {
- if (Hflag || (nfile > 1 && !hflag))
- (void) fprintf(stdout, "%s:", file);
- if (!rflag)
- (void) fprintf(stdout, "%lld\n", tln);
+ plen = strlen(pp->pattern);
+ /* '^' pattern '$' */
+ nplen = 1 + plen + 1 + 1;
+ if ((cp = malloc(nplen)) == NULL) {
+ (void) fprintf(stderr,
+ gettext("%s: out of memory\n"),
+ cmdname);
+ exit(2);
+ }
+ cq = cp;
+ *cq++ = '^';
+ cq = strcpy(cq, pp->pattern) + plen;
+ *cq++ = '$';
+ *cq = '\0';
+ free(pp->pattern);
+ pp->pattern = cp;
}
- return;
+
+ if (Fflag) {
+ if (use_wchar) {
+ /*
+ * Fflag && mblocale && iflag
+ * Fflag && mblocale && !xflag
+ */
+ size_t n;
+ n = strlen(pp->pattern) + 1;
+ if ((pp->wpattern =
+ malloc(sizeof (wchar_t) * n)) == NULL) {
+ (void) fprintf(stderr,
+ gettext("%s: out of memory\n"),
+ cmdname);
+ exit(2);
+ }
+ if (mbstowcs(pp->wpattern, pp->pattern, n) ==
+ (size_t)-1) {
+ (void) fprintf(stderr,
+ gettext("%s: failed to convert "
+ "\"%s\" to wide-characters\n"),
+ cmdname, pp->pattern);
+ exit(2);
+ }
+ if (iflag) {
+ wchar_t *wp;
+ for (wp = pp->wpattern; *wp != L'\0';
+ wp++) {
+ *wp = towlower((wint_t)*wp);
+ }
+ }
+ free(pp->pattern);
+ } else {
+ /*
+ * Fflag && mblocale && !iflag
+ * Fflag && !mblocale && iflag
+ * Fflag && !mblocale && !iflag
+ */
+ if (iflag) {
+ unsigned char *cp;
+ for (cp = (unsigned char *)pp->pattern;
+ *cp != '\0'; cp++) {
+ *cp = tolower(*cp);
+ }
+ }
+ }
+ /*
+ * fgrep: No regular expressions.
+ */
+ continue;
+ }
+
+ /*
+ * For non-fgrep, compile the regular expression,
+ * give an informative error message, and exit if
+ * it didn't compile.
+ */
+ if ((rv = regcomp(&pp->re, pp->pattern, regflags)) != 0) {
+ (void) regerror(rv, &pp->re, errstr, sizeof (errstr));
+ (void) fprintf(stderr,
+ gettext("%s: RE error in %s: %s\n"),
+ cmdname, pp->pattern, errstr);
+ exit(2);
+ }
+ free(pp->pattern);
+ }
+
+ /*
+ * Decide if we are able to run the Boyer-Moore-Gosper algorithm.
+ * Use the Boyer-Moore-Gosper algorithm if:
+ * - fgrep (Fflag)
+ * - singlebyte locale (!mblocale)
+ * - 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 == 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) &&
+ conflag == 0;
+}
+
+/*
+ * Search a newline from the beginning of the string
+ */
+static char *
+find_nl(const char *ptr, size_t len)
+{
+ while (len-- != 0) {
+ if (*ptr++ == '\n') {
+ return ((char *)--ptr);
+ }
+ }
+ return (NULL);
+}
+
+/*
+ * Search a newline from the end of the string
+ */
+static char *
+rfind_nl(const char *ptr, size_t len)
+{
+ const char *uptr = ptr + len;
+ while (len--) {
+ if (*--uptr == '\n') {
+ return ((char *)uptr);
+ }
+ }
+ return (NULL);
+}
+
+/*
+ * Duplicate the specified string converting each character
+ * into a lower case.
+ */
+static char *
+istrdup(const char *s1)
+{
+ static size_t ibuflen = 0;
+ static char *ibuf = NULL;
+ size_t slen;
+ char *p;
+
+ slen = strlen(s1);
+ if (slen >= ibuflen) {
+ /* ibuf does not fit to s1 */
+ ibuflen = slen + 1;
+ ibuf = realloc(ibuf, ibuflen);
+ if (ibuf == NULL) {
+ (void) fprintf(stderr,
+ gettext("%s: out of memory\n"), cmdname);
+ exit(2);
+ }
+ }
+ p = ibuf;
+ do {
+ *p++ = tolower(*s1);
+ } while (*s1++ != '\0');
+ return (ibuf);
+}
+
+/*
+ * Do grep on a single file.
+ * Return true in any lines matched.
+ *
+ * We have two strategies:
+ * The fast one is used when we have a single pattern with
+ * a string known to occur in the pattern. We can then
+ * do a BMG match on the whole buffer.
+ * This is an order of magnitude faster.
+ * Otherwise we split the buffer into lines,
+ * and check for a match on each line.
+ */
+static int
+grep(int fd, const char *fn)
+{
+ 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;
+ boolean_t nearmatch; /* w/in N+1 of last match */
+ boolean_t havematch = B_FALSE; /* have a match in context */
+ size_t prntlen;
+
+ if (patterns == NULL)
+ return (0); /* no patterns to match -- just return */
+
+ pp = patterns;
+
+ if (use_bmg) {
+ bmgcomp(pp->pattern, strlen(pp->pattern));
}
- lnum = 0;
- ptr = prntbuf;
- for (;;) {
- /* look for next newline */
- if ((ptrend = memchr(ptr + offset, '\n', count)) == NULL) {
- offset += count;
+ if (use_wchar && outline == NULL) {
+ outbuflen = BUFSIZE + 1;
+ outline = malloc(sizeof (wchar_t) * outbuflen);
+ if (outline == NULL) {
+ (void) fprintf(stderr, gettext("%s: out of memory\n"),
+ cmdname);
+ exit(2);
+ }
+ }
+
+ if (prntbuf == NULL) {
+ prntbuflen = BUFSIZE;
+ if ((prntbuf = malloc(prntbuflen + 1)) == NULL) {
+ (void) fprintf(stderr, gettext("%s: out of memory\n"),
+ cmdname);
+ exit(2);
+ }
+ }
+
+ if (conflag != 0 && (conbuf == NULL)) {
+ conbuflen = BUFSIZE;
+ if ((conbuf = malloc(BUFSIZE+1)) == NULL) {
+ (void) fprintf(stderr, gettext("%s: out of memory\n"),
+ cmdname);
+ exit(2);
+ }
+ }
+ nearmatch = (conmatches != 0);
+ blkoffset = line_offset = 0;
+ lineno = 0;
+ linenum = 1;
+ newlinep = 1;
+ data_len = 0;
+ for (; ; ) {
+ long count;
+ off_t offset = 0;
+ char separate;
+ boolean_t last_ctx = B_FALSE, eof = B_FALSE;
+
+ if (data_len == 0) {
+ /*
+ * If no data in the buffer, reset ptr
+ */
+ ptr = prntbuf;
+ if (conflag != 0 && conptr == NULL) {
+ conptr = conbuf;
+ conptrend = conptr - 1;
+ }
+ }
+ if (ptr == prntbuf) {
/*
- * shift unused data to the beginning of the buffer
+ * The current data chunk starts from prntbuf.
+ * This means either the buffer has no data
+ * or the buffer has no newline.
+ * So, read more data from input.
*/
+ count = read(fd, ptr + data_len, prntbuflen - data_len);
+ if (count < 0) {
+ /* read error */
+ if (cflag) {
+ if (outfn && !rflag) {
+ (void) fprintf(stdout,
+ "%s:", fn);
+ }
+ if (!qflag && !rflag) {
+ (void) fprintf(stdout, "%lld\n",
+ matches);
+ }
+ }
+ return (0);
+ } else if (count == 0) {
+ /* no new data */
+ eof = B_TRUE;
+
+ if (data_len == 0) {
+ /* end of file already reached */
+ if (conflag != 0) {
+ if (conptrend >= conptr)
+ *conptrend = '\n';
+ last_ctx = B_TRUE;
+ goto L_next_line;
+ } else {
+ goto out;
+ }
+ }
+ /* last line of file has no newline */
+ ptrend = ptr + data_len;
+ newlinep = 0;
+ goto L_start_process;
+ }
+ offset = data_len;
+ data_len += count;
+ }
+
+ /*
+ * Look for newline in the chunk
+ * between ptr + offset and ptr + data_len - offset.
+ */
+ ptrend = find_nl(ptr + offset, data_len - offset);
+ if (ptrend == NULL) {
+ /* no newline found in this chunk */
if (ptr > prntbuf) {
- (void) memmove(prntbuf, ptr, offset);
- ptr = prntbuf;
+ /*
+ * Move remaining data to the beginning
+ * of the buffer.
+ * Remaining data lie from ptr for
+ * data_len bytes.
+ */
+ (void) memmove(prntbuf, ptr, data_len);
}
+ if (data_len == prntbuflen) {
+ /*
+ * Not enough room in the buffer
+ */
+ if (prntbuflen > SIZE_MAX - BUFSIZE) {
+ (void) fprintf(stderr,
+ gettext("%s: buflen would"
+ " overflow\n"),
+ cmdname);
+ exit(2);
+ }
+
+ prntbuflen += BUFSIZE;
+ prntbuf = realloc(prntbuf, prntbuflen + 1);
+ if (prntbuf == NULL) {
+ (void) fprintf(stderr,
+ gettext("%s: out of memory\n"),
+ cmdname);
+ exit(2);
+ }
+ }
+ ptr = prntbuf;
+ /* read the next input */
+ continue;
+ }
+L_start_process:
+ /*
+ * Beginning of the chunk: ptr
+ * End of the chunk: ptr + data_len
+ * Beginning of the line: ptr
+ * End of the line: ptrend
+ *
+ * conptr: Beginning of the context.
+ * conptrend: If context is empty, conptr - 1 (invalid memory).
+ * Otherwise, Last newline in the context.
+ */
+
+ if (use_bmg) {
/*
- * re-allocate a larger buffer if this one is full
+ * Use Boyer-Moore-Gosper algorithm to find out if
+ * this chunk (not this line) contains the specified
+ * pattern. If not, restart from the last line
+ * of this chunk.
*/
- if (offset + GBUFSIZ > fw_lPrntBufLen) {
+ char *bline;
+ bline = bmgexec(ptr, ptr + data_len);
+ if (bline == NULL) {
/*
- * allocate a new buffer and preserve the
- * contents...
+ * No pattern found in this chunk.
+ * Need to find the last line
+ * in this chunk.
*/
- fw_lPrntBufLen += GBUFSIZ;
- if ((prntbuf = realloc(prntbuf,
- fw_lPrntBufLen)) == NULL)
- exit(2);
+ ptrend = rfind_nl(ptr, data_len);
/*
- * set up a bigger linebuffer (this is only used
- * for case insensitive operations). Contents do
- * not have to be preserved.
+ * When this chunk does not contain newline,
+ * ptrend becomes NULL, which should happen
+ * when the last line of file does not end
+ * with a newline. At such a point,
+ * newlinep should have been set to 0.
+ * Therefore, just after jumping to
+ * L_skip_line, the main for-loop quits,
+ * and the line_len value won't be
+ * used.
+ */
+ line_len = ptrend - ptr;
+ goto L_skip_line;
+ }
+ if (bline > ptrend) {
+ /*
+ * Pattern found not in the first line
+ * of this chunk.
+ * Discard the first line.
*/
- free(linebuf);
- if ((linebuf = malloc(fw_lPrntBufLen)) == NULL)
+ line_len = ptrend - ptr;
+ goto L_skip_line;
+ }
+ /*
+ * Pattern found in the first line of this chunk.
+ * Using this result.
+ */
+ *ptrend = '\0';
+ line_len = ptrend - ptr;
+
+ /*
+ * before jumping to L_next_line,
+ * need to handle xflag if specified
+ */
+ if (xflag && (line_len != bmglen ||
+ strcmp(bmgpat, ptr) != 0)) {
+ /* didn't match */
+ pp = NULL;
+ } else {
+ pp = patterns; /* to make it happen */
+ }
+ goto L_next_line;
+ }
+ lineno++;
+ /*
+ * Line starts from ptr and ends at ptrend.
+ * line_len will be the length of the line.
+ */
+ *ptrend = '\0';
+ line_len = ptrend - ptr;
+
+ /*
+ * From now, the process will be performed based
+ * on the line from ptr to ptrend.
+ */
+ if (use_wchar) {
+ size_t len;
+
+ if (line_len >= outbuflen) {
+ outbuflen = line_len + 1;
+ outline = realloc(outline,
+ sizeof (wchar_t) * outbuflen);
+ if (outline == NULL) {
+ (void) fprintf(stderr,
+ gettext("%s: out of memory\n"),
+ cmdname);
exit(2);
+ }
+ }
- ptr = prntbuf;
+ len = mbstowcs(outline, ptr, line_len);
+ if (len == (size_t)-1) {
+ (void) fprintf(stderr, gettext(
+ "%s: input file \"%s\": line %lld: invalid multibyte character\n"),
+ cmdname, fn, lineno);
+ /* never match a line with invalid sequence */
+ goto L_skip_line;
}
+ outline[len] = L'\0';
- p = prntbuf + offset;
- if ((count = read(temp, p, GBUFSIZ)) > 0)
- continue;
+ if (iflag) {
+ wchar_t *cp;
+ for (cp = outline; *cp != '\0'; cp++) {
+ *cp = towlower((wint_t)*cp);
+ }
+ }
- if (offset == 0)
- /* end of file already reached */
- break;
+ if (xflag) {
+ for (pp = patterns; pp; pp = pp->next) {
+ if (outline[0] == pp->wpattern[0] &&
+ wcscmp(outline,
+ pp->wpattern) == 0) {
+ /* matched */
+ break;
+ }
+ }
+ } else {
+ for (pp = patterns; pp; pp = pp->next) {
+ if (wcswcs(outline, pp->wpattern)
+ != NULL) {
+ /* matched */
+ break;
+ }
+ }
+ }
+ } else if (Fflag) {
+ /* fgrep in byte-oriented handling */
+ char *fptr;
+ if (iflag) {
+ fptr = istrdup(ptr);
+ } else {
+ fptr = ptr;
+ }
+ if (xflag) {
+ /* 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;
- /* last line of file has no newline */
- ptrend = ptr + offset;
- nlflag = 0;
+ rv = regexec(&pp->re, ptr, 0, NULL, 0);
+ if (rv == REG_OK) {
+ /* matched */
+ break;
+ }
+
+ switch (rv) {
+ case REG_NOMATCH:
+ break;
+ case REG_ECHAR:
+ (void) fprintf(stderr, gettext(
+ "%s: input file \"%s\": line %lld: invalid multibyte character\n"),
+ cmdname, fn, lineno);
+ break;
+ default:
+ (void) regerror(rv, &pp->re, errstr,
+ sizeof (errstr));
+ (void) fprintf(stderr, gettext(
+ "%s: input file \"%s\": line %lld: %s\n"),
+ cmdname, fn, lineno, errstr);
+ 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 == 0)
+ goto L_next_line;
+
+ /* Do we have room to add this line to the context buffer? */
+ if ((line_len + 1) > (conbuflen -
+ (conptrend >= conptr) ? conptrend - conbuf : 0)) {
+ char *oldconbuf = conbuf;
+ char *oldconptr = conptr;
+ long tmp = matchptr - conptr;
+
+ if (conbuflen > SIZE_MAX - BUFSIZE) {
+ (void) fprintf(stderr,
+ gettext("%s: buflen would overflow\n"),
+ cmdname);
+ exit(2);
+ }
+
+ 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 + 1, ptr, line_len);
+ conptrend += line_len + 1;
+ *conptrend = '\n';
+
+ if (nvflag == (pp != NULL)) {
+ /* matched */
+ if (havematch) {
+ if ((conflag & AFTER) != 0) {
+ 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 -
+ (conptrend - conptr - line_len);
+ }
+
+ if (conflag == BEFORE)
+ conbprnt = 1;
+
+ lastmatch = conptrend - conptr;
+ havematch = B_TRUE;
+ goto L_next_line;
+ }
+
+ if (!havematch) {
+ if ((conflag & BEFORE) != 0) {
+ if (conbcnt >= conblen) {
+ char *tmp = conptr;
+ conptr = find_nl(conptr,
+ conptrend - conptr) + 1;
+ if (bflag)
+ blkoffset += conptr - tmp;
+ linenum++;
+ nearmatch = B_TRUE;
+ } else {
+ conbcnt++;
+ }
+ }
+ if (conflag == AFTER)
+ nearmatch = B_TRUE;
+ } 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 (!last_ctx && nvflag == (pp != NULL)) {
+ matches++;
+ if (!nextend)
+ matchptr = (conflag != 0) ? 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 (havematch && (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;
+ prntptr = conptr;
+ if (conmatches++ && nearmatch && !cflag)
+ (void) fwrite("--\n", 1, 3, stdout);
+ } else if (conflag == 0 && nvflag == (pp != NULL)) {
+ *ptrend = '\n';
+ prntlen = line_len + 1;
+ prntptr = ptr;
+ linenum = lineno;
+ blkoffset = line_offset;
+ } else if (eof) {
+ /* No match and no more data */
+ goto out;
} else {
- next_ptr = ptrend + 1;
- next_count = offset + count - (next_ptr - ptr);
- nlflag = 1;
+ /* No match, or we're not done building context */
+ goto L_skip_line;
}
- lnum++;
- *ptrend = '\0';
- if (iflag) {
+ prntptrend = prntptr - 1;
+ while ((prntptrend = find_nl(prntptrend + 1,
+ prntlen)) != NULL) {
+
/*
- * Make a lower case copy of the record
+ * GNU grep uses '-' for context lines and ':' for
+ * matching lines, so replicate that here.
*/
- p = ptr;
- for (lbuf = linebuf; p < ptrend; )
- *lbuf++ = (char)tolower((int)
- (unsigned char)*p++);
- *lbuf = '\0';
- lbuf = linebuf;
- } else
+ if (prntptrend == matchptr) {
+ if (eof && nextptr) {
+ matchptr = nextend;
+ nextptr = NULL;
+ } else {
+ matchptr = NULL;
+ }
+ separate = ':';
+ } else {
+ separate = '-';
+ }
+
/*
- * Use record as is
+ * Handle q, l, and c flags.
*/
- lbuf = ptr;
+ if (qflag) {
+ /* no need to continue */
+ /*
+ * End of this line is ptrend.
+ * We have read up to ptr + data_len.
+ */
+ off_t pos;
+ pos = ptr + data_len - (ptrend + 1);
+ (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;
+ }
- /* lflag only once */
- if ((step(lbuf, expbuf) ^ vflag) && succeed(file) == 1)
- break;
+ if (eof)
+ goto out;
+
+ /*
+ * Update context buffer and variables post-print
+ */
+ if (conflag != 0) {
+ conptr = conbuf;
+ conaprnt = conbprnt = 0;
+ nearmatch = B_FALSE;
+ 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;
+ havematch = B_TRUE;
+ } else {
+ conptrend = conptr - 1;
+ conacnt = 0;
+ lastmatch = 0;
+ havematch = B_FALSE;
+ }
+ nextptr = nextend = NULL;
+ }
- if (!nlflag)
+L_skip_line:
+ if (!newlinep)
break;
- ptr = next_ptr;
- count = next_count;
- offset = 0;
+ data_len -= line_len + 1;
+ line_offset += line_len + 1;
+ ptr = ptrend + 1;
}
- (void) close(temp);
- if (cflag && !qflag) {
- if (Hflag || (!hflag && ((nfile > 1) ||
- (rflag && outfn))))
- (void) fprintf(stdout, "%s:", file);
- (void) fprintf(stdout, "%lld\n", tln);
+out:
+ if (cflag) {
+ if (Hflag || outfn) {
+ (void) printf("%s:", fn);
+ }
+ if (!qflag) {
+ (void) printf("%lld\n", matches);
+ }
}
+ return (matches != 0);
}
-static int
-succeed(const char *f)
+/*
+ * usage message for grep
+ */
+static void
+usage(void)
{
- int nchars;
- nsucc = (nsucc == 2) ? 2 : 1;
+ if (egrep || fgrep) {
+ (void) fprintf(stderr, gettext("Usage:\t%s"), cmdname);
+ (void) fprintf(stderr,
+ gettext(" [-c|-l|-q] [-r|-R] "
+ "[-A num] [-B num] [-C num|-num] "
+ "[-bhHinsvx] pattern_list [file ...]\n"));
- if (qflag) {
- /* no need to continue */
- return (1);
- }
+ (void) fprintf(stderr, "\t%s", cmdname);
+ (void) fprintf(stderr,
+ gettext(" [-c|-l|-q] [-r|-R] "
+ "[-A num] [-B num] [-C num|-num] "
+ "[-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 num] [-B num] [-C num|-num] "
+ "[-bhHinsvx] pattern_list [file ...]\n"));
- if (cflag) {
- tln++;
- return (0);
- }
+ (void) fprintf(stderr, "\t%s", cmdname);
+ (void) fprintf(stderr,
+ gettext(" [-c|-l|-q] [-r|-R] "
+ "[-A num] [-B num] [-C num|-num] "
+ "[-bhHinsvx] [-e pattern_list]... "
+ "[-f pattern_file]... [file...]\n"));
- if (lflag) {
- (void) fprintf(stdout, "%s\n", f);
- return (1);
- }
+ (void) fprintf(stderr, "\t%s", cmdname);
+ (void) fprintf(stderr,
+ gettext(" -E [-c|-l|-q] [-r|-R] "
+ "[-A num] [-B num] [-C num|-num] "
+ "[-bhHinsvx] pattern_list [file ...]\n"));
- if (Hflag || (!hflag && (nfile > 1 || (rflag && outfn)))) {
- /* print filename */
- (void) fprintf(stdout, "%s:", f);
+ (void) fprintf(stderr, "\t%s", cmdname);
+ (void) fprintf(stderr,
+ gettext(" -E [-c|-l|-q] [-r|-R] "
+ "[-A num] [-B num] [-C num|-num] "
+ "[-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 num] [-B num] [-C num|-num] "
+ "[-bhHinsvx] pattern_list [file ...]\n"));
+
+ (void) fprintf(stderr, "\t%s", cmdname);
+ (void) fprintf(stderr,
+ gettext(" -F [-c|-l|-q] "
+ "[-A num] [-B num] [-C num|-num] "
+ "[-bhHinsvx] [-e pattern_list]... "
+ "[-f pattern_file]... [file...]\n"));
}
+ exit(2);
+ /* NOTREACHED */
+}
- if (bflag)
- /* print block number */
- (void) fprintf(stdout, "%lld:", (offset_t)
- ((lseek(temp, (off_t)0, SEEK_CUR) - 1) / BLKSIZE));
+/*
+ * Compile literal pattern into BMG tables
+ */
+static void
+bmgcomp(char *pat, int len)
+{
+ int i;
+ int tlen;
+ unsigned char *uc = (unsigned char *)pat;
- if (nflag)
- /* print line number */
- (void) fprintf(stdout, "%lld:", lnum);
+ bmglen = len;
+ bmgpat = pat;
- if (nlflag) {
- /* newline at end of line */
- *ptrend = '\n';
- nchars = ptrend - ptr + 1;
- } else {
- /* don't write sentinel \0 */
- nchars = ptrend - ptr;
+ for (i = 0; i < M_CSETSIZE; i++) {
+ bmgtab[i] = len;
}
- (void) fwrite(ptr, 1, nchars, stdout);
- return (0);
+ len--;
+ for (tlen = len, i = 0; i <= len; i++, tlen--) {
+ bmgtab[*uc++] = tlen;
+ }
}
-static void
-regerr(int err)
+/*
+ * BMG search.
+ */
+static char *
+bmgexec(char *str, char *end)
{
- errmsg("grep: RE error %d: ", err);
- switch (err) {
- case 11:
- err = 0;
- break;
- case 16:
- err = 1;
- break;
- case 25:
- err = 2;
- break;
- case 41:
- err = 3;
- break;
- case 42:
- err = 4;
- break;
- case 43:
- err = 5;
- break;
- case 44:
- err = 6;
- break;
- case 45:
- err = 7;
- break;
- case 46:
- err = 8;
- break;
- case 49:
- err = 9;
- break;
- case 50:
- err = 10;
- break;
- case 67:
- err = 11;
- break;
- default:
- err = 12;
- break;
- }
+ int t;
+ char *k, *s, *p;
- errmsg("%s\n", gettext(errstr[err]));
- exit(2);
+ k = str + bmglen - 1;
+ if (bmglen == 1) {
+ return (memchr(str, bmgpat[0], end - str));
+ }
+ for (; ; ) {
+ /* inner loop, should be most optimized */
+ while (k < end && (t = bmgtab[(unsigned char)*k]) != 0) {
+ k += t;
+ }
+ if (k >= end) {
+ return (NULL);
+ }
+ for (s = k, p = bmgpat + bmglen - 1; *--s == *--p; ) {
+ if (p == bmgpat) {
+ return (s);
+ }
+ }
+ k++;
+ }
+ /* NOTREACHED */
}
diff --git a/usr/src/cmd/grep/grep.xcl b/usr/src/cmd/grep/grep.xcl
deleted file mode 100644
index 8133757616..0000000000
--- a/usr/src/cmd/grep/grep.xcl
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-msgid ""
-msgid "hblcnsviy"
-msgid "%s[-c|-l|-q] [-bhinsv%sx]"
-msgid "%s:"
-msgid "%ld\n"
-msgid "%s\n"
-msgid "%ld:"
diff --git a/usr/src/cmd/grep_xpg4/Makefile b/usr/src/cmd/grep_xpg4/Makefile
deleted file mode 100644
index fb7c7d1a58..0000000000
--- a/usr/src/cmd/grep_xpg4/Makefile
+++ /dev/null
@@ -1,72 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-PROG= grep
-XPG4PROG= grep
-FFILE= fgrep
-EFILE= egrep
-
-include ../Makefile.cmd
-
-CERRWARN += -_gcc=-Wno-parentheses
-CERRWARN += -_gcc=-Wno-uninitialized
-
-ROOTXPG4LINKS = $(ROOTXPG4BIN)/$(FFILE) $(ROOTXPG4BIN)/$(EFILE)
-
-CFLAGS += $(CCVERBOSE)
-CPPFLAGS += -D_FILE_OFFSET_BITS=64
-
-POFILE= grep_xpg4.po
-POFILES= grep.po
-
-.KEEP_STATE:
-
-all: $(XPG4)
-
-install: all $(ROOTXPG4PROG) $(ROOTXPG4LINKS)
-
-$(ROOTXPG4LINKS): $(ROOTXPG4PROG)
- -$(RM) $@
- -$(LN) $(ROOTXPG4PROG) $@
-
-$(POFILE): $(POFILES)
- $(RM) $@
- $(CP) $(POFILES) $@
-
-# Make the links locally for test purposes
-test: $(FFILE) $(EFILE)
-
-$(FFILE): $(XPG4PROG)
- @$(RM) $(FFILE); $(LN) $(XPG4PROG) $(FFILE)
-
-$(EFILE): $(XPG4PROG)
- @$(RM) $(EFILE); $(LN) $(XPG4PROG) $(EFILE)
-
-clean:
-
-lint: lint_PROG
-
-include ../Makefile.targ
diff --git a/usr/src/cmd/grep_xpg4/grep.c b/usr/src/cmd/grep_xpg4/grep.c
deleted file mode 100644
index cb49a807c9..0000000000
--- a/usr/src/cmd/grep_xpg4/grep.c
+++ /dev/null
@@ -1,1640 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * grep - pattern matching program - combined grep, egrep, and fgrep.
- * Based on MKS grep command, with XCU & Solaris mods.
- */
-
-/*
- * Copyright 1985, 1992 by Mortice Kern Systems Inc. All rights reserved.
- *
- */
-
-/* Copyright 2017 Nexenta Systems, Inc. All rights reserved. */
-
-/*
- * Copyright 2013 Damian Bogel. All rights reserved.
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <regex.h>
-#include <limits.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <locale.h>
-#include <wchar.h>
-#include <errno.h>
-#include <unistd.h>
-#include <wctype.h>
-#include <ftw.h>
-#include <sys/param.h>
-
-#define STDIN_FILENAME gettext("(standard input)")
-
-#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 */
-
-typedef struct _PATTERN {
- char *pattern; /* original pattern */
- wchar_t *wpattern; /* wide, lowercased pattern */
- struct _PATTERN *next;
- regex_t re; /* compiled pattern */
-} PATTERN;
-
-static PATTERN *patterns;
-static char errstr[128]; /* regerror string buffer */
-static int regflags = 0; /* regcomp options */
-static int matched = 0; /* return of the grep() */
-static int errors = 0; /* count of errors */
-static uchar_t fgrep = 0; /* Invoked as fgrep */
-static uchar_t egrep = 0; /* Invoked as egrep */
-static boolean_t nvflag = B_TRUE; /* Print matching lines */
-static uchar_t cflag; /* Count of matches */
-static uchar_t iflag; /* Case insensitve matching */
-static uchar_t Hflag; /* Precede lines by file name */
-static uchar_t hflag; /* Supress printing of filename */
-static uchar_t lflag; /* Print file names of matches */
-static uchar_t nflag; /* Precede lines by line number */
-static uchar_t rflag; /* Search directories recursively */
-static uchar_t bflag; /* Preccede matches by block number */
-static uchar_t sflag; /* Suppress file error messages */
-static uchar_t qflag; /* Suppress standard output */
-static uchar_t wflag; /* Search for expression as a word */
-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);
-static void usage(void);
-static int grep(int, const char *);
-static void bmgcomp(char *, int);
-static char *bmgexec(char *, char *);
-static int recursive(const char *, const struct stat *, int, struct FTW *);
-static void process_path(const char *);
-static void process_file(const char *, int);
-
-/*
- * 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;
-
- (void) setlocale(LC_ALL, "");
-#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
-#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
-#endif
- (void) textdomain(TEXT_DOMAIN);
-
- /*
- * true if this is running on the multibyte locale
- */
- mblocale = (MB_CUR_MAX > 1);
- /*
- * Skip leading slashes
- */
- cmdname = argv[0];
- if (ap = strrchr(cmdname, '/'))
- cmdname = ap + 1;
-
- ap = cmdname;
- /*
- * Detect egrep/fgrep via command name, map to -E and -F options.
- */
- if (*ap == 'e' || *ap == 'E') {
- regflags |= REG_EXTENDED;
- egrep++;
- } else {
- 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;
-
- /* isdigit() check prevents negative arguments */
- 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();
- }
-
- errno = 0;
- conalen = conblen = strtoul(&argv[i][1], (char **)NULL,
- 10);
-
- if (errno != 0 || conalen >= ULONG_MAX) {
- (void) fprintf(stderr, gettext(
- "%s: Bad context argument\n"), argv[0]);
- } else 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 = B_FALSE;
- break;
-
- case 'c': /* POSIX: write count */
- cflag++;
- break;
-
- case 'i': /* POSIX: ignore case */
- iflag++;
- regflags |= REG_ICASE;
- break;
-
- case 'l': /* POSIX: Write filenames only */
- lflag++;
- break;
-
- case 'n': /* POSIX: Write line numbers */
- nflag++;
- break;
-
- case 'r': /* Solaris: search recursively */
- rflag++;
- break;
-
- case 'b': /* Solaris: Write file block numbers */
- bflag++;
- break;
-
- case 's': /* POSIX: No error msgs for files */
- sflag++;
- break;
-
- case 'e': /* POSIX: pattern list */
- n_pattern++;
- pattern_list = realloc(pattern_list,
- sizeof (char *) * n_pattern);
- if (pattern_list == NULL) {
- (void) fprintf(stderr,
- gettext("%s: out of memory\n"),
- cmdname);
- exit(2);
- }
- *(pattern_list + n_pattern - 1) = optarg;
- break;
-
- case 'f': /* POSIX: pattern file */
- fflag = 1;
- n_file++;
- file_list = realloc(file_list,
- sizeof (char *) * n_file);
- if (file_list == NULL) {
- (void) fprintf(stderr,
- gettext("%s: out of memory\n"),
- cmdname);
- exit(2);
- }
- *(file_list + n_file - 1) = optarg;
- break;
-
- /* based on options order h or H is set as in GNU grep */
- case 'h': /* Solaris: supress printing of file name */
- hflag = 1;
- Hflag = 0;
- break;
- /* Solaris: precede every matching with file name */
- case 'H':
- Hflag = 1;
- hflag = 0;
- break;
-
- case 'q': /* POSIX: quiet: status only */
- qflag++;
- break;
-
- case 'w': /* Solaris: treat pattern as word */
- wflag++;
- break;
-
- case 'x': /* POSIX: full line matches */
- xflag++;
- regflags |= REG_ANCHOR;
- break;
-
- case 'E': /* POSIX: Extended RE's */
- regflags |= REG_EXTENDED;
- Eflag++;
- break;
-
- case 'F': /* POSIX: strings, not RE's */
- Fflag++;
- break;
-
- case 'R': /* Solaris: like rflag, but follow symlinks */
- Rflag++;
- rflag++;
- break;
-
- case 'A': /* print N lines after each match */
- errno = 0;
- conalen = strtoul(optarg, &test, 10);
- /* *test will be non-null if optarg is negative */
- if (errno != 0 || *test != '\0' ||
- conalen >= ULONG_MAX) {
- (void) fprintf(stderr, gettext(
- "%s: Bad context argument: %s\n"),
- argv[0], optarg);
- exit(2);
- }
- if (conalen)
- conflag |= AFTER;
- else
- conflag &= ~AFTER;
- break;
- case 'B': /* print N lines before each match */
- errno = 0;
- conblen = strtoul(optarg, &test, 10);
- /* *test will be non-null if optarg is negative */
- if (errno != 0 || *test != '\0' ||
- conblen >= ULONG_MAX) {
- (void) fprintf(stderr, gettext(
- "%s: Bad context argument: %s\n"),
- argv[0], optarg);
- exit(2);
- }
- if (conblen)
- conflag |= BEFORE;
- else
- conflag &= ~BEFORE;
- break;
- case 'C': /* print N lines around each match */
- errno = 0;
- tval = strtoul(optarg, &test, 10);
- /* *test will be non-null if optarg is negative */
- if (errno != 0 || *test != '\0' || tval >= ULONG_MAX) {
- (void) fprintf(stderr, gettext(
- "%s: Bad context argument: %s\n"),
- argv[0], optarg);
- exit(2);
- }
- if (tval) {
- if ((conflag & BEFORE) == 0)
- conblen = tval;
- if ((conflag & AFTER) == 0)
- conalen = tval;
- conflag = CONTEXT;
- }
- break;
-
- default:
- usage();
- }
- }
- /*
- * If we're invoked as egrep or fgrep we need to do some checks
- */
-
- if (egrep || fgrep) {
- /*
- * Use of -E or -F with egrep or fgrep is illegal
- */
- if (Eflag || Fflag)
- usage();
- /*
- * Don't allow use of wflag with egrep / fgrep
- */
- if (wflag)
- usage();
- /*
- * For Solaris the -s flag is equivalent to XCU -q
- */
- if (sflag)
- qflag++;
- /*
- * done with above checks - set the appropriate flags
- */
- if (egrep)
- Eflag++;
- else /* Else fgrep */
- Fflag++;
- }
-
- if (wflag && (Eflag || Fflag)) {
- /*
- * -w cannot be specified with grep -F
- */
- usage();
- }
-
- /*
- * -E and -F flags are mutually exclusive - check for this
- */
- if (Eflag && Fflag)
- usage();
-
- /*
- * -l overrides -H like in GNU grep
- */
- if (lflag)
- Hflag = 0;
-
- /*
- * -c, -l and -q flags are mutually exclusive
- * We have -c override -l like in Solaris.
- * -q overrides -l & -c programmatically in grep() function.
- */
- if (cflag && lflag)
- lflag = 0;
-
- argv += optind - 1;
- argc -= optind - 1;
-
- /*
- * Now handling -e and -f option
- */
- if (pattern_list) {
- for (i = 0; i < n_pattern; i++) {
- addpattern(pattern_list[i]);
- }
- free(pattern_list);
- }
- if (file_list) {
- for (i = 0; i < n_file; i++) {
- addfile(file_list[i]);
- }
- free(file_list);
- }
-
- /*
- * No -e or -f? Make sure there is one more arg, use it as the pattern.
- */
- if (patterns == NULL && !fflag) {
- if (argc < 2)
- usage();
- addpattern(argv[1]);
- argc--;
- argv++;
- }
-
- /*
- * If -x flag is not specified or -i flag is specified
- * with fgrep in a multibyte locale, need to use
- * the wide character APIs. Otherwise, byte-oriented
- * process will be done.
- */
- use_wchar = Fflag && mblocale && (!xflag || iflag);
-
- /*
- * Compile Patterns and also decide if BMG can be used
- */
- fixpatterns();
-
- /* Process all files: stdin, or rest of arg list */
- if (argc < 2) {
- matched = grep(0, STDIN_FILENAME);
- } else {
- if (Hflag || (argc > 2 && hflag == 0))
- outfn = 1; /* Print filename on match line */
- for (argv++; *argv != NULL; argv++) {
- process_path(*argv);
- }
- }
- /*
- * Return() here is used instead of exit
- */
-
- (void) fflush(stdout);
-
- if (errors)
- return (2);
- return (matched ? 0 : 1);
-}
-
-static void
-process_path(const char *path)
-{
- struct stat st;
- int walkflags = FTW_CHDIR;
- char *buf = NULL;
-
- if (rflag) {
- if (stat(path, &st) != -1 &&
- (st.st_mode & S_IFMT) == S_IFDIR) {
- outfn = 1; /* Print filename */
-
- /*
- * Add trailing slash if arg
- * is directory, to resolve symlinks.
- */
- if (path[strlen(path) - 1] != '/') {
- (void) asprintf(&buf, "%s/", path);
- if (buf != NULL)
- path = buf;
- }
-
- /*
- * Search through subdirs if path is directory.
- * Don't follow symlinks if Rflag is not set.
- */
- if (!Rflag)
- walkflags |= FTW_PHYS;
-
- if (nftw(path, recursive, MAX_DEPTH, walkflags) != 0) {
- if (!sflag)
- (void) fprintf(stderr,
- gettext("%s: can't open \"%s\"\n"),
- cmdname, path);
- errors = 1;
- }
- return;
- }
- }
- process_file(path, 0);
-}
-
-/*
- * Read and process all files in directory recursively.
- */
-static int
-recursive(const char *name, const struct stat *statp, int info, struct FTW *ftw)
-{
- /*
- * Process files and follow symlinks if Rflag set.
- */
- if (info != FTW_F) {
- /* Report broken symlinks and unreadable files */
- if (!sflag &&
- (info == FTW_SLN || info == FTW_DNR || info == FTW_NS)) {
- (void) fprintf(stderr,
- gettext("%s: can't open \"%s\"\n"), cmdname, name);
- }
- return (0);
- }
-
-
- /* Skip devices and pipes if Rflag is not set */
- if (!Rflag && !S_ISREG(statp->st_mode))
- return (0);
- /* Pass offset to relative name from FTW_CHDIR */
- process_file(name, ftw->base);
- return (0);
-}
-
-/*
- * Opens file and call grep function.
- */
-static void
-process_file(const char *name, int base)
-{
- int fd;
-
- if ((fd = open(name + base, O_RDONLY)) == -1) {
- errors = 1;
- if (!sflag) /* Silent mode */
- (void) fprintf(stderr, gettext(
- "%s: can't open \"%s\"\n"),
- cmdname, name);
- return;
- }
- matched |= grep(fd, name);
- (void) close(fd);
-
- if (ferror(stdout)) {
- (void) fprintf(stderr, gettext(
- "%s: error writing to stdout\n"),
- cmdname);
- (void) fflush(stdout);
- exit(2);
- }
-
-}
-
-/*
- * Add a file of strings to the pattern list.
- */
-static void
-addfile(const char *fn)
-{
- FILE *fp;
- char *inbuf;
- char *bufp;
- size_t bufsiz, buflen, bufused;
-
- /*
- * Open the pattern file
- */
- if ((fp = fopen(fn, "r")) == NULL) {
- (void) fprintf(stderr, gettext("%s: can't open \"%s\"\n"),
- cmdname, fn);
- exit(2);
- }
- bufsiz = BUFSIZE;
- if ((inbuf = malloc(bufsiz)) == NULL) {
- (void) fprintf(stderr,
- gettext("%s: out of memory\n"), cmdname);
- exit(2);
- }
- bufp = inbuf;
- bufused = 0;
- /*
- * Read in the file, reallocing as we need more memory
- */
- while (fgets(bufp, bufsiz - bufused, fp) != NULL) {
- buflen = strlen(bufp);
- bufused += buflen;
- if (bufused + 1 == bufsiz && bufp[buflen - 1] != '\n') {
- /*
- * if this line does not fit to the buffer,
- * realloc larger buffer
- */
- bufsiz += BUFSIZE;
- if ((inbuf = realloc(inbuf, bufsiz)) == NULL) {
- (void) fprintf(stderr,
- gettext("%s: out of memory\n"),
- cmdname);
- exit(2);
- }
- bufp = inbuf + bufused;
- continue;
- }
- if (bufp[buflen - 1] == '\n') {
- bufp[--buflen] = '\0';
- }
- addpattern(inbuf);
-
- bufp = inbuf;
- bufused = 0;
- }
- free(inbuf);
- free(prntbuf);
- free(conbuf);
- (void) fclose(fp);
-}
-
-/*
- * Add a string to the pattern list.
- */
-static void
-addpattern(char *s)
-{
- PATTERN *pp;
- char *wordbuf;
- char *np;
-
- for (; ; ) {
- np = strchr(s, '\n');
- if (np != NULL)
- *np = '\0';
- if ((pp = malloc(sizeof (PATTERN))) == NULL) {
- (void) fprintf(stderr, gettext(
- "%s: out of memory\n"),
- cmdname);
- exit(2);
- }
- if (wflag) {
- /*
- * Solaris wflag support: Add '<' '>' to pattern to
- * select it as a word. Doesn't make sense with -F
- * but we're Libertarian.
- */
- size_t slen, wordlen;
-
- slen = strlen(s);
- wordlen = slen + 5; /* '\\' '<' s '\\' '>' '\0' */
- if ((wordbuf = malloc(wordlen)) == NULL) {
- (void) fprintf(stderr,
- gettext("%s: out of memory\n"),
- cmdname);
- exit(2);
- }
- (void) strcpy(wordbuf, "\\<");
- (void) strcpy(wordbuf + 2, s);
- (void) strcpy(wordbuf + 2 + slen, "\\>");
- } else {
- if ((wordbuf = strdup(s)) == NULL) {
- (void) fprintf(stderr,
- gettext("%s: out of memory\n"),
- cmdname);
- exit(2);
- }
- }
- pp->pattern = wordbuf;
- pp->next = patterns;
- patterns = pp;
- if (np == NULL)
- break;
- s = np + 1;
- }
-}
-
-/*
- * Fix patterns.
- * Must do after all arguments read, in case later -i option.
- */
-static void
-fixpatterns(void)
-{
- PATTERN *pp;
- int rv, fix_pattern, npatterns;
-
- /*
- * As REG_ANCHOR flag is not supported in the current Solaris,
- * need to fix the specified pattern if -x is specified with
- * grep or egrep
- */
- fix_pattern = !Fflag && xflag;
-
- for (npatterns = 0, pp = patterns; pp != NULL; pp = pp->next) {
- npatterns++;
- if (fix_pattern) {
- char *cp, *cq;
- size_t plen, nplen;
-
- plen = strlen(pp->pattern);
- /* '^' pattern '$' */
- nplen = 1 + plen + 1 + 1;
- if ((cp = malloc(nplen)) == NULL) {
- (void) fprintf(stderr,
- gettext("%s: out of memory\n"),
- cmdname);
- exit(2);
- }
- cq = cp;
- *cq++ = '^';
- cq = strcpy(cq, pp->pattern) + plen;
- *cq++ = '$';
- *cq = '\0';
- free(pp->pattern);
- pp->pattern = cp;
- }
-
- if (Fflag) {
- if (use_wchar) {
- /*
- * Fflag && mblocale && iflag
- * Fflag && mblocale && !xflag
- */
- size_t n;
- n = strlen(pp->pattern) + 1;
- if ((pp->wpattern =
- malloc(sizeof (wchar_t) * n)) == NULL) {
- (void) fprintf(stderr,
- gettext("%s: out of memory\n"),
- cmdname);
- exit(2);
- }
- if (mbstowcs(pp->wpattern, pp->pattern, n) ==
- (size_t)-1) {
- (void) fprintf(stderr,
- gettext("%s: failed to convert "
- "\"%s\" to wide-characters\n"),
- cmdname, pp->pattern);
- exit(2);
- }
- if (iflag) {
- wchar_t *wp;
- for (wp = pp->wpattern; *wp != L'\0';
- wp++) {
- *wp = towlower((wint_t)*wp);
- }
- }
- free(pp->pattern);
- } else {
- /*
- * Fflag && mblocale && !iflag
- * Fflag && !mblocale && iflag
- * Fflag && !mblocale && !iflag
- */
- if (iflag) {
- unsigned char *cp;
- for (cp = (unsigned char *)pp->pattern;
- *cp != '\0'; cp++) {
- *cp = tolower(*cp);
- }
- }
- }
- /*
- * fgrep: No regular expressions.
- */
- continue;
- }
-
- /*
- * For non-fgrep, compile the regular expression,
- * give an informative error message, and exit if
- * it didn't compile.
- */
- if ((rv = regcomp(&pp->re, pp->pattern, regflags)) != 0) {
- (void) regerror(rv, &pp->re, errstr, sizeof (errstr));
- (void) fprintf(stderr,
- gettext("%s: RE error in %s: %s\n"),
- cmdname, pp->pattern, errstr);
- exit(2);
- }
- free(pp->pattern);
- }
-
- /*
- * Decide if we are able to run the Boyer-Moore-Gosper algorithm.
- * Use the Boyer-Moore-Gosper algorithm if:
- * - fgrep (Fflag)
- * - singlebyte locale (!mblocale)
- * - 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 == 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) &&
- conflag == 0;
-}
-
-/*
- * Search a newline from the beginning of the string
- */
-static char *
-find_nl(const char *ptr, size_t len)
-{
- while (len-- != 0) {
- if (*ptr++ == '\n') {
- return ((char *)--ptr);
- }
- }
- return (NULL);
-}
-
-/*
- * Search a newline from the end of the string
- */
-static char *
-rfind_nl(const char *ptr, size_t len)
-{
- const char *uptr = ptr + len;
- while (len--) {
- if (*--uptr == '\n') {
- return ((char *)uptr);
- }
- }
- return (NULL);
-}
-
-/*
- * Duplicate the specified string converting each character
- * into a lower case.
- */
-static char *
-istrdup(const char *s1)
-{
- static size_t ibuflen = 0;
- static char *ibuf = NULL;
- size_t slen;
- char *p;
-
- slen = strlen(s1);
- if (slen >= ibuflen) {
- /* ibuf does not fit to s1 */
- ibuflen = slen + 1;
- ibuf = realloc(ibuf, ibuflen);
- if (ibuf == NULL) {
- (void) fprintf(stderr,
- gettext("%s: out of memory\n"), cmdname);
- exit(2);
- }
- }
- p = ibuf;
- do {
- *p++ = tolower(*s1);
- } while (*s1++ != '\0');
- return (ibuf);
-}
-
-/*
- * Do grep on a single file.
- * Return true in any lines matched.
- *
- * We have two strategies:
- * The fast one is used when we have a single pattern with
- * a string known to occur in the pattern. We can then
- * do a BMG match on the whole buffer.
- * This is an order of magnitude faster.
- * Otherwise we split the buffer into lines,
- * and check for a match on each line.
- */
-static int
-grep(int fd, const char *fn)
-{
- 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;
- boolean_t nearmatch; /* w/in N+1 of last match */
- boolean_t havematch = B_FALSE; /* have a match in context */
- size_t prntlen;
-
- if (patterns == NULL)
- return (0); /* no patterns to match -- just return */
-
- pp = patterns;
-
- if (use_bmg) {
- bmgcomp(pp->pattern, strlen(pp->pattern));
- }
-
- if (use_wchar && outline == NULL) {
- outbuflen = BUFSIZE + 1;
- outline = malloc(sizeof (wchar_t) * outbuflen);
- if (outline == NULL) {
- (void) fprintf(stderr, gettext("%s: out of memory\n"),
- cmdname);
- exit(2);
- }
- }
-
- if (prntbuf == NULL) {
- prntbuflen = BUFSIZE;
- if ((prntbuf = malloc(prntbuflen + 1)) == NULL) {
- (void) fprintf(stderr, gettext("%s: out of memory\n"),
- cmdname);
- exit(2);
- }
- }
-
- if (conflag != 0 && (conbuf == NULL)) {
- conbuflen = BUFSIZE;
- if ((conbuf = malloc(BUFSIZE+1)) == NULL) {
- (void) fprintf(stderr, gettext("%s: out of memory\n"),
- cmdname);
- exit(2);
- }
- }
-
- nearmatch = (conmatches != 0);
- blkoffset = line_offset = 0;
- lineno = 0;
- linenum = 1;
- newlinep = 1;
- data_len = 0;
- for (; ; ) {
- long count;
- off_t offset = 0;
- char separate;
- boolean_t last_ctx = B_FALSE, eof = B_FALSE;
-
- if (data_len == 0) {
- /*
- * If no data in the buffer, reset ptr
- */
- ptr = prntbuf;
- if (conflag != 0 && conptr == NULL) {
- conptr = conbuf;
- conptrend = conptr - 1;
- }
- }
- if (ptr == prntbuf) {
- /*
- * The current data chunk starts from prntbuf.
- * This means either the buffer has no data
- * or the buffer has no newline.
- * So, read more data from input.
- */
- count = read(fd, ptr + data_len, prntbuflen - data_len);
- if (count < 0) {
- /* read error */
- if (cflag) {
- if (outfn && !rflag) {
- (void) fprintf(stdout,
- "%s:", fn);
- }
- if (!qflag && !rflag) {
- (void) fprintf(stdout, "%lld\n",
- matches);
- }
- }
- return (0);
- } else if (count == 0) {
- /* no new data */
- eof = B_TRUE;
-
- if (data_len == 0) {
- /* end of file already reached */
- if (conflag != 0) {
- if (conptrend >= conptr)
- *conptrend = '\n';
- last_ctx = B_TRUE;
- goto L_next_line;
- } else {
- goto out;
- }
- }
- /* last line of file has no newline */
- ptrend = ptr + data_len;
- newlinep = 0;
- goto L_start_process;
- }
- offset = data_len;
- data_len += count;
- }
-
- /*
- * Look for newline in the chunk
- * between ptr + offset and ptr + data_len - offset.
- */
- ptrend = find_nl(ptr + offset, data_len - offset);
- if (ptrend == NULL) {
- /* no newline found in this chunk */
- if (ptr > prntbuf) {
- /*
- * Move remaining data to the beginning
- * of the buffer.
- * Remaining data lie from ptr for
- * data_len bytes.
- */
- (void) memmove(prntbuf, ptr, data_len);
- }
- if (data_len == prntbuflen) {
- /*
- * Not enough room in the buffer
- */
- if (prntbuflen > SIZE_MAX - BUFSIZE) {
- (void) fprintf(stderr,
- gettext("%s: buflen would"
- " overflow\n"),
- cmdname);
- exit(2);
- }
-
- prntbuflen += BUFSIZE;
- prntbuf = realloc(prntbuf, prntbuflen + 1);
- if (prntbuf == NULL) {
- (void) fprintf(stderr,
- gettext("%s: out of memory\n"),
- cmdname);
- exit(2);
- }
- }
- ptr = prntbuf;
- /* read the next input */
- continue;
- }
-L_start_process:
-
- /*
- * Beginning of the chunk: ptr
- * End of the chunk: ptr + data_len
- * Beginning of the line: ptr
- * End of the line: ptrend
- *
- * conptr: Beginning of the context.
- * conptrend: If context is empty, conptr - 1 (invalid memory).
- * Otherwise, Last newline in the context.
- */
-
- if (use_bmg) {
- /*
- * Use Boyer-Moore-Gosper algorithm to find out if
- * this chunk (not this line) contains the specified
- * pattern. If not, restart from the last line
- * of this chunk.
- */
- char *bline;
- bline = bmgexec(ptr, ptr + data_len);
- if (bline == NULL) {
- /*
- * No pattern found in this chunk.
- * Need to find the last line
- * in this chunk.
- */
- ptrend = rfind_nl(ptr, data_len);
-
- /*
- * When this chunk does not contain newline,
- * ptrend becomes NULL, which should happen
- * when the last line of file does not end
- * with a newline. At such a point,
- * newlinep should have been set to 0.
- * Therefore, just after jumping to
- * L_skip_line, the main for-loop quits,
- * and the line_len value won't be
- * used.
- */
- line_len = ptrend - ptr;
- goto L_skip_line;
- }
- if (bline > ptrend) {
- /*
- * Pattern found not in the first line
- * of this chunk.
- * Discard the first line.
- */
- line_len = ptrend - ptr;
- goto L_skip_line;
- }
- /*
- * Pattern found in the first line of this chunk.
- * Using this result.
- */
- *ptrend = '\0';
- line_len = ptrend - ptr;
-
- /*
- * before jumping to L_next_line,
- * need to handle xflag if specified
- */
- if (xflag && (line_len != bmglen ||
- strcmp(bmgpat, ptr) != 0)) {
- /* didn't match */
- pp = NULL;
- } else {
- pp = patterns; /* to make it happen */
- }
- goto L_next_line;
- }
- lineno++;
- /*
- * Line starts from ptr and ends at ptrend.
- * line_len will be the length of the line.
- */
- *ptrend = '\0';
- line_len = ptrend - ptr;
-
- /*
- * From now, the process will be performed based
- * on the line from ptr to ptrend.
- */
- if (use_wchar) {
- size_t len;
-
- if (line_len >= outbuflen) {
- outbuflen = line_len + 1;
- outline = realloc(outline,
- sizeof (wchar_t) * outbuflen);
- if (outline == NULL) {
- (void) fprintf(stderr,
- gettext("%s: out of memory\n"),
- cmdname);
- exit(2);
- }
- }
-
- len = mbstowcs(outline, ptr, line_len);
- if (len == (size_t)-1) {
- (void) fprintf(stderr, gettext(
- "%s: input file \"%s\": line %lld: invalid multibyte character\n"),
- cmdname, fn, lineno);
- /* never match a line with invalid sequence */
- goto L_skip_line;
- }
- outline[len] = L'\0';
-
- if (iflag) {
- wchar_t *cp;
- for (cp = outline; *cp != '\0'; cp++) {
- *cp = towlower((wint_t)*cp);
- }
- }
-
- if (xflag) {
- for (pp = patterns; pp; pp = pp->next) {
- if (outline[0] == pp->wpattern[0] &&
- wcscmp(outline,
- pp->wpattern) == 0) {
- /* matched */
- break;
- }
- }
- } else {
- for (pp = patterns; pp; pp = pp->next) {
- if (wcswcs(outline, pp->wpattern)
- != NULL) {
- /* matched */
- break;
- }
- }
- }
- } else if (Fflag) {
- /* fgrep in byte-oriented handling */
- char *fptr;
- if (iflag) {
- fptr = istrdup(ptr);
- } else {
- fptr = ptr;
- }
- if (xflag) {
- /* 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;
- }
-
- switch (rv) {
- case REG_NOMATCH:
- break;
- case REG_ECHAR:
- (void) fprintf(stderr, gettext(
- "%s: input file \"%s\": line %lld: invalid multibyte character\n"),
- cmdname, fn, lineno);
- break;
- default:
- (void) regerror(rv, &pp->re, errstr,
- sizeof (errstr));
- (void) fprintf(stderr, gettext(
- "%s: input file \"%s\": line %lld: %s\n"),
- cmdname, fn, lineno, errstr);
- 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 == 0)
- goto L_next_line;
-
- /* Do we have room to add this line to the context buffer? */
- if ((line_len + 1) > (conbuflen -
- (conptrend >= conptr) ? conptrend - conbuf : 0)) {
- char *oldconbuf = conbuf;
- char *oldconptr = conptr;
- long tmp = matchptr - conptr;
-
- if (conbuflen > SIZE_MAX - BUFSIZE) {
- (void) fprintf(stderr,
- gettext("%s: buflen would overflow\n"),
- cmdname);
- exit(2);
- }
-
- 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 + 1, ptr, line_len);
- conptrend += line_len + 1;
- *conptrend = '\n';
-
- if (nvflag == (pp != NULL)) {
- /* matched */
- if (havematch) {
- if ((conflag & AFTER) != 0) {
- 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 -
- (conptrend - conptr - line_len);
- }
-
- if (conflag == BEFORE)
- conbprnt = 1;
-
- lastmatch = conptrend - conptr;
- havematch = B_TRUE;
- goto L_next_line;
- }
-
- if (!havematch) {
- if ((conflag & BEFORE) != 0) {
- if (conbcnt >= conblen) {
- char *tmp = conptr;
- conptr = find_nl(conptr,
- conptrend - conptr) + 1;
- if (bflag)
- blkoffset += conptr - tmp;
- linenum++;
- nearmatch = B_TRUE;
- } else {
- conbcnt++;
- }
- }
- if (conflag == AFTER)
- nearmatch = B_TRUE;
- } 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 (!last_ctx && nvflag == (pp != NULL)) {
- matches++;
- if (!nextend)
- matchptr = (conflag != 0) ? 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 (havematch && (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;
- prntptr = conptr;
- if (conmatches++ && nearmatch && !cflag)
- (void) fwrite("--\n", 1, 3, stdout);
- } else if (conflag == 0 && nvflag == (pp != NULL)) {
- *ptrend = '\n';
- prntlen = line_len + 1;
- 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;
- }
-
- prntptrend = prntptr - 1;
- 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 */
- /*
- * End of this line is ptrend.
- * We have read up to ptr + data_len.
- */
- off_t pos;
- pos = ptr + data_len - (ptrend + 1);
- (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 != 0) {
- conptr = conbuf;
- conaprnt = conbprnt = 0;
- nearmatch = B_FALSE;
- 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;
- havematch = B_TRUE;
- } else {
- conptrend = conptr - 1;
- conacnt = 0;
- lastmatch = 0;
- havematch = B_FALSE;
- }
- 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) {
- (void) printf("%lld\n", matches);
- }
- }
- return (matches != 0);
-}
-
-/*
- * usage message for grep
- */
-static void
-usage(void)
-{
- if (egrep || fgrep) {
- (void) fprintf(stderr, gettext("Usage:\t%s"), cmdname);
- (void) fprintf(stderr,
- gettext(" [-c|-l|-q] [-r|-R] "
- "[-A num] [-B num] [-C num|-num] "
- "[-bhHinsvx] pattern_list [file ...]\n"));
-
- (void) fprintf(stderr, "\t%s", cmdname);
- (void) fprintf(stderr,
- gettext(" [-c|-l|-q] [-r|-R] "
- "[-A num] [-B num] [-C num|-num] "
- "[-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 num] [-B num] [-C num|-num] "
- "[-bhHinsvx] pattern_list [file ...]\n"));
-
- (void) fprintf(stderr, "\t%s", cmdname);
- (void) fprintf(stderr,
- gettext(" [-c|-l|-q] [-r|-R] "
- "[-A num] [-B num] [-C num|-num] "
- "[-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 num] [-B num] [-C num|-num] "
- "[-bhHinsvx] pattern_list [file ...]\n"));
-
- (void) fprintf(stderr, "\t%s", cmdname);
- (void) fprintf(stderr,
- gettext(" -E [-c|-l|-q] [-r|-R] "
- "[-A num] [-B num] [-C num|-num] "
- "[-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 num] [-B num] [-C num|-num] "
- "[-bhHinsvx] pattern_list [file ...]\n"));
-
- (void) fprintf(stderr, "\t%s", cmdname);
- (void) fprintf(stderr,
- gettext(" -F [-c|-l|-q] "
- "[-A num] [-B num] [-C num|-num] "
- "[-bhHinsvx] [-e pattern_list]... "
- "[-f pattern_file]... [file...]\n"));
- }
- exit(2);
- /* NOTREACHED */
-}
-
-/*
- * Compile literal pattern into BMG tables
- */
-static void
-bmgcomp(char *pat, int len)
-{
- int i;
- int tlen;
- unsigned char *uc = (unsigned char *)pat;
-
- bmglen = len;
- bmgpat = pat;
-
- for (i = 0; i < M_CSETSIZE; i++) {
- bmgtab[i] = len;
- }
-
- len--;
- for (tlen = len, i = 0; i <= len; i++, tlen--) {
- bmgtab[*uc++] = tlen;
- }
-}
-
-/*
- * BMG search.
- */
-static char *
-bmgexec(char *str, char *end)
-{
- int t;
- char *k, *s, *p;
-
- k = str + bmglen - 1;
- if (bmglen == 1) {
- return (memchr(str, bmgpat[0], end - str));
- }
- for (; ; ) {
- /* inner loop, should be most optimized */
- while (k < end && (t = bmgtab[(unsigned char)*k]) != 0) {
- k += t;
- }
- if (k >= end) {
- return (NULL);
- }
- for (s = k, p = bmgpat + bmglen - 1; *--s == *--p; ) {
- if (p == bmgpat) {
- return (s);
- }
- }
- k++;
- }
- /* NOTREACHED */
-}
diff --git a/usr/src/cmd/ldap/ns_ldap/idsconfig.sh b/usr/src/cmd/ldap/ns_ldap/idsconfig.sh
index 8f36137cc3..4d3df78e42 100644
--- a/usr/src/cmd/ldap/ns_ldap/idsconfig.sh
+++ b/usr/src/cmd/ldap/ns_ldap/idsconfig.sh
@@ -984,7 +984,7 @@ init()
DOM="" # Set to NULL
# If DNS domain (resolv.conf) exists use that, otherwise use domainname.
if [ -f /etc/resolv.conf ]; then
- DOM=`/usr/xpg4/bin/grep -i -E '^domain|^search' /etc/resolv.conf \
+ DOM=`/usr/bin/grep -i -E '^domain|^search' /etc/resolv.conf \
| awk '{ print $2 }' | tail -1`
fi
diff --git a/usr/src/cmd/sgs/test/ld/x64/tls/ie/x64-ie-test.sh b/usr/src/cmd/sgs/test/ld/x64/tls/ie/x64-ie-test.sh
index d7fe25a511..61dd87bce0 100644
--- a/usr/src/cmd/sgs/test/ld/x64/tls/ie/x64-ie-test.sh
+++ b/usr/src/cmd/sgs/test/ld/x64/tls/ie/x64-ie-test.sh
@@ -16,7 +16,7 @@ function grep_test {
name=$1
pattern=$2
- if /usr/xpg4/bin/fgrep -q "${pattern}"; then
+ if /usr/bin/fgrep -q "${pattern}"; then
print -u2 "pass: $name"
else
print -u2 "FAIL: $name"
diff --git a/usr/src/cmd/tsol/misc/txzonemgr.sh b/usr/src/cmd/tsol/misc/txzonemgr.sh
index 179a0e8170..47ac3cc425 100644
--- a/usr/src/cmd/tsol/misc/txzonemgr.sh
+++ b/usr/src/cmd/tsol/misc/txzonemgr.sh
@@ -1415,7 +1415,7 @@ tearDownZones() {
gettext "OK to destroy all zones [y|N]? "
read ans
printf "%s\n" "$ans" \
- | /usr/xpg4/bin/grep -Eq "$(locale yesexpr)"
+ | /usr/bin/grep -Eq "$(locale yesexpr)"
if [ $? -ne 0 ] ; then
gettext "canceled.\n"
return 1
diff --git a/usr/src/lib/libsaveargs/tests/functional/test.sh b/usr/src/lib/libsaveargs/tests/functional/test.sh
index dea1059b2c..e4a8e2688a 100644
--- a/usr/src/lib/libsaveargs/tests/functional/test.sh
+++ b/usr/src/lib/libsaveargs/tests/functional/test.sh
@@ -20,7 +20,7 @@ function tester {
./$prog >/dev/null &
pid=$!
- if (/usr/bin/amd64/pstack $pid | /usr/xpg4/bin/grep -q "${pattern}"); then
+ if (/usr/bin/amd64/pstack $pid | /usr/bin/grep -q "${pattern}"); then
echo "pass: ${prog}"
else
echo "FAIL: ${prog}"
diff --git a/usr/src/lib/libshell/common/tests/sun_solaris_cr_6887363_shell_sometimes_mishandles_return_value_of_its_child_process.sh b/usr/src/lib/libshell/common/tests/sun_solaris_cr_6887363_shell_sometimes_mishandles_return_value_of_its_child_process.sh
index f302f6379e..93e559c0a7 100644
--- a/usr/src/lib/libshell/common/tests/sun_solaris_cr_6887363_shell_sometimes_mishandles_return_value_of_its_child_process.sh
+++ b/usr/src/lib/libshell/common/tests/sun_solaris_cr_6887363_shell_sometimes_mishandles_return_value_of_its_child_process.sh
@@ -172,7 +172,7 @@ out="$(unset VMALLOC_OPTIONS VMDEBUG ; cat_test | ${SHELL} 2>&1)" || err_exit "U
[[ "${out}" != "" ]] || err_exit "No output from test"
# filter output and check it
-out2="$(/usr/xpg4/bin/egrep -v '^((read-seq|read-rand|syncread-seq|syncread-seq)[[:space:][:blank:]]*)*$' <<<"${out}")"
+out2="$(/usr/bin/egrep -v '^((read-seq|read-rand|syncread-seq|syncread-seq)[[:space:][:blank:]]*)*$' <<<"${out}")"
[[ "${out2}" == "" ]] || err_exit "Unexpected output '${out2}'"
diff --git a/usr/src/lib/libshell/misc/shell_styleguide.docbook b/usr/src/lib/libshell/misc/shell_styleguide.docbook
index 0376912d1f..74bc7501b5 100644
--- a/usr/src/lib/libshell/misc/shell_styleguide.docbook
+++ b/usr/src/lib/libshell/misc/shell_styleguide.docbook
@@ -352,9 +352,9 @@ done
At least
<simplelist type="inline">
<member>print</member>
- <member>/usr/bin/fgrep</member><member>/usr/xpg4/bin/fgrep</member>
- <member>/usr/bin/grep</member> <member>/usr/xpg4/bin/grep</member>
- <member>/usr/bin/egrep</member><member>/usr/xpg4/bin/egrep</member>
+ <member>/usr/bin/fgrep</member>
+ <member>/usr/bin/grep</member>
+ <member>/usr/bin/egrep</member>
</simplelist>
support <literal>--</literal> as "end of arguments"-terminator.
</para></note>
diff --git a/usr/src/man/man1/egrep.1 b/usr/src/man/man1/egrep.1
index 9fdf321590..b3d8d2ca96 100644
--- a/usr/src/man/man1/egrep.1
+++ b/usr/src/man/man1/egrep.1
@@ -9,44 +9,28 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH EGREP 1 "May 3, 2013"
+.TH EGREP 1 "Nov 28, 2017"
.SH NAME
egrep \- search a file for a pattern using full regular expressions
.SH SYNOPSIS
.LP
.nf
-\fB/usr/bin/egrep\fR [\fB-bcHhilnqsv\fR] \fB-e\fR \fIpattern_list\fR [\fIfile...\fR]
-.fi
-
-.LP
-.nf
-\fB/usr/bin/egrep\fR [\fB-bcHhilnqsv\fR] \fB-f\fR \fIfile\fR [\fIfile...\fR]
-.fi
-
-.LP
-.nf
-\fB/usr/bin/egrep\fR [\fB-bcHhilnqsv\fR] \fIpattern\fR [\fIfile...\fR]
-.fi
-
-.LP
-.nf
-\fB/usr/xpg4/bin/egrep\fR [\fB-bcHhilnqsvx\fR] \fB-e\fR \fIpattern_list\fR [\fB-f\fR \fIfile\fR]
+\fB/usr/bin/egrep\fR [\fB-bcHhilnqsvx\fR] \fB-e\fR \fIpattern_list\fR [\fB-f\fR \fIfile\fR]
[\fIfile...\fR]
.fi
.LP
.nf
-\fB/usr/xpg4/bin/egrep\fR [\fB-bcHhilnqsvx\fR] [\fB-e\fR \fIpattern_list\fR] \fB-f\fR \fIfile\fR
+\fB/usr/bin/egrep\fR [\fB-bcHhilnqsvx\fR] [\fB-e\fR \fIpattern_list\fR] \fB-f\fR \fIfile\fR
[\fIfile...\fR]
.fi
.LP
.nf
-\fB/usr/xpg4/bin/egrep\fR [\fB-bcHhilnqsvx\fR] \fIpattern\fR [\fIfile...\fR]
+\fB/usr/bin/egrep\fR [\fB-bcHhilnqsvx\fR] \fIpattern\fR [\fIfile...\fR]
.fi
.SH DESCRIPTION
-.sp
.LP
The \fBegrep\fR (\fIexpression grep\fR) utility searches files for a pattern of
characters and prints all lines that contain that pattern. \fBegrep\fR uses
@@ -58,37 +42,9 @@ fast deterministic algorithm that sometimes needs exponential space.
If no files are specified, \fBegrep\fR assumes standard input. Normally, each
line found is copied to the standard output. The file name is printed before
each line found if there is more than one input file.
-.SS "/usr/bin/egrep"
-.sp
.LP
-The \fB/usr/bin/egrep\fR utility accepts full regular expressions as described
-on the \fBregexp\fR(5) manual page, except for \fB\e(\fR and \fB\e)\fR,
-\fB\e(\fR and \fB\e)\fR, \fB\e{\fR and \fB\e}\fR, \fB\e<\fR and \fB\e>\fR, and
-\fB\en\fR, and with the addition of:
-.RS +4
-.TP
-1.
-A full regular expression followed by \fB+\fR that matches one or more
-occurrences of the full regular expression.
-.RE
-.RS +4
-.TP
-2.
-A full regular expression followed by \fB?\fR that matches 0 or 1
-occurrences of the full regular expression.
-.RE
-.RS +4
-.TP
-3.
-Full regular expressions separated by | or by a \fBNEWLINE\fR that match
-strings that are matched by any of the expressions.
-.RE
-.RS +4
-.TP
-4.
-A full regular expression that can be enclosed in parentheses \fB()\fRfor
-grouping.
-.RE
+The \fBegrep\fR utility accepts the same form of full regular expressions as
+\fBgrep\fR(1) -E option.
.sp
.LP
Be careful using the characters \fB$\fR, \fB*\fR, \fB[\fR, \fB^\fR, |, \fB(\fR,
@@ -99,23 +55,15 @@ expression\fR in single quotes (\fBa\'\fR\fBa\'\fR).
.LP
The order of precedence of operators is \fB[\|]\fR, then \fB*\|?\|+\fR, then
concatenation, then | and NEWLINE.
-.SS "/usr/xpg4/bin/egrep"
-.sp
-.LP
-The \fB/usr/xpg4/bin/egrep\fR utility uses the regular expressions described in
-the \fBEXTENDED REGULAR EXPRESSIONS\fR section of the \fBregex\fR(5) manual
-page.
.SH OPTIONS
-.sp
.LP
-The following options are supported for both \fB/usr/bin/egrep\fR and
-\fB/usr/xpg4/bin/egrep\fR:
+The following options are supported:
.sp
.ne 2
.na
\fB\fB-b\fR\fR
.ad
-.RS 19n
+.RS 6n
Precede each line by the block number on which it was found. This can be useful
in locating block numbers by context (first block is 0).
.RE
@@ -125,7 +73,7 @@ in locating block numbers by context (first block is 0).
.na
\fB\fB-c\fR\fR
.ad
-.RS 19n
+.RS 6n
Print only a count of the lines that contain the pattern.
.RE
@@ -134,7 +82,7 @@ Print only a count of the lines that contain the pattern.
.na
\fB\fB-e\fR \fIpattern_list\fR\fR
.ad
-.RS 19n
+.RS 6n
Search for a \fIpattern_list\fR (\fIfull regular expression\fR that begins with
a \fB\(mi\fR).
.RE
@@ -144,7 +92,7 @@ a \fB\(mi\fR).
.na
\fB\fB-f\fR \fIfile\fR\fR
.ad
-.RS 19n
+.RS 6n
Take the list of \fIfull\fR \fIregular\fR \fIexpressions\fR from \fIfile\fR.
.RE
@@ -153,7 +101,7 @@ Take the list of \fIfull\fR \fIregular\fR \fIexpressions\fR from \fIfile\fR.
.na
\fB\fB-H\fR\fR
.ad
-.RS 19n
+.RS 6n
Precedes each line by the name of the file containing the matching line.
.RE
@@ -162,7 +110,7 @@ Precedes each line by the name of the file containing the matching line.
.na
\fB\fB-h\fR\fR
.ad
-.RS 19n
+.RS 6n
Suppress printing of filenames when searching multiple files.
.RE
@@ -171,7 +119,7 @@ Suppress printing of filenames when searching multiple files.
.na
\fB\fB-i\fR\fR
.ad
-.RS 19n
+.RS 6n
Ignore upper/lower case distinction during comparisons.
.RE
@@ -180,7 +128,7 @@ Ignore upper/lower case distinction during comparisons.
.na
\fB\fB-l\fR\fR
.ad
-.RS 19n
+.RS 6n
Print the names of files with matching lines once, separated by NEWLINEs. Does
not repeat the names of files when the pattern is found more than once.
.RE
@@ -190,7 +138,7 @@ not repeat the names of files when the pattern is found more than once.
.na
\fB\fB-n\fR\fR
.ad
-.RS 19n
+.RS 6n
Precede each line by its line number in the file (first line is 1).
.RE
@@ -199,7 +147,7 @@ Precede each line by its line number in the file (first line is 1).
.na
\fB\fB-q\fR\fR
.ad
-.RS 19n
+.RS 6n
Quiet. Does not write anything to the standard output, regardless of matching
lines. Exits with zero status if an input line is selected.
.RE
@@ -209,7 +157,7 @@ lines. Exits with zero status if an input line is selected.
.na
\fB\fB-s\fR\fR
.ad
-.RS 19n
+.RS 6n
Legacy equivalent of \fB-q\fR.
.RE
@@ -218,14 +166,10 @@ Legacy equivalent of \fB-q\fR.
.na
\fB\fB-v\fR\fR
.ad
-.RS 19n
+.RS 6n
Print all lines except those that contain the pattern.
.RE
-.SS "/usr/xpg4/bin/egrep"
-.sp
-.LP
-The following options are supported for \fB/usr/xpg4/bin/egrep\fR only:
.sp
.ne 2
.na
@@ -237,7 +181,6 @@ entire fixed string or regular expression to be matching lines.
.RE
.SH OPERANDS
-.sp
.LP
The following operands are supported:
.sp
@@ -250,40 +193,25 @@ A path name of a file to be searched for the patterns. If no \fIfile\fR
operands are specified, the standard input is used.
.RE
-.SS "/usr/bin/egrep"
-.sp
-.ne 2
-.na
-\fB\fIpattern\fR\fR
-.ad
-.RS 11n
-Specify a pattern to be used during the search for input.
-.RE
-
-.SS "/usr/xpg4/bin/egrep"
-.sp
.ne 2
.na
\fB\fIpattern\fR\fR
.ad
-.RS 11n
+.RS 8n
Specify one or more patterns to be used during the search for input. This
-operand is treated as if it were specified as \fB-e\fR\fIpattern_list.\fR.
+operand is treated as if it were specified as \fB-e\fR\fIpattern_list\fR.
.RE
.SH USAGE
-.sp
.LP
See \fBlargefile\fR(5) for the description of the behavior of \fBegrep\fR when
encountering files greater than or equal to 2 Gbyte ( 2^31 bytes).
.SH ENVIRONMENT VARIABLES
-.sp
.LP
See \fBenviron\fR(5) for descriptions of the following environment variables
that affect the execution of \fBegrep\fR: \fBLC_COLLATE\fR, \fBLC_CTYPE\fR,
\fBLC_MESSAGES\fR, and \fBNLSPATH\fR.
.SH EXIT STATUS
-.sp
.LP
The following exit values are returned:
.sp
@@ -314,24 +242,8 @@ For syntax errors or inaccessible files (even if matches were found).
.RE
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.SS "/usr/bin/egrep"
-.sp
-
-.sp
-.TS
-box;
-c | c
-l | l .
-ATTRIBUTE TYPE ATTRIBUTE VALUE
-_
-CSI Not Enabled
-.TE
-
-.SS "/usr/xpg4/bin/egrep"
-.sp
.sp
.TS
@@ -344,22 +256,22 @@ CSI Enabled
.TE
.SH SEE ALSO
-.sp
.LP
\fBfgrep\fR(1), \fBgrep\fR(1), \fBsed\fR(1), \fBsh\fR(1), \fBattributes\fR(5),
\fBenviron\fR(5), \fBlargefile\fR(5), \fBregex\fR(5), \fBregexp\fR(5),
\fBXPG4\fR(5)
.SH NOTES
-.sp
.LP
Ideally there should be only one \fBgrep\fR command, but there is not a single
algorithm that spans a wide enough range of space-time trade-offs.
.sp
.LP
Lines are limited only by the size of the available virtual memory.
-.SS "/usr/xpg4/bin/egrep"
-.sp
.LP
-The \fB/usr/xpg4/bin/egrep\fR utility is identical to \fB/usr/xpg4/bin/grep\fR
+The \fB/usr/bin/egrep\fR utility is identical to \fB/usr/bin/grep\fR
\fB-E\fR. See \fBgrep\fR(1). Portable applications should use
-\fB/usr/xpg4/bin/grep\fR \fB-E\fR.
+\fB/usr/bin/grep\fR \fB-E\fR.
+.LP
+In the past the behavior of \fB/usr/xpg4/bin/egrep\fR and
+\fB/usr/bin/egrep\fR utilities was different. Now \fB/usr/bin/egrep\fR
+is replaced by \fB/usr/xpg4/bin/egrep\fR.
diff --git a/usr/src/man/man1/fgrep.1 b/usr/src/man/man1/fgrep.1
index 7c254b67ff..3bf3b724e5 100644
--- a/usr/src/man/man1/fgrep.1
+++ b/usr/src/man/man1/fgrep.1
@@ -9,44 +9,28 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH FGREP 1 "May 3, 2013"
+.TH FGREP 1 "Nov 28, 2017"
.SH NAME
fgrep \- search a file for a fixed-character string
.SH SYNOPSIS
.LP
.nf
-\fB/usr/bin/fgrep\fR [\fB-bcHhilnqsvx\fR] \fB-e\fR \fIpattern_list\fR [\fIfile...\fR]
-.fi
-
-.LP
-.nf
-\fB/usr/bin/fgrep\fR [\fB-bcHhilnqsvx\fR] \fB-f\fR \fIfile\fR [\fIfile...\fR]
-.fi
-
-.LP
-.nf
-\fB/usr/bin/fgrep\fR [\fB-bcHhilnqsvx\fR] \fIpattern\fR [\fIfile...\fR]
-.fi
-
-.LP
-.nf
-\fB/usr/xpg4/bin/fgrep\fR [\fB-bcHhilnqsvx\fR] \fB-e\fR \fIpattern_list\fR [\fB-f\fR \fIfile\fR]
+\fB/usr/bin/fgrep\fR [\fB-bcHhilnqsvx\fR] \fB-e\fR \fIpattern_list\fR [\fB-f\fR \fIfile\fR]
[\fIfile...\fR]
.fi
.LP
.nf
-\fB/usr/xpg4/bin/fgrep\fR [\fB-bcHhilnqsvx\fR] [\fB-e\fR \fIpattern_list\fR] \fB-f\fR \fIfile\fR
+\fB/usr/bin/fgrep\fR [\fB-bcHhilnqsvx\fR] [\fB-e\fR \fIpattern_list\fR] \fB-f\fR \fIfile\fR
[\fIfile...\fR]
.fi
.LP
.nf
-\fB/usr/xpg4/bin/fgrep\fR [\fB-bcHhilnqsvx\fR] \fIpattern\fR [\fIfile...\fR]
+\fB/usr/bin/fgrep\fR [\fB-bcHhilnqsvx\fR] \fIpattern\fR [\fIfile...\fR]
.fi
.SH DESCRIPTION
-.sp
.LP
The \fBfgrep\fR (fast \fBgrep\fR) utility searches files for a character string
and prints all lines that contain that string. \fBfgrep\fR is different from
@@ -66,16 +50,14 @@ If no files are specified, \fBfgrep\fR assumes standard input. Normally, each
line that is found is copied to the standard output. The file name is printed
before each line that is found if there is more than one input file.
.SH OPTIONS
-.sp
.LP
-The following options are supported for both \fB/usr/bin/fgrep\fR and
-\fB/usr/xpg4/bin/fgrep\fR:
+The following options are supported:
.sp
.ne 2
.na
\fB\fB-b\fR\fR
.ad
-.RS 19n
+.RS 6n
Precedes each line by the block number on which the line was found. This can be
useful in locating block numbers by context. The first block is 0.
.RE
@@ -85,7 +67,7 @@ useful in locating block numbers by context. The first block is 0.
.na
\fB\fB-c\fR\fR
.ad
-.RS 19n
+.RS 6n
Prints only a count of the lines that contain the pattern.
.RE
@@ -94,7 +76,7 @@ Prints only a count of the lines that contain the pattern.
.na
\fB\fB-e\fR \fIpattern_list\fR\fR
.ad
-.RS 19n
+.RS 6n
Searches for a \fIstring\fR in \fIpattern-list\fR. This is useful when the
\fIstring\fR begins with a \fB\(mi\fR\&.
.RE
@@ -104,7 +86,7 @@ Searches for a \fIstring\fR in \fIpattern-list\fR. This is useful when the
.na
\fB\fB-f\fR \fIpattern-file\fR\fR
.ad
-.RS 19n
+.RS 6n
Takes the list of patterns from \fIpattern-file\fR.
.RE
@@ -113,7 +95,7 @@ Takes the list of patterns from \fIpattern-file\fR.
.na
\fB\fB-H\fR\fR
.ad
-.RS 19n
+.RS 6n
Precedes each line by the name of the file containing the matching line.
.RE
@@ -122,7 +104,7 @@ Precedes each line by the name of the file containing the matching line.
.na
\fB\fB-h\fR\fR
.ad
-.RS 19n
+.RS 6n
Suppresses printing of files when searching multiple files.
.RE
@@ -131,7 +113,7 @@ Suppresses printing of files when searching multiple files.
.na
\fB\fB-i\fR\fR
.ad
-.RS 19n
+.RS 6n
Ignores upper/lower case distinction during comparisons.
.RE
@@ -140,7 +122,7 @@ Ignores upper/lower case distinction during comparisons.
.na
\fB\fB-l\fR\fR
.ad
-.RS 19n
+.RS 6n
Prints the names of files with matching lines once, separated by new-lines.
Does not repeat the names of files when the pattern is found more than once.
.RE
@@ -150,7 +132,7 @@ Does not repeat the names of files when the pattern is found more than once.
.na
\fB\fB-n\fR\fR
.ad
-.RS 19n
+.RS 6n
Precedes each line by its line number in the file. The first line is 1.
.RE
@@ -159,7 +141,7 @@ Precedes each line by its line number in the file. The first line is 1.
.na
\fB\fB-q\fR\fR
.ad
-.RS 19n
+.RS 6n
Quiet. Does not write anything to the standard output, regardless of matching
lines. Exits with zero status if an input line is selected.
.RE
@@ -169,7 +151,7 @@ lines. Exits with zero status if an input line is selected.
.na
\fB\fB-s\fR\fR
.ad
-.RS 19n
+.RS 6n
Legacy equivalent of \fB-q\fR.
.RE
@@ -178,7 +160,7 @@ Legacy equivalent of \fB-q\fR.
.na
\fB\fB-v\fR\fR
.ad
-.RS 19n
+.RS 6n
Prints all lines except those that contain the pattern.
.RE
@@ -187,12 +169,11 @@ Prints all lines except those that contain the pattern.
.na
\fB\fB-x\fR\fR
.ad
-.RS 19n
+.RS 6n
Prints only lines that are matched entirely.
.RE
.SH OPERANDS
-.sp
.LP
The following operands are supported:
.sp
@@ -205,40 +186,25 @@ Specifies a path name of a file to be searched for the patterns. If no
\fIfile\fR operands are specified, the standard input will be used.
.RE
-.SS "/usr/bin/fgrep"
-.sp
-.ne 2
-.na
-\fB\fIpattern\fR\fR
-.ad
-.RS 11n
-Specifies a pattern to be used during the search for input.
-.RE
-
-.SS "/usr/xpg4/bin/fgrep"
-.sp
.ne 2
.na
\fB\fIpattern\fR\fR
.ad
-.RS 11n
+.RS 8n
Specifies one or more patterns to be used during the search for input. This
operand is treated as if it were specified as \fB-e\fR \fIpattern_list\fR.
.RE
.SH USAGE
-.sp
.LP
See \fBlargefile\fR(5) for the description of the behavior of \fBfgrep\fR when
encountering files greater than or equal to 2 Gbyte ( 2^31 bytes).
.SH ENVIRONMENT VARIABLES
-.sp
.LP
See \fBenviron\fR(5) for descriptions of the following environment variables
that affect the execution of \fBfgrep\fR: \fBLC_COLLATE\fR, \fBLC_CTYPE\fR,
\fBLC_MESSAGES\fR, and \fBNLSPATH\fR.
.SH EXIT STATUS
-.sp
.LP
The following exit values are returned:
.sp
@@ -268,11 +234,7 @@ If no matches are found
For syntax errors or inaccessible files, even if matches were found.
.RE
-.SS "/usr/xpg4/bin/fgrep"
-.sp
-
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
.sp
@@ -286,21 +248,21 @@ CSI Enabled
.TE
.SH SEE ALSO
-.sp
.LP
\fBed\fR(1), \fBegrep\fR(1), \fBgrep\fR(1), \fBsed\fR(1), \fBsh\fR(1),
\fBattributes\fR(5), \fBenviron\fR(5), \fBlargefile\fR(5), \fBXPG4\fR(5)
.SH NOTES
-.sp
.LP
Ideally, there should be only one \fBgrep\fR command, but there is not a single
algorithm that spans a wide enough range of space-time tradeoffs.
.sp
.LP
Lines are limited only by the size of the available virtual memory.
-.SS "/usr/xpg4/bin/fgrep"
-.sp
.LP
-The \fB/usr/xpg4/bin/fgrep\fR utility is identical to \fB/usr/xpg4/bin/grep\fR
+The \fB/usr/bin/fgrep\fR utility is identical to \fB/usr/bin/grep\fR
\fB-F\fR (see \fBgrep\fR(1)). Portable applications should use
-\fB/usr/xpg4/bin/grep\fR \fB-F\fR.
+\fB/usr/bin/grep\fR \fB-F\fR.
+.LP
+In the past the behavior of \fB/usr/xpg4/bin/fgrep\fR and
+\fB/usr/bin/fgrep\fR utilities was different. Now \fB/usr/bin/fgrep\fR
+is replaced by \fB/usr/xpg4/bin/fgrep\fR.
diff --git a/usr/src/man/man1/grep.1 b/usr/src/man/man1/grep.1
index f3e3402269..0b663de61b 100644
--- a/usr/src/man/man1/grep.1
+++ b/usr/src/man/man1/grep.1
@@ -10,33 +10,27 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH GREP 1 "June 5, 2017"
+.TH GREP 1 "Nov 28, 2017"
.SH NAME
grep \- search a file for a pattern
.SH SYNOPSIS
.LP
.nf
-\fB/usr/bin/grep\fR [\fB-c\fR | \fB-l\fR |\fB-q\fR] [\fB-r\fR | \fB-R\fR] [\fB-bHhinsvw\fR]
- \fIlimited-regular-expression\fR [\fIfilename\fR]...
-.fi
-
-.LP
-.nf
-\fB/usr/xpg4/bin/grep\fR [\fB-E\fR | \fB-F\fR] [\fB-c\fR | \fB-l\fR | \fB-q\fR] [\fB-r\fR | \fB-R\fR]
+\fB/usr/bin/grep\fR [\fB-E\fR | \fB-F\fR] [\fB-c\fR | \fB-l\fR | \fB-q\fR] [\fB-r\fR | \fB-R\fR]
[\fB-bHhinsvwx\fR] [\fB-A\fR \fInumber\fR] [\fB-B\fR \fInumber\fR] [\fB-C\fR \fInumber\fR | \fB-\fR\fInumber\fR] \fB-e\fR \fIpattern_list\fR... [\fB-f\fR \fIpattern_file\fR]...
[\fIfile\fR]...
.fi
.LP
.nf
-\fB/usr/xpg4/bin/grep\fR [\fB-E\fR | \fB-F\fR] [\fB-c\fR | \fB-l\fR | \fB-q\fR] [\fB-r\fR | \fB-R\fR]
+\fB/usr/bin/grep\fR [\fB-E\fR | \fB-F\fR] [\fB-c\fR | \fB-l\fR | \fB-q\fR] [\fB-r\fR | \fB-R\fR]
[\fB-bHhinsvwx\fR] [\fB-A\fR \fInumber\fR] [\fB-B\fR \fInumber\fR] [\fB-C\fR \fInumber\fR | \fB-\fR\fInumber\fR] [\fB-e\fR \fIpattern_list\fR]... \fB-f\fR \fIpattern_file\fR...
[\fIfile\fR]...
.fi
.LP
.nf
-\fB/usr/xpg4/bin/grep\fR [\fB-E\fR | \fB-F\fR] [\fB-c\fR | \fB-l\fR | \fB-q\fR] [\fB-r\fR | \fB-R\fR]
+\fB/usr/bin/grep\fR [\fB-E\fR | \fB-F\fR] [\fB-c\fR | \fB-l\fR | \fB-q\fR] [\fB-r\fR | \fB-R\fR]
[\fB-bHhinsvwx\fR] [\fB-A\fR \fInumber\fR] [\fB-B\fR \fInumber\fR] [\fB-C\fR \fInumber\fR | \fB-\fR\fInumber\fR] \fIpattern\fR [\fIfile\fR]...
.fi
@@ -55,23 +49,28 @@ in single quotes \fB\'\fR\&...\fB\'\fR\&.
If no files are specified, \fBgrep\fR assumes standard input. Normally, each
line found is copied to standard output. The file name is printed before each
line found if there is more than one input file.
-.SS "/usr/bin/grep"
.LP
-The \fB/usr/bin/grep\fR utility uses limited regular expressions like those
-described on the \fBregexp\fR(5) manual page to match the patterns.
-.SS "/usr/xpg4/bin/grep"
-.LP
-The options \fB-E\fR and \fB-F\fR affect the way \fB/usr/xpg4/bin/grep\fR
+The options \fB-E\fR and \fB-F\fR affect the way \fBgrep\fR
interprets \fIpattern_list\fR. If \fB-E\fR is specified,
-\fB/usr/xpg4/bin/grep\fR interprets \fIpattern_list\fR as a full regular
+\fBgrep\fR interprets \fIpattern_list\fR as a full regular
expression (see \fB-E\fR for description). If \fB-F\fR is specified,
\fBgrep\fR interprets \fIpattern_list\fR as a fixed string. If neither are
specified, \fBgrep\fR interprets \fIpattern_list\fR as a basic regular
expression as described on \fBregex\fR(5) manual page.
.SH OPTIONS
.LP
-The following options are supported for both \fB/usr/bin/grep\fR and
-\fB/usr/xpg4/bin/grep\fR:
+The following options are supported:
+.sp
+.ne 2
+.na
+\fB\fB-A\fR \fInumber\fR\fR
+.ad
+.RS 6n
+Prints \fInumber\fR input lines of context after each matching line. If there
+are multiple matching lines, their context lines are separated by a \fB--\fR
+delimiter line.
+.RE
+
.sp
.ne 2
.na
@@ -85,141 +84,179 @@ useful in locating block numbers by context (first block is 0).
.sp
.ne 2
.na
-\fB\fB-c\fR\fR
+\fB\fB-B\fR \fInumber\fR\fR
.ad
.RS 6n
-Prints only a count of the lines that contain the pattern.
+Prints \fInumber\fR input lines of context before each matching line. If there
+are multiple matching lines, their context lines are separated by a \fB--\fR
+delimiter line.
.RE
.sp
.ne 2
.na
-\fB\fB-H\fR\fR
+\fB\fB-c\fR\fR
.ad
.RS 6n
-Precedes each line by the name of the file containing the matching line.
+Prints only a count of the lines that contain the pattern.
.RE
.sp
.ne 2
.na
-\fB\fB-h\fR\fR
+\fB\fB-H\fR\fR
.ad
.RS 6n
-Prevents the name of the file containing the matching line from being prepended
-to that line. Used when searching multiple files.
+Precedes each line by the name of the file containing the matching line.
.RE
.sp
.ne 2
.na
-\fB\fB-i\fR\fR
+\fB\fB-e\fR \fIpattern_list\fR\fR
.ad
.RS 6n
-Ignores upper/lower case distinction during comparisons.
+Specifies one or more patterns to be used during the search for input. Patterns
+in \fIpattern_list\fR must be separated by a NEWLINE character. A null pattern
+can be specified by two adjacent newline characters in \fIpattern_list\fR.
+Unless the \fB-E\fR or \fB-F\fR option is also specified, each pattern is
+treated as a basic regular expression. Multiple \fB-e\fR and \fB-f\fR options
+are accepted by \fBgrep\fR. All of the specified patterns are used when
+matching lines, but the order of evaluation is unspecified.
.RE
.sp
.ne 2
.na
-\fB\fB-l\fR\fR
+\fB\fB-E\fR\fR
.ad
.RS 6n
-Prints only the names of files with matching lines, separated by NEWLINE
-characters. Does not repeat the names of files when the pattern is found more
-than once.
+Matches using full regular expressions. Treats each pattern specified as a full
+regular expression. If any entire full regular expression pattern matches an
+input line, the line is matched. A null full regular expression matches every
+line. Each pattern is interpreted as a full regular expression as described on
+the \fBregex\fR(5) manual page, except for \fB\e(\fR and \fB\e)\fR, and
+including:
+.RS +4
+.TP
+1.
+A full regular expression followed by \fB+\fR that matches one or more
+occurrences of the full regular expression.
+.RE
+.RS +4
+.TP
+2.
+A full regular expression followed by \fB?\fR that matches 0 or 1
+occurrences of the full regular expression.
+.RE
+.RS +4
+.TP
+3.
+Full regular expressions separated by | or by a new-line that match strings
+that are matched by any of the expressions.
+.RE
+.RS +4
+.TP
+4.
+A full regular expression that is enclosed in parentheses \fB()\fR for
+grouping.
+.RE
+The order of precedence of operators is \fB[\|]\fR, then \fB*\|?\|+\fR, then
+concatenation, then | and new-line.
.RE
.sp
.ne 2
.na
-\fB\fB-n\fR\fR
+\fB\fB-f\fR \fIpattern_file\fR\fR
.ad
.RS 6n
-Precedes each line by its line number in the file (first line is 1).
+Reads one or more patterns from the file named by the path name
+\fIpattern_file\fR. Patterns in \fIpattern_file\fR are terminated by a NEWLINE
+character. A null pattern can be specified by an empty line in
+\fIpattern_file\fR. Unless the \fB-E\fR or \fB-F\fR option is also specified,
+each pattern is treated as a basic regular expression.
.RE
.sp
.ne 2
.na
-\fB\fB-r\fR\fR
+\fB\fB-F\fR\fR
.ad
.RS 6n
-Read all files under each directory, recursively. Follow symbolic links on
-the command line, but skip symlinks that are encountered recursively. If file
-is a device, FIFO, or socket, skip it.
+Matches using fixed strings. Treats each pattern specified as a string instead
+of a regular expression. If an input line contains any of the patterns as a
+contiguous sequence of bytes, the line is matched. A null string matches every
+line. See \fBfgrep\fR(1) for more information.
.RE
.sp
.ne 2
.na
-\fB\fB-R\fR\fR
+\fB\fB-h\fR\fR
.ad
.RS 6n
-Read all files under each directory, recursively, following all symbolic links.
+Prevents the name of the file containing the matching line from being prepended
+to that line. Used when searching multiple files.
.RE
.sp
.ne 2
.na
-\fB\fB-q\fR\fR
+\fB\fB-i\fR\fR
.ad
.RS 6n
-Quiet. Does not write anything to the standard output, regardless of matching
-lines. Exits with zero status if an input line is selected.
+Ignores upper/lower case distinction during comparisons.
.RE
.sp
.ne 2
.na
-\fB\fB-s\fR\fR
+\fB\fB-l\fR\fR
.ad
.RS 6n
-Suppresses error messages about nonexistent or unreadable files.
+Prints only the names of files with matching lines, separated by NEWLINE
+characters. Does not repeat the names of files when the pattern is found more
+than once.
.RE
.sp
.ne 2
.na
-\fB\fB-v\fR\fR
+\fB\fB-n\fR\fR
.ad
.RS 6n
-Prints all lines except those that contain the pattern.
+Precedes each line by its line number in the file (first line is 1).
.RE
.sp
.ne 2
.na
-\fB\fB-w\fR\fR
+\fB\fB-r\fR\fR
.ad
.RS 6n
-Searches for the expression as a word as if surrounded by \fB\e<\fR and
-\fB\e>\fR\&.
+Read all files under each directory, recursively. Follow symbolic links on
+the command line, but skip symlinks that are encountered recursively. If file
+is a device, FIFO, or socket, skip it.
.RE
-.SS "/usr/xpg4/bin/grep"
-.LP
-The following options are supported for \fB/usr/xpg4/bin/grep\fR only:
.sp
.ne 2
.na
-\fB\fB-A\fR \fInumber\fR\fR
+\fB\fB-R\fR\fR
.ad
-.RS 19n
-Prints \fInumber\fR input lines of context after each matching line. If there
-are multiple matching lines, their context lines are separated by a \fB--\fR
-delimiter line.
+.RS 6n
+Read all files under each directory, recursively, following all symbolic links.
.RE
.sp
.ne 2
.na
-\fB\fB-B\fR \fInumber\fR\fR
+\fB\fB-q\fR\fR
.ad
-.RS 19n
-Prints \fInumber\fR input lines of context before each matching line. If there
-are multiple matching lines, their context lines are separated by a \fB--\fR
-delimiter line.
+.RS 6n
+Quiet. Does not write anything to the standard output, regardless of matching
+lines. Exits with zero status if an input line is selected.
.RE
.sp
@@ -231,91 +268,38 @@ delimiter line.
.na
\fB\fB-C\fR \fInumber\fR\fR
.ad
-.RS 19n
+.RS 6n
Prints \fInumber\fR input lines of context before and \fInumber\fR input lines
of context after each matching line. If there are multiple matching lines,
their context lines are separated by a \fB--\fR delimiter line.
.RE
-
.sp
.ne 2
.na
-\fB\fB-e\fR \fIpattern_list\fR\fR
-.ad
-.RS 19n
-Specifies one or more patterns to be used during the search for input. Patterns
-in \fIpattern_list\fR must be separated by a NEWLINE character. A null pattern
-can be specified by two adjacent newline characters in \fIpattern_list\fR.
-Unless the \fB-E\fR or \fB-F\fR option is also specified, each pattern is
-treated as a basic regular expression. Multiple \fB-e\fR and \fB-f\fR options
-are accepted by \fBgrep\fR. All of the specified patterns are used when
-matching lines, but the order of evaluation is unspecified.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fB-E\fR\fR
+\fB\fB-s\fR\fR
.ad
-.RS 19n
-Matches using full regular expressions. Treats each pattern specified as a full
-regular expression. If any entire full regular expression pattern matches an
-input line, the line is matched. A null full regular expression matches every
-line. Each pattern is interpreted as a full regular expression as described on
-the \fBregex\fR(5) manual page, except for \fB\e(\fR and \fB\e)\fR, and
-including:
-.RS +4
-.TP
-1.
-A full regular expression followed by \fB+\fR that matches one or more
-occurrences of the full regular expression.
-.RE
-.RS +4
-.TP
-2.
-A full regular expression followed by \fB?\fR that matches 0 or 1
-occurrences of the full regular expression.
-.RE
-.RS +4
-.TP
-3.
-Full regular expressions separated by | or by a new-line that match strings
-that are matched by any of the expressions.
-.RE
-.RS +4
-.TP
-4.
-A full regular expression that is enclosed in parentheses \fB()\fR for
-grouping.
-.RE
-The order of precedence of operators is \fB[\|]\fR, then \fB*\|?\|+\fR, then
-concatenation, then | and new-line.
+.RS 6n
+Suppresses error messages about nonexistent or unreadable files.
.RE
.sp
.ne 2
.na
-\fB\fB-f\fR \fIpattern_file\fR\fR
+\fB\fB-v\fR\fR
.ad
-.RS 19n
-Reads one or more patterns from the file named by the path name
-\fIpattern_file\fR. Patterns in \fIpattern_file\fR are terminated by a NEWLINE
-character. A null pattern can be specified by an empty line in
-\fIpattern_file\fR. Unless the \fB-E\fR or \fB-F\fR option is also specified,
-each pattern is treated as a basic regular expression.
+.RS 6n
+Prints all lines except those that contain the pattern.
.RE
.sp
.ne 2
.na
-\fB\fB-F\fR\fR
+\fB\fB-w\fR\fR
.ad
-.RS 19n
-Matches using fixed strings. Treats each pattern specified as a string instead
-of a regular expression. If an input line contains any of the patterns as a
-contiguous sequence of bytes, the line is matched. A null string matches every
-line. See \fBfgrep\fR(1) for more information.
+.RS 6n
+Searches for the expression as a word as if surrounded by \fB\e<\fR and
+\fB\e>\fR\&.
.RE
.sp
@@ -323,7 +307,7 @@ line. See \fBfgrep\fR(1) for more information.
.na
\fB\fB-x\fR\fR
.ad
-.RS 19n
+.RS 6n
Considers only input lines that use all characters in the line to match an
entire fixed string or regular expression to be matching lines.
.RE
@@ -341,21 +325,11 @@ A path name of a file to be searched for the patterns. If no \fIfile\fR
operands are specified, the standard input is used.
.RE
-.SS "/usr/bin/grep"
-.ne 2
-.na
-\fB\fIpattern\fR\fR
-.ad
-.RS 11n
-Specifies a pattern to be used during the search for input.
-.RE
-
-.SS "/usr/xpg4/bin/grep"
.ne 2
.na
\fB\fIpattern\fR\fR
.ad
-.RS 11n
+.RS 8n
Specifies one or more patterns to be used during the search for input. This
operand is treated as if it were specified as \fB-e\fR \fIpattern_list\fR.
.RE
@@ -437,22 +411,22 @@ All of the following commands print all lines containing strings \fBabc\fR or
.sp
.in +2
.nf
-example% \fB/usr/xpg4/bin/grep 'abc
+example% \fB/usr/bin/grep 'abc
def'\fR
-example% \fB/usr/xpg4/bin/grep -e 'abc
+example% \fB/usr/bin/grep -e 'abc
def'\fR
-example% \fB/usr/xpg4/bin/grep -e 'abc' -e 'def'\fR
-example% \fB/usr/xpg4/bin/grep -E 'abc|def'\fR
-example% \fB/usr/xpg4/bin/grep -E -e 'abc|def'\fR
-example% \fB/usr/xpg4/bin/grep -E -e 'abc' -e 'def'\fR
-example% \fB/usr/xpg4/bin/grep -E 'abc
+example% \fB/usr/bin/grep -e 'abc' -e 'def'\fR
+example% \fB/usr/bin/grep -E 'abc|def'\fR
+example% \fB/usr/bin/grep -E -e 'abc|def'\fR
+example% \fB/usr/bin/grep -E -e 'abc' -e 'def'\fR
+example% \fB/usr/bin/grep -E 'abc
def'\fR
-example% \fB/usr/xpg4/bin/grep -E -e 'abc
+example% \fB/usr/bin/grep -E -e 'abc
def'\fR
-example% \fB/usr/xpg4/bin/grep -F -e 'abc' -e 'def'\fR
-example% \fB/usr/xpg4/bin/grep -F 'abc
+example% \fB/usr/bin/grep -F -e 'abc' -e 'def'\fR
+example% \fB/usr/bin/grep -F 'abc
def'\fR
-example% \fB/usr/xpg4/bin/grep -F -e 'abc
+example% \fB/usr/bin/grep -F -e 'abc
def'\fR
.fi
.in -2
@@ -468,8 +442,10 @@ Both of the following commands print all lines matching exactly \fBabc\fR or
.sp
.in +2
.nf
-example% \fB/usr/xpg4/bin/grep -E '^abc$ ^def$'\fR
-example% \fB/usr/xpg4/bin/grep -F -x 'abc def'\fR
+example% \fB/usr/bin/grep -E '^abc$
+^def$'\fR
+example% \fB/usr/bin/grep -F -x 'abc
+def'\fR
.fi
.in -2
.sp
@@ -512,18 +488,6 @@ Syntax errors or inaccessible files (even if matches were found).
.SH ATTRIBUTES
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
-.SS "/usr/bin/grep"
-
-.TS
-box;
-c | c
-l | l .
-ATTRIBUTE TYPE ATTRIBUTE VALUE
-_
-CSI Not Enabled
-.TE
-
-.SS "/usr/xpg4/bin/grep"
.TS
box;
@@ -544,13 +508,11 @@ Standard See \fBstandards\fR(5).
\fBenviron\fR(5), \fBlargefile\fR(5), \fBregex\fR(5), \fBregexp\fR(5),
\fBstandards\fR(5)
.SH NOTES
-.SS "/usr/bin/grep"
-.LP
-Lines are limited only by the size of the available virtual memory. If there is
-a line with embedded nulls, \fBgrep\fR only matches up to the first null. If
-the line matches, the entire line is printed.
-.SS "/usr/xpg4/bin/grep"
.LP
The results are unspecified if input files contain lines longer than
\fBLINE_MAX\fR bytes or contain binary data. \fBLINE_MAX\fR is defined in
\fB/usr/include/limits.h\fR.
+.LP
+In the past the behavior of \fB/usr/xpg4/bin/grep\fR and
+\fB/usr/bin/grep\fR utilities was different. Now \fB/usr/bin/grep\fR
+is replaced by \fB/usr/xpg4/bin/grep\fR.
diff --git a/usr/src/man/man1/locale.1 b/usr/src/man/man1/locale.1
index 3230020206..d522854c50 100644
--- a/usr/src/man/man1/locale.1
+++ b/usr/src/man/man1/locale.1
@@ -7,7 +7,7 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH LOCALE 1 "Dec 20, 1996"
+.TH LOCALE 1 "Nov 28, 2017"
.SH NAME
locale \- get locale-specific information
.SH SYNOPSIS
@@ -22,7 +22,6 @@ locale \- get locale-specific information
.fi
.SH DESCRIPTION
-.sp
.LP
The \fBlocale\fR utility writes information about the current locale
environment, or all public locales, to the standard output. For the purposes of
@@ -52,7 +51,6 @@ Specifying a category name selects the named category and all keywords in that
category.
.RE
.SH OPTIONS
-.sp
.LP
The following options are supported:
.sp
@@ -97,7 +95,6 @@ Writes names of available charmaps; see \fBlocaledef\fR(1).
.RE
.SH OPERANDS
-.sp
.LP
The following operand is supported:
.sp
@@ -182,7 +179,7 @@ a user-supplied response is affirmative:
.sp
.in +2
.nf
-\fBif printf "%s\en" "$response" | /usr/xpg4/bin/grep -Eq\e
+\fBif printf "%s\en" "$response" | /usr/bin/grep -Eq\e
"$(locale yesexpr)"
then
affirmative processing goes here
@@ -194,7 +191,6 @@ fi\fR
.sp
.SH ENVIRONMENT VARIABLES
-.sp
.LP
See \fBenviron\fR(5) for the descriptions of \fBLANG\fR, \fBLC_ALL\fR,
\fBLC_CTYPE\fR, \fBLC_MESSAGES\fR, and \fBNLSPATH\fR.
@@ -204,7 +200,6 @@ The \fBLANG\fR, \fBLC_*\fR, and \fBNLSPATH\fR environment variables must
specify the current locale environment to be written out. These environment
variables will be used if the \fB-a\fR option is not specified.
.SH EXIT STATUS
-.sp
.LP
The following exit values are returned:
.sp
@@ -226,7 +221,6 @@ An error occurred.
.RE
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
.sp
@@ -244,12 +238,10 @@ Interface Stability Standard
.TE
.SH SEE ALSO
-.sp
.LP
\fBlocaledef\fR(1), \fBattributes\fR(5), \fBcharmap\fR(5), \fBenviron\fR(5),
\fBlocale\fR(5), \fBstandards\fR(5)
.SH NOTES
-.sp
.LP
If \fBLC_CTYPE\fR or keywords in the category \fBLC_CTYPE\fR are specified,
only the values in the range \fB0x00\fR-\fB0x7f\fR are written out.
diff --git a/usr/src/pkg/manifests/SUNWcs.mf b/usr/src/pkg/manifests/SUNWcs.mf
index c42953185d..b547cef60f 100644
--- a/usr/src/pkg/manifests/SUNWcs.mf
+++ b/usr/src/pkg/manifests/SUNWcs.mf
@@ -739,14 +739,12 @@ file path=usr/bin/dumpcs mode=0555
file path=usr/bin/dumpkeys mode=0555
file path=usr/bin/echo mode=0555
file path=usr/bin/ed mode=0555
-file path=usr/bin/egrep mode=0555
file path=usr/bin/eject mode=0555
file path=usr/bin/env mode=0555
file path=usr/bin/expr mode=0555
file path=usr/bin/false mode=0555
file path=usr/bin/fdetach mode=0555
file path=usr/bin/fdformat mode=4555
-file path=usr/bin/fgrep mode=0555
file path=usr/bin/file mode=0555
file path=usr/bin/find mode=0555
file path=usr/bin/fmt mode=0555
@@ -1499,9 +1497,11 @@ hardlink path=usr/bin/digest target=../../usr/lib/isaexec
hardlink path=usr/bin/dispgid target=../../usr/bin/ckgid
hardlink path=usr/bin/dispuid target=../../usr/bin/ckuid
hardlink path=usr/bin/edit target=../has/bin/edit
+hardlink path=usr/bin/egrep target=../../usr/bin/grep
hardlink path=usr/bin/encrypt target=../../usr/lib/isaexec
hardlink path=usr/bin/fc target=../../usr/bin/alias
hardlink path=usr/bin/fg target=../../usr/bin/alias
+hardlink path=usr/bin/fgrep target=../../usr/bin/grep
hardlink path=usr/bin/getopts target=../../usr/bin/alias
hardlink path=usr/bin/hash target=../../usr/bin/alias
hardlink path=usr/bin/jobs target=../../usr/bin/alias
diff --git a/usr/src/pkg/manifests/system-test-utiltest.mf b/usr/src/pkg/manifests/system-test-utiltest.mf
index 1bf15858bd..df0e0cfd4e 100644
--- a/usr/src/pkg/manifests/system-test-utiltest.mf
+++ b/usr/src/pkg/manifests/system-test-utiltest.mf
@@ -216,6 +216,10 @@ file path=opt/util-tests/tests/files/gout6 mode=0444
file path=opt/util-tests/tests/files/gout60 mode=0444
file path=opt/util-tests/tests/files/gout61 mode=0444
file path=opt/util-tests/tests/files/gout62 mode=0444
+file path=opt/util-tests/tests/files/gout63 mode=0444
+file path=opt/util-tests/tests/files/gout64 mode=0444
+file path=opt/util-tests/tests/files/gout65 mode=0444
+file path=opt/util-tests/tests/files/gout66 mode=0444
file path=opt/util-tests/tests/files/gout7 mode=0444
file path=opt/util-tests/tests/files/gout8 mode=0444
file path=opt/util-tests/tests/files/gout9 mode=0444
@@ -227,6 +231,7 @@ file path=opt/util-tests/tests/files/test4 mode=0444
file path=opt/util-tests/tests/files/test5 mode=0444
file path=opt/util-tests/tests/files/test6 mode=0444
file path=opt/util-tests/tests/files/test7 mode=0444
+file path=opt/util-tests/tests/files/testnl mode=0444
file path=opt/util-tests/tests/grep_test mode=0555
file path=opt/util-tests/tests/iconv_test mode=0555
file path=opt/util-tests/tests/libnvpair_json/json_00_blank mode=0555
diff --git a/usr/src/pkg/manifests/system-xopen-xcu4.mf b/usr/src/pkg/manifests/system-xopen-xcu4.mf
index 380cffd73d..c9de2bb7fa 100644
--- a/usr/src/pkg/manifests/system-xopen-xcu4.mf
+++ b/usr/src/pkg/manifests/system-xopen-xcu4.mf
@@ -52,7 +52,6 @@ file path=usr/xpg4/bin/expr mode=0555
file path=usr/xpg4/bin/file mode=0555
file path=usr/xpg4/bin/find mode=0555
file path=usr/xpg4/bin/getconf mode=0555
-file path=usr/xpg4/bin/grep mode=0555
file path=usr/xpg4/bin/id mode=0555
file path=usr/xpg4/bin/link mode=0555
file path=usr/xpg4/bin/ls mode=0555
@@ -67,9 +66,7 @@ file path=usr/xpg4/bin/rm mode=0555
file path=usr/xpg4/bin/sort mode=0555
file path=usr/xpg4/bin/stty mode=0555
file path=usr/xpg4/bin/who mode=0555
-hardlink path=usr/xpg4/bin/egrep target=../../../usr/xpg4/bin/grep
hardlink path=usr/xpg4/bin/ex target=../../../usr/xpg4/bin/edit
-hardlink path=usr/xpg4/bin/fgrep target=../../../usr/xpg4/bin/grep
hardlink path=usr/xpg4/bin/ln target=../../../usr/xpg4/bin/cp
hardlink path=usr/xpg4/bin/mv target=../../../usr/xpg4/bin/cp
hardlink path=usr/xpg4/bin/vedit target=../../../usr/xpg4/bin/edit
@@ -88,9 +85,12 @@ link path=usr/xpg4/bin/bg target=../../bin/alias
link path=usr/xpg4/bin/cd target=../../bin/alias
link path=usr/xpg4/bin/command target=../../bin/alias
link path=usr/xpg4/bin/df target=../../sbin/df
+link path=usr/xpg4/bin/egrep target=../../bin/grep
link path=usr/xpg4/bin/fc target=../../bin/alias
link path=usr/xpg4/bin/fg target=../../bin/alias
+link path=usr/xpg4/bin/fgrep target=../../bin/grep
link path=usr/xpg4/bin/getopts target=../../bin/alias
+link path=usr/xpg4/bin/grep target=../../bin/grep
link path=usr/xpg4/bin/hash target=../../bin/alias
link path=usr/xpg4/bin/ipcs target=../../bin/ipcs
link path=usr/xpg4/bin/jobs target=../../bin/alias
diff --git a/usr/src/test/util-tests/tests/grep_xpg4/files/Makefile b/usr/src/test/util-tests/tests/grep_xpg4/files/Makefile
index 9edb976649..cec093b8a1 100644
--- a/usr/src/test/util-tests/tests/grep_xpg4/files/Makefile
+++ b/usr/src/test/util-tests/tests/grep_xpg4/files/Makefile
@@ -90,7 +90,12 @@ PROGS = test0 \
gout59 \
gout60 \
gout61 \
- gout62
+ gout62 \
+ gout63 \
+ gout64 \
+ gout65 \
+ gout66 \
+ testnl
CMDS = $(PROGS:%=$(TESTDIR)/%)
$(CMDS) := FILEMODE = 0444
diff --git a/usr/src/test/util-tests/tests/grep_xpg4/grep_test.ksh b/usr/src/test/util-tests/tests/grep_xpg4/grep_test.ksh
index a544bd789c..0df113d490 100644
--- a/usr/src/test/util-tests/tests/grep_xpg4/grep_test.ksh
+++ b/usr/src/test/util-tests/tests/grep_xpg4/grep_test.ksh
@@ -15,7 +15,7 @@
# Copyright 2017 Nexenta Systems, Inc. All rights reserved.
#
-XGREP=${XGREP:=/usr/xpg4/bin/grep}
+XGREP=${XGREP:=/usr/bin/grep}
FILEDIR=$MY_TESTS/tests/files
fail() {
diff --git a/usr/src/test/zfs-tests/tests/functional/acl/acl_common.kshlib b/usr/src/test/zfs-tests/tests/functional/acl/acl_common.kshlib
index 2d8d02b28e..f6b1e80cbe 100644
--- a/usr/src/test/zfs-tests/tests/functional/acl/acl_common.kshlib
+++ b/usr/src/test/zfs-tests/tests/functional/acl/acl_common.kshlib
@@ -410,7 +410,7 @@ function get_xattr #<obj>
fi
for xattr in `runat $obj ls | \
- /usr/xpg4/bin/egrep -v -e SUNWattr_ro -e SUNWattr_rw` ; do
+ /usr/bin/egrep -v -e SUNWattr_ro -e SUNWattr_rw` ; do
runat $obj sum $xattr
done
}
diff --git a/usr/src/tools/scripts/elfcmp.sh b/usr/src/tools/scripts/elfcmp.sh
index ab27b2064c..c1010419c3 100644
--- a/usr/src/tools/scripts/elfcmp.sh
+++ b/usr/src/tools/scripts/elfcmp.sh
@@ -24,8 +24,6 @@
# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "%Z%%M% %I% %E% SMI"
-#
# elfcmp - compare significant sections in two ELF files
#
# usage: elfcmp [-v] [-S] [-s section ...] <f1> <f2>
@@ -82,7 +80,7 @@ list_alloc_sections() {
}
signing_filter() {
- /usr/xpg4/bin/grep -v -e \\$SHSTRTAB -e \\.SUNW_signature
+ /usr/bin/grep -v -e \\$SHSTRTAB -e \\.SUNW_signature
}
# get section lists for both files into temp files