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 );
12
+
13
+ static void pickaxe (struct diff_queue_struct * q , struct diff_options * o ,
14
+ regex_t * regexp , kwset_t kws , pickaxe_fn fn )
15
+ {
16
+ int i ;
17
+ struct diff_queue_struct outq ;
18
+
19
+ DIFF_QUEUE_CLEAR (& outq );
20
+
21
+ if (o -> pickaxe_opts & DIFF_PICKAXE_ALL ) {
22
+ /* Showing the whole changeset if needle exists */
23
+ for (i = 0 ; i < q -> nr ; i ++ ) {
24
+ struct diff_filepair * p = q -> queue [i ];
25
+ if (fn (p , o , regexp , kws ))
26
+ return ; /* do not munge the queue */
27
+ }
28
+
29
+ /*
30
+ * Otherwise we will clear the whole queue by copying
31
+ * the empty outq at the end of this function, but
32
+ * first clear the current entries in the queue.
33
+ */
34
+ for (i = 0 ; i < q -> nr ; i ++ )
35
+ diff_free_filepair (q -> queue [i ]);
36
+ } else {
37
+ /* Showing only the filepairs that has the needle */
38
+ for (i = 0 ; i < q -> nr ; i ++ ) {
39
+ struct diff_filepair * p = q -> queue [i ];
40
+ if (fn (p , o , regexp , kws ))
41
+ diff_q (& outq , p );
42
+ else
43
+ diff_free_filepair (p );
44
+ }
45
+ }
46
+
47
+ free (q -> queue );
48
+ * q = outq ;
49
+ }
50
+
11
51
struct diffgrep_cb {
12
52
regex_t * regexp ;
13
53
int hit ;
@@ -45,7 +85,8 @@ static void fill_one(struct diff_filespec *one,
45
85
}
46
86
}
47
87
48
- static int diff_grep (struct diff_filepair * p , regex_t * regexp , struct diff_options * o )
88
+ static int diff_grep (struct diff_filepair * p , struct diff_options * o ,
89
+ regex_t * regexp , kwset_t kws )
49
90
{
50
91
regmatch_t regmatch ;
51
92
struct userdiff_driver * textconv_one = NULL ;
@@ -95,12 +136,8 @@ static int diff_grep(struct diff_filepair *p, regex_t *regexp, struct diff_optio
95
136
96
137
static void diffcore_pickaxe_grep (struct diff_options * o )
97
138
{
98
- struct diff_queue_struct * q = & diff_queued_diff ;
99
- int i , has_changes , err ;
139
+ int err ;
100
140
regex_t regex ;
101
- struct diff_queue_struct outq ;
102
- outq .queue = NULL ;
103
- outq .nr = outq .alloc = 0 ;
104
141
105
142
err = regcomp (& regex , o -> pickaxe , REG_EXTENDED | REG_NEWLINE );
106
143
if (err ) {
@@ -110,51 +147,21 @@ static void diffcore_pickaxe_grep(struct diff_options *o)
110
147
die ("invalid log-grep regex: %s" , errbuf );
111
148
}
112
149
113
- if (o -> pickaxe_opts & DIFF_PICKAXE_ALL ) {
114
- /* Showing the whole changeset if needle exists */
115
- for (i = has_changes = 0 ; !has_changes && i < q -> nr ; i ++ ) {
116
- struct diff_filepair * p = q -> queue [i ];
117
- if (diff_grep (p , & regex , o ))
118
- has_changes ++ ;
119
- }
120
- if (has_changes )
121
- return ; /* do not munge the queue */
122
-
123
- /*
124
- * Otherwise we will clear the whole queue by copying
125
- * the empty outq at the end of this function, but
126
- * first clear the current entries in the queue.
127
- */
128
- for (i = 0 ; i < q -> nr ; i ++ )
129
- diff_free_filepair (q -> queue [i ]);
130
- } else {
131
- /* Showing only the filepairs that has the needle */
132
- for (i = 0 ; i < q -> nr ; i ++ ) {
133
- struct diff_filepair * p = q -> queue [i ];
134
- if (diff_grep (p , & regex , o ))
135
- diff_q (& outq , p );
136
- else
137
- diff_free_filepair (p );
138
- }
139
- }
150
+ pickaxe (& diff_queued_diff , o , & regex , NULL , diff_grep );
140
151
141
152
regfree (& regex );
142
-
143
- free (q -> queue );
144
- * q = outq ;
145
153
return ;
146
154
}
147
155
148
- static unsigned int contains (struct diff_filespec * one ,
149
- const char * needle , unsigned long len ,
156
+ static unsigned int contains (struct diff_filespec * one , struct diff_options * o ,
150
157
regex_t * regexp , kwset_t kws )
151
158
{
152
159
unsigned int cnt ;
153
160
unsigned long sz ;
154
161
const char * data ;
155
- if (diff_populate_filespec ( one , 0 ) )
162
+ if (! o -> pickaxe [ 0 ] )
156
163
return 0 ;
157
- if (! len )
164
+ if (diff_populate_filespec ( one , 0 ) )
158
165
return 0 ;
159
166
160
167
sz = one -> size ;
@@ -176,32 +183,47 @@ static unsigned int contains(struct diff_filespec *one,
176
183
177
184
} else { /* Classic exact string match */
178
185
while (sz ) {
179
- size_t offset = kwsexec (kws , data , sz , NULL );
186
+ struct kwsmatch kwsm ;
187
+ size_t offset = kwsexec (kws , data , sz , & kwsm );
180
188
const char * found ;
181
189
if (offset == -1 )
182
190
break ;
183
191
else
184
192
found = data + offset ;
185
- sz -= found - data + len ;
186
- data = found + len ;
193
+ sz -= found - data + kwsm . size [ 0 ] ;
194
+ data = found + kwsm . size [ 0 ] ;
187
195
cnt ++ ;
188
196
}
189
197
}
190
198
diff_free_filespec_data (one );
191
199
return cnt ;
192
200
}
193
201
202
+ static int has_changes (struct diff_filepair * p , struct diff_options * o ,
203
+ regex_t * regexp , kwset_t kws )
204
+ {
205
+ if (!DIFF_FILE_VALID (p -> one )) {
206
+ if (!DIFF_FILE_VALID (p -> two ))
207
+ return 0 ; /* ignore unmerged */
208
+ /* created */
209
+ return contains (p -> two , o , regexp , kws ) != 0 ;
210
+ }
211
+ if (!DIFF_FILE_VALID (p -> two ))
212
+ return contains (p -> one , o , regexp , kws ) != 0 ;
213
+ if (!diff_unmodified_pair (p )) {
214
+ return contains (p -> one , o , regexp , kws ) !=
215
+ contains (p -> two , o , regexp , kws );
216
+ }
217
+ return 0 ;
218
+ }
219
+
194
220
static void diffcore_pickaxe_count (struct diff_options * o )
195
221
{
196
222
const char * needle = o -> pickaxe ;
197
223
int opts = o -> pickaxe_opts ;
198
- struct diff_queue_struct * q = & diff_queued_diff ;
199
224
unsigned long len = strlen (needle );
200
- int i , has_changes ;
201
225
regex_t regex , * regexp = NULL ;
202
226
kwset_t kws = NULL ;
203
- struct diff_queue_struct outq ;
204
- DIFF_QUEUE_CLEAR (& outq );
205
227
206
228
if (opts & DIFF_PICKAXE_REGEX ) {
207
229
int err ;
@@ -220,72 +242,12 @@ static void diffcore_pickaxe_count(struct diff_options *o)
220
242
kwsprep (kws );
221
243
}
222
244
223
- if (opts & DIFF_PICKAXE_ALL ) {
224
- /* Showing the whole changeset if needle exists */
225
- for (i = has_changes = 0 ; !has_changes && i < q -> nr ; i ++ ) {
226
- struct diff_filepair * p = q -> queue [i ];
227
- if (!DIFF_FILE_VALID (p -> one )) {
228
- if (!DIFF_FILE_VALID (p -> two ))
229
- continue ; /* ignore unmerged */
230
- /* created */
231
- if (contains (p -> two , needle , len , regexp , kws ))
232
- has_changes ++ ;
233
- }
234
- else if (!DIFF_FILE_VALID (p -> two )) {
235
- if (contains (p -> one , needle , len , regexp , kws ))
236
- has_changes ++ ;
237
- }
238
- else if (!diff_unmodified_pair (p ) &&
239
- contains (p -> one , needle , len , regexp , kws ) !=
240
- contains (p -> two , needle , len , regexp , kws ))
241
- has_changes ++ ;
242
- }
243
- if (has_changes )
244
- return ; /* not munge the queue */
245
-
246
- /* otherwise we will clear the whole queue
247
- * by copying the empty outq at the end of this
248
- * function, but first clear the current entries
249
- * in the queue.
250
- */
251
- for (i = 0 ; i < q -> nr ; i ++ )
252
- diff_free_filepair (q -> queue [i ]);
253
- }
254
- else
255
- /* Showing only the filepairs that has the needle */
256
- for (i = 0 ; i < q -> nr ; i ++ ) {
257
- struct diff_filepair * p = q -> queue [i ];
258
- has_changes = 0 ;
259
- if (!DIFF_FILE_VALID (p -> one )) {
260
- if (!DIFF_FILE_VALID (p -> two ))
261
- ; /* ignore unmerged */
262
- /* created */
263
- else if (contains (p -> two , needle , len , regexp ,
264
- kws ))
265
- has_changes = 1 ;
266
- }
267
- else if (!DIFF_FILE_VALID (p -> two )) {
268
- if (contains (p -> one , needle , len , regexp , kws ))
269
- has_changes = 1 ;
270
- }
271
- else if (!diff_unmodified_pair (p ) &&
272
- contains (p -> one , needle , len , regexp , kws ) !=
273
- contains (p -> two , needle , len , regexp , kws ))
274
- has_changes = 1 ;
275
-
276
- if (has_changes )
277
- diff_q (& outq , p );
278
- else
279
- diff_free_filepair (p );
280
- }
245
+ pickaxe (& diff_queued_diff , o , regexp , kws , has_changes );
281
246
282
247
if (opts & DIFF_PICKAXE_REGEX )
283
248
regfree (& regex );
284
249
else
285
250
kwsfree (kws );
286
-
287
- free (q -> queue );
288
- * q = outq ;
289
251
return ;
290
252
}
291
253
0 commit comments