1/*2* Copyright (C) 2005 Junio C Hamano3*/4#include "cache.h"5#include "diff.h"6#include "diffcore.h"7#include <fnmatch.h>89static char **order;10static int order_cnt;1112static void prepare_order(const char *orderfile)13{14int fd, cnt, pass;15void *map;16char *cp, *endp;17struct stat st;1819if (order)20return;2122fd = open(orderfile, O_RDONLY);23if (fd < 0)24return;25if (fstat(fd, &st)) {26close(fd);27return;28}29map = mmap(NULL, st.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);30close(fd);31if (-1 == (int)(long)map)32return;33endp = map + st.st_size;34for (pass = 0; pass < 2; pass++) {35cnt = 0;36cp = map;37while (cp < endp) {38char *ep;39for (ep = cp; ep < endp && *ep != '\n'; ep++)40;41/* cp to ep has one line */42if (*cp == '\n' || *cp == '#')43; /* comment */44else if (pass == 0)45cnt++;46else {47if (*ep == '\n') {48*ep = 0;49order[cnt] = cp;50}51else {52order[cnt] = xmalloc(ep-cp+1);53memcpy(order[cnt], cp, ep-cp);54order[cnt][ep-cp] = 0;55}56cnt++;57}58if (ep < endp)59ep++;60cp = ep;61}62if (pass == 0) {63order_cnt = cnt;64order = xmalloc(sizeof(*order) * cnt);65}66}67}6869struct pair_order {70struct diff_filepair *pair;71int orig_order;72int order;73};7475static int match_order(const char *path)76{77int i;78char p[PATH_MAX];7980for (i = 0; i < order_cnt; i++) {81strcpy(p, path);82while (p[0]) {83char *cp;84if (!fnmatch(order[i], p, 0))85return i;86cp = strrchr(p, '/');87if (!cp)88break;89*cp = 0;90}91}92return order_cnt;93}9495static int compare_pair_order(const void *a_, const void *b_)96{97struct pair_order const *a, *b;98a = (struct pair_order const *)a_;99b = (struct pair_order const *)b_;100if (a->order != b->order)101return a->order - b->order;102return a->orig_order - b->orig_order;103}104105void diffcore_order(const char *orderfile)106{107struct diff_queue_struct *q = &diff_queued_diff;108struct pair_order *o = xmalloc(sizeof(*o) * q->nr);109int i;110111prepare_order(orderfile);112for (i = 0; i < q->nr; i++) {113o[i].pair = q->queue[i];114o[i].orig_order = i;115o[i].order = match_order(o[i].pair->two->path);116}117qsort(o, q->nr, sizeof(*o), compare_pair_order);118for (i = 0; i < q->nr; i++)119q->queue[i] = o[i].pair;120free(o);121return;122}