summaryrefslogtreecommitdiff
path: root/src/grep.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/grep.c')
-rw-r--r--src/grep.c190
1 files changed, 102 insertions, 88 deletions
diff --git a/src/grep.c b/src/grep.c
index 4c5d0bba..a1a8c26f 100644
--- a/src/grep.c
+++ b/src/grep.c
@@ -245,7 +245,11 @@ static struct exclude *excluded_patterns;
static struct exclude *included_patterns;
/* Short options. */
static char const short_options[] =
-"0123456789A:B:C:D:EFGHIPTUVX:abcd:e:f:hiKLlm:noqRrsuvwxyZz";
+"0123456789A:B:C:D:HITUVabcd:e:f:hiKLlm:noqRrsuvwxyZz"
+#ifdef GREP_PROGRAM
+"EFGPX:"
+#endif
+;
/* Non-boolean long options that have no corresponding short equivalents. */
enum
@@ -262,8 +266,14 @@ enum
/* Long options equivalences. */
static struct option const long_options[] =
{
+#ifdef GREP_PROGRAM
+ {"basic-regexp", no_argument, NULL, 'G'},
+ {"extended-regexp", no_argument, NULL, 'E'},
+ {"fixed-regexp", no_argument, NULL, 'F'},
+ {"fixed-strings", no_argument, NULL, 'F'},
+ {"perl-regexp", no_argument, NULL, 'P'},
+#endif
{"after-context", required_argument, NULL, 'A'},
- {"basic-regexp", no_argument, NULL, 'G'},
{"before-context", required_argument, NULL, 'B'},
{"binary-files", required_argument, NULL, BINARY_FILES_OPTION},
{"byte-offset", no_argument, NULL, 'b'},
@@ -273,14 +283,11 @@ static struct option const long_options[] =
{"count", no_argument, NULL, 'c'},
{"devices", required_argument, NULL, 'D'},
{"directories", required_argument, NULL, 'd'},
- {"extended-regexp", no_argument, NULL, 'E'},
{"exclude", required_argument, NULL, EXCLUDE_OPTION},
{"exclude-from", required_argument, NULL, EXCLUDE_FROM_OPTION},
{"file", required_argument, NULL, 'f'},
{"files-with-matches", no_argument, NULL, 'l'},
{"files-without-match", no_argument, NULL, 'L'},
- {"fixed-regexp", no_argument, NULL, 'F'},
- {"fixed-strings", no_argument, NULL, 'F'},
{"help", no_argument, &show_help, 1},
{"include", required_argument, NULL, INCLUDE_OPTION},
{"ignore-case", no_argument, NULL, 'i'},
@@ -296,7 +303,6 @@ static struct option const long_options[] =
{"null", no_argument, NULL, 'Z'},
{"null-data", no_argument, NULL, 'z'},
{"only-matching", no_argument, NULL, 'o'},
- {"perl-regexp", no_argument, NULL, 'P'},
{"quiet", no_argument, NULL, 'q'},
{"recursive", no_argument, NULL, 'r'},
{"recursive", no_argument, NULL, 'R'},
@@ -345,8 +351,10 @@ static inline int undossify_input PARAMS ((register char *, size_t));
#endif
/* Functions we'll use to search. */
-static void (*compile) PARAMS ((char const *, size_t));
-static size_t (*execute) PARAMS ((char const *, size_t, size_t *, int));
+#ifdef GREP_PROGRAM
+static compile_fp_t compile;
+static execute_fp_t execute;
+#endif
/* Like error, but suppress the diagnostic if requested. */
static void
@@ -774,7 +782,7 @@ print_line_middle (const char *beg, const char *lim)
}
while ( lim > beg
- && ( (match_offset = (*execute) (ibeg, lim - beg, &match_size, 1))
+ && ( (match_offset = execute(ibeg, lim - beg, &match_size, 1))
!= (size_t) -1))
{
char const *b = beg + match_offset;
@@ -896,7 +904,7 @@ prpending (char const *lim)
size_t match_size;
--pending;
if (outleft
- || (((*execute) (lastout, nl + 1 - lastout, &match_size, 0) == (size_t) -1)
+ || ((execute(lastout, nl + 1 - lastout, &match_size, 0) == (size_t) -1)
== !out_invert))
prline (lastout, nl + 1, SEP_CHAR_CONTEXT);
else
@@ -986,7 +994,7 @@ grepbuf (char const *beg, char const *lim)
nlines = 0;
p = beg;
- while ((match_offset = (*execute) (p, lim - p, &match_size, 0)) != (size_t) -1)
+ while ((match_offset = execute(p, lim - p, &match_size, 0)) != (size_t) -1)
{
char const *b = p + match_offset;
char const *endp = b + match_size;
@@ -1354,18 +1362,31 @@ usage (int status)
{
printf (_("Usage: %s [OPTION]... PATTERN [FILE]...\n"), program_name);
printf (_("\
-Search for PATTERN in each FILE or standard input.\n\
+Search for PATTERN in each FILE or standard input.\n"));
+#if defined(EGREP_PROGRAM)
+ printf (_("\
+PATTERN is an extended regular expression (ERE).\n"));
+#elif defined(FGREP_PROGRAM)
+ printf (_("\
+PATTERN is a set of newline-separated fixed strings.\n"));
+#else
+ printf (_("\
+PATTERN is, by default, a basic regular expression (BRE).\n"));
+#endif /* ?GREP_PROGRAM */
+ printf (_("\
Example: %s -i 'hello world' menu.h main.c\n\
\n\
Regexp selection and interpretation:\n"), program_name);
+#ifdef GREP_PROGRAM
printf (_("\
- -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\
+ -E, --extended-regexp PATTERN is an extended regular expression (ERE)\n\
+ -F, --fixed-strings PATTERN is a set of newline-separated fixed strings\n\
+ -G, --basic-regexp PATTERN is a basic regular expression (BRE)\n\
-P, --perl-regexp PATTERN is a Perl regular expression\n"));
/* -X is undocumented on purpose. */
+#endif /* GREP_PROGRAM */
printf (_("\
- -e, --regexp=PATTERN use PATTERN as a regular expression\n\
+ -e, --regexp=PATTERN use PATTERN for matching\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\
@@ -1420,8 +1441,19 @@ Context control:\n\
WHEN is `always', `never', or `auto'\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\
+\n"));
+#if defined(EGREP_PROGRAM)
+ printf (_("\
+Invocation as `egrep' is deprecated; use `grep -E' instead.\n"));
+#elif defined(FGREP_PROGRAM)
+ printf (_("\
+Invocation as `fgrep' is deprecated; use `grep -F' instead.\n"));
+#else
+ printf (_("\
`egrep' means `grep -E'. `fgrep' means `grep -F'.\n\
+Direct invocation as either `egrep' or `fgrep' is deprecated.\n"));
+#endif /* ?GREP_PROGRAM */
+ printf (_("\
With no FILE, or when FILE is -, read standard input. If less than two FILEs\n\
are given, assume -h. Exit status is 0 if any line was selected, 1 otherwise;\n\
if any error occurs and -q was not given, the exit status is 2.\n"));
@@ -1430,6 +1462,9 @@ if any error occurs and -q was not given, the exit status is 2.\n"));
exit (status);
}
+#ifdef GREP_PROGRAM
+static char const *matcher;
+
/* Set the matcher to M, reporting any conflicts. */
static void
setmatcher (char const *m)
@@ -1445,45 +1480,50 @@ static int
install_matcher (char const *name)
{
int i;
-#if defined(HAVE_SETRLIMIT)
- struct rlimit rlim;
-#endif
for (i = 0; matchers[i].compile; i++)
if (strcmp (name, matchers[i].name) == 0)
{
compile = matchers[i].compile;
execute = matchers[i].execute;
-#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_STACK)
- /* I think every platform needs to do this, so that regex.c
- doesn't oveflow the stack. The default value of
- `re_max_failures' is too large for some platforms: it needs
- more than 3MB-large stack.
-
- The test for HAVE_SETRLIMIT should go into `configure'. */
- if (!getrlimit (RLIMIT_STACK, &rlim))
- {
- long newlim;
- extern long int re_max_failures; /* from regex.c */
-
- /* Approximate the amount regex.c needs, plus some more. */
- newlim = re_max_failures * 2 * 20 * sizeof (char *);
- if (newlim > rlim.rlim_max)
- {
- newlim = rlim.rlim_max;
- re_max_failures = newlim / (2 * 20 * sizeof (char *));
- }
- if (rlim.rlim_cur < newlim)
- {
- rlim.rlim_cur = newlim;
- setrlimit (RLIMIT_STACK, &rlim);
- }
- }
-#endif
return 1;
}
return 0;
}
+#endif /* GREP_PROGRAM */
+
+static void
+set_limits(void)
+{
+#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_STACK)
+ struct rlimit rlim;
+
+ /* I think every platform needs to do this, so that regex.c
+ doesn't oveflow the stack. The default value of
+ `re_max_failures' is too large for some platforms: it needs
+ more than 3MB-large stack.
+
+ The test for HAVE_SETRLIMIT should go into `configure'. */
+ if (!getrlimit (RLIMIT_STACK, &rlim))
+ {
+ long newlim;
+ extern long int re_max_failures; /* from regex.c */
+
+ /* Approximate the amount regex.c needs, plus some more. */
+ newlim = re_max_failures * 2 * 20 * sizeof (char *);
+ if (newlim > rlim.rlim_max)
+ {
+ newlim = rlim.rlim_max;
+ re_max_failures = newlim / (2 * 20 * sizeof (char *));
+ }
+ if (rlim.rlim_cur < newlim)
+ {
+ rlim.rlim_cur = newlim;
+ setrlimit (RLIMIT_STACK, &rlim);
+ }
+ }
+#endif
+}
/* Find the white-space-separated options specified by OPTIONS, and
using BUF to store copies of these options, set ARGV[0], ARGV[1],
@@ -1741,38 +1781,6 @@ main (int argc, char **argv)
initialize_main (&argc, &argv);
program_name = argv[0];
- if (program_name && strrchr (program_name, '/'))
- program_name = strrchr (program_name, '/') + 1;
-
- if (!strcmp(program_name, "egrep"))
- setmatcher ("egrep");
- if (!strcmp(program_name, "fgrep"))
- setmatcher ("fgrep");
-
-#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. */
- if (program_name)
- {
- char *p = program_name;
- char *bslash = strrchr (argv[0], '\\');
-
- if (bslash && bslash >= program_name) /* for mixed forward/backslash case */
- program_name = bslash + 1;
- else if (program_name == argv[0]
- && argv[0][0] && argv[0][1] == ':') /* "c:progname" */
- program_name = argv[0] + 2;
-
- /* Collapse the letter-case, so `strcmp' could be used hence. */
- for ( ; *p; p++)
- if (*p >= 'A' && *p <= 'Z')
- *p += 'a' - 'A';
-
- /* Remove the .exe extension, if any. */
- if ((p = strrchr (program_name, '.')) && strcmp (p, ".exe") == 0)
- *p = '\0';
- }
-#endif
keys = NULL;
keycc = 0;
@@ -1828,6 +1836,7 @@ main (int argc, char **argv)
error (2, 0, _("unknown devices method"));
break;
+#ifdef GREP_PROGRAM
case 'E':
setmatcher ("egrep");
break;
@@ -1844,6 +1853,11 @@ main (int argc, char **argv)
setmatcher ("grep");
break;
+ case 'X': /* undocumented on purpose */
+ setmatcher (optarg);
+ break;
+#endif /* GREP_PROGRAM */
+
case 'H':
with_filenames = 1;
break;
@@ -1872,10 +1886,6 @@ main (int argc, char **argv)
show_version = 1;
break;
- case 'X': /* undocumented on purpose */
- setmatcher (optarg);
- break;
-
case 'a':
binary_files = TEXT_BINARY_FILES;
break;
@@ -2120,16 +2130,13 @@ main (int argc, char **argv)
parse_grep_colors();
}
- if (! matcher)
- matcher = "grep";
-
if (show_version)
{
printf ("%s\n\n", PACKAGE_STRING);
printf (_("\
-Copyright (C) 1988, 1992-1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.\n"));
+Copyright (C) 1988, 1992-2002, 2004, 2005 Free Software Foundation, Inc.\n"));
printf (_("\
-This is free software; see the source for copying conditions. There is NO\n\
+This is free software; see the source for copying conditions. There is NO\n\
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"));
printf ("\n");
exit (0);
@@ -2159,15 +2166,22 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"))
else
usage (2);
+#ifdef GREP_PROGRAM
+ if (! matcher)
+ matcher = "grep";
+
if (!install_matcher (matcher) && !install_matcher ("default"))
abort ();
+#endif /* GREP_PROGRAM */
+
+ set_limits();
#ifdef MBS_SUPPORT
if (match_icase)
mb_icase_keys (&keys, &keycc);
#endif /* MBS_SUPPORT */
- (*compile)(keys, keycc);
+ compile(keys, keycc);
if ((argc - optind > 1 && !no_filenames) || with_filenames)
out_file = 1;