summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2016-12-20 08:56:06 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2016-12-20 18:06:22 -0800
commit214be13d33a26ab45231afe8e983d9a174aae282 (patch)
tree8eca98d5f11dee7d6cbb49906e814581b3e31be3
parent75bca3ca0a6ea87a66531ab7c0f8859e1d6c4300 (diff)
downloadgrep-214be13d33a26ab45231afe8e983d9a174aae282.tar.gz
grep: simplify matcher configuration
* src/grep.c (matcher, compile): Remove static vars. (compile_fp_t): Now takes a 3rd syntax argument. (Gcomppile, Ecompile, Acompile, GAcompile, PAcompile): Remove. (struct matcher): Now nameless, since it is used only once. Make 'name' a bit shorter. New member 'syntax'. (matchers): Initialize it, and change removed functions to GEAcompile. (F_MATCHER_INDEX, G_MATCHER_INDEX): New constants. (setmatcher): New arg MATCHER, and return new matcher index. Avoid unnecessary call to strcmp. (main): Keep matcher as a local int, not a global pointer. * src/kwsearch.c (Fcompile): * src/pcresearch.c (Pcompile): Ignore the 3rd syntax argument.
-rw-r--r--src/grep.c111
-rw-r--r--src/kwsearch.c2
-rw-r--r--src/pcresearch.c2
-rw-r--r--src/search.h4
4 files changed, 41 insertions, 78 deletions
diff --git a/src/grep.c b/src/grep.c
index 76f83d58..574a3800 100644
--- a/src/grep.c
+++ b/src/grep.c
@@ -491,8 +491,6 @@ bool match_words;
bool match_lines;
char eolbyte;
-static char const *matcher;
-
/* For error messages. */
/* The input file name, or (if standard input) null or a --label argument. */
static char const *filename;
@@ -577,9 +575,8 @@ static bool seek_failed;
static bool seek_data_failed;
/* Functions we'll use to search. */
-typedef void (*compile_fp_t) (char const *, size_t);
+typedef void (*compile_fp_t) (char const *, size_t, reg_syntax_t);
typedef size_t (*execute_fp_t) (char const *, size_t, size_t *, char const *);
-static compile_fp_t compile;
static execute_fp_t execute;
static char const *
@@ -2019,70 +2016,36 @@ if any error occurs and -q is not given, the exit status is 2.\n"));
/* Pattern compilers and matchers. */
-static void
-Gcompile (char const *pattern, size_t size)
-{
- GEAcompile (pattern, size, RE_SYNTAX_GREP);
-}
-
-static void
-Ecompile (char const *pattern, size_t size)
-{
- GEAcompile (pattern, size, RE_SYNTAX_EGREP);
-}
-
-static void
-Acompile (char const *pattern, size_t size)
-{
- GEAcompile (pattern, size, RE_SYNTAX_AWK);
-}
-
-static void
-GAcompile (char const *pattern, size_t size)
-{
- GEAcompile (pattern, size, RE_SYNTAX_GNU_AWK);
-}
-
-static void
-PAcompile (char const *pattern, size_t size)
-{
- GEAcompile (pattern, size, RE_SYNTAX_POSIX_AWK);
-}
-
-struct matcher
+static struct
{
- char const name[16];
+ char const name[12];
+ int syntax; /* used if compile == GEAcompile */
compile_fp_t compile;
execute_fp_t execute;
+} const matchers[] = {
+ { "grep", RE_SYNTAX_GREP, GEAcompile, EGexecute },
+ { "egrep", RE_SYNTAX_EGREP, GEAcompile, EGexecute },
+ { "fgrep", 0, Fcompile, Fexecute, },
+ { "awk", RE_SYNTAX_AWK, GEAcompile, EGexecute },
+ { "gawk", RE_SYNTAX_GNU_AWK, GEAcompile, EGexecute },
+ { "posixawk", RE_SYNTAX_POSIX_AWK, GEAcompile, EGexecute },
+ { "perl", 0, Pcompile, Pexecute, },
};
-static struct matcher const matchers[] = {
- { "grep", Gcompile, EGexecute },
- { "egrep", Ecompile, EGexecute },
- { "fgrep", Fcompile, Fexecute },
- { "awk", Acompile, EGexecute },
- { "gawk", GAcompile, EGexecute },
- { "posixawk", PAcompile, EGexecute },
- { "perl", Pcompile, Pexecute },
- { "", NULL, NULL },
-};
+/* Keep these in sync with the 'matchers' table. */
+enum { F_MATCHER_INDEX = 2, G_MATCHER_INDEX = 0 };
-/* Set the matcher to M if available. Exit in case of conflicts or if
- M is not available. */
-static void
-setmatcher (char const *m)
+/* Return the index of the matcher corresponding to M if available.
+ MATCHER is the index of the previous matcher, or -1 if none.
+ Exit in case of conflicts or if M is not available. */
+static int
+setmatcher (char const *m, int matcher)
{
- struct matcher const *p;
-
- if (matcher && !STREQ (matcher, m))
- die (EXIT_TROUBLE, 0, _("conflicting matchers specified"));
-
- for (p = matchers; p->compile; p++)
- if (STREQ (m, p->name))
+ for (int i = 0; i < sizeof matchers / sizeof *matchers; i++)
+ if (STREQ (m, matchers[i].name))
{
- matcher = p->name;
- compile = p->compile;
- execute = p->execute;
- return;
+ if (0 <= matcher && matcher != i)
+ die (EXIT_TROUBLE, 0, _("conflicting matchers specified"));
+ return i;
}
die (EXIT_TROUBLE, 0, _("invalid matcher %s"), m);
@@ -2367,6 +2330,7 @@ main (int argc, char **argv)
{
char *keys = NULL;
size_t keycc = 0, oldcc, keyalloc = 0;
+ int matcher = -1;
bool with_filenames = false;
size_t cc;
int opt, prepended;
@@ -2409,9 +2373,6 @@ main (int argc, char **argv)
error (0, 0, _("warning: GREP_OPTIONS is deprecated;"
" please use an alias or script"));
- compile = matchers[0].compile;
- execute = matchers[0].execute;
-
while (prev_optind = optind,
(opt = get_nondigit_option (argc, argv, &default_context)) != -1)
switch (opt)
@@ -2440,23 +2401,23 @@ main (int argc, char **argv)
break;
case 'E':
- setmatcher ("egrep");
+ matcher = setmatcher ("egrep", matcher);
break;
case 'F':
- setmatcher ("fgrep");
+ matcher = setmatcher ("fgrep", matcher);
break;
case 'P':
- setmatcher ("perl");
+ matcher = setmatcher ("perl", matcher);
break;
case 'G':
- setmatcher ("grep");
+ matcher = setmatcher ("grep", matcher);
break;
case 'X': /* undocumented on purpose */
- setmatcher (optarg);
+ matcher = setmatcher (optarg, matcher);
break;
case 'H':
@@ -2794,24 +2755,26 @@ main (int argc, char **argv)
initialize_unibyte_mask ();
+ if (matcher < 0)
+ matcher = G_MATCHER_INDEX;
+
/* In a unibyte locale, switch from fgrep to grep if
the pattern matches words (where grep is typically faster).
In a multibyte locale, switch from fgrep to grep if either
(1) the pattern has an encoding error (where fgrep might not work), or
(2) case is ignored and a fast fgrep ignore-case is not available. */
- if (compile == Fcompile
+ if (matcher == F_MATCHER_INDEX
&& (MB_CUR_MAX <= 1
? match_words
: (contains_encoding_error (keys, keycc)
|| (match_icase && !fgrep_icase_available (keys, keycc)))))
{
fgrep_to_grep_pattern (&keys, &keycc);
- matcher = "grep";
- compile = Gcompile;
- execute = EGexecute;
+ matcher = G_MATCHER_INDEX;
}
- compile (keys, keycc);
+ execute = matchers[matcher].execute;
+ matchers[matcher].compile (keys, keycc, matchers[matcher].syntax);
free (keys);
/* We need one byte prior and one after. */
char eolbytes[3] = { 0, eolbyte, 0 };
diff --git a/src/kwsearch.c b/src/kwsearch.c
index c3e69b39..72759735 100644
--- a/src/kwsearch.c
+++ b/src/kwsearch.c
@@ -34,7 +34,7 @@ wordchar (wint_t wc)
static kwset_t kwset;
void
-Fcompile (char const *pattern, size_t size)
+Fcompile (char const *pattern, size_t size, reg_syntax_t ignored)
{
size_t total = size;
diff --git a/src/pcresearch.c b/src/pcresearch.c
index 108baff8..0e34861d 100644
--- a/src/pcresearch.c
+++ b/src/pcresearch.c
@@ -88,7 +88,7 @@ static int empty_match[2];
#endif
void
-Pcompile (char const *pattern, size_t size)
+Pcompile (char const *pattern, size_t size, reg_syntax_t ignored)
{
#if !HAVE_LIBPCRE
die (EXIT_TROUBLE, 0,
diff --git a/src/search.h b/src/search.h
index 4957a639..1ff5be22 100644
--- a/src/search.h
+++ b/src/search.h
@@ -57,11 +57,11 @@ extern void GEAcompile (char const *, size_t, reg_syntax_t);
extern size_t EGexecute (char const *, size_t, size_t *, char const *);
/* kwsearch.c */
-extern void Fcompile (char const *, size_t);
+extern void Fcompile (char const *, size_t, reg_syntax_t);
extern size_t Fexecute (char const *, size_t, size_t *, char const *);
/* pcresearch.c */
-extern void Pcompile (char const *, size_t);
+extern void Pcompile (char const *, size_t, reg_syntax_t);
extern size_t Pexecute (char const *, size_t, size_t *, char const *);
/* Return the number of bytes in the character at the start of S, which