summaryrefslogtreecommitdiff
path: root/diffcore-pickaxe.c
diff options
context:
space:
mode:
Diffstat (limited to 'diffcore-pickaxe.c')
-rw-r--r--diffcore-pickaxe.c56
1 files changed, 36 insertions, 20 deletions
diff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c
index 7715c13ec4..341529b5a8 100644
--- a/diffcore-pickaxe.c
+++ b/diffcore-pickaxe.c
@@ -7,6 +7,8 @@
#include "diffcore.h"
#include "xdiff-interface.h"
#include "kwset.h"
+#include "commit.h"
+#include "quote.h"
typedef int (*pickaxe_fn)(mmfile_t *one, mmfile_t *two,
struct diff_options *o,
@@ -21,7 +23,6 @@ static void diffgrep_consume(void *priv, char *line, unsigned long len)
{
struct diffgrep_cb *data = priv;
regmatch_t regmatch;
- int hold;
if (line[0] != '+' && line[0] != '-')
return;
@@ -31,11 +32,8 @@ static void diffgrep_consume(void *priv, char *line, unsigned long len)
* caller early.
*/
return;
- /* Yuck -- line ought to be "const char *"! */
- hold = line[len];
- line[len] = '\0';
- data->hit = !regexec(data->regexp, line + 1, 1, &regmatch, 0);
- line[len] = hold;
+ data->hit = !regexec_buf(data->regexp, line + 1, len - 1, 1,
+ &regmatch, 0);
}
static int diff_grep(mmfile_t *one, mmfile_t *two,
@@ -48,9 +46,11 @@ static int diff_grep(mmfile_t *one, mmfile_t *two,
xdemitconf_t xecfg;
if (!one)
- return !regexec(regexp, two->ptr, 1, &regmatch, 0);
+ return !regexec_buf(regexp, two->ptr, two->size,
+ 1, &regmatch, 0);
if (!two)
- return !regexec(regexp, one->ptr, 1, &regmatch, 0);
+ return !regexec_buf(regexp, one->ptr, one->size,
+ 1, &regmatch, 0);
/*
* We have both sides; need to run textual diff and see if
@@ -81,12 +81,15 @@ static unsigned int contains(mmfile_t *mf, regex_t *regexp, kwset_t kws)
regmatch_t regmatch;
int flags = 0;
- assert(data[sz] == '\0');
- while (*data && !regexec(regexp, data, 1, &regmatch, flags)) {
+ while (sz && *data &&
+ !regexec_buf(regexp, data, sz, 1, &regmatch, flags)) {
flags |= REG_NOTBOL;
data += regmatch.rm_eo;
- if (*data && regmatch.rm_so == regmatch.rm_eo)
+ sz -= regmatch.rm_eo;
+ if (sz && *data && regmatch.rm_so == regmatch.rm_eo) {
data++;
+ sz--;
+ }
cnt++;
}
@@ -198,6 +201,18 @@ static void pickaxe(struct diff_queue_struct *q, struct diff_options *o,
*q = outq;
}
+static void regcomp_or_die(regex_t *regex, const char *needle, int cflags)
+{
+ int err = regcomp(regex, needle, cflags);
+ if (err) {
+ /* The POSIX.2 people are surely sick */
+ char errbuf[1024];
+ regerror(err, regex, errbuf, 1024);
+ regfree(regex);
+ die("invalid regex: %s", errbuf);
+ }
+}
+
void diffcore_pickaxe(struct diff_options *o)
{
const char *needle = o->pickaxe;
@@ -206,18 +221,19 @@ void diffcore_pickaxe(struct diff_options *o)
kwset_t kws = NULL;
if (opts & (DIFF_PICKAXE_REGEX | DIFF_PICKAXE_KIND_G)) {
- int err;
int cflags = REG_EXTENDED | REG_NEWLINE;
if (DIFF_OPT_TST(o, PICKAXE_IGNORE_CASE))
cflags |= REG_ICASE;
- err = regcomp(&regex, needle, cflags);
- if (err) {
- /* The POSIX.2 people are surely sick */
- char errbuf[1024];
- regerror(err, &regex, errbuf, 1024);
- regfree(&regex);
- die("invalid regex: %s", errbuf);
- }
+ regcomp_or_die(&regex, needle, cflags);
+ regexp = &regex;
+ } else if (DIFF_OPT_TST(o, PICKAXE_IGNORE_CASE) &&
+ has_non_ascii(needle)) {
+ struct strbuf sb = STRBUF_INIT;
+ int cflags = REG_NEWLINE | REG_ICASE;
+
+ basic_regex_quote_buf(&sb, needle);
+ regcomp_or_die(&regex, sb.buf, cflags);
+ strbuf_release(&sb);
regexp = &regex;
} else {
kws = kwsalloc(DIFF_OPT_TST(o, PICKAXE_IGNORE_CASE)