Junio C Hamano | 52e9578 | 2005-05-21 02:40:01 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2005 Junio C Hamano |
| 3 | */ |
| 4 | #include "cache.h" |
| 5 | #include "diff.h" |
| 6 | #include "diffcore.h" |
Junio C Hamano | 52e9578 | 2005-05-21 02:40:01 -0700 | [diff] [blame] | 7 | |
Junio C Hamano | 2002eed | 2005-07-23 16:35:25 -0700 | [diff] [blame] | 8 | static unsigned int contains(struct diff_filespec *one, |
| 9 | const char *needle, unsigned long len) |
Junio C Hamano | 52e9578 | 2005-05-21 02:40:01 -0700 | [diff] [blame] | 10 | { |
Junio C Hamano | 2002eed | 2005-07-23 16:35:25 -0700 | [diff] [blame] | 11 | unsigned int cnt; |
Junio C Hamano | 52e9578 | 2005-05-21 02:40:01 -0700 | [diff] [blame] | 12 | unsigned long offset, sz; |
| 13 | const char *data; |
Junio C Hamano | f0c6b2a | 2005-05-27 15:56:38 -0700 | [diff] [blame] | 14 | if (diff_populate_filespec(one, 0)) |
Junio C Hamano | 52e9578 | 2005-05-21 02:40:01 -0700 | [diff] [blame] | 15 | return 0; |
Junio C Hamano | 2002eed | 2005-07-23 16:35:25 -0700 | [diff] [blame] | 16 | |
Junio C Hamano | 52e9578 | 2005-05-21 02:40:01 -0700 | [diff] [blame] | 17 | sz = one->size; |
| 18 | data = one->data; |
Junio C Hamano | 2002eed | 2005-07-23 16:35:25 -0700 | [diff] [blame] | 19 | cnt = 0; |
| 20 | |
| 21 | /* Yes, I've heard of strstr(), but the thing is *data may |
| 22 | * not be NUL terminated. Sue me. |
| 23 | */ |
| 24 | for (offset = 0; offset + len <= sz; offset++) { |
| 25 | /* we count non-overlapping occurrences of needle */ |
| 26 | if (!memcmp(needle, data + offset, len)) { |
| 27 | offset += len - 1; |
| 28 | cnt++; |
| 29 | } |
| 30 | } |
| 31 | return cnt; |
Junio C Hamano | 52e9578 | 2005-05-21 02:40:01 -0700 | [diff] [blame] | 32 | } |
| 33 | |
Junio C Hamano | 367cec1 | 2005-05-27 15:55:28 -0700 | [diff] [blame] | 34 | void diffcore_pickaxe(const char *needle, int opts) |
Junio C Hamano | 52e9578 | 2005-05-21 02:40:01 -0700 | [diff] [blame] | 35 | { |
Junio C Hamano | 38c6f78 | 2005-05-21 19:40:36 -0700 | [diff] [blame] | 36 | struct diff_queue_struct *q = &diff_queued_diff; |
Junio C Hamano | 52e9578 | 2005-05-21 02:40:01 -0700 | [diff] [blame] | 37 | unsigned long len = strlen(needle); |
Junio C Hamano | 367cec1 | 2005-05-27 15:55:28 -0700 | [diff] [blame] | 38 | int i, has_changes; |
Junio C Hamano | 52e9578 | 2005-05-21 02:40:01 -0700 | [diff] [blame] | 39 | struct diff_queue_struct outq; |
| 40 | outq.queue = NULL; |
| 41 | outq.nr = outq.alloc = 0; |
| 42 | |
Junio C Hamano | 367cec1 | 2005-05-27 15:55:28 -0700 | [diff] [blame] | 43 | if (opts & DIFF_PICKAXE_ALL) { |
| 44 | /* Showing the whole changeset if needle exists */ |
| 45 | for (i = has_changes = 0; !has_changes && i < q->nr; i++) { |
| 46 | struct diff_filepair *p = q->queue[i]; |
| 47 | if (!DIFF_FILE_VALID(p->one)) { |
| 48 | if (!DIFF_FILE_VALID(p->two)) |
| 49 | continue; /* ignore unmerged */ |
| 50 | /* created */ |
| 51 | if (contains(p->two, needle, len)) |
| 52 | has_changes++; |
| 53 | } |
| 54 | else if (!DIFF_FILE_VALID(p->two)) { |
| 55 | if (contains(p->one, needle, len)) |
| 56 | has_changes++; |
| 57 | } |
| 58 | else if (!diff_unmodified_pair(p) && |
| 59 | contains(p->one, needle, len) != |
| 60 | contains(p->two, needle, len)) |
| 61 | has_changes++; |
Junio C Hamano | 52e9578 | 2005-05-21 02:40:01 -0700 | [diff] [blame] | 62 | } |
Junio C Hamano | 367cec1 | 2005-05-27 15:55:28 -0700 | [diff] [blame] | 63 | if (has_changes) |
| 64 | return; /* not munge the queue */ |
| 65 | |
| 66 | /* otherwise we will clear the whole queue |
| 67 | * by copying the empty outq at the end of this |
| 68 | * function, but first clear the current entries |
| 69 | * in the queue. |
| 70 | */ |
| 71 | for (i = 0; i < q->nr; i++) |
| 72 | diff_free_filepair(q->queue[i]); |
Junio C Hamano | 52e9578 | 2005-05-21 02:40:01 -0700 | [diff] [blame] | 73 | } |
Junio C Hamano | 367cec1 | 2005-05-27 15:55:28 -0700 | [diff] [blame] | 74 | else |
| 75 | /* Showing only the filepairs that has the needle */ |
| 76 | for (i = 0; i < q->nr; i++) { |
| 77 | struct diff_filepair *p = q->queue[i]; |
| 78 | has_changes = 0; |
| 79 | if (!DIFF_FILE_VALID(p->one)) { |
| 80 | if (!DIFF_FILE_VALID(p->two)) |
| 81 | ; /* ignore unmerged */ |
| 82 | /* created */ |
| 83 | else if (contains(p->two, needle, len)) |
| 84 | has_changes = 1; |
| 85 | } |
| 86 | else if (!DIFF_FILE_VALID(p->two)) { |
| 87 | if (contains(p->one, needle, len)) |
| 88 | has_changes = 1; |
| 89 | } |
| 90 | else if (!diff_unmodified_pair(p) && |
| 91 | contains(p->one, needle, len) != |
| 92 | contains(p->two, needle, len)) |
| 93 | has_changes = 1; |
| 94 | |
| 95 | if (has_changes) |
| 96 | diff_q(&outq, p); |
| 97 | else |
| 98 | diff_free_filepair(p); |
| 99 | } |
| 100 | |
Junio C Hamano | 52e9578 | 2005-05-21 02:40:01 -0700 | [diff] [blame] | 101 | free(q->queue); |
| 102 | *q = outq; |
| 103 | return; |
| 104 | } |