16
17
typedef int (*pickaxe_fn)(mmfile_t *one, mmfile_t *two,
18
struct diff_options *o,
19
- regex_t *regexp, kwset_t kws);
19
+ regex_t *regexp, kwset_t kws,
20
+ const struct range_set *ranges);
21
22
struct diffgrep_cb {
23
regex_t *regexp;
43
44
static int diff_grep(mmfile_t *one, mmfile_t *two,
45
struct diff_options *o,
45
- regex_t *regexp, kwset_t kws UNUSED)
46
+ regex_t *regexp, kwset_t kws UNUSED,
47
+ const struct range_set *ranges)
48
{
49
struct diffgrep_cb ecbdata;
50
xpparam_t xpp;
52
int ret;
53
54
/*
53
- * We have both sides; need to run textual diff and see if
54
- * the pattern appears on added/deleted lines.
55
+ * We have both sides; need to run textual diff and see if the
56
+ * pattern appears on added/deleted lines. Under -L (ranges set),
57
+ * forward only the tracked range's lines so the match is scoped.
58
+ * -G needs only a hit/no-hit answer, so the line-number bookkeeping
59
+ * the filter does for -L patch and check output is irrelevant here.
60
*/
61
memset(&xpp, 0, sizeof(xpp));
62
memset(&xecfg, 0, sizeof(xecfg));
70
* An xdiff error might be our "data->hit" from above. See the
71
* comment for xdiff_emit_line_fn in xdiff-interface.h
72
*/
68
- ret = xdi_diff_outf(one, two, NULL, diffgrep_consume,
69
- &ecbdata, &xpp, &xecfg);
73
+ if (ranges)
74
+ ret = diff_emit_line_ranges(one, two, ranges, diffgrep_consume,
75
+ &ecbdata, &xpp, &xecfg);
76
+ else
77
+ ret = xdi_diff_outf(one, two, NULL, diffgrep_consume,
78
+ &ecbdata, &xpp, &xecfg);
79
if (ecbdata.hit)
80
return 1;
81
if (ret)
128
129
static int has_changes(mmfile_t *one, mmfile_t *two,
130
struct diff_options *o UNUSED,
122
- regex_t *regexp, kwset_t kws)
131
+ regex_t *regexp, kwset_t kws,
132
+ const struct range_set *ranges UNUSED)
133
{
134
+ /*
135
+ * -S counts needle occurrences in each whole blob. Scoping this to
136
+ * a -L range is left to a follow-up; for now -S ignores the range.
137
+ */
138
unsigned int c1 = one ? contains(one, regexp, kws, 0) : 0;
139
unsigned int c2 = two ? contains(two, regexp, kws, c1 + 1) : 0;
140
return c1 != c2;
146
struct userdiff_driver *textconv_one = NULL;
147
struct userdiff_driver *textconv_two = NULL;
148
mmfile_t mf1, mf2;
149
+ const struct range_set *ranges;
150
int ret;
151
152
/* ignore unmerged */
184
mf1.size = fill_textconv(o->repo, textconv_one, p->one, &mf1.ptr);
185
mf2.size = fill_textconv(o->repo, textconv_two, p->two, &mf2.ptr);
186
172
- ret = fn(&mf1, &mf2, o, regexp, kws);
187
+ /*
188
+ * -L scopes the search to the tracked range, but the range is in
189
+ * original-file line coordinates that do not map onto textconv
190
+ * output, so search the whole file when textconv is in play.
191
+ */
192
+ ranges = (textconv_one || textconv_two) ? NULL : p->line_ranges;
193
+ ret = fn(&mf1, &mf2, o, regexp, kws, ranges);
194
195
if (textconv_one)
196
free(mf1.ptr);