static int pickaxe_match(struct diff_filepair *p, struct diff_options *o, regex_t *regexp, kwset_t kws, pickaxe_fn fn) { struct userdiff_driver *textconv_one = NULL; struct userdiff_driver *textconv_two = NULL; mmfile_t mf1, mf2; int ret; /* ignore unmerged */ if (!DIFF_FILE_VALID(p->one) && !DIFF_FILE_VALID(p->two)) return 0; if (o->objfind) { return (DIFF_FILE_VALID(p->one) && oidset_contains(o->objfind, &p->one->oid)) || (DIFF_FILE_VALID(p->two) && oidset_contains(o->objfind, &p->two->oid)); } if (!o->pickaxe[0]) return 0; if (o->flags.allow_textconv) { textconv_one = get_textconv(o->repo->index, p->one); textconv_two = get_textconv(o->repo->index, p->two); } /* * If we have an unmodified pair, we know that the count will be the * same and don't even have to load the blobs. Unless textconv is in * play, _and_ we are using two different textconv filters (e.g., * because a pair is an exact rename with different textconv attributes * for each side, which might generate different content). */ if (textconv_one == textconv_two && diff_unmodified_pair(p)) return 0; mf1.size = fill_textconv(o->repo, textconv_one, p->one, &mf1.ptr); mf2.size = fill_textconv(o->repo, textconv_two, p->two, &mf2.ptr); ret = fn(DIFF_FILE_VALID(p->one) ? &mf1 : NULL, DIFF_FILE_VALID(p->two) ? &mf2 : NULL, o, regexp, kws); if (textconv_one) free(mf1.ptr); if (textconv_two) free(mf2.ptr); diff_free_filespec_data(p->one); diff_free_filespec_data(p->two); return ret; }
static unsigned int contains(struct diff_filespec *one, const char *needle, unsigned long len, regex_t *regexp) { unsigned int cnt; unsigned long sz; const char *data; if (diff_populate_filespec(one, 0)) return 0; if (!len) return 0; sz = one->size; data = one->data; cnt = 0; if (regexp) { regmatch_t regmatch; int flags = 0; assert(data[sz] == '\0'); while (*data && !regexec(regexp, data, 1, ®match, flags)) { flags |= REG_NOTBOL; data += regmatch.rm_eo; if (*data && regmatch.rm_so == regmatch.rm_eo) data++; cnt++; } } else { /* Classic exact string match */ 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; }