Sync with 'maint'
[git/gitster.git] / diffcore-order.c
blob912513d3e67a9b277dd24a93992c456a061b196f
1 /*
2 * Copyright (C) 2005 Junio C Hamano
3 */
4 #include "git-compat-util.h"
5 #include "gettext.h"
6 #include "diff.h"
7 #include "diffcore.h"
8 #include "wildmatch.h"
10 static char **order;
11 static int order_cnt;
13 static void prepare_order(const char *orderfile)
15 int cnt, pass;
16 struct strbuf sb = STRBUF_INIT;
17 const char *cp, *endp;
18 ssize_t sz;
20 if (order)
21 return;
23 sz = strbuf_read_file(&sb, orderfile, 0);
24 if (sz < 0)
25 die_errno(_("failed to read orderfile '%s'"), orderfile);
26 endp = sb.buf + sz;
28 for (pass = 0; pass < 2; pass++) {
29 cnt = 0;
30 cp = sb.buf;
31 while (cp < endp) {
32 const char *ep;
33 for (ep = cp; ep < endp && *ep != '\n'; ep++)
35 /* cp to ep has one line */
36 if (*cp == '\n' || *cp == '#')
37 ; /* comment */
38 else if (pass == 0)
39 cnt++;
40 else {
41 order[cnt] = xmemdupz(cp, ep - cp);
42 cnt++;
44 if (ep < endp)
45 ep++;
46 cp = ep;
48 if (pass == 0) {
49 order_cnt = cnt;
50 ALLOC_ARRAY(order, cnt);
54 strbuf_release(&sb);
57 static int match_order(const char *path)
59 int i;
60 static struct strbuf p = STRBUF_INIT;
62 for (i = 0; i < order_cnt; i++) {
63 strbuf_reset(&p);
64 strbuf_addstr(&p, path);
65 while (p.buf[0]) {
66 char *cp;
67 if (!wildmatch(order[i], p.buf, 0))
68 return i;
69 cp = strrchr(p.buf, '/');
70 if (!cp)
71 break;
72 *cp = 0;
75 return order_cnt;
78 static int compare_objs_order(const void *a_, const void *b_)
80 struct obj_order const *a, *b;
81 a = (struct obj_order const *)a_;
82 b = (struct obj_order const *)b_;
83 if (a->order != b->order)
84 return a->order - b->order;
85 return a->orig_order - b->orig_order;
88 void order_objects(const char *orderfile, obj_path_fn_t obj_path,
89 struct obj_order *objs, int nr)
91 int i;
93 if (!nr)
94 return;
96 prepare_order(orderfile);
97 for (i = 0; i < nr; i++) {
98 objs[i].orig_order = i;
99 objs[i].order = match_order(obj_path(objs[i].obj));
101 QSORT(objs, nr, compare_objs_order);
104 static const char *pair_pathtwo(void *obj)
106 struct diff_filepair *pair = (struct diff_filepair *)obj;
108 return pair->two->path;
111 void diffcore_order(const char *orderfile)
113 struct diff_queue_struct *q = &diff_queued_diff;
114 struct obj_order *o;
115 int i;
117 if (!q->nr)
118 return;
120 ALLOC_ARRAY(o, q->nr);
121 for (i = 0; i < q->nr; i++)
122 o[i].obj = q->queue[i];
123 order_objects(orderfile, pair_pathtwo, o, q->nr);
124 for (i = 0; i < q->nr; i++)
125 q->queue[i] = o[i].obj;
126 free(o);
127 return;