1#include "cache.h"2#include "xdiff-interface.h"34static int parse_num(char **cp_p, int *num_p)5{6char *cp = *cp_p;7int num = 0;8int read_some;910while ('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}1819int 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}34else35*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}45else46*nn = 1;47return -!!memcmp(cp, " @@", 3);48}4950static 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}6364int xdiff_outf(void *priv_, mmbuffer_t *mb, int nbuf)65{66struct xdiff_emit_state *priv = priv_;67int i;6869for (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}105106int read_mmfile(mmfile_t *ptr, const char *filename)107{108struct stat st;109FILE *f;110size_t sz;111112if (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 8000126int 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}