diffcore-pathspec.con commit git-rev-parse: split "revs" and "non-revs" (8ebb018)
   1/*
   2 * Copyright (C) 2005 Junio C Hamano
   3 */
   4#include "cache.h"
   5#include "diff.h"
   6#include "diffcore.h"
   7
   8struct path_spec {
   9        const char *spec;
  10        int len;
  11};
  12
  13static int matches_pathspec(const char *name, struct path_spec *s, int cnt)
  14{
  15        int i;
  16        int namelen;
  17
  18        if (cnt == 0)
  19                return 1;
  20
  21        namelen = strlen(name);
  22        for (i = 0; i < cnt; i++) {
  23                int len = s[i].len;
  24                if (namelen < len)
  25                        continue;
  26                if (memcmp(s[i].spec, name, len))
  27                        continue;
  28                if (s[i].spec[len-1] == '/' ||
  29                    name[len] == 0 ||
  30                    name[len] == '/')
  31                        return 1;
  32        }
  33        return 0;
  34}
  35
  36void diffcore_pathspec(const char **pathspec)
  37{
  38        struct diff_queue_struct *q = &diff_queued_diff;
  39        int i, speccnt;
  40        struct diff_queue_struct outq;
  41        struct path_spec *spec;
  42
  43        outq.queue = NULL;
  44        outq.nr = outq.alloc = 0;
  45
  46        for (i = 0; pathspec[i]; i++)
  47                ;
  48        speccnt = i;
  49        spec = xmalloc(sizeof(*spec) * speccnt);
  50        for (i = 0; pathspec[i]; i++) {
  51                spec[i].spec = pathspec[i];
  52                spec[i].len = strlen(pathspec[i]);
  53        }
  54
  55        for (i = 0; i < q->nr; i++) {
  56                struct diff_filepair *p = q->queue[i];
  57                if (matches_pathspec(p->two->path, spec, speccnt))
  58                        diff_q(&outq, p);
  59                else
  60                        diff_free_filepair(p);
  61        }
  62        free(q->queue);
  63        *q = outq;
  64        return;
  65}