Fix filehandle leak in "git branch -D"
[git/git-p4.git] / diffcore-order.c
blob2a4bd8232eb185f195c513c3509a72a92d172818
1 /*
2 * Copyright (C) 2005 Junio C Hamano
3 */
4 #include "cache.h"
5 #include "diff.h"
6 #include "diffcore.h"
8 static char **order;
9 static int order_cnt;
11 static void prepare_order(const char *orderfile)
13 int fd, cnt, pass;
14 void *map;
15 char *cp, *endp;
16 struct stat st;
17 size_t sz;
19 if (order)
20 return;
22 fd = open(orderfile, O_RDONLY);
23 if (fd < 0)
24 return;
25 if (fstat(fd, &st)) {
26 close(fd);
27 return;
29 sz = xsize_t(st.st_size);
30 map = mmap(NULL, sz, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
31 close(fd);
32 if (map == MAP_FAILED)
33 return;
34 endp = (char *) map + sz;
35 for (pass = 0; pass < 2; pass++) {
36 cnt = 0;
37 cp = map;
38 while (cp < endp) {
39 char *ep;
40 for (ep = cp; ep < endp && *ep != '\n'; ep++)
42 /* cp to ep has one line */
43 if (*cp == '\n' || *cp == '#')
44 ; /* comment */
45 else if (pass == 0)
46 cnt++;
47 else {
48 if (*ep == '\n') {
49 *ep = 0;
50 order[cnt] = cp;
52 else {
53 order[cnt] = xmalloc(ep-cp+1);
54 memcpy(order[cnt], cp, ep-cp);
55 order[cnt][ep-cp] = 0;
57 cnt++;
59 if (ep < endp)
60 ep++;
61 cp = ep;
63 if (pass == 0) {
64 order_cnt = cnt;
65 order = xmalloc(sizeof(*order) * cnt);
70 struct pair_order {
71 struct diff_filepair *pair;
72 int orig_order;
73 int order;
76 static int match_order(const char *path)
78 int i;
79 char p[PATH_MAX];
81 for (i = 0; i < order_cnt; i++) {
82 strcpy(p, path);
83 while (p[0]) {
84 char *cp;
85 if (!fnmatch(order[i], p, 0))
86 return i;
87 cp = strrchr(p, '/');
88 if (!cp)
89 break;
90 *cp = 0;
93 return order_cnt;
96 static int compare_pair_order(const void *a_, const void *b_)
98 struct pair_order const *a, *b;
99 a = (struct pair_order const *)a_;
100 b = (struct pair_order const *)b_;
101 if (a->order != b->order)
102 return a->order - b->order;
103 return a->orig_order - b->orig_order;
106 void diffcore_order(const char *orderfile)
108 struct diff_queue_struct *q = &diff_queued_diff;
109 struct pair_order *o;
110 int i;
112 if (!q->nr)
113 return;
115 o = xmalloc(sizeof(*o) * q->nr);
116 prepare_order(orderfile);
117 for (i = 0; i < q->nr; i++) {
118 o[i].pair = q->queue[i];
119 o[i].orig_order = i;
120 o[i].order = match_order(o[i].pair->two->path);
122 qsort(o, q->nr, sizeof(*o), compare_pair_order);
123 for (i = 0; i < q->nr; i++)
124 q->queue[i] = o[i].pair;
125 free(o);
126 return;