Skip to content
Snippets Groups Projects
Select Git revision
  • 833e48259e23aea76f3765d28d1b2200332301f7
  • passt default
  • master
  • pu
  • todo
  • next
  • maint
  • v2.8.0-rc1
  • v2.8.0-rc0
  • v2.7.2
  • v2.7.1
  • v2.7.0
  • v2.6.5
  • v2.7.0-rc3
  • v2.7.0-rc2
  • v2.7.0-rc1
  • v2.7.0-rc0
  • v2.6.4
  • v2.6.3
  • v2.6.2
  • v2.6.1
  • v2.3.10
  • v2.5.4
  • v2.4.10
  • v2.6.0
  • v2.6.0-rc3
  • v2.5.3
27 results

diffcore-order.c

Blame
  • user avatar
    Junio C Hamano authored
    We started using wildmatch() in place of fnmatch(3); complete the
    process and stop using fnmatch(3).
    
    * nd/no-more-fnmatch:
      actually remove compat fnmatch source code
      stop using fnmatch (either native or compat)
      Revert "test-wildmatch: add "perf" command to compare wildmatch and fnmatch"
      use wildmatch() directly without fnmatch() wrapper
    650c90a1
    History
    diffcore-order.c 2.43 KiB
    /*
     * Copyright (C) 2005 Junio C Hamano
     */
    #include "cache.h"
    #include "diff.h"
    #include "diffcore.h"
    
    static char **order;
    static int order_cnt;
    
    static void prepare_order(const char *orderfile)
    {
    	int cnt, pass;
    	struct strbuf sb = STRBUF_INIT;
    	void *map;
    	char *cp, *endp;
    	ssize_t sz;
    
    	if (order)
    		return;
    
    	sz = strbuf_read_file(&sb, orderfile, 0);
    	if (sz < 0)
    		die_errno(_("failed to read orderfile '%s'"), orderfile);
    	map = strbuf_detach(&sb, NULL);
    	endp = (char *) map + sz;
    
    	for (pass = 0; pass < 2; pass++) {
    		cnt = 0;
    		cp = map;
    		while (cp < endp) {
    			char *ep;
    			for (ep = cp; ep < endp && *ep != '\n'; ep++)
    				;
    			/* cp to ep has one line */
    			if (*cp == '\n' || *cp == '#')
    				; /* comment */
    			else if (pass == 0)
    				cnt++;
    			else {
    				if (*ep == '\n') {
    					*ep = 0;
    					order[cnt] = cp;
    				} else {
    					order[cnt] = xmemdupz(cp, ep - cp);
    				}
    				cnt++;
    			}
    			if (ep < endp)
    				ep++;
    			cp = ep;
    		}
    		if (pass == 0) {
    			order_cnt = cnt;
    			order = xmalloc(sizeof(*order) * cnt);
    		}
    	}
    }
    
    static int match_order(const char *path)
    {
    	int i;
    	static struct strbuf p = STRBUF_INIT;
    
    	for (i = 0; i < order_cnt; i++) {
    		strbuf_reset(&p);
    		strbuf_addstr(&p, path);
    		while (p.buf[0]) {
    			char *cp;
    			if (!wildmatch(order[i], p.buf, 0, NULL))
    				return i;
    			cp = strrchr(p.buf, '/');
    			if (!cp)
    				break;
    			*cp = 0;
    		}
    	}
    	return order_cnt;
    }
    
    static int compare_objs_order(const void *a_, const void *b_)
    {
    	struct obj_order const *a, *b;
    	a = (struct obj_order const *)a_;
    	b = (struct obj_order const *)b_;
    	if (a->order != b->order)
    		return a->order - b->order;
    	return a->orig_order - b->orig_order;
    }
    
    void order_objects(const char *orderfile, obj_path_fn_t obj_path,
    		   struct obj_order *objs, int nr)
    {
    	int i;
    
    	if (!nr)
    		return;
    
    	prepare_order(orderfile);
    	for (i = 0; i < nr; i++) {
    		objs[i].orig_order = i;
    		objs[i].order = match_order(obj_path(objs[i].obj));
    	}
    	qsort(objs, nr, sizeof(*objs), compare_objs_order);
    }
    
    static const char *pair_pathtwo(void *obj)
    {
    	struct diff_filepair *pair = (struct diff_filepair *)obj;
    
    	return pair->two->path;
    }
    
    void diffcore_order(const char *orderfile)
    {
    	struct diff_queue_struct *q = &diff_queued_diff;
    	struct obj_order *o;
    	int i;
    
    	if (!q->nr)
    		return;
    
    	o = xmalloc(sizeof(*o) * q->nr);
    	for (i = 0; i < q->nr; i++)
    		o[i].obj = q->queue[i];
    	order_objects(orderfile, pair_pathtwo, o, q->nr);
    	for (i = 0; i < q->nr; i++)
    		q->queue[i] = o[i].obj;
    	free(o);
    	return;
    }