Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/grep.c
diff options
context:
space:
mode:
Diffstat (limited to 'grep.c')
-rw-r--r--grep.c51
1 files changed, 49 insertions, 2 deletions
diff --git a/grep.c b/grep.c
index 4468519d5c..fc0ed73ef3 100644
--- a/grep.c
+++ b/grep.c
@@ -356,6 +356,18 @@ static NORETURN void compile_regexp_failed(const struct grep_pat *p,
die("%s'%s': %s", where, p->pattern, error);
}
+static int is_fixed(const char *s, size_t len)
+{
+ size_t i;
+
+ for (i = 0; i < len; i++) {
+ if (is_regex_special(s[i]))
+ return 0;
+ }
+
+ return 1;
+}
+
#ifdef USE_LIBPCRE1
static void compile_pcre1_regexp(struct grep_pat *p, const struct grep_opt *opt)
{
@@ -602,7 +614,6 @@ static int pcre2match(struct grep_pat *p, const char *line, const char *eol,
static void free_pcre2_pattern(struct grep_pat *p)
{
}
-#endif /* !USE_LIBPCRE2 */
static void compile_fixed_regexp(struct grep_pat *p, struct grep_opt *opt)
{
@@ -623,11 +634,13 @@ static void compile_fixed_regexp(struct grep_pat *p, struct grep_opt *opt)
compile_regexp_failed(p, errbuf);
}
}
+#endif /* !USE_LIBPCRE2 */
static void compile_regexp(struct grep_pat *p, struct grep_opt *opt)
{
int err;
int regflags = REG_NEWLINE;
+ int pat_is_fixed;
p->word_regexp = opt->word_regexp;
p->ignore_case = opt->ignore_case;
@@ -636,8 +649,42 @@ static void compile_regexp(struct grep_pat *p, struct grep_opt *opt)
if (memchr(p->pattern, 0, p->patternlen) && !opt->pcre2)
die(_("given pattern contains NULL byte (via -f <file>). This is only supported with -P under PCRE v2"));
- if (opt->fixed) {
+ pat_is_fixed = is_fixed(p->pattern, p->patternlen);
+ if (opt->fixed || pat_is_fixed) {
+#ifdef USE_LIBPCRE2
+ opt->pcre2 = 1;
+ if (pat_is_fixed) {
+ compile_pcre2_pattern(p, opt);
+ } else {
+ /*
+ * E.g. t7811-grep-open.sh relies on the
+ * pattern being restored.
+ */
+ char *old_pattern = p->pattern;
+ size_t old_patternlen = p->patternlen;
+ struct strbuf sb = STRBUF_INIT;
+
+ /*
+ * There is the PCRE2_LITERAL flag, but it's
+ * only in PCRE v2 10.30 and later. Needing to
+ * ifdef our way around that and dealing with
+ * it + PCRE2_MULTILINE being an error is more
+ * complex than just quoting this ourselves.
+ */
+ strbuf_add(&sb, "\\Q", 2);
+ strbuf_add(&sb, p->pattern, p->patternlen);
+ strbuf_add(&sb, "\\E", 2);
+
+ p->pattern = sb.buf;
+ p->patternlen = sb.len;
+ compile_pcre2_pattern(p, opt);
+ p->pattern = old_pattern;
+ p->patternlen = old_patternlen;
+ strbuf_release(&sb);
+ }
+#else /* !USE_LIBPCRE2 */
compile_fixed_regexp(p, opt);
+#endif /* !USE_LIBPCRE2 */
return;
}