0a66ded9533009a8efb840db5377f0abf5fccb1b
[git.git] / xdiff-interface.c
1 #include "cache.h"
2 #include "xdiff-interface.h"
3
4 static void consume_one(void *priv_, char *s, unsigned long size)
5 {
6         struct xdiff_emit_state *priv = priv_;
7         char *ep;
8         while (size) {
9                 unsigned long this_size;
10                 ep = memchr(s, '\n', size);
11                 this_size = (ep == NULL) ? size : (ep - s + 1);
12                 priv->consume(priv, s, this_size);
13                 size -= this_size;
14                 s += this_size;
15         }
16 }
17
18 int xdiff_outf(void *priv_, mmbuffer_t *mb, int nbuf)
19 {
20         struct xdiff_emit_state *priv = priv_;
21         int i;
22
23         for (i = 0; i < nbuf; i++) {
24                 if (mb[i].ptr[mb[i].size-1] != '\n') {
25                         /* Incomplete line */
26                         priv->remainder = realloc(priv->remainder,
27                                                   priv->remainder_size +
28                                                   mb[i].size);
29                         memcpy(priv->remainder + priv->remainder_size,
30                                mb[i].ptr, mb[i].size);
31                         priv->remainder_size += mb[i].size;
32                         continue;
33                 }
34
35                 /* we have a complete line */
36                 if (!priv->remainder) {
37                         consume_one(priv, mb[i].ptr, mb[i].size);
38                         continue;
39                 }
40                 priv->remainder = realloc(priv->remainder,
41                                           priv->remainder_size +
42                                           mb[i].size);
43                 memcpy(priv->remainder + priv->remainder_size,
44                        mb[i].ptr, mb[i].size);
45                 consume_one(priv, priv->remainder,
46                             priv->remainder_size + mb[i].size);
47                 free(priv->remainder);
48                 priv->remainder = NULL;
49                 priv->remainder_size = 0;
50         }
51         if (priv->remainder) {
52                 consume_one(priv, priv->remainder, priv->remainder_size);
53                 free(priv->remainder);
54                 priv->remainder = NULL;
55                 priv->remainder_size = 0;
56         }
57         return 0;
58 }