You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
124 lines
2.2 KiB
124 lines
2.2 KiB
/* |
|
* Copyright (C) 2005 Junio C Hamano |
|
*/ |
|
#include "cache.h" |
|
#include "diff.h" |
|
#include "diffcore.h" |
|
|
|
static char **order; |
|
static int order_cnt; |
|
|
|
static void prepare_order(const char *orderfile) |
|
{ |
|
int fd, cnt, pass; |
|
void *map; |
|
char *cp, *endp; |
|
struct stat st; |
|
size_t sz; |
|
|
|
if (order) |
|
return; |
|
|
|
fd = open(orderfile, O_RDONLY); |
|
if (fd < 0) |
|
return; |
|
if (fstat(fd, &st)) { |
|
close(fd); |
|
return; |
|
} |
|
sz = xsize_t(st.st_size); |
|
map = mmap(NULL, sz, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); |
|
close(fd); |
|
if (map == MAP_FAILED) |
|
return; |
|
endp = (char *) map + sz; |
|
for (pass = 0; pass < 2; pass++) { |
|
cnt = 0; |
|
cp = map; |
|
while (cp < endp) { |
|
char *ep; |
|
for (ep = cp; ep < endp && *ep != '\n'; ep++) |
|
; |
|
/* cp to ep has one line */ |
|
if (*cp == '\n' || *cp == '#') |
|
; /* comment */ |
|
else if (pass == 0) |
|
cnt++; |
|
else { |
|
if (*ep == '\n') { |
|
*ep = 0; |
|
order[cnt] = cp; |
|
} else { |
|
order[cnt] = xmemdupz(cp, ep - cp); |
|
} |
|
cnt++; |
|
} |
|
if (ep < endp) |
|
ep++; |
|
cp = ep; |
|
} |
|
if (pass == 0) { |
|
order_cnt = cnt; |
|
order = xmalloc(sizeof(*order) * cnt); |
|
} |
|
} |
|
} |
|
|
|
struct pair_order { |
|
struct diff_filepair *pair; |
|
int orig_order; |
|
int order; |
|
}; |
|
|
|
static int match_order(const char *path) |
|
{ |
|
int i; |
|
char p[PATH_MAX]; |
|
|
|
for (i = 0; i < order_cnt; i++) { |
|
strcpy(p, path); |
|
while (p[0]) { |
|
char *cp; |
|
if (!fnmatch(order[i], p, 0)) |
|
return i; |
|
cp = strrchr(p, '/'); |
|
if (!cp) |
|
break; |
|
*cp = 0; |
|
} |
|
} |
|
return order_cnt; |
|
} |
|
|
|
static int compare_pair_order(const void *a_, const void *b_) |
|
{ |
|
struct pair_order const *a, *b; |
|
a = (struct pair_order const *)a_; |
|
b = (struct pair_order const *)b_; |
|
if (a->order != b->order) |
|
return a->order - b->order; |
|
return a->orig_order - b->orig_order; |
|
} |
|
|
|
void diffcore_order(const char *orderfile) |
|
{ |
|
struct diff_queue_struct *q = &diff_queued_diff; |
|
struct pair_order *o; |
|
int i; |
|
|
|
if (!q->nr) |
|
return; |
|
|
|
o = xmalloc(sizeof(*o) * q->nr); |
|
prepare_order(orderfile); |
|
for (i = 0; i < q->nr; i++) { |
|
o[i].pair = q->queue[i]; |
|
o[i].orig_order = i; |
|
o[i].order = match_order(o[i].pair->two->path); |
|
} |
|
qsort(o, q->nr, sizeof(*o), compare_pair_order); |
|
for (i = 0; i < q->nr; i++) |
|
q->queue[i] = o[i].pair; |
|
free(o); |
|
return; |
|
}
|
|
|