Git fork
at reftables-rust 129 lines 2.4 kB view raw
1/* 2 * Copyright (C) 2005 Junio C Hamano 3 */ 4 5#include "git-compat-util.h" 6#include "gettext.h" 7#include "diff.h" 8#include "diffcore.h" 9#include "wildmatch.h" 10 11static char **order; 12static int order_cnt; 13 14static void prepare_order(const char *orderfile) 15{ 16 int cnt, pass; 17 struct strbuf sb = STRBUF_INIT; 18 const char *cp, *endp; 19 ssize_t sz; 20 21 if (order) 22 return; 23 24 sz = strbuf_read_file(&sb, orderfile, 0); 25 if (sz < 0) 26 die_errno(_("failed to read orderfile '%s'"), orderfile); 27 endp = sb.buf + sz; 28 29 for (pass = 0; pass < 2; pass++) { 30 cnt = 0; 31 cp = sb.buf; 32 while (cp < endp) { 33 const char *ep; 34 for (ep = cp; ep < endp && *ep != '\n'; ep++) 35 ; 36 /* cp to ep has one line */ 37 if (*cp == '\n' || *cp == '#') 38 ; /* comment */ 39 else if (pass == 0) 40 cnt++; 41 else { 42 order[cnt] = xmemdupz(cp, ep - cp); 43 cnt++; 44 } 45 if (ep < endp) 46 ep++; 47 cp = ep; 48 } 49 if (pass == 0) { 50 order_cnt = cnt; 51 ALLOC_ARRAY(order, cnt); 52 } 53 } 54 55 strbuf_release(&sb); 56} 57 58static int match_order(const char *path) 59{ 60 int i; 61 static struct strbuf p = STRBUF_INIT; 62 63 for (i = 0; i < order_cnt; i++) { 64 strbuf_reset(&p); 65 strbuf_addstr(&p, path); 66 while (p.buf[0]) { 67 char *cp; 68 if (!wildmatch(order[i], p.buf, 0)) 69 return i; 70 cp = strrchr(p.buf, '/'); 71 if (!cp) 72 break; 73 *cp = 0; 74 } 75 } 76 return order_cnt; 77} 78 79static int compare_objs_order(const void *a_, const void *b_) 80{ 81 struct obj_order const *a, *b; 82 a = (struct obj_order const *)a_; 83 b = (struct obj_order const *)b_; 84 if (a->order != b->order) 85 return a->order - b->order; 86 return a->orig_order - b->orig_order; 87} 88 89void order_objects(const char *orderfile, obj_path_fn_t obj_path, 90 struct obj_order *objs, int nr) 91{ 92 int i; 93 94 if (!nr) 95 return; 96 97 prepare_order(orderfile); 98 for (i = 0; i < nr; i++) { 99 objs[i].orig_order = i; 100 objs[i].order = match_order(obj_path(objs[i].obj)); 101 } 102 QSORT(objs, nr, compare_objs_order); 103} 104 105static const char *pair_pathtwo(void *obj) 106{ 107 struct diff_filepair *pair = (struct diff_filepair *)obj; 108 109 return pair->two->path; 110} 111 112void diffcore_order(const char *orderfile) 113{ 114 struct diff_queue_struct *q = &diff_queued_diff; 115 struct obj_order *o; 116 int i; 117 118 if (!q->nr) 119 return; 120 121 ALLOC_ARRAY(o, q->nr); 122 for (i = 0; i < q->nr; i++) 123 o[i].obj = q->queue[i]; 124 order_objects(orderfile, pair_pathtwo, o, q->nr); 125 for (i = 0; i < q->nr; i++) 126 q->queue[i] = o[i].obj; 127 free(o); 128 return; 129}