git/xdiff-interface.c
Jonas Fonseca 83572c1a91 Use xrealloc instead of realloc
Change places that use realloc, without a proper error path, to instead use
xrealloc. Drop an erroneous error path in the daemon code that used errno
in the die message in favour of the simpler xrealloc.

Signed-off-by: Jonas Fonseca <fonseca@diku.dk>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-08-26 17:54:06 -07:00

105 lines
2.2 KiB
C

#include "cache.h"
#include "xdiff-interface.h"
static int parse_num(char **cp_p, int *num_p)
{
char *cp = *cp_p;
int num = 0;
int read_some;
while ('0' <= *cp && *cp <= '9')
num = num * 10 + *cp++ - '0';
if (!(read_some = cp - *cp_p))
return -1;
*cp_p = cp;
*num_p = num;
return 0;
}
int parse_hunk_header(char *line, int len,
int *ob, int *on,
int *nb, int *nn)
{
char *cp;
cp = line + 4;
if (parse_num(&cp, ob)) {
bad_line:
return error("malformed diff output: %s", line);
}
if (*cp == ',') {
cp++;
if (parse_num(&cp, on))
goto bad_line;
}
else
*on = 1;
if (*cp++ != ' ' || *cp++ != '+')
goto bad_line;
if (parse_num(&cp, nb))
goto bad_line;
if (*cp == ',') {
cp++;
if (parse_num(&cp, nn))
goto bad_line;
}
else
*nn = 1;
return -!!memcmp(cp, " @@", 3);
}
static void consume_one(void *priv_, char *s, unsigned long size)
{
struct xdiff_emit_state *priv = priv_;
char *ep;
while (size) {
unsigned long this_size;
ep = memchr(s, '\n', size);
this_size = (ep == NULL) ? size : (ep - s + 1);
priv->consume(priv, s, this_size);
size -= this_size;
s += this_size;
}
}
int xdiff_outf(void *priv_, mmbuffer_t *mb, int nbuf)
{
struct xdiff_emit_state *priv = priv_;
int i;
for (i = 0; i < nbuf; i++) {
if (mb[i].ptr[mb[i].size-1] != '\n') {
/* Incomplete line */
priv->remainder = xrealloc(priv->remainder,
priv->remainder_size +
mb[i].size);
memcpy(priv->remainder + priv->remainder_size,
mb[i].ptr, mb[i].size);
priv->remainder_size += mb[i].size;
continue;
}
/* we have a complete line */
if (!priv->remainder) {
consume_one(priv, mb[i].ptr, mb[i].size);
continue;
}
priv->remainder = xrealloc(priv->remainder,
priv->remainder_size +
mb[i].size);
memcpy(priv->remainder + priv->remainder_size,
mb[i].ptr, mb[i].size);
consume_one(priv, priv->remainder,
priv->remainder_size + mb[i].size);
free(priv->remainder);
priv->remainder = NULL;
priv->remainder_size = 0;
}
if (priv->remainder) {
consume_one(priv, priv->remainder, priv->remainder_size);
free(priv->remainder);
priv->remainder = NULL;
priv->remainder_size = 0;
}
return 0;
}