aboutsummaryrefslogtreecommitdiff
path: root/diffcore-pickaxe.c
diff options
context:
space:
mode:
Diffstat (limited to 'diffcore-pickaxe.c')
-rw-r--r--diffcore-pickaxe.c27
1 files changed, 14 insertions, 13 deletions
diff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c
index 286919e71..d0ef83970 100644
--- a/diffcore-pickaxe.c
+++ b/diffcore-pickaxe.c
@@ -10,7 +10,7 @@ static unsigned int contains(struct diff_filespec *one,
regex_t *regexp)
{
unsigned int cnt;
- unsigned long offset, sz;
+ unsigned long sz;
const char *data;
if (diff_populate_filespec(one, 0))
return 0;
@@ -25,25 +25,26 @@ static unsigned int contains(struct diff_filespec *one,
regmatch_t regmatch;
int flags = 0;
+ assert(data[sz] == '\0');
while (*data && !regexec(regexp, data, 1, &regmatch, flags)) {
flags |= REG_NOTBOL;
- data += regmatch.rm_so;
- if (*data) data++;
+ data += regmatch.rm_eo;
+ if (*data && regmatch.rm_so == regmatch.rm_eo)
+ data++;
cnt++;
}
} else { /* Classic exact string match */
- /* Yes, I've heard of strstr(), but the thing is *data may
- * not be NUL terminated. Sue me.
- */
- for (offset = 0; offset + len <= sz; offset++) {
- /* we count non-overlapping occurrences of needle */
- if (!memcmp(needle, data + offset, len)) {
- offset += len - 1;
- cnt++;
- }
+ while (sz) {
+ const char *found = memmem(data, sz, needle, len);
+ if (!found)
+ break;
+ sz -= found - data + len;
+ data = found + len;
+ cnt++;
}
}
+ diff_free_filespec_data(one);
return cnt;
}
@@ -101,7 +102,7 @@ void diffcore_pickaxe(const char *needle, int opts)
for (i = 0; i < q->nr; i++)
diff_free_filepair(q->queue[i]);
}
- else
+ else
/* Showing only the filepairs that has the needle */
for (i = 0; i < q->nr; i++) {
struct diff_filepair *p = q->queue[i];