88#include "xdiff-interface.h"
99#include "kwset.h"
1010
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 );
1217
1318static void pickaxe (struct diff_queue_struct * q , struct diff_options * o ,
1419 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,
2227 /* Showing the whole changeset if needle exists */
2328 for (i = 0 ; i < q -> nr ; i ++ ) {
2429 struct diff_filepair * p = q -> queue [i ];
25- if (fn (p , o , regexp , kws ))
30+ if (pickaxe_match (p , o , regexp , kws , fn ))
2631 return ; /* do not munge the queue */
2732 }
2833
@@ -37,7 +42,7 @@ static void pickaxe(struct diff_queue_struct *q, struct diff_options *o,
3742 /* Showing only the filepairs that has the needle */
3843 for (i = 0 ; i < q -> nr ; i ++ ) {
3944 struct diff_filepair * p = q -> queue [i ];
40- if (fn (p , o , regexp , kws ))
45+ if (pickaxe_match (p , o , regexp , kws , fn ))
4146 diff_q (& outq , p );
4247 else
4348 diff_free_filepair (p );
@@ -74,64 +79,33 @@ static void diffgrep_consume(void *priv, char *line, unsigned long len)
7479 line [len ] = hold ;
7580}
7681
77- 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 ,
7884 regex_t * regexp , kwset_t kws )
7985{
8086 regmatch_t regmatch ;
81- struct userdiff_driver * textconv_one = NULL ;
82- struct userdiff_driver * textconv_two = NULL ;
83- mmfile_t mf1 , mf2 ;
84- int hit ;
87+ struct diffgrep_cb ecbdata ;
88+ xpparam_t xpp ;
89+ xdemitconf_t xecfg ;
8590
86- if (!o -> pickaxe [0 ])
87- 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 );
8895
89- if (DIFF_OPT_TST (o , ALLOW_TEXTCONV )) {
90- textconv_one = get_textconv (p -> one );
91- textconv_two = get_textconv (p -> two );
92- }
93-
94- if (textconv_one == textconv_two && diff_unmodified_pair (p ))
95- return 0 ;
96-
97- mf1 .size = fill_textconv (textconv_one , p -> one , & mf1 .ptr );
98- mf2 .size = fill_textconv (textconv_two , p -> two , & mf2 .ptr );
99-
100- if (!DIFF_FILE_VALID (p -> one )) {
101- if (!DIFF_FILE_VALID (p -> two ))
102- hit = 0 ; /* ignore unmerged */
103- else
104- /* created "two" -- does it have what we are looking for? */
105- hit = !regexec (regexp , mf2 .ptr , 1 , & regmatch , 0 );
106- } else if (!DIFF_FILE_VALID (p -> two )) {
107- /* removed "one" -- did it have what we are looking for? */
108- hit = !regexec (regexp , mf1 .ptr , 1 , & regmatch , 0 );
109- } else {
110- /*
111- * We have both sides; need to run textual diff and see if
112- * the pattern appears on added/deleted lines.
113- */
114- struct diffgrep_cb ecbdata ;
115- xpparam_t xpp ;
116- xdemitconf_t xecfg ;
117-
118- memset (& xpp , 0 , sizeof (xpp ));
119- memset (& xecfg , 0 , sizeof (xecfg ));
120- ecbdata .regexp = regexp ;
121- ecbdata .hit = 0 ;
122- xecfg .ctxlen = o -> context ;
123- xecfg .interhunkctxlen = o -> interhunkcontext ;
124- xdi_diff_outf (& mf1 , & mf2 , diffgrep_consume , & ecbdata ,
125- & xpp , & xecfg );
126- hit = ecbdata .hit ;
127- }
128- if (textconv_one )
129- free (mf1 .ptr );
130- if (textconv_two )
131- free (mf2 .ptr );
132- diff_free_filespec_data (p -> one );
133- diff_free_filespec_data (p -> two );
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 ;
135109}
136110
137111static void diffcore_pickaxe_grep (struct diff_options * o )
@@ -198,8 +172,19 @@ static unsigned int contains(mmfile_t *mf, struct diff_options *o,
198172 return cnt ;
199173}
200174
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 ,
202177 regex_t * regexp , kwset_t kws )
178+ {
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 )
203188{
204189 struct userdiff_driver * textconv_one = NULL ;
205190 struct userdiff_driver * textconv_two = NULL ;
@@ -209,6 +194,10 @@ static int has_changes(struct diff_filepair *p, struct diff_options *o,
209194 if (!o -> pickaxe [0 ])
210195 return 0 ;
211196
197+ /* ignore unmerged */
198+ if (!DIFF_FILE_VALID (p -> one ) && !DIFF_FILE_VALID (p -> two ))
199+ return 0 ;
200+
212201 if (DIFF_OPT_TST (o , ALLOW_TEXTCONV )) {
213202 textconv_one = get_textconv (p -> one );
214203 textconv_two = get_textconv (p -> two );
@@ -227,18 +216,9 @@ static int has_changes(struct diff_filepair *p, struct diff_options *o,
227216 mf1 .size = fill_textconv (textconv_one , p -> one , & mf1 .ptr );
228217 mf2 .size = fill_textconv (textconv_two , p -> two , & mf2 .ptr );
229218
230- if (!DIFF_FILE_VALID (p -> one )) {
231- if (!DIFF_FILE_VALID (p -> two ))
232- ret = 0 ; /* ignore unmerged */
233- else
234- /* created */
235- ret = contains (& mf2 , o , regexp , kws ) != 0 ;
236- }
237- else if (!DIFF_FILE_VALID (p -> two )) /* removed */
238- ret = contains (& mf1 , o , regexp , kws ) != 0 ;
239- else
240- ret = contains (& mf1 , o , regexp , kws ) !=
241- 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 );
242222
243223 if (textconv_one )
244224 free (mf1 .ptr );
0 commit comments