1#include "cache.h"
2#include "xdiff-interface.h"
34
static int parse_num(char **cp_p, int *num_p)
5{
6char *cp = *cp_p;
7int num = 0;
8int read_some;
910
while ('0' <= *cp && *cp <= '9')
11num = num * 10 + *cp++ - '0';
12if (!(read_some = cp - *cp_p))
13return -1;
14*cp_p = cp;
15*num_p = num;
16return 0;
17}
1819
int parse_hunk_header(char *line, int len,
20int *ob, int *on,
21int *nb, int *nn)
22{
23char *cp;
24cp = line + 4;
25if (parse_num(&cp, ob)) {
26bad_line:
27return error("malformed diff output: %s", line);
28}
29if (*cp == ',') {
30cp++;
31if (parse_num(&cp, on))
32goto bad_line;
33}
34else
35*on = 1;
36if (*cp++ != ' ' || *cp++ != '+')
37goto bad_line;
38if (parse_num(&cp, nb))
39goto bad_line;
40if (*cp == ',') {
41cp++;
42if (parse_num(&cp, nn))
43goto bad_line;
44}
45else
46*nn = 1;
47return -!!memcmp(cp, " @@", 3);
48}
4950
static void consume_one(void *priv_, char *s, unsigned long size)
51{
52struct xdiff_emit_state *priv = priv_;
53char *ep;
54while (size) {
55unsigned long this_size;
56ep = memchr(s, '\n', size);
57this_size = (ep == NULL) ? size : (ep - s + 1);
58priv->consume(priv, s, this_size);
59size -= this_size;
60s += this_size;
61}
62}
6364
int xdiff_outf(void *priv_, mmbuffer_t *mb, int nbuf)
65{
66struct xdiff_emit_state *priv = priv_;
67int i;
6869
for (i = 0; i < nbuf; i++) {
70if (mb[i].ptr[mb[i].size-1] != '\n') {
71/* Incomplete line */
72priv->remainder = xrealloc(priv->remainder,
73priv->remainder_size +
74mb[i].size);
75memcpy(priv->remainder + priv->remainder_size,
76mb[i].ptr, mb[i].size);
77priv->remainder_size += mb[i].size;
78continue;
79}
8081
/* we have a complete line */
82if (!priv->remainder) {
83consume_one(priv, mb[i].ptr, mb[i].size);
84continue;
85}
86priv->remainder = xrealloc(priv->remainder,
87priv->remainder_size +
88mb[i].size);
89memcpy(priv->remainder + priv->remainder_size,
90mb[i].ptr, mb[i].size);
91consume_one(priv, priv->remainder,
92priv->remainder_size + mb[i].size);
93free(priv->remainder);
94priv->remainder = NULL;
95priv->remainder_size = 0;
96}
97if (priv->remainder) {
98consume_one(priv, priv->remainder, priv->remainder_size);
99free(priv->remainder);
100priv->remainder = NULL;
101priv->remainder_size = 0;
102}
103return 0;
104}
105106
int read_mmfile(mmfile_t *ptr, const char *filename)
107{
108struct stat st;
109FILE *f;
110size_t sz;
111112
if (stat(filename, &st))
113return error("Could not stat %s", filename);
114if ((f = fopen(filename, "rb")) == NULL)
115return error("Could not open %s", filename);
116sz = xsize_t(st.st_size);
117ptr->ptr = xmalloc(sz);
118if (fread(ptr->ptr, sz, 1, f) != 1)
119return error("Could not read %s", filename);
120fclose(f);
121ptr->size = sz;
122return 0;
123}
124125
#define FIRST_FEW_BYTES 8000
126int buffer_is_binary(const char *ptr, unsigned long size)
127{
128if (FIRST_FEW_BYTES < size)
129size = FIRST_FEW_BYTES;
130return !!memchr(ptr, 0, size);
131}