pickaxe: factor out pickaxe

Move the duplicate diff queue loop into its own function that accepts a match function: has_changes() for -S and diff_grep() for -G. Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>

René Scharfe committed Oct 6, 2011 at 18:50 UTC 8a94151d61eda539a3588f2ad009e0117867525f
1 file changed +43 -67
diffcore-pickaxe.c
+43 -67
@@ -8,6 +8,46 @@
8 #include "xdiff-interface.h"
9 #include "kwset.h"
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 +
51 struct diffgrep_cb {
52 regex_t *regexp;
53 int hit;
@@ -96,12 +136,8 @@ static int diff_grep(struct diff_filepair *p, struct diff_options *o,
136
137 static void diffcore_pickaxe_grep(struct diff_options *o)
138 {
99 - struct diff_queue_struct *q = &diff_queued_diff;
100 - int i, err;
139 + int err;
140 regex_t regex;
102 - struct diff_queue_struct outq;
103 - outq.queue = NULL;
104 - outq.nr = outq.alloc = 0;
141
142 err = regcomp(&regex, o->pickaxe, REG_EXTENDED | REG_NEWLINE);
143 if (err) {
@@ -111,36 +147,8 @@ static void diffcore_pickaxe_grep(struct diff_options *o)
147 die("invalid log-grep regex: %s", errbuf);
148 }
149
114 - if (o->pickaxe_opts & DIFF_PICKAXE_ALL) {
115 - /* Showing the whole changeset if needle exists */
116 - for (i = 0; i < q->nr; i++) {
117 - struct diff_filepair *p = q->queue[i];
118 - if (diff_grep(p, o, &regex, NULL))
119 - goto out; /* do not munge the queue */
120 - }
150 + pickaxe(&diff_queued_diff, o, &regex, NULL, diff_grep);
151
122 - /*
123 - * Otherwise we will clear the whole queue by copying
124 - * the empty outq at the end of this function, but
125 - * first clear the current entries in the queue.
126 - */
127 - for (i = 0; i < q->nr; i++)
128 - diff_free_filepair(q->queue[i]);
129 - } else {
130 - /* Showing only the filepairs that has the needle */
131 - for (i = 0; i < q->nr; i++) {
132 - struct diff_filepair *p = q->queue[i];
133 - if (diff_grep(p, o, &regex, NULL))
134 - diff_q(&outq, p);
135 - else
136 - diff_free_filepair(p);
137 - }
138 - }
139 -
140 - free(q->queue);
141 - *q = outq;
142 -
143 - out:
152 regfree(&regex);
153 return;
154 }
@@ -213,13 +221,9 @@ static void diffcore_pickaxe_count(struct diff_options *o)
221 {
222 const char *needle = o->pickaxe;
223 int opts = o->pickaxe_opts;
216 - struct diff_queue_struct *q = &diff_queued_diff;
224 unsigned long len = strlen(needle);
218 - int i;
225 regex_t regex, *regexp = NULL;
226 kwset_t kws = NULL;
221 - struct diff_queue_struct outq;
222 - DIFF_QUEUE_CLEAR(&outq);
227
228 if (opts & DIFF_PICKAXE_REGEX) {
229 int err;
@@ -238,36 +242,8 @@ static void diffcore_pickaxe_count(struct diff_options *o)
242 kwsprep(kws);
243 }
244
241 - if (opts & DIFF_PICKAXE_ALL) {
242 - /* Showing the whole changeset if needle exists */
243 - for (i = 0; i < q->nr; i++) {
244 - struct diff_filepair *p = q->queue[i];
245 - if (has_changes(p, o, regexp, kws))
246 - goto out; /* do not munge the queue */
247 - }
248 -
249 - /* otherwise we will clear the whole queue
250 - * by copying the empty outq at the end of this
251 - * function, but first clear the current entries
252 - * in the queue.
253 - */
254 - for (i = 0; i < q->nr; i++)
255 - diff_free_filepair(q->queue[i]);
256 - }
257 - else
258 - /* Showing only the filepairs that has the needle */
259 - for (i = 0; i < q->nr; i++) {
260 - struct diff_filepair *p = q->queue[i];
261 - if (has_changes(p, o, regexp, kws))
262 - diff_q(&outq, p);
263 - else
264 - diff_free_filepair(p);
265 - }
266 -
267 - free(q->queue);
268 - *q = outq;
245 + pickaxe(&diff_queued_diff, o, regexp, kws, has_changes);
246
270 - out:
247 if (opts & DIFF_PICKAXE_REGEX)
248 regfree(&regex);
249 else