summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/grep
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/grep')
-rw-r--r--gnu/usr.bin/grep/Makefile51
-rw-r--r--gnu/usr.bin/grep/config.h188
-rw-r--r--gnu/usr.bin/grep/dfa.c132
-rw-r--r--gnu/usr.bin/grep/dfa.h9
-rw-r--r--gnu/usr.bin/grep/doc/Makefile6
-rw-r--r--gnu/usr.bin/grep/getopt.c2
-rw-r--r--gnu/usr.bin/grep/getopt.h2
-rw-r--r--gnu/usr.bin/grep/getpagesize.h2
-rw-r--r--gnu/usr.bin/grep/grep.1273
-rw-r--r--gnu/usr.bin/grep/grep.c505
-rw-r--r--gnu/usr.bin/grep/grep.h8
-rw-r--r--gnu/usr.bin/grep/kwset.c2
-rw-r--r--gnu/usr.bin/grep/kwset.h2
-rw-r--r--gnu/usr.bin/grep/obstack.c2
-rw-r--r--gnu/usr.bin/grep/obstack.h2
-rw-r--r--gnu/usr.bin/grep/search.c70
16 files changed, 720 insertions, 536 deletions
diff --git a/gnu/usr.bin/grep/Makefile b/gnu/usr.bin/grep/Makefile
new file mode 100644
index 0000000..b1875fe
--- /dev/null
+++ b/gnu/usr.bin/grep/Makefile
@@ -0,0 +1,51 @@
+# $FreeBSD$
+
+GREP_LIBZ=YES
+
+PROG= grep
+SRCS= dfa.c getopt.c getopt1.c grep.c kwset.c obstack.c savedir.c search.c \
+ stpcpy.c
+
+CFLAGS+=-I${.CURDIR} -DHAVE_CONFIG_H
+
+LINKS+= ${BINDIR}/grep ${BINDIR}/egrep \
+ ${BINDIR}/grep ${BINDIR}/fgrep
+MLINKS= grep.1 egrep.1 grep.1 fgrep.1
+
+DPADD+= ${LIBGNUREGEX}
+LDADD+= -lgnuregex
+
+.if defined(GREP_LIBZ) && !empty(GREP_LIBZ)
+LDADD+= -lz
+DPADD+= ${LIBZ}
+CFLAGS+=-DHAVE_LIBZ=1
+LINKS+= ${BINDIR}/grep ${BINDIR}/zgrep \
+ ${BINDIR}/grep ${BINDIR}/zegrep \
+ ${BINDIR}/grep ${BINDIR}/zfgrep
+MLINKS+=grep.1 zgrep.1 grep.1 zegrep.1 grep.1 zfgrep.1
+.endif
+
+SUBDIR+=doc
+
+check: all
+ @failed=0; total=0; \
+ for tst in ${TESTS}; do \
+ total=$$(($$total+1)); \
+ if GREP=${.OBJDIR}/${PROG} srcdir=${.CURDIR}/tests \
+ ${.CURDIR}/tests/$$tst; then \
+ echo "PASS: $$tst"; \
+ else \
+ failed=$$(($$failed+1)); \
+ echo "FAIL: $$tst"; \
+ fi; \
+ done; \
+ if [ "$$failed" -eq 0 ]; then \
+ echo "All $$total tests passed"; \
+ else \
+ echo "$$failed of $$total tests failed"; \
+ fi
+
+TESTS= warning.sh khadafy.sh spencer1.sh bre.sh ere.sh status.sh empty.sh \
+ options.sh
+
+.include <bsd.prog.mk>
diff --git a/gnu/usr.bin/grep/config.h b/gnu/usr.bin/grep/config.h
new file mode 100644
index 0000000..415df26
--- /dev/null
+++ b/gnu/usr.bin/grep/config.h
@@ -0,0 +1,188 @@
+/* $FreeBSD$ */
+
+/* config.h. Generated automatically by configure. */
+/* config.hin. Generated automatically from configure.in by autoheader. */
+
+/* Define if using alloca.c. */
+/* #undef C_ALLOCA */
+
+/* Define if the closedir function returns void instead of int. */
+/* #undef CLOSEDIR_VOID */
+
+/* Define to empty if the keyword does not work. */
+/* #undef const */
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define if you have alloca, as a function or macro. */
+#define HAVE_ALLOCA 1
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+/* #undef HAVE_ALLOCA_H */
+
+/* Define if you have a working `mmap' system call. */
+#define HAVE_MMAP 1
+
+/* Define as __inline if that's what the C compiler calls it. */
+/* #undef inline */
+
+/* Define to `long' if <sys/types.h> doesn't define. */
+/* #undef off_t */
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+/* #undef size_t */
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+/* #undef STACK_DIRECTION */
+
+/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */
+/* #undef STAT_MACROS_BROKEN */
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to use grep's error-checking malloc in the kwset routines. */
+#define GREP 1
+
+/* Package name. */
+#define PACKAGE "grep"
+
+/* Version number. */
+#define VERSION "2.3"
+
+/* Hack for Visual C++ suggested by irox. */
+/* #undef alloca */
+
+/* #undef HAVE_STPCPY */
+
+/* #undef ENABLE_NLS */
+
+/* #undef HAVE_CATGETS */
+
+/* #undef HAVE_GETTEXT */
+
+#define HAVE_LC_MESSAGES 1
+
+/*
+ * DOS specific
+ */
+/* #undef HAVE_DOS_FILE_NAMES */
+
+/* Define if you have the __argz_count function. */
+/* #undef HAVE___ARGZ_COUNT */
+
+/* Define if you have the __argz_next function. */
+/* #undef HAVE___ARGZ_NEXT */
+
+/* Define if you have the __argz_stringify function. */
+/* #undef HAVE___ARGZ_STRINGIFY */
+
+/* Define if you have the btowc function. */
+/* #undef HAVE_BTOWC */
+
+/* Define if you have the dcgettext function. */
+/* #undef HAVE_DCGETTEXT */
+
+/* Define if you have the getcwd function. */
+#define HAVE_GETCWD 1
+
+/* Define if you have the getpagesize function. */
+#define HAVE_GETPAGESIZE 1
+
+/* Define if you have the isascii function. */
+#define HAVE_ISASCII 1
+
+/* Define if you have the memchr function. */
+#define HAVE_MEMCHR 1
+
+/* Define if you have the munmap function. */
+#define HAVE_MUNMAP 1
+
+/* Define if you have the putenv function. */
+#define HAVE_PUTENV 1
+
+/* Define if you have the setenv function. */
+#define HAVE_SETENV 1
+
+/* Define if you have the setlocale function. */
+#define HAVE_SETLOCALE 1
+
+/* Define if you have the setmode function. */
+#define HAVE_SETMODE 1
+
+/* Define if you have the stpcpy function. */
+/* #undef HAVE_STPCPY */
+
+/* Define if you have the strcasecmp function. */
+#define HAVE_STRCASECMP 1
+
+/* Define if you have the strchr function. */
+#define HAVE_STRCHR 1
+
+/* Define if you have the strdup function. */
+#define HAVE_STRDUP 1
+
+/* Define if you have the strerror function. */
+#define HAVE_STRERROR 1
+
+/* Define if you have the <argz.h> header file. */
+/* #undef HAVE_ARGZ_H */
+
+/* Define if you have the <dirent.h> header file. */
+#define HAVE_DIRENT_H 1
+
+/* Define if you have the <libintl.h> header file. */
+/* #undef HAVE_LIBINTL_H */
+
+/* Define if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define if you have the <locale.h> header file. */
+#define HAVE_LOCALE_H 1
+
+/* Define if you have the <malloc.h> header file. */
+/* #undef HAVE_MALLOC_H */
+
+/* Define if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define if you have the <ndir.h> header file. */
+/* #undef HAVE_NDIR_H */
+
+/* Define if you have the <nl_types.h> header file. */
+#define HAVE_NL_TYPES_H 1
+
+/* Define if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define if you have the <sys/dir.h> header file. */
+/* #undef HAVE_SYS_DIR_H */
+
+/* Define if you have the <sys/ndir.h> header file. */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define if you have the <wchar.h> header file. */
+/* #undef HAVE_WCHAR_H */
+
+/* Define if you have the <wctype.h> header file. */
+/* #undef HAVE_WCTYPE_H */
+
+/* Define if you have the i library (-li). */
+/* #undef HAVE_LIBI */
diff --git a/gnu/usr.bin/grep/dfa.c b/gnu/usr.bin/grep/dfa.c
index 40a926b..9f20c37 100644
--- a/gnu/usr.bin/grep/dfa.c
+++ b/gnu/usr.bin/grep/dfa.c
@@ -18,6 +18,8 @@
/* Written June, 1988 by Mike Haertel
Modified July, 1988 by Arthur David Olson to assist BMG speedups */
+/* $FreeBSD$ */
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -90,7 +92,11 @@ extern void free();
# endif
#endif
+#ifdef __FreeBSD__
+#include <gnuregex.h>
+#else
#include "regex.h"
+#endif
#include "dfa.h"
/* HPUX, define those as macros in sys/param.h */
@@ -144,6 +150,25 @@ static char **comsubs PARAMS ((char *left, char *right));
static char **addlists PARAMS ((char **old, char **new));
static char **inboth PARAMS ((char **left, char **right));
+#ifdef __FreeBSD__
+static int
+collate_range_cmp(c1, c2)
+ int c1, c2;
+{
+ static char s1[2], s2[2];
+ int r;
+
+ if (c1 == c2)
+ return 0;
+ s1[0] = c1;
+ s2[0] = c2;
+ if ((r = strcoll(s1, s2)) == 0)
+ r = c1 - c2;
+
+ return r;
+}
+#endif
+
static ptr_t
xcalloc(n, s)
size_t n;
@@ -328,20 +353,15 @@ static reg_syntax_t syntax_bits, syntax_bits_set;
/* Flag for case-folding letters into sets. */
static int case_fold;
-/* End-of-line byte in data. */
-static unsigned char eolbyte;
-
/* Entry point to set syntax options. */
void
-dfasyntax(bits, fold, eol)
+dfasyntax(bits, fold)
reg_syntax_t bits;
int fold;
- int eol;
{
syntax_bits_set = 1;
syntax_bits = bits;
case_fold = fold;
- eolbyte = eol;
}
/* Lexical analyzer. All the dross that deals with the obnoxious
@@ -560,32 +580,11 @@ lex()
goto normal_char;
if (backslash != ((syntax_bits & RE_NO_BK_BRACES) == 0))
goto normal_char;
- if (!(syntax_bits & RE_CONTEXT_INDEP_OPS) && laststart)
- goto normal_char;
-
- if (syntax_bits & RE_NO_BK_BRACES)
- {
- /* Scan ahead for a valid interval; if it's not valid,
- treat it as a literal '{'. */
- int lo = -1, hi = -1;
- char const *p = lexptr;
- char const *lim = p + lexleft;
- for (; p != lim && ISDIGIT (*p); p++)
- lo = (lo < 0 ? 0 : lo * 10) + *p - '0';
- if (p != lim && *p == ',')
- while (++p != lim && ISDIGIT (*p))
- hi = (hi < 0 ? 0 : hi * 10) + *p - '0';
- else
- hi = lo;
- if (p == lim || *p != '}'
- || lo < 0 || RE_DUP_MAX < hi || (0 <= hi && hi < lo))
- goto normal_char;
- }
-
- minrep = 0;
+ minrep = maxrep = 0;
/* Cases:
{M} - exact count
{M,} - minimum count, maximum is infinity
+ {,M} - 0 through M
{M,N} - M through N */
FETCH(c, _("unfinished repeat count"));
if (ISDIGIT(c))
@@ -599,27 +598,16 @@ lex()
minrep = 10 * minrep + c - '0';
}
}
- else
+ else if (c != ',')
dfaerror(_("malformed repeat count"));
if (c == ',')
- {
- FETCH (c, _("unfinished repeat count"));
- if (! ISDIGIT (c))
- maxrep = -1;
- else
- {
- maxrep = c - '0';
- for (;;)
- {
- FETCH (c, _("unfinished repeat count"));
- if (! ISDIGIT (c))
- break;
- maxrep = 10 * maxrep + c - '0';
- }
- if (0 <= maxrep && maxrep < minrep)
- dfaerror (_("malformed repeat count"));
- }
- }
+ for (;;)
+ {
+ FETCH(c, _("unfinished repeat count"));
+ if (!ISDIGIT(c))
+ break;
+ maxrep = 10 * maxrep + c - '0';
+ }
else
maxrep = minrep;
if (!(syntax_bits & RE_NO_BK_BRACES))
@@ -671,7 +659,7 @@ lex()
zeroset(ccl);
notset(ccl);
if (!(syntax_bits & RE_DOT_NEWLINE))
- clrbit(eolbyte, ccl);
+ clrbit('\n', ccl);
if (syntax_bits & RE_DOT_NOT_NULL)
clrbit('\0', ccl);
laststart = 0;
@@ -751,6 +739,24 @@ lex()
}
else
c2 = c;
+#ifdef __FreeBSD__
+ if (collate_range_cmp(c, c2) <= 0)
+ {
+ token c3;
+
+ for (c3 = 0; c3 < NOTCHAR; ++c3) {
+ if (collate_range_cmp(c, c3) <= 0 &&
+ collate_range_cmp(c3, c2) <= 0) {
+ setbit(c3, ccl);
+ if (case_fold)
+ if (ISUPPER(c3))
+ setbit(tolower(c3), ccl);
+ else if (ISLOWER(c))
+ setbit(toupper(c3), ccl);
+ }
+ }
+ }
+#else
while (c <= c2)
{
setbit(c, ccl);
@@ -761,6 +767,7 @@ lex()
setbit(toupper(c), ccl);
++c;
}
+#endif
skip:
;
}
@@ -769,7 +776,7 @@ lex()
{
notset(ccl);
if (syntax_bits & RE_HAT_LISTS_NOT_NEWLINE)
- clrbit(eolbyte, ccl);
+ clrbit('\n', ccl);
}
laststart = 0;
return lasttok = CSET + charclass_index(ccl);
@@ -935,7 +942,7 @@ closure()
{
ntokens = nsubtoks(dfa->tindex);
tindex = dfa->tindex - ntokens;
- if (maxrep < 0)
+ if (maxrep == 0)
addtok(PLUS);
if (minrep == 0)
addtok(QMARK);
@@ -1598,7 +1605,7 @@ dfastate(s, d, trans)
for (i = 0; i < NOTCHAR; ++i)
if (IS_WORD_CONSTITUENT(i))
setbit(i, letters);
- setbit(eolbyte, newline);
+ setbit('\n', newline);
}
zeroset(matches);
@@ -1619,7 +1626,7 @@ dfastate(s, d, trans)
{
if (! MATCHES_NEWLINE_CONTEXT(pos.constraint,
d->states[s].newline, 1))
- clrbit(eolbyte, matches);
+ clrbit('\n', matches);
if (! MATCHES_NEWLINE_CONTEXT(pos.constraint,
d->states[s].newline, 0))
for (j = 0; j < CHARCLASS_INTS; ++j)
@@ -1730,7 +1737,7 @@ dfastate(s, d, trans)
state_letter = state;
for (i = 0; i < NOTCHAR; ++i)
trans[i] = (IS_WORD_CONSTITUENT(i)) ? state_letter : state;
- trans[eolbyte] = state_newline;
+ trans['\n'] = state_newline;
}
else
for (i = 0; i < NOTCHAR; ++i)
@@ -1754,7 +1761,7 @@ dfastate(s, d, trans)
/* Find out if the new state will want any context information. */
wants_newline = 0;
- if (tstbit(eolbyte, labels[i]))
+ if (tstbit('\n', labels[i]))
for (j = 0; j < follows.nelem; ++j)
if (PREV_NEWLINE_DEPENDENT(follows.elems[j].constraint))
wants_newline = 1;
@@ -1786,7 +1793,7 @@ dfastate(s, d, trans)
{
int c = j * INTBITS + k;
- if (c == eolbyte)
+ if (c == '\n')
trans[c] = state_newline;
else if (IS_WORD_CONSTITUENT(c))
trans[c] = state_letter;
@@ -1877,8 +1884,8 @@ build_state(s, d)
/* Keep the newline transition in a special place so we can use it as
a sentinel. */
- d->newlines[s] = trans[eolbyte];
- trans[eolbyte] = -1;
+ d->newlines[s] = trans['\n'];
+ trans['\n'] = -1;
if (ACCEPTING(s, *d))
d->fails[s] = trans;
@@ -1926,7 +1933,6 @@ dfaexec(d, begin, end, newline, count, backref)
register unsigned char *p; /* Current input character. */
register int **trans, *t; /* Copy of d->trans so it can be optimized
into a register. */
- register unsigned char eol = eolbyte; /* Likewise for eolbyte. */
static int sbit[NOTCHAR]; /* Table for anding with d->success. */
static int sbit_init;
@@ -1937,7 +1943,7 @@ dfaexec(d, begin, end, newline, count, backref)
sbit_init = 1;
for (i = 0; i < NOTCHAR; ++i)
sbit[i] = (IS_WORD_CONSTITUENT(i)) ? 2 : 1;
- sbit[eol] = 4;
+ sbit['\n'] = 4;
}
if (! d->tralloc)
@@ -1946,7 +1952,7 @@ dfaexec(d, begin, end, newline, count, backref)
s = s1 = 0;
p = (unsigned char *) begin;
trans = d->trans;
- *end = eol;
+ *end = '\n';
for (;;)
{
@@ -1974,7 +1980,7 @@ dfaexec(d, begin, end, newline, count, backref)
}
/* If the previous character was a newline, count it. */
- if (count && (char *) p <= end && p[-1] == eol)
+ if (count && (char *) p <= end && p[-1] == '\n')
++*count;
/* Check if we've run off the end of the buffer. */
@@ -1988,7 +1994,7 @@ dfaexec(d, begin, end, newline, count, backref)
continue;
}
- if (p[-1] == eol && newline)
+ if (p[-1] == '\n' && newline)
{
s = d->newlines[s1];
continue;
diff --git a/gnu/usr.bin/grep/dfa.h b/gnu/usr.bin/grep/dfa.h
index f2fef4b..1e12515 100644
--- a/gnu/usr.bin/grep/dfa.h
+++ b/gnu/usr.bin/grep/dfa.h
@@ -17,6 +17,8 @@
/* Written June, 1988 by Mike Haertel */
+/* $FreeBSD$ */
+
/* FIXME:
2. We should not export so much of the DFA internals.
In addition to clobbering modularity, we eat up valuable
@@ -320,10 +322,9 @@ struct dfa
/* Entry points. */
-/* dfasyntax() takes three arguments; the first sets the syntax bits described
- earlier in this file, the second sets the case-folding flag, and the
- third specifies the line terminator. */
-extern void dfasyntax PARAMS ((reg_syntax_t, int, int));
+/* dfasyntax() takes two arguments; the first sets the syntax bits described
+ earlier in this file, and the second sets the case-folding flag. */
+extern void dfasyntax PARAMS ((reg_syntax_t, int));
/* Compile the given string of the given length into the given struct dfa.
Final argument is a flag specifying whether to build a searching or an
diff --git a/gnu/usr.bin/grep/doc/Makefile b/gnu/usr.bin/grep/doc/Makefile
new file mode 100644
index 0000000..82620f9
--- /dev/null
+++ b/gnu/usr.bin/grep/doc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+INFO= grep
+INFOSECTION= "System Utilities"
+
+.include <bsd.info.mk>
diff --git a/gnu/usr.bin/grep/getopt.c b/gnu/usr.bin/grep/getopt.c
index eac576b..f919ed7 100644
--- a/gnu/usr.bin/grep/getopt.c
+++ b/gnu/usr.bin/grep/getopt.c
@@ -23,6 +23,8 @@
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+
+/* $FreeBSD$ */
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
Ditto for AIX 3.2 and <stdlib.h>. */
diff --git a/gnu/usr.bin/grep/getopt.h b/gnu/usr.bin/grep/getopt.h
index 2d8c8f9..4209871 100644
--- a/gnu/usr.bin/grep/getopt.h
+++ b/gnu/usr.bin/grep/getopt.h
@@ -19,6 +19,8 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+/* $FreeBSD$ */
+
#ifndef _GETOPT_H
#define _GETOPT_H 1
diff --git a/gnu/usr.bin/grep/getpagesize.h b/gnu/usr.bin/grep/getpagesize.h
index a064973..4d562216 100644
--- a/gnu/usr.bin/grep/getpagesize.h
+++ b/gnu/usr.bin/grep/getpagesize.h
@@ -1,5 +1,7 @@
/* Emulate getpagesize on systems that lack it. */
+/* $FreeBSD$ */
+
#ifndef HAVE_GETPAGESIZE
# ifdef VMS
diff --git a/gnu/usr.bin/grep/grep.1 b/gnu/usr.bin/grep/grep.1
index 0cee267..75361a9 100644
--- a/gnu/usr.bin/grep/grep.1
+++ b/gnu/usr.bin/grep/grep.1
@@ -1,69 +1,29 @@
.\" grep man page
-.if !\n(.g \{\
-. if !\w|\*(lq| \{\
-. ds lq ``
-. if \w'\(lq' .ds lq "\(lq
-. \}
-. if !\w|\*(rq| \{\
-. ds rq ''
-. if \w'\(rq' .ds rq "\(rq
-. \}
-.\}
+.\" $FreeBSD$
.de Id
.ds Dt \\$4
..
-.Id $Id: grep.1,v 1.7 1999/10/12 20:41:01 alainm Exp $
+.Id $Id: grep.1,v 1.1 1998/11/22 06:45:20 alainm Exp $
.TH GREP 1 \*(Dt "GNU Project"
.SH NAME
-grep, egrep, fgrep \- print lines matching a pattern
+grep, egrep, fgrep, zgrep \- print lines matching a pattern
.SH SYNOPSIS
.B grep
-.RB [ \- [ ABC ]
-.IR NUM ]
-.RB [ \-EFGHLUVZabchilnqrsuvwxyz ]
-.RB [ \-e
-.I PATTERN
-|
-.B \-f
-.IR FILE ]
-.RB [ \-d
-.IR ACTION ]
-.RB [ \-\^\-directories=\fIACTION\fP ]
-.RB [ \-\^\-extended-regexp ]
-.RB [ \-\^\-fixed-strings ]
-.RB [ \-\^\-basic-regexp ]
-.RB [ \-\^\-regexp=\fIPATTERN\fP ]
-.RB [ \-\^\-file=\fIFILE\fP ]
-.RB [ \-\^\-ignore-case ]
-.RB [ \-\^\-word-regexp ]
-.RB [ \-\^\-line-regexp ]
-.RB [ \-\^\-line-regexp ]
-.RB [ \-\^\-no-messages ]
-.RB [ \-\^\-invert-match ]
-.RB [ \-\^\-version ]
-.RB [ \-\^\-help ]
-.RB [ \-\^\-byte-offset ]
-.RB [ \-\^\-line-number ]
-.RB [ \-\^\-with-filename ]
-.RB [ \-\^\-no-filename ]
-.RB [ \-\^\-quiet ]
-.RB [ \-\^\-silent ]
-.RB [ \-\^\-text ]
-.RB [ \-\^\-files-without-match ]
-.RB [ \-\^\-files-with-matches ]
-.RB [ \-\^\-count ]
-.RB [ \-\^\-before-context=\fINUM\fP ]
-.RB [ \-\^\-after-context=\fINUM\fP ]
-.RB [ \-\^\-context [ =\fINUM\fP ]]
-.RB [ \-\^\-binary ]
-.RB [ \-\^\-unix-byte-offsets ]
-.RB [ \-\^\-mmap ]
-.RB [ \-\^\-null ]
-.RB [ \-\^\-recursive ]
-.RI [ file .\|.\|.]
+[-[AB] NUM] [-CEFGVZabchiLlnqrsvwxyUu] [-e PATTERN | -f FILE]
+[-d ACTION] [--directories=ACTION]
+[--extended-regexp] [--fixed-strings] [--basic-regexp]
+[--regexp=PATTERN] [--file=FILE] [--ignore-case] [--word-regexp]
+[--line-regexp] [--line-regexp] [--no-messages] [--revert-match]
+[--version] [--help] [--byte-offset] [--line-number]
+[--with-filename] [--no-filename] [--quiet] [--silent] [--text]
+[--files-without-match] [--files-with-matcces] [--count]
+[--before-context=NUM] [--after-context=NUM] [--context]
+[--binary] [--unix-byte-offsets] [--recursive]
+[--decompress]
+.I files...
.SH DESCRIPTION
.PP
-.B Grep
+.B grep
searches the named input
.I files
(or standard input if no files are named, or
@@ -81,80 +41,83 @@ There are three major variants of
controlled by the following options.
.PD 0
.TP
-.BR \-G ", " \-\^\-basic-regexp
+.B \-G, --basic-regexp
Interpret
.I pattern
as a basic regular expression (see below). This is the default.
.TP
-.BR \-E ", " \-\^\-extended-regexp
+.B \-E, --extended-regexp
Interpret
.I pattern
as an extended regular expression (see below).
.TP
-.BR \-F ", " \-\^\-fixed-strings
+.B \-F, --fixed-strings
Interpret
.I pattern
as a list of fixed strings, separated by newlines,
any of which is to be matched.
-.PP
+.LP
In addition, two variant programs
.B egrep
and
.B fgrep
are available.
-.B Egrep
-is the same as
-.BR "grep\ \-E" .
-.B Fgrep
+.B egrep
+is similar (but not identical) to
+.BR "grep\ \-E" ,
+and is compatible with the historical Unix
+.BR egrep .
+.B fgrep
is the same as
.BR "grep\ \-F" .
+.B zgrep
+is the same as
+.BR "grep\ \-Z" .
.PD
-.PP
+.LP
All variants of
.B grep
understand the following options:
.PD 0
.TP
-.BI \-A " NUM" "\fR,\fP \-\^\-after-context=" NUM
+.BI \-A " NUM" ", --after-context=" NUM
Print
.I NUM
lines of trailing context after matching lines.
.TP
-.BI \-B " NUM" "\fR,\fP \-\^\-before-context=" NUM
+.BI \-B " NUM" ", --before-context=" NUM
Print
.I NUM
lines of leading context before matching lines.
.TP
-.BI \-C " \fR[\fPNUM\fR]\fP" "\fR,\fP \-\^\-context\fR[\fP=" NUM\fR]\fP
-Print
+.BI \-C ,\ --context"[=NUM]"
+Print
.I NUM
lines (default 2) of output context.
.TP
-.BI \- NUM
-Same as
-.BI \-\^\-context= NUM
-lines of leading and trailing context. However,
+.BI \- NUM \
+Same as --context=NUM lines of leading and trailing context. However,
.B grep
will never print any given line more than once.
.TP
-.BR \-V ", " \-\^\-version
+.B \-V, --version
Print the version number of
.B grep
to standard error. This version number should
be included in all bug reports (see below).
.TP
-.BR \-b ", " \-\^\-byte-offset
+.B \-b, --byte-offset
Print the byte offset within the input file before
each line of output.
.TP
-.BR \-c ", " \-\^\-count
+.B \-c, --count
Suppress normal output; instead print a count of
matching lines for each input file.
With the
-.BR \-v ", " \-\^\-invert-match
+.B \-v, --revert-match
option (see below), count non-matching lines.
.TP
-.BI \-d " ACTION" "\fR,\fP \-\^\-directories=" ACTION
+.BI \-d " ACTION" ", --directories=" ACTION
If an input file is a directory, use
.I ACTION
to process it. By default,
@@ -177,78 +140,75 @@ this is equivalent to the
.B \-r
option.
.TP
-.BI \-e " PATTERN" "\fR,\fP \-\^\-regexp=" PATTERN
+.BI \-e " PATTERN" ", --regexp=" PATTERN
Use
.I PATTERN
as the pattern; useful to protect patterns beginning with
.BR \- .
.TP
-.BI \-f " FILE" "\fR,\fP \-\^\-file=" FILE
+.BI \-f " FILE" ", --file=" FILE
Obtain patterns from
.IR FILE ,
one per line.
The empty file contains zero patterns, and therfore matches nothing.
.TP
-.BR \-H ", " \-\^\-with-filename
-Print the filename for each match.
-.TP
-.BR \-h ", " \-\^\-no-filename
+.B \-h, --no-filename
Suppress the prefixing of filenames on output
when multiple files are searched.
.TP
-.BR \-i ", " \-\^\-ignore-case
+.B \-i, --ignore-case
Ignore case distinctions in both the
.I pattern
and the input files.
.TP
-.BR \-L ", " \-\^\-files-without-match
+.B \-L, --files-without-match
Suppress normal output; instead print the name
of each input file from which no output would
-normally have been printed. The scanning will stop
+normally have been printed. The scanning will stop
on the first match.
.TP
-.BR \-l ", " \-\^\-files-with-matches
+.B \-l, --files-with-matches
Suppress normal output; instead print
the name of each input file from which output
-would normally have been printed. The scanning will
+would normally have been printed. The scanning will
stop on the first match.
.TP
-.BR \-n ", " \-\^\-line-number
+.B \-n, --line-number
Prefix each line of output with the line number
within its input file.
.TP
-.BR \-q ", " \-\^\-quiet ", " \-\^\-silent
-Quiet; suppress normal output. The scanning will stop
+.B \-q, --quiet, --silent
+Quiet; suppress normal output. The scanning will stop
on the first match.
Also see the
.B \-s
or
-.B \-\^\-no-messages
+.B --no-messages
option below.
.TP
-.BR \-r ", " \-\^\-recursive
+.B \-r, --recursive
Read all files under each directory, recursively;
this is equivalent to the
.B "\-d recurse"
option.
.TP
-.BR \-s ", " \-\^\-no-messages
+.B \-s, --no-messages
Suppress error messages about nonexistent or unreadable files.
-Portability note: unlike \s-1GNU\s0
+Portability note: unlike GNU
.BR grep ,
-traditional
+BSD
.B grep
-did not conform to \s-1POSIX.2\s0, because traditional
+does not comply with POSIX.2, because BSD
.B grep
-lacked a
+lacks a
.B \-q
option and its
.B \-s
-option behaved like \s-1GNU\s0
+option behaves like GNU
.BR grep 's
.B \-q
option.
-Shell scripts intended to be portable to traditional
+Shell scripts intended to be portable to BSD
.B grep
should avoid both
.B \-q
@@ -256,7 +216,7 @@ and
.B \-s
and should redirect output to /dev/null instead.
.TP
-.BR \-a ", " \-\^\-text
+.B \-a, --text
Do not suppress output lines that contain binary data.
Normally, if the first few bytes of a file indicate that
the file contains binary data,
@@ -267,10 +227,10 @@ This option causes
to act as if the file is a text file,
even if it would otherwise be treated as binary.
.TP
-.BR \-v ", " \-\^\-invert-match
+.B \-v, --revert-match
Invert the sense of matching, to select non-matching lines.
.TP
-.BR \-w ", " \-\^\-word-regexp
+.B \-w, --word-regexp
Select only those lines containing matches that form whole words.
The test is that the matching substring must either be at the
beginning of the line, or preceded by a non-word constituent
@@ -278,14 +238,14 @@ character. Similarly, it must be either at the end of the line
or followed by a non-word constituent character. Word-constituent
characters are letters, digits, and the underscore.
.TP
-.BR \-x ", " \-\^\-line-regexp
+.B \-x, --line-regexp
Select only those matches that exactly match the whole line.
.TP
.B \-y
Obsolete synonym for
.BR \-i .
.TP
-.BR \-U ", " \-\^\-binary
+.B \-U, --binary
Treat the file(s) as binary. By default, under MS-DOS and MS-Windows,
.BR grep
guesses the file type by looking at the contents of the first 32KB
@@ -301,11 +261,10 @@ work correctly). Specifying
overrules this guesswork, causing all files to be read and passed to the
matching mechanism verbatim; if the file is a text file with CR/LF
pairs at the end of each line, this will cause some regular
-expressions to fail.
-This option has no effect on platforms other than MS-DOS and
+expressions to fail. This option is only supported on MS-DOS and
MS-Windows.
.TP
-.BR \-u ", " \-\^\-unix-byte-offsets
+.B \-u, --unix-byte-offsets
Report Unix-style byte offsets. This switch causes
.B grep
to report byte offsets as if the file were Unix-style text file, i.e. with
@@ -313,41 +272,14 @@ CR characters stripped off. This will produce results identical to running
.B grep
on a Unix machine. This option has no effect unless
.B \-b
-option is also used;
-it has no effect on platforms other than MS-DOS and MS-Windows.
-.TP
-.B \-\^\-mmap
-If possible, use the
-.BR mmap (2)
-system call to read input, instead of
-the default
-.BR read (2)
-system call. In some situations,
-.B -\^-mmap
-yields better performance. However,
-.B -\^-mmap
-can cause undefined behavior (including core dumps)
-if an input file shrinks while
-.B grep
-is operating, or if an I/O error occurs.
+option is also used; it is only supported on MS-DOS and MS-Windows.
+.PD
+.LP
+Following option is only available if compiled with zlib(3) library:
+.PD 0
.TP
-.BR \-Z ", " \-\^\-null
-Output a zero byte (the \s-1ASCII\s0
-.B NUL
-character) instead of the character that normally follows a file name.
-For example,
-.B "grep \-lZ"
-outputs a zero byte after each file name instead of the usual newline.
-This option makes the output unambiguous, even in the presence of file
-names containing unusual characters like newlines. This option can be
-used with commands like
-.BR "find \-print0" ,
-.BR "perl \-0" ,
-.BR "sort \-z" ,
-and
-.B "xargs \-0"
-to process arbitrary file names,
-even those that contain newline characters.
+.B \-Z, --decompress
+Decompress the input data before searching.
.PD
.SH "REGULAR EXPRESSIONS"
.PP
@@ -355,10 +287,10 @@ A regular expression is a pattern that describes a set of strings.
Regular expressions are constructed analogously to arithmetic
expressions, by using various operators to combine smaller expressions.
.PP
-.B Grep
+.B grep
understands two different versions of regular expression syntax:
-\*(lqbasic\*(rq and \*(lqextended.\*(rq In
-.RB "\s-1GNU\s0\ " grep ,
+``basic'' and ``extended.'' In
+.RB "GNU\ " grep ,
there is no difference in available functionality using either syntax.
In other implementations, basic regular expressions are less powerful.
The following description applies to extended regular expressions;
@@ -470,6 +402,11 @@ The preceding item is matched
.I n
or more times.
.TP
+.BI {, m }
+The preceding item is optional and is matched at most
+.I m
+times.
+.TP
.BI { n , m }
The preceding item is matched at least
.I n
@@ -519,35 +456,20 @@ versions
and
.BR \e) .
.PP
-Traditional
-.B egrep
-did not support the
-.B {
-metacharacter, and some
-.B egrep
-implementations support
-.B \e{
-instead, so portable scripts should avoid
-.B {
-in
-.B egrep
-patterns and should use
-.B [{]
-to match a literal
-.BR { .
-.PP
-\s-1GNU\s0
+In
.B egrep
-attempts to support traditional usage by assuming that
+the metacharacter
.B {
-is not special if it would be the start of an invalid interval
-specification. For example, the shell command
-.B "egrep '{1'"
-searches for the two-character string
-.B {1
-instead of reporting a syntax error in the regular expression.
-\s-1POSIX.2\s0 allows this behavior as an extension, but portable scripts
-should avoid it.
+loses its special meaning; instead use
+.BR \e{ .
+.SH ENVIRONMENT
+The environment variable
+.B GREP_OPTIONS
+can hold a set of default
+options for
+.I grep.
+These options are interpreted first and can be overwritten by explicit command
+line parameters.
.SH DIAGNOSTICS
.PP
Normally, exit status is 0 if matches were found,
@@ -561,8 +483,7 @@ other system errors.
.PP
Email bug reports to
.BR bug-gnu-utils@gnu.org .
-Be sure to include the word \*(lqgrep\*(rq somewhere in the
-\*(lqSubject:\*(rq field.
+Be sure to include the word ``grep'' somewhere in the ``Subject:'' field.
.PP
Large repetition counts in the
.BI { m , n }
@@ -574,5 +495,3 @@ and space, and may cause
to run out of memory.
.PP
Backreferences are very slow, and may require exponential time.
-.\" Work around problems with some troff -man implementations.
-.br
diff --git a/gnu/usr.bin/grep/grep.c b/gnu/usr.bin/grep/grep.c
index 445eeca..569f43a 100644
--- a/gnu/usr.bin/grep/grep.c
+++ b/gnu/usr.bin/grep/grep.c
@@ -17,6 +17,9 @@
02111-1307, USA. */
/* Written July 1992 by Mike Haertel. */
+/* Builtin decompression 1997 by Wolfram Schneider <wosch@FreeBSD.org>. */
+
+/* $FreeBSD$ */
#ifdef HAVE_CONFIG_H
# include <config.h>
@@ -55,13 +58,6 @@ static int show_help;
/* If non-zero, print the version on standard output and exit. */
static int show_version;
-/* If nonzero, use mmap if possible. */
-static int mmap_option;
-
-/* Short options. */
-static char const short_options[] =
-"0123456789A:B:C::EFGHUVX:abcd:e:f:hiLlnqrsuvwxyZz";
-
/* Long options equivalences. */
static struct option long_options[] =
{
@@ -82,30 +78,32 @@ static struct option long_options[] =
{"ignore-case", no_argument, NULL, 'i'},
{"line-number", no_argument, NULL, 'n'},
{"line-regexp", no_argument, NULL, 'x'},
- {"mmap", no_argument, &mmap_option, 1},
{"no-filename", no_argument, NULL, 'h'},
{"no-messages", no_argument, NULL, 's'},
- {"null", no_argument, NULL, 'Z'},
- {"null-data", no_argument, NULL, 'z'},
{"quiet", no_argument, NULL, 'q'},
{"recursive", no_argument, NULL, 'r'},
{"regexp", required_argument, NULL, 'e'},
- {"invert-match", no_argument, NULL, 'v'},
+ {"revert-match", no_argument, NULL, 'v'},
{"silent", no_argument, NULL, 'q'},
{"text", no_argument, NULL, 'a'},
+#if O_BINARY
{"binary", no_argument, NULL, 'U'},
{"unix-byte-offsets", no_argument, NULL, 'u'},
+#endif
{"version", no_argument, NULL, 'V'},
{"with-filename", no_argument, NULL, 'H'},
{"word-regexp", no_argument, NULL, 'w'},
+#if HAVE_LIBZ > 0
+ {"decompress", no_argument, NULL, 'Z'},
+#endif
{0, 0, 0, 0}
};
/* Define flags declared in grep.h. */
+char const *matcher;
int match_icase;
int match_words;
int match_lines;
-unsigned char eolbyte;
/* For error messages. */
static char *prog;
@@ -123,10 +121,7 @@ static enum
static int ck_atoi PARAMS ((char const *, int *));
static void usage PARAMS ((int)) __attribute__((noreturn));
static void error PARAMS ((const char *, int));
-static void setmatcher PARAMS ((char const *));
-static int install_matcher PARAMS ((char const *));
-static int prepend_args PARAMS ((char const *, char *, char **));
-static void prepend_default_options PARAMS ((char const *, int *, char ***));
+static int setmatcher PARAMS ((char const *));
static char *page_alloc PARAMS ((size_t, char **));
static int reset PARAMS ((int, char const *, struct stats *));
static int fillbuf PARAMS ((size_t, struct stats *));
@@ -226,18 +221,23 @@ static char *ubuffer; /* Unaligned base of buffer. */
static char *buffer; /* Base of buffer. */
static size_t bufsalloc; /* Allocated size of buffer save region. */
static size_t bufalloc; /* Total buffer size. */
-#define PREFERRED_SAVE_FACTOR 5 /* Preferred value of bufalloc / bufsalloc. */
static int bufdesc; /* File descriptor. */
static char *bufbeg; /* Beginning of user-visible stuff. */
static char *buflim; /* Limit of user-visible stuff. */
static size_t pagesize; /* alignment of memory pages */
-static off_t bufoffset; /* Read offset; defined on regular files. */
#if defined(HAVE_MMAP)
-static int bufmapped; /* True if buffer is memory-mapped. */
+static int bufmapped; /* True for ordinary files. */
+static off_t bufoffset; /* What read() normally remembers. */
static off_t initial_bufoffset; /* Initial value of bufoffset. */
#endif
+#if HAVE_LIBZ > 0
+#include <zlib.h>
+static gzFile gzbufdesc; /* zlib file descriptor. */
+static int Zflag; /* uncompress before searching. */
+#endif
+
/* Return VAL aligned to the next multiple of ALIGNMENT. VAL can be
an integer or a pointer. Both args must be free of side effects. */
#define ALIGN_TO(val, alignment) \
@@ -245,26 +245,32 @@ static off_t initial_bufoffset; /* Initial value of bufoffset. */
? (val) \
: (val) + ((alignment) - (size_t) (val) % (alignment)))
-/* Return the address of a page-aligned buffer of size SIZE,
- reallocating it from *UP. Set *UP to the newly allocated (but
- possibly unaligned) buffer used to build the aligned buffer. To
- free the buffer, free (*UP). */
+/* Return the address of a new page-aligned buffer of size SIZE. Set
+ *UP to the newly allocated (but possibly unaligned) buffer used to
+ *build the aligned buffer. To free the buffer, free (*UP). */
static char *
page_alloc (size, up)
size_t size;
char **up;
{
+ /* HAVE_WORKING_VALLOC means that valloc is properly declared, and
+ you can free the result of valloc. This symbol is not (yet)
+ autoconfigured. It can be useful to define HAVE_WORKING_VALLOC
+ while debugging, since some debugging memory allocators might
+ catch more bugs if this symbol is enabled. */
+#if HAVE_WORKING_VALLOC
+ *up = valloc (size);
+ return *up;
+#else
size_t asize = size + pagesize - 1;
if (size <= asize)
{
- char *p = *up ? realloc (*up, asize) : malloc (asize);
- if (p)
- {
- *up = p;
- return ALIGN_TO (p, pagesize);
- }
+ *up = malloc (asize);
+ if (*up)
+ return ALIGN_TO (*up, pagesize);
}
return NULL;
+#endif
}
/* Reset the buffer for a new file, returning zero if we should skip it.
@@ -275,9 +281,7 @@ reset (fd, file, stats)
char const *file;
struct stats *stats;
{
- if (pagesize)
- bufsalloc = ALIGN_TO (bufalloc / PREFERRED_SAVE_FACTOR, pagesize);
- else
+ if (pagesize == 0)
{
size_t ubufsalloc;
pagesize = getpagesize ();
@@ -289,195 +293,162 @@ reset (fd, file, stats)
ubufsalloc = BUFSALLOC;
#endif
bufsalloc = ALIGN_TO (ubufsalloc, pagesize);
- bufalloc = PREFERRED_SAVE_FACTOR * bufsalloc;
+ bufalloc = 5 * bufsalloc;
/* The 1 byte of overflow is a kludge for dfaexec(), which
inserts a sentinel newline at the end of the buffer
being searched. There's gotta be a better way... */
if (bufsalloc < ubufsalloc
- || bufalloc / PREFERRED_SAVE_FACTOR != bufsalloc
- || bufalloc + 1 < bufalloc
+ || bufalloc / 5 != bufsalloc || bufalloc + 1 < bufalloc
|| ! (buffer = page_alloc (bufalloc + 1, &ubuffer)))
fatal (_("memory exhausted"), 0);
+ bufbeg = buffer;
+ buflim = buffer;
}
-
- buflim = buffer;
+#if HAVE_LIBZ > 0
+ if (Zflag) {
+ gzbufdesc = gzdopen(fd, "r");
+ if (gzbufdesc == NULL)
+ fatal(_("memory exhausted"), 0);
+ }
+#endif
bufdesc = fd;
- if (fstat (fd, &stats->stat) != 0)
- {
- error ("fstat", errno);
- return 0;
- }
+ if (
+#if defined(HAVE_MMAP)
+ 1
+#else
+ directories != READ_DIRECTORIES
+#endif
+ )
+ if (fstat (fd, &stats->stat) != 0)
+ {
+ error ("fstat", errno);
+ return 0;
+ }
if (directories == SKIP_DIRECTORIES && S_ISDIR (stats->stat.st_mode))
return 0;
- if (S_ISREG (stats->stat.st_mode))
- {
- if (file)
- bufoffset = 0;
- else
- {
- bufoffset = lseek (fd, 0, SEEK_CUR);
- if (bufoffset < 0)
- {
- error ("lseek", errno);
- return 0;
- }
- }
-#ifdef HAVE_MMAP
- initial_bufoffset = bufoffset;
- bufmapped = mmap_option && bufoffset % pagesize == 0;
+#if defined(HAVE_MMAP)
+ if (
+#if HAVE_LIBZ > 0
+ Zflag ||
#endif
- }
+ !S_ISREG (stats->stat.st_mode))
+ bufmapped = 0;
else
{
-#ifdef HAVE_MMAP
- bufmapped = 0;
-#endif
+ bufmapped = 1;
+ bufoffset = initial_bufoffset = file ? 0 : lseek (fd, 0, 1);
}
+#endif
return 1;
}
/* Read new stuff into the buffer, saving the specified
amount of old stuff. When we're done, 'bufbeg' points
to the beginning of the buffer contents, and 'buflim'
- points just after the end. Return zero if there's an error. */
+ points just after the end. Return count of new stuff. */
static int
fillbuf (save, stats)
size_t save;
struct stats *stats;
{
- size_t fillsize = 0;
- int cc = 1;
- size_t readsize;
-
- /* Offset from start of unaligned buffer to start of old stuff
- that we want to save. */
- size_t saved_offset = buflim - ubuffer - save;
+ int cc;
+#if defined(HAVE_MMAP)
+ caddr_t maddr;
+#endif
- if (bufsalloc < save)
+ if (save > bufsalloc)
{
- size_t aligned_save = ALIGN_TO (save, pagesize);
- size_t maxalloc = (size_t) -1;
- size_t newalloc;
-
- if (S_ISREG (stats->stat.st_mode))
- {
- /* Calculate an upper bound on how much memory we should allocate.
- We can't use ALIGN_TO here, since off_t might be longer than
- size_t. Watch out for arithmetic overflow. */
- off_t to_be_read = stats->stat.st_size - bufoffset;
- size_t slop = to_be_read % pagesize;
- off_t aligned_to_be_read = to_be_read + (slop ? pagesize - slop : 0);
- off_t maxalloc_off = aligned_save + aligned_to_be_read;
- if (0 <= maxalloc_off && maxalloc_off == (size_t) maxalloc_off)
- maxalloc = maxalloc_off;
- }
-
- /* Grow bufsalloc until it is at least as great as `save'; but
- if there is an overflow, just grow it to the next page boundary. */
- while (bufsalloc < save)
- if (bufsalloc < bufsalloc * 2)
- bufsalloc *= 2;
- else
- {
- bufsalloc = aligned_save;
- break;
- }
-
- /* Grow the buffer size to be PREFERRED_SAVE_FACTOR times
- bufsalloc.... */
- newalloc = PREFERRED_SAVE_FACTOR * bufsalloc;
- if (maxalloc < newalloc)
- {
- /* ... except don't grow it more than a pagesize past the
- file size, as that might cause unnecessary memory
- exhaustion if the file is large. */
- newalloc = maxalloc;
- bufsalloc = aligned_save;
- }
-
- /* Check that the above calculations made progress, which might
- not occur if there is arithmetic overflow. If there's no
- progress, or if the new buffer size is larger than the old
- and buffer reallocation fails, report memory exhaustion. */
- if (bufsalloc < save || newalloc < save
- || (newalloc == save && newalloc != maxalloc)
- || (bufalloc < newalloc
- && ! (buffer
- = page_alloc ((bufalloc = newalloc) + 1, &ubuffer))))
+ char *nubuffer;
+ char *nbuffer;
+
+ while (save > bufsalloc)
+ bufsalloc *= 2;
+ bufalloc = 5 * bufsalloc;
+ if (bufalloc / 5 != bufsalloc || bufalloc + 1 < bufalloc
+ || ! (nbuffer = page_alloc (bufalloc + 1, &nubuffer)))
fatal (_("memory exhausted"), 0);
- }
- bufbeg = buffer + bufsalloc - save;
- memmove (bufbeg, ubuffer + saved_offset, save);
- readsize = bufalloc - bufsalloc;
+ bufbeg = nbuffer + bufsalloc - save;
+ memcpy (bufbeg, buflim - save, save);
+ free (ubuffer);
+ ubuffer = nubuffer;
+ buffer = nbuffer;
+ }
+ else
+ {
+ bufbeg = buffer + bufsalloc - save;
+ memcpy (bufbeg, buflim - save, save);
+ }
#if defined(HAVE_MMAP)
- if (bufmapped)
+ if (bufmapped && bufoffset % pagesize == 0
+ && stats->stat.st_size - bufoffset >= bufalloc - bufsalloc)
{
- size_t mmapsize = readsize;
-
- /* Don't mmap past the end of the file; some hosts don't allow this.
- Use `read' on the last page. */
- if (stats->stat.st_size - bufoffset < mmapsize)
- {
- mmapsize = stats->stat.st_size - bufoffset;
- mmapsize -= mmapsize % pagesize;
- }
-
- if (mmapsize
- && (mmap ((caddr_t) (buffer + bufsalloc), mmapsize,
- PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED,
- bufdesc, bufoffset)
- != (caddr_t) -1))
+ maddr = buffer + bufsalloc;
+ maddr = mmap (maddr, bufalloc - bufsalloc, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_FIXED, bufdesc, bufoffset);
+ if (maddr == (caddr_t) -1)
{
- /* Do not bother to use madvise with MADV_SEQUENTIAL or
- MADV_WILLNEED on the mmapped memory. One might think it
- would help, but it slows us down about 30% on SunOS 4.1. */
- fillsize = mmapsize;
+ /* This used to issue a warning, but on some hosts
+ (e.g. Solaris 2.5) mmap can fail merely because some
+ other process has an advisory read lock on the file.
+ There's no point alarming the user about this misfeature. */
+#if 0
+ fprintf (stderr, _("%s: warning: %s: %s\n"), prog, filename,
+ strerror (errno));
+#endif
+ goto tryread;
}
- else
+#if 0
+ /* You might thing this (or MADV_WILLNEED) would help,
+ but it doesn't, at least not on a Sun running 4.1.
+ In fact, it actually slows us down about 30%! */
+ madvise (maddr, bufalloc - bufsalloc, MADV_SEQUENTIAL);
+#endif
+ cc = bufalloc - bufsalloc;
+ bufoffset += cc;
+ }
+ else
+ {
+ tryread:
+ /* We come here when we're not going to use mmap() any more.
+ Note that we need to synchronize the file offset the
+ first time through. */
+ if (bufmapped)
{
- /* Stop using mmap on this file. Synchronize the file
- offset. Do not warn about mmap failures. On some hosts
- (e.g. Solaris 2.5) mmap can fail merely because some
- other process has an advisory read lock on the file.
- There's no point alarming the user about this misfeature. */
bufmapped = 0;
- if (bufoffset != initial_bufoffset
- && lseek (bufdesc, bufoffset, SEEK_SET) < 0)
- {
- error ("lseek", errno);
- cc = 0;
- }
+ if (bufoffset != initial_bufoffset)
+ lseek (bufdesc, bufoffset, 0);
}
- }
-#endif /*HAVE_MMAP*/
-
- if (! fillsize)
- {
- ssize_t bytesread;
- while ((bytesread = read (bufdesc, buffer + bufsalloc, readsize)) < 0
- && errno == EINTR)
- continue;
- if (bytesread < 0)
- cc = 0;
+#if HAVE_LIBZ > 0
+ if (Zflag)
+ cc = gzread (gzbufdesc, buffer + bufsalloc, bufalloc - bufsalloc);
else
- fillsize = bytesread;
+#endif
+ cc = read (bufdesc, buffer + bufsalloc, bufalloc - bufsalloc);
}
-
- bufoffset += fillsize;
+#else
+#if HAVE_LIBZ > 0
+ if (Zflag)
+ cc = gzread (gzbufdesc, buffer + bufsalloc, bufalloc - bufsalloc);
+ else
+#endif
+ cc = read (bufdesc, buffer + bufsalloc, bufalloc - bufsalloc);
+#endif /*HAVE_MMAP*/
#if O_BINARY
- if (fillsize)
- fillsize = undossify_input (buffer + bufsalloc, fillsize);
+ if (cc > 0)
+ cc = undossify_input (buffer + bufsalloc, cc);
#endif
- buflim = buffer + bufsalloc + fillsize;
+ if (cc > 0)
+ buflim = buffer + bufsalloc + cc;
+ else
+ buflim = buffer + bufsalloc;
return cc;
}
/* Flags controlling the style of output. */
static int always_text; /* Assume the input is always text. */
-static int filename_mask; /* If zero, output nulls after filenames. */
static int out_quiet; /* Suppress all normal output. */
static int out_invert; /* Print nonmatching stuff. */
static int out_file; /* Print filenames. */
@@ -509,9 +480,11 @@ nlscan (lim)
char *lim;
{
char *beg;
- for (beg = lastnl; (beg = memchr (beg, eolbyte, lim - beg)); beg++)
- totalnl++;
- lastnl = lim;
+
+ for (beg = lastnl; beg < lim; ++beg)
+ if (*beg == '\n')
+ ++totalnl;
+ lastnl = beg;
}
static void
@@ -540,7 +513,7 @@ prline (beg, lim, sep)
int sep;
{
if (out_file)
- printf ("%s%c", filename, sep & filename_mask);
+ printf ("%s%c", filename, sep);
if (out_line)
{
nlscan (beg);
@@ -573,7 +546,7 @@ prpending (lim)
while (pending > 0 && lastout < lim)
{
--pending;
- if ((nl = memchr (lastout, eolbyte, lim - lastout)) != 0)
+ if ((nl = memchr (lastout, '\n', lim - lastout)) != 0)
++nl;
else
nl = lim;
@@ -591,7 +564,6 @@ prtext (beg, lim, nlinesp)
{
static int used; /* avoid printing "--" before any output */
char *bp, *p, *nl;
- char eol = eolbyte;
int i, n;
if (!out_quiet && pending > 0)
@@ -608,7 +580,7 @@ prtext (beg, lim, nlinesp)
if (p > bp)
do
--p;
- while (p > bp && p[-1] != eol);
+ while (p > bp && p[-1] != '\n');
/* We only print the "--" separator if our output is
discontiguous from the last output in the file. */
@@ -617,7 +589,7 @@ prtext (beg, lim, nlinesp)
while (p < beg)
{
- nl = memchr (p, eol, beg - p);
+ nl = memchr (p, '\n', beg - p);
prline (p, nl + 1, '-');
p = nl + 1;
}
@@ -628,7 +600,7 @@ prtext (beg, lim, nlinesp)
/* Caller wants a line count. */
for (n = 0; p < lim; ++n)
{
- if ((nl = memchr (p, eol, lim - p)) != 0)
+ if ((nl = memchr (p, '\n', lim - p)) != 0)
++nl;
else
nl = lim;
@@ -642,7 +614,7 @@ prtext (beg, lim, nlinesp)
if (!out_quiet)
prline (beg, lim, ':');
- pending = out_quiet ? 0 : out_after;
+ pending = out_after;
used = 1;
}
@@ -657,14 +629,13 @@ grepbuf (beg, lim)
int nlines, n;
register char *p, *b;
char *endp;
- char eol = eolbyte;
nlines = 0;
p = beg;
while ((b = (*execute)(p, lim - p, &endp)) != 0)
{
/* Avoid matching the empty line at the end of the buffer. */
- if (b == lim && ((b > beg && b[-1] == eol) || b == beg))
+ if (b == lim && ((b > beg && b[-1] == '\n') || b == beg))
break;
if (!out_invert)
{
@@ -701,7 +672,6 @@ grep (fd, file, stats)
int not_text;
size_t residue, save;
char *beg, *lim;
- char eol = eolbyte;
if (!reset (fd, file, stats))
return 0;
@@ -711,6 +681,11 @@ grep (fd, file, stats)
{
/* Close fd now, so that we don't open a lot of file descriptors
when we recurse deeply. */
+#if HAVE_LIBZ > 0
+ if (Zflag)
+ gzclose(gzbufdesc);
+ else
+#endif
if (close (fd) != 0)
error (file, errno);
return grepdir (file, stats) - 2;
@@ -725,7 +700,7 @@ grep (fd, file, stats)
residue = 0;
save = 0;
- if (! fillbuf (save, stats))
+ if (fillbuf (save, stats) < 0)
{
if (! (is_EISDIR (errno, file) && suppress_errors))
error (filename, errno);
@@ -733,7 +708,7 @@ grep (fd, file, stats)
}
not_text = (! (always_text | out_quiet)
- && memchr (bufbeg, eol ? '\0' : '\200', buflim - bufbeg));
+ && memchr (bufbeg, '\0', buflim - bufbeg));
done_on_match += not_text;
out_quiet += not_text;
@@ -745,7 +720,7 @@ grep (fd, file, stats)
if (buflim - bufbeg == save)
break;
beg = bufbeg + save - residue;
- for (lim = buflim; lim > beg && lim[-1] != eol; --lim)
+ for (lim = buflim; lim > beg && lim[-1] != '\n'; --lim)
;
residue = buflim - lim;
if (beg < lim)
@@ -763,7 +738,7 @@ grep (fd, file, stats)
++i;
do
--beg;
- while (beg > bufbeg && beg[-1] != eol);
+ while (beg > bufbeg && beg[-1] != '\n');
}
if (beg != lastout)
lastout = 0;
@@ -771,7 +746,7 @@ grep (fd, file, stats)
totalcc += buflim - bufbeg - save;
if (out_line)
nlscan (beg);
- if (! fillbuf (save, stats))
+ if (fillbuf (save, stats) < 0)
{
if (! (is_EISDIR (errno, file) && suppress_errors))
error (filename, errno);
@@ -809,8 +784,7 @@ grepfile (file, stats)
}
else
{
- while ((desc = open (file, O_RDONLY)) < 0 && errno == EINTR)
- continue;
+ desc = open (file, O_RDONLY);
if (desc < 0)
{
@@ -869,21 +843,30 @@ grepfile (file, stats)
if (count_matches)
{
if (out_file)
- printf ("%s%c", filename, ':' & filename_mask);
+ printf ("%s:", filename);
printf ("%d\n", count);
}
- status = !count;
- if (list_files == 1 - 2 * status)
- printf ("%s%c", filename, '\n' & filename_mask);
+ if (count)
+ {
+ status = 0;
+ if (list_files == 1)
+ printf ("%s\n", filename);
+ }
+ else
+ {
+ status = 1;
+ if (list_files == -1)
+ printf ("%s\n", filename);
+ }
- if (file)
- while (close (desc) != 0)
- if (errno != EINTR)
- {
- error (file, errno);
- break;
- }
+#if HAVE_LIBZ > 0
+ if (Zflag)
+ gzclose(gzbufdesc);
+ else
+#endif
+ if (file && close (desc) != 0)
+ error (file, errno);
}
return status;
@@ -899,8 +882,8 @@ grepdir (dir, stats)
char *name_space;
for (ancestor = stats; (ancestor = ancestor->parent) != 0; )
- if (ancestor->stat.st_ino == stats->stat.st_ino
- && ancestor->stat.st_dev == stats->stat.st_dev)
+ if (! ((ancestor->stat.st_ino ^ stats->stat.st_ino)
+ | (ancestor->stat.st_dev ^ stats->stat.st_dev)))
{
if (!suppress_errors)
fprintf (stderr, _("%s: warning: %s: %s\n"), prog, dir,
@@ -963,28 +946,24 @@ int status;
printf (_("Usage: %s [OPTION]... PATTERN [FILE] ...\n"), prog);
printf (_("\
Search for PATTERN in each FILE or standard input.\n\
-Example: %s -i 'hello.*world' menu.h main.c\n\
\n\
-Regexp selection and interpretation:\n"), prog);
- printf (_("\
+Regexp selection and interpretation:\n\
-E, --extended-regexp PATTERN is an extended regular expression\n\
- -F, --fixed-strings PATTERN is a set of newline-separated strings\n\
- -G, --basic-regexp PATTERN is a basic regular expression\n"));
- printf (_("\
+ -F, --fixed-regexp PATTERN is a fixed string separated by newlines\n\
+ -G, --basic-regexp PATTERN is a basic regular expression\n\
-e, --regexp=PATTERN use PATTERN as a regular expression\n\
-f, --file=FILE obtain PATTERN from FILE\n\
-i, --ignore-case ignore case distinctions\n\
-w, --word-regexp force PATTERN to match only whole words\n\
- -x, --line-regexp force PATTERN to match only whole lines\n\
- -z, --null-data a data line ends in 0 byte, not newline\n"));
+ -x, --line-regexp force PATTERN to match only whole lines\n"));
printf (_("\
\n\
Miscellaneous:\n\
-s, --no-messages suppress error messages\n\
- -v, --invert-match select non-matching lines\n\
+ -v, --revert-match select non-matching lines\n\
-V, --version print version information and exit\n\
- --help display this help and exit\n\
- --mmap use memory-mapped input if possible\n"));
+ -Z, --decompress decompress input before searching (HAVE_LIBZ=1)\n\
+ --help display this help and exit\n"));
printf (_("\
\n\
Output control:\n\
@@ -999,42 +978,31 @@ Output control:\n\
-r, --recursive equivalent to --directories=recurse.\n\
-L, --files-without-match only print FILE names containing no match\n\
-l, --files-with-matches only print FILE names containing matches\n\
- -c, --count only print a count of matching lines per FILE\n\
- -Z, --null print 0 byte after FILE name\n"));
+ -c, --count only print a count of matching lines per FILE\n"));
printf (_("\
\n\
Context control:\n\
-B, --before-context=NUM print NUM lines of leading context\n\
-A, --after-context=NUM print NUM lines of trailing context\n\
-C, --context[=NUM] print NUM (default 2) lines of output context\n\
- unless overridden by -A or -B\n\
+ unless overriden by -A or -B\n\
-NUM same as --context=NUM\n\
-U, --binary do not strip CR characters at EOL (MSDOS)\n\
-u, --unix-byte-offsets report offsets as if CRs were not there (MSDOS)\n\
\n\
-`egrep' means `grep -E'. `fgrep' means `grep -F'.\n\
-With no FILE, or when FILE is -, read standard input. If less than\n\
-two FILEs given, assume -h. Exit status is 0 if match, 1 if no match,\n\
-and 2 if trouble.\n"));
+If no -[GEF], then `egrep' assumes -E, `fgrep' -F, else -G.\n\
+With no FILE, or when FILE is -, read standard input. If less than\n\
+two FILEs given, assume -h. Exit with 0 if matches, with 1 if none.\n\
+Exit with 2 if syntax errors or system errors.\n"));
printf (_("\nReport bugs to <bug-gnu-utils@gnu.org>.\n"));
}
exit (status);
}
-/* Set the matcher to M, reporting any conflicts. */
-static void
-setmatcher (m)
- char const *m;
-{
- if (matcher && strcmp (matcher, m) != 0)
- fatal (_("conflicting matchers specified"), 0);
- matcher = m;
-}
-
/* Go through the matchers vector and look for the specified matcher.
If we find it, install it in compile and execute, and return 1. */
static int
-install_matcher (name)
+setmatcher (name)
char const *name;
{
int i;
@@ -1155,6 +1123,13 @@ main (argc, argv)
if (prog && strrchr (prog, '/'))
prog = strrchr (prog, '/') + 1;
+#if HAVE_LIBZ > 0
+ if (prog[0] == 'z') {
+ Zflag = 1;
+ ++prog;
+ }
+#endif
+
#if defined(__MSDOS__) || defined(_WIN32)
/* DOS and MS-Windows use backslashes as directory separators, and usually
have an .exe suffix. They also have case-insensitive filesystems. */
@@ -1183,8 +1158,7 @@ main (argc, argv)
keys = NULL;
keycc = 0;
with_filenames = 0;
- eolbyte = '\n';
- filename_mask = ~0;
+ matcher = NULL;
/* The value -1 means to use DEFAULT_CONTEXT. */
out_after = out_before = -1;
@@ -1205,8 +1179,15 @@ main (argc, argv)
prepend_default_options (getenv ("GREP_OPTIONS"), &argc, &argv);
- while ((opt = getopt_long (argc, argv, short_options, long_options, NULL))
- != -1)
+ while ((opt = getopt_long (argc, argv,
+#if O_BINARY
+ "0123456789A:B:C::EFGHVX:abcd:e:f:hiLlnqrsvwxyUu",
+#elif HAVE_LIBZ > 0
+ "0123456789A:B:C::EFGHRVX:Zabcd:e:f:hiLlnqrsvwxy",
+#else
+ "0123456789A:B:C::EFGHRVX:abcd:e:f:hiLlnqrsvwxy",
+#endif
+ long_options, NULL)) != EOF)
switch (opt)
{
case '0':
@@ -1248,33 +1229,44 @@ main (argc, argv)
default_context = 2;
break;
case 'E':
- setmatcher ("egrep");
+ if (matcher && strcmp (matcher, "posix-egrep") != 0)
+ fatal (_("you may specify only one of -E, -F, or -G"), 0);
+ matcher = "posix-egrep";
break;
case 'F':
- setmatcher ("fgrep");
+ if (matcher && strcmp(matcher, "fgrep") != 0)
+ fatal(_("you may specify only one of -E, -F, or -G"), 0);;
+ matcher = "fgrep";
break;
case 'G':
- setmatcher ("grep");
+ if (matcher && strcmp (matcher, "grep") != 0)
+ fatal (_("you may specify only one of -E, -F, or -G"), 0);
+ matcher = "grep";
break;
case 'H':
with_filenames = 1;
break;
- case 'U':
#if O_BINARY
+ case 'U':
dos_use_file_type = DOS_BINARY;
-#endif
break;
case 'u':
-#if O_BINARY
dos_report_unix_offset = 1;
-#endif
break;
+#endif
case 'V':
show_version = 1;
break;
case 'X':
- setmatcher (optarg);
+ if (matcher)
+ fatal (_("matcher already specified"), 0);
+ matcher = optarg;
break;
+#if HAVE_LIBZ > 0
+ case 'Z':
+ Zflag = 1;
+ break;
+#endif
case 'a':
always_text = 1;
break;
@@ -1349,6 +1341,7 @@ main (argc, argv)
done_on_match = 1;
out_quiet = 1;
break;
+ case 'R':
case 'r':
directories = RECURSE_DIRECTORIES;
break;
@@ -1364,12 +1357,6 @@ main (argc, argv)
case 'x':
match_lines = 1;
break;
- case 'Z':
- filename_mask = 0;
- break;
- case 'z':
- eolbyte = '\0';
- break;
case 0:
/* long options */
break;
@@ -1383,12 +1370,9 @@ main (argc, argv)
if (out_before < 0)
out_before = default_context;
- if (! matcher)
- matcher = "grep";
-
if (show_version)
{
- printf (_("%s (GNU grep) %s\n"), matcher, VERSION);
+ printf (_("grep (GNU grep) %s\n"), VERSION);
printf ("\n");
printf (_("\
Copyright (C) 1988, 1992-1998, 1999 Free Software Foundation, Inc.\n"));
@@ -1420,7 +1404,10 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"))
else
usage (2);
- if (!install_matcher (matcher) && !install_matcher ("default"))
+ if (! matcher)
+ matcher = prog;
+
+ if (!setmatcher (matcher) && !setmatcher ("default"))
abort ();
(*compile)(keys, keycc);
diff --git a/gnu/usr.bin/grep/grep.h b/gnu/usr.bin/grep/grep.h
index 13f55a2..e12cff5 100644
--- a/gnu/usr.bin/grep/grep.h
+++ b/gnu/usr.bin/grep/grep.h
@@ -16,6 +16,8 @@
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
+/* $FreeBSD$ */
+
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6) || __STRICT_ANSI__
# define __attribute__(x)
#endif
@@ -35,12 +37,14 @@ extern struct matcher
char *(*execute) PARAMS ((char *, size_t, char **));
} matchers[];
-/* Exported from fgrepmat.c, egrepmat.c, grepmat.c. */
+/* Exported from grep.c. */
extern char const *matcher;
+/* Exported from fgrepmat.c, egrepmat.c, grepmat.c. */
+extern char const default_matcher[];
+
/* The following flags are exported from grep for the matchers
to look at. */
extern int match_icase; /* -i */
extern int match_words; /* -w */
extern int match_lines; /* -x */
-extern unsigned char eolbyte; /* -z */
diff --git a/gnu/usr.bin/grep/kwset.c b/gnu/usr.bin/grep/kwset.c
index c7b088b..adde8a7 100644
--- a/gnu/usr.bin/grep/kwset.c
+++ b/gnu/usr.bin/grep/kwset.c
@@ -20,6 +20,8 @@
The author may be reached (Email) at the address mike@ai.mit.edu,
or (US mail) as Mike Haertel c/o Free Software Foundation. */
+/* $FreeBSD$ */
+
/* The algorithm implemented by these routines bears a startling resemblence
to one discovered by Beate Commentz-Walter, although it is not identical.
See "A String Matching Algorithm Fast on the Average," Technical Report,
diff --git a/gnu/usr.bin/grep/kwset.h b/gnu/usr.bin/grep/kwset.h
index e699258..f812b2e 100644
--- a/gnu/usr.bin/grep/kwset.h
+++ b/gnu/usr.bin/grep/kwset.h
@@ -20,6 +20,8 @@
The author may be reached (Email) at the address mike@ai.mit.edu,
or (US mail) as Mike Haertel c/o Free Software Foundation. */
+/* $FreeBSD$ */
+
struct kwsmatch
{
int index; /* Index number of matching keyword. */
diff --git a/gnu/usr.bin/grep/obstack.c b/gnu/usr.bin/grep/obstack.c
index 4258c12..c77fdd4 100644
--- a/gnu/usr.bin/grep/obstack.c
+++ b/gnu/usr.bin/grep/obstack.c
@@ -20,6 +20,8 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* $FreeBSD$ */
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
diff --git a/gnu/usr.bin/grep/obstack.h b/gnu/usr.bin/grep/obstack.h
index 5c03f68..df785c3 100644
--- a/gnu/usr.bin/grep/obstack.h
+++ b/gnu/usr.bin/grep/obstack.h
@@ -20,6 +20,8 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* $FreeBSD$ */
+
/* Summary:
All the apparent functions defined here are macros. The idea
diff --git a/gnu/usr.bin/grep/search.c b/gnu/usr.bin/grep/search.c
index 8fb3af0..a3ca56c 100644
--- a/gnu/usr.bin/grep/search.c
+++ b/gnu/usr.bin/grep/search.c
@@ -18,13 +18,19 @@
/* Written August 1992 by Mike Haertel. */
+/* $FreeBSD$ */
+
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/types.h>
#include "system.h"
#include "grep.h"
+#ifdef __FreeBSD__
+#include <gnuregex.h>
+#else
#include "regex.h"
+#endif
#include "dfa.h"
#include "kwset.h"
@@ -42,6 +48,7 @@ struct matcher matchers[] = {
{ "default", Gcompile, EGexecute },
{ "grep", Gcompile, EGexecute },
{ "egrep", Ecompile, EGexecute },
+ { "posix-egrep", Ecompile, EGexecute },
{ "awk", Ecompile, EGexecute },
{ "fgrep", Fcompile, Fexecute },
{ 0, 0, 0 },
@@ -54,7 +61,7 @@ struct matcher matchers[] = {
static struct dfa dfa;
/* Regex compiled regexp. */
-static struct re_pattern_buffer regexbuf;
+static struct re_pattern_buffer regex;
/* KWset compiled pattern. For Ecompile and Gcompile, we compile
a list of strings, at least one of which is known to occur in
@@ -133,9 +140,9 @@ Gcompile(pattern, size)
const char *err;
re_set_syntax(RE_SYNTAX_GREP | RE_HAT_LISTS_NOT_NEWLINE);
- dfasyntax(RE_SYNTAX_GREP | RE_HAT_LISTS_NOT_NEWLINE, match_icase, eolbyte);
+ dfasyntax(RE_SYNTAX_GREP | RE_HAT_LISTS_NOT_NEWLINE, match_icase);
- if ((err = re_compile_pattern(pattern, size, &regexbuf)) != 0)
+ if ((err = re_compile_pattern(pattern, size, &regex)) != 0)
fatal(err, 0);
/* In the match_words and match_lines cases, we use a different pattern
@@ -148,8 +155,7 @@ Gcompile(pattern, size)
(^|[^A-Za-z_])(userpattern)([^A-Za-z_]|$).
In the whole-line case, we use the pattern:
^(userpattern)$.
- BUG: Using [A-Za-z_] is locale-dependent!
- So will use [:alnum:] */
+ BUG: Using [A-Za-z_] is locale-dependent! */
char *n = malloc(size + 50);
int i = 0;
@@ -159,14 +165,14 @@ Gcompile(pattern, size)
if (match_lines)
strcpy(n, "^\\(");
if (match_words)
- strcpy(n, "\\(^\\|[^[:alnum:]_]\\)\\(");
+ strcpy(n, "\\(^\\|[^0-9A-Za-z_]\\)\\(");
i = strlen(n);
memcpy(n + i, pattern, size);
i += size;
if (match_words)
- strcpy(n + i, "\\)\\([^[:alnum:]_]\\|$\\)");
+ strcpy(n + i, "\\)\\([^0-9A-Za-z_]\\|$\\)");
if (match_lines)
strcpy(n + i, "\\)$");
@@ -186,18 +192,23 @@ Ecompile(pattern, size)
{
const char *err;
- if (strcmp(matcher, "awk") == 0)
+ if (strcmp(matcher, "posix-egrep") == 0)
+ {
+ re_set_syntax(RE_SYNTAX_POSIX_EGREP);
+ dfasyntax(RE_SYNTAX_POSIX_EGREP, match_icase);
+ }
+ else if (strcmp(matcher, "awk") == 0)
{
re_set_syntax(RE_SYNTAX_AWK);
- dfasyntax(RE_SYNTAX_AWK, match_icase, eolbyte);
+ dfasyntax(RE_SYNTAX_AWK, match_icase);
}
else
{
- re_set_syntax (RE_SYNTAX_POSIX_EGREP);
- dfasyntax (RE_SYNTAX_POSIX_EGREP, match_icase, eolbyte);
+ re_set_syntax(RE_SYNTAX_EGREP);
+ dfasyntax(RE_SYNTAX_EGREP, match_icase);
}
- if ((err = re_compile_pattern(pattern, size, &regexbuf)) != 0)
+ if ((err = re_compile_pattern(pattern, size, &regex)) != 0)
fatal(err, 0);
/* In the match_words and match_lines cases, we use a different pattern
@@ -210,8 +221,7 @@ Ecompile(pattern, size)
(^|[^A-Za-z_])(userpattern)([^A-Za-z_]|$).
In the whole-line case, we use the pattern:
^(userpattern)$.
- BUG: Using [A-Za-z_] is locale-dependent!
- so will use the char class */
+ BUG: Using [A-Za-z_] is locale-dependent! */
char *n = malloc(size + 50);
int i = 0;
@@ -221,14 +231,14 @@ Ecompile(pattern, size)
if (match_lines)
strcpy(n, "^(");
if (match_words)
- strcpy(n, "(^|[^[:alnum:]_])(");
+ strcpy(n, "(^|[^0-9A-Za-z_])(");
i = strlen(n);
memcpy(n + i, pattern, size);
i += size;
if (match_words)
- strcpy(n + i, ")([^[:alnum:]_]|$)");
+ strcpy(n + i, ")([^0-9A-Za-z_]|$)");
if (match_lines)
strcpy(n + i, ")$");
@@ -248,7 +258,6 @@ EGexecute(buf, size, endp)
char **endp;
{
register char *buflim, *beg, *end, save;
- char eol = eolbyte;
int backref, start, len;
struct kwsmatch kwsm;
static struct re_registers regs; /* This is static on account of a BRAIN-DEAD
@@ -266,10 +275,10 @@ EGexecute(buf, size, endp)
goto failure;
/* Narrow down to the line containing the candidate, and
run it through DFA. */
- end = memchr(beg, eol, buflim - beg);
+ end = memchr(beg, '\n', buflim - beg);
if (!end)
end = buflim;
- while (beg > buf && beg[-1] != eol)
+ while (beg > buf && beg[-1] != '\n')
--beg;
save = *end;
if (kwsm.index < lastexact)
@@ -293,10 +302,10 @@ EGexecute(buf, size, endp)
if (!beg)
goto failure;
/* Narrow down to the line we've found. */
- end = memchr(beg, eol, buflim - beg);
+ end = memchr(beg, '\n', buflim - beg);
if (!end)
end = buflim;
- while (beg > buf && beg[-1] != eol)
+ while (beg > buf && beg[-1] != '\n')
--beg;
/* Successful, no backreferences encountered! */
if (!backref)
@@ -304,8 +313,8 @@ EGexecute(buf, size, endp)
}
/* If we've made it to this point, this means DFA has seen
a probable match, and we need to run it through Regex. */
- regexbuf.not_eol = 0;
- if ((start = re_search(&regexbuf, beg, end - beg, 0, end - beg, &regs)) >= 0)
+ regex.not_eol = 0;
+ if ((start = re_search(&regex, beg, end - beg, 0, end - beg, &regs)) >= 0)
{
len = regs.end[0] - start;
if ((!match_lines && !match_words)
@@ -328,8 +337,8 @@ EGexecute(buf, size, endp)
{
/* Try a shorter length anchored at the same place. */
--len;
- regexbuf.not_eol = 1;
- len = re_match(&regexbuf, beg, start + len, start, &regs);
+ regex.not_eol = 1;
+ len = re_match(&regex, beg, start + len, start, &regs);
}
if (len <= 0)
{
@@ -337,8 +346,8 @@ EGexecute(buf, size, endp)
if (start == end - beg)
break;
++start;
- regexbuf.not_eol = 0;
- start = re_search(&regexbuf, beg, end - beg,
+ regex.not_eol = 0;
+ start = re_search(&regex, beg, end - beg,
start, end - beg - start, &regs);
len = regs.end[0] - start;
}
@@ -387,7 +396,6 @@ Fexecute(buf, size, endp)
{
register char *beg, *try, *end;
register size_t len;
- char eol = eolbyte;
struct kwsmatch kwsmatch;
for (beg = buf; beg <= buf + size; ++beg)
@@ -397,9 +405,9 @@ Fexecute(buf, size, endp)
len = kwsmatch.size[0];
if (match_lines)
{
- if (beg > buf && beg[-1] != eol)
+ if (beg > buf && beg[-1] != '\n')
continue;
- if (beg + len < buf + size && beg[len] != eol)
+ if (beg + len < buf + size && beg[len] != '\n')
continue;
goto success;
}
@@ -423,7 +431,7 @@ Fexecute(buf, size, endp)
return 0;
success:
- if ((end = memchr(beg + len, eol, (buf + size) - (beg + len))) != 0)
+ if ((end = memchr(beg + len, '\n', (buf + size) - (beg + len))) != 0)
++end;
else
end = buf + size;
OpenPOWER on IntegriCloud