diffcore-order: export generic ordering interface
diffcore_order() interface only accepts a queue of `struct diff_filepair`. In the next patches, we'll want to order `struct combine_diff_path` by path, so let's first rework diffcore-order to also provide generic low-level interface for ordering arbitrary objects, provided they have path accessors. The new interface is: - `struct obj_order` for describing objects to ordering routine, and - order_objects() for actually doing the ordering work. Signed-off-by: Kirill Smelkov <kirr@mns.spb.ru> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Kirill Smelkov committed
Jan 20, 2014 at 20:20 UTC
1df4320fa25d3784b035936b35725460d46f1ca0
2 files changed
+46
-19
diffcore-order.c
+32
-19
@@ -57,12 +57,6 @@ static void prepare_order(const char *orderfile)
57
}
58
}
59
60
-struct pair_order {
61
- struct diff_filepair *pair;
62
- int orig_order;
63
- int order;
64
-};
65
-
60
static int match_order(const char *path)
61
{
62
int i;
@@ -84,35 +78,54 @@ static int match_order(const char *path)
78
return order_cnt;
79
}
80
87
-static int compare_pair_order(const void *a_, const void *b_)
81
+static int compare_objs_order(const void *a_, const void *b_)
82
{
89
- struct pair_order const *a, *b;
90
- a = (struct pair_order const *)a_;
91
- b = (struct pair_order const *)b_;
83
+ struct obj_order const *a, *b;
84
+ a = (struct obj_order const *)a_;
85
+ b = (struct obj_order const *)b_;
86
if (a->order != b->order)
87
return a->order - b->order;
88
return a->orig_order - b->orig_order;
89
}
90
91
+void order_objects(const char *orderfile, obj_path_fn_t obj_path,
92
+ struct obj_order *objs, int nr)
93
+{
94
+ int i;
95
+
96
+ if (!nr)
97
+ return;
98
+
99
+ prepare_order(orderfile);
100
+ for (i = 0; i < nr; i++) {
101
+ objs[i].orig_order = i;
102
+ objs[i].order = match_order(obj_path(objs[i].obj));
103
+ }
104
+ qsort(objs, nr, sizeof(*objs), compare_objs_order);
105
+}
106
+
107
+static const char *pair_pathtwo(void *obj)
108
+{
109
+ struct diff_filepair *pair = (struct diff_filepair *)obj;
110
+
111
+ return pair->two->path;
112
+}
113
+
114
void diffcore_order(const char *orderfile)
115
{
116
struct diff_queue_struct *q = &diff_queued_diff;
100
- struct pair_order *o;
117
+ struct obj_order *o;
118
int i;
119
120
if (!q->nr)
121
return;
122
123
o = xmalloc(sizeof(*o) * q->nr);
107
- prepare_order(orderfile);
108
- for (i = 0; i < q->nr; i++) {
109
- o[i].pair = q->queue[i];
110
- o[i].orig_order = i;
111
- o[i].order = match_order(o[i].pair->two->path);
112
- }
113
- qsort(o, q->nr, sizeof(*o), compare_pair_order);
124
for (i = 0; i < q->nr; i++)
115
- q->queue[i] = o[i].pair;
125
+ o[i].obj = q->queue[i];
126
+ order_objects(orderfile, pair_pathtwo, o, q->nr);
127
+ for (i = 0; i < q->nr; i++)
128
+ q->queue[i] = o[i].obj;
129
free(o);
130
return;
131
}
diffcore.h
+14
@@ -109,6 +109,20 @@ extern void diffcore_merge_broken(void);
109
extern void diffcore_pickaxe(struct diff_options *);
110
extern void diffcore_order(const char *orderfile);
111
112
+/* low-level interface to diffcore_order */
113
+struct obj_order {
114
+ void *obj; /* setup by caller */
115
+
116
+ /* setup/used by order_objects() */
117
+ int orig_order;
118
+ int order;
119
+};
120
+
121
+typedef const char *(*obj_path_fn_t)(void *obj);
122
+
123
+void order_objects(const char *orderfile, obj_path_fn_t obj_path,
124
+ struct obj_order *objs, int nr);
125
+
126
#define DIFF_DEBUG 0
127
#if DIFF_DEBUG
128
void diff_debug_filespec(struct diff_filespec *, int, const char *);