diff options
Diffstat (limited to 'gnu/usr.bin/grep')
-rw-r--r-- | gnu/usr.bin/grep/Makefile | 51 | ||||
-rw-r--r-- | gnu/usr.bin/grep/config.h | 188 | ||||
-rw-r--r-- | gnu/usr.bin/grep/dfa.c | 132 | ||||
-rw-r--r-- | gnu/usr.bin/grep/dfa.h | 9 | ||||
-rw-r--r-- | gnu/usr.bin/grep/doc/Makefile | 6 | ||||
-rw-r--r-- | gnu/usr.bin/grep/getopt.c | 2 | ||||
-rw-r--r-- | gnu/usr.bin/grep/getopt.h | 2 | ||||
-rw-r--r-- | gnu/usr.bin/grep/getpagesize.h | 2 | ||||
-rw-r--r-- | gnu/usr.bin/grep/grep.1 | 273 | ||||
-rw-r--r-- | gnu/usr.bin/grep/grep.c | 505 | ||||
-rw-r--r-- | gnu/usr.bin/grep/grep.h | 8 | ||||
-rw-r--r-- | gnu/usr.bin/grep/kwset.c | 2 | ||||
-rw-r--r-- | gnu/usr.bin/grep/kwset.h | 2 | ||||
-rw-r--r-- | gnu/usr.bin/grep/obstack.c | 2 | ||||
-rw-r--r-- | gnu/usr.bin/grep/obstack.h | 2 | ||||
-rw-r--r-- | gnu/usr.bin/grep/search.c | 70 |
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, ®exbuf)) != 0) + if ((err = re_compile_pattern(pattern, size, ®ex)) != 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, ®exbuf)) != 0) + if ((err = re_compile_pattern(pattern, size, ®ex)) != 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(®exbuf, beg, end - beg, 0, end - beg, ®s)) >= 0) + regex.not_eol = 0; + if ((start = re_search(®ex, beg, end - beg, 0, end - beg, ®s)) >= 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(®exbuf, beg, start + len, start, ®s); + regex.not_eol = 1; + len = re_match(®ex, beg, start + len, start, ®s); } if (len <= 0) { @@ -337,8 +346,8 @@ EGexecute(buf, size, endp) if (start == end - beg) break; ++start; - regexbuf.not_eol = 0; - start = re_search(®exbuf, beg, end - beg, + regex.not_eol = 0; + start = re_search(®ex, beg, end - beg, start, end - beg - start, ®s); 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; |