8
8
#include "xdiff-interface.h"
9
9
#include "kwset.h"
10
10
11
- typedef int (* pickaxe_fn )(struct diff_filepair * p , struct diff_options * o , regex_t * regexp , kwset_t kws );
11
+ typedef int (* pickaxe_fn )(mmfile_t * one , mmfile_t * two ,
12
+ struct diff_options * o ,
13
+ regex_t * regexp , kwset_t kws );
14
+
15
+ static int pickaxe_match (struct diff_filepair * p , struct diff_options * o ,
16
+ regex_t * regexp , kwset_t kws , pickaxe_fn fn );
12
17
13
18
static void pickaxe (struct diff_queue_struct * q , struct diff_options * o ,
14
19
regex_t * regexp , kwset_t kws , pickaxe_fn fn )
@@ -22,7 +27,7 @@ static void pickaxe(struct diff_queue_struct *q, struct diff_options *o,
22
27
/* Showing the whole changeset if needle exists */
23
28
for (i = 0 ; i < q -> nr ; i ++ ) {
24
29
struct diff_filepair * p = q -> queue [i ];
25
- if (fn (p , o , regexp , kws ))
30
+ if (pickaxe_match (p , o , regexp , kws , fn ))
26
31
return ; /* do not munge the queue */
27
32
}
28
33
@@ -37,7 +42,7 @@ static void pickaxe(struct diff_queue_struct *q, struct diff_options *o,
37
42
/* Showing only the filepairs that has the needle */
38
43
for (i = 0 ; i < q -> nr ; i ++ ) {
39
44
struct diff_filepair * p = q -> queue [i ];
40
- if (fn (p , o , regexp , kws ))
45
+ if (pickaxe_match (p , o , regexp , kws , fn ))
41
46
diff_q (& outq , p );
42
47
else
43
48
diff_free_filepair (p );
@@ -74,64 +79,33 @@ static void diffgrep_consume(void *priv, char *line, unsigned long len)
74
79
line [len ] = hold ;
75
80
}
76
81
77
- static void fill_one (struct diff_filespec * one ,
78
- mmfile_t * mf , struct userdiff_driver * * textconv )
79
- {
80
- if (DIFF_FILE_VALID (one )) {
81
- * textconv = get_textconv (one );
82
- mf -> size = fill_textconv (* textconv , one , & mf -> ptr );
83
- } else {
84
- memset (mf , 0 , sizeof (* mf ));
85
- }
86
- }
87
-
88
- static int diff_grep (struct diff_filepair * p , struct diff_options * o ,
82
+ static int diff_grep (mmfile_t * one , mmfile_t * two ,
83
+ struct diff_options * o ,
89
84
regex_t * regexp , kwset_t kws )
90
85
{
91
86
regmatch_t regmatch ;
92
- struct userdiff_driver * textconv_one = NULL ;
93
- struct userdiff_driver * textconv_two = NULL ;
94
- mmfile_t mf1 , mf2 ;
95
- int hit ;
87
+ struct diffgrep_cb ecbdata ;
88
+ xpparam_t xpp ;
89
+ xdemitconf_t xecfg ;
96
90
97
- if (diff_unmodified_pair (p ))
98
- return 0 ;
91
+ if (!one )
92
+ return !regexec (regexp , two -> ptr , 1 , & regmatch , 0 );
93
+ if (!two )
94
+ return !regexec (regexp , one -> ptr , 1 , & regmatch , 0 );
99
95
100
- fill_one (p -> one , & mf1 , & textconv_one );
101
- fill_one (p -> two , & mf2 , & textconv_two );
102
-
103
- if (!mf1 .ptr ) {
104
- if (!mf2 .ptr )
105
- return 0 ; /* ignore unmerged */
106
- /* created "two" -- does it have what we are looking for? */
107
- hit = !regexec (regexp , mf2 .ptr , 1 , & regmatch , 0 );
108
- } else if (!mf2 .ptr ) {
109
- /* removed "one" -- did it have what we are looking for? */
110
- hit = !regexec (regexp , mf1 .ptr , 1 , & regmatch , 0 );
111
- } else {
112
- /*
113
- * We have both sides; need to run textual diff and see if
114
- * the pattern appears on added/deleted lines.
115
- */
116
- struct diffgrep_cb ecbdata ;
117
- xpparam_t xpp ;
118
- xdemitconf_t xecfg ;
119
-
120
- memset (& xpp , 0 , sizeof (xpp ));
121
- memset (& xecfg , 0 , sizeof (xecfg ));
122
- ecbdata .regexp = regexp ;
123
- ecbdata .hit = 0 ;
124
- xecfg .ctxlen = o -> context ;
125
- xecfg .interhunkctxlen = o -> interhunkcontext ;
126
- xdi_diff_outf (& mf1 , & mf2 , diffgrep_consume , & ecbdata ,
127
- & xpp , & xecfg );
128
- hit = ecbdata .hit ;
129
- }
130
- if (textconv_one )
131
- free (mf1 .ptr );
132
- if (textconv_two )
133
- free (mf2 .ptr );
134
- return hit ;
96
+ /*
97
+ * We have both sides; need to run textual diff and see if
98
+ * the pattern appears on added/deleted lines.
99
+ */
100
+ memset (& xpp , 0 , sizeof (xpp ));
101
+ memset (& xecfg , 0 , sizeof (xecfg ));
102
+ ecbdata .regexp = regexp ;
103
+ ecbdata .hit = 0 ;
104
+ xecfg .ctxlen = o -> context ;
105
+ xecfg .interhunkctxlen = o -> interhunkcontext ;
106
+ xdi_diff_outf (one , two , diffgrep_consume , & ecbdata ,
107
+ & xpp , & xecfg );
108
+ return ecbdata .hit ;
135
109
}
136
110
137
111
static void diffcore_pickaxe_grep (struct diff_options * o )
@@ -198,17 +172,37 @@ static unsigned int contains(mmfile_t *mf, struct diff_options *o,
198
172
return cnt ;
199
173
}
200
174
201
- static int has_changes (struct diff_filepair * p , struct diff_options * o ,
175
+ static int has_changes (mmfile_t * one , mmfile_t * two ,
176
+ struct diff_options * o ,
202
177
regex_t * regexp , kwset_t kws )
203
178
{
204
- struct userdiff_driver * textconv_one = get_textconv (p -> one );
205
- struct userdiff_driver * textconv_two = get_textconv (p -> two );
179
+ if (!one )
180
+ return contains (two , o , regexp , kws ) != 0 ;
181
+ if (!two )
182
+ return contains (one , o , regexp , kws ) != 0 ;
183
+ return contains (one , o , regexp , kws ) != contains (two , o , regexp , kws );
184
+ }
185
+
186
+ static int pickaxe_match (struct diff_filepair * p , struct diff_options * o ,
187
+ regex_t * regexp , kwset_t kws , pickaxe_fn fn )
188
+ {
189
+ struct userdiff_driver * textconv_one = NULL ;
190
+ struct userdiff_driver * textconv_two = NULL ;
206
191
mmfile_t mf1 , mf2 ;
207
192
int ret ;
208
193
209
194
if (!o -> pickaxe [0 ])
210
195
return 0 ;
211
196
197
+ /* ignore unmerged */
198
+ if (!DIFF_FILE_VALID (p -> one ) && !DIFF_FILE_VALID (p -> two ))
199
+ return 0 ;
200
+
201
+ if (DIFF_OPT_TST (o , ALLOW_TEXTCONV )) {
202
+ textconv_one = get_textconv (p -> one );
203
+ textconv_two = get_textconv (p -> two );
204
+ }
205
+
212
206
/*
213
207
* If we have an unmodified pair, we know that the count will be the
214
208
* same and don't even have to load the blobs. Unless textconv is in
@@ -219,20 +213,12 @@ static int has_changes(struct diff_filepair *p, struct diff_options *o,
219
213
if (textconv_one == textconv_two && diff_unmodified_pair (p ))
220
214
return 0 ;
221
215
222
- fill_one ( p -> one , & mf1 , & textconv_one );
223
- fill_one ( p -> two , & mf2 , & textconv_two );
216
+ mf1 . size = fill_textconv ( textconv_one , p -> one , & mf1 . ptr );
217
+ mf2 . size = fill_textconv ( textconv_two , p -> two , & mf2 . ptr );
224
218
225
- if (!mf1 .ptr ) {
226
- if (!mf2 .ptr )
227
- ret = 0 ; /* ignore unmerged */
228
- /* created */
229
- ret = contains (& mf2 , o , regexp , kws ) != 0 ;
230
- }
231
- else if (!mf2 .ptr ) /* removed */
232
- ret = contains (& mf1 , o , regexp , kws ) != 0 ;
233
- else
234
- ret = contains (& mf1 , o , regexp , kws ) !=
235
- contains (& mf2 , o , regexp , kws );
219
+ ret = fn (DIFF_FILE_VALID (p -> one ) ? & mf1 : NULL ,
220
+ DIFF_FILE_VALID (p -> two ) ? & mf2 : NULL ,
221
+ o , regexp , kws );
236
222
237
223
if (textconv_one )
238
224
free (mf1 .ptr );
0 commit comments