summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2021-11-14 08:12:59 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2021-11-14 12:13:28 -0800
commit50d5fbb7c3b0cc9e44c7166a75248877a8580b37 (patch)
tree74b1d08ec468d515a5a8631c667c819b927ef83b /src
parentc6283a2c922d3c35474a0cc77904a6216ff6cf83 (diff)
downloadgrep-50d5fbb7c3b0cc9e44c7166a75248877a8580b37.tar.gz
grep: use PCRE2_EXTRA_MATCH_LINE
* src/pcresearch.c (Pcompile): If available, use PCRE2_EXTRA_MATCH_LINE instead of doing it by hand. Simplify construction of substitute regular expression.
Diffstat (limited to 'src')
-rw-r--r--src/pcresearch.c54
1 files changed, 30 insertions, 24 deletions
diff --git a/src/pcresearch.c b/src/pcresearch.c
index fdecbe8c..6e1f2176 100644
--- a/src/pcresearch.c
+++ b/src/pcresearch.c
@@ -122,16 +122,8 @@ Pcompile (char *pattern, idx_t size, reg_syntax_t ignored, bool exact)
{
PCRE2_SIZE e;
int ec;
- static char const wprefix[] = "(?<!\\w)(?:";
- static char const wsuffix[] = ")(?!\\w)";
- static char const xprefix[] = "^(?:";
- static char const xsuffix[] = ")$";
- int fix_len_max = MAX (sizeof wprefix - 1 + sizeof wsuffix - 1,
- sizeof xprefix - 1 + sizeof xsuffix - 1);
- unsigned char *re = xmalloc (size + fix_len_max + 1);
int flags = PCRE2_DOLLAR_ENDONLY | (match_icase ? PCRE2_CASELESS : 0);
char *patlim = pattern + size;
- char *n = (char *)re;
struct pcre_comp *pc = xcalloc (1, sizeof (*pc));
pcre2_compile_context *ccontext = pcre2_compile_context_create (NULL);
@@ -154,27 +146,41 @@ Pcompile (char *pattern, idx_t size, reg_syntax_t ignored, bool exact)
if (rawmemchr (pattern, '\n') != patlim)
die (EXIT_TROUBLE, 0, _("the -P option only supports a single pattern"));
- *n = '\0';
- if (match_words)
- strcpy (n, wprefix);
+ void *re_storage = NULL;
if (match_lines)
- strcpy (n, xprefix);
- n += strlen (n);
- memcpy (n, pattern, size);
- n += size;
- if (match_words && !match_lines)
{
- strcpy (n, wsuffix);
- n += strlen (wsuffix);
+#ifdef PCRE2_EXTRA_MATCH_LINE
+ pcre2_set_compile_extra_options (ccontext, PCRE2_EXTRA_MATCH_LINE);
+#else
+ static char const /* These sizes omit trailing NUL. */
+ xprefix[4] = "^(?:", xsuffix[2] = ")$";
+ idx_t re_size = size + sizeof xprefix + sizeof xsuffix;
+ char *re = re_storage = ximalloc (re_size);
+ char *rez = mempcpy (re, xprefix, sizeof xprefix);
+ rez = mempcpy (rez, pattern, size);
+ memcpy (rez, xsuffix, sizeof xsuffix);
+ pattern = re;
+ size = re_size;
+#endif
}
- if (match_lines)
+ else if (match_words)
{
- strcpy (n, xsuffix);
- n += strlen (xsuffix);
+ /* PCRE2_EXTRA_MATCH_WORD is incompatible with grep -w;
+ do things the grep way. */
+ static char const /* These sizes omit trailing NUL. */
+ wprefix[10] = "(?<!\\w)(?:", wsuffix[7] = ")(?!\\w)";
+ idx_t re_size = size + sizeof wprefix + sizeof wsuffix;
+ char *re = re_storage = ximalloc (re_size);
+ char *rez = mempcpy (re, wprefix, sizeof wprefix);
+ rez = mempcpy (rez, pattern, size);
+ memcpy (rez, wsuffix, sizeof wsuffix);
+ pattern = re;
+ size = re_size;
}
pcre2_set_character_tables (ccontext, pcre2_maketables (NULL));
- pc->cre = pcre2_compile (re, n - (char *)re, flags, &ec, &e, ccontext);
+ pc->cre = pcre2_compile ((PCRE2_SPTR) pattern, size, flags,
+ &ec, &e, ccontext);
if (!pc->cre)
{
enum { ERRBUFSIZ = 256 }; /* Taken from pcre2grep.c ERRBUFSIZ. */
@@ -183,6 +189,8 @@ Pcompile (char *pattern, idx_t size, reg_syntax_t ignored, bool exact)
die (EXIT_TROUBLE, 0, "%s", ep);
}
+ free (re_storage);
+
pc->data = pcre2_match_data_create_from_pattern (pc->cre, NULL);
ec = pcre2_jit_compile (pc->cre, PCRE2_JIT_COMPLETE);
@@ -194,8 +202,6 @@ Pcompile (char *pattern, idx_t size, reg_syntax_t ignored, bool exact)
pc->jit_stack_size = 32 << 10;
}
- free (re);
-
pc->empty_match[false] = jit_exec (pc, "", 0, 0, PCRE2_NOTBOL);
pc->empty_match[true] = jit_exec (pc, "", 0, 0, 0);