Junio C Hamano | d9ea73e | 2006-04-05 02:03:58 -0700 | [diff] [blame] | 1 | #include "cache.h" |
| 2 | #include "xdiff-interface.h" |
| 3 | |
Junio C Hamano | a0fd314 | 2006-04-06 22:29:55 -0700 | [diff] [blame] | 4 | static int parse_num(char **cp_p, int *num_p) |
Junio C Hamano | c1e335a | 2006-04-05 12:22:35 -0700 | [diff] [blame] | 5 | { |
| 6 | char *cp = *cp_p; |
Junio C Hamano | a0fd314 | 2006-04-06 22:29:55 -0700 | [diff] [blame] | 7 | int num = 0; |
Junio C Hamano | c1e335a | 2006-04-05 12:22:35 -0700 | [diff] [blame] | 8 | int read_some; |
| 9 | |
| 10 | while ('0' <= *cp && *cp <= '9') |
| 11 | num = num * 10 + *cp++ - '0'; |
| 12 | if (!(read_some = cp - *cp_p)) |
| 13 | return -1; |
| 14 | *cp_p = cp; |
| 15 | *num_p = num; |
| 16 | return 0; |
| 17 | } |
| 18 | |
| 19 | int parse_hunk_header(char *line, int len, |
Junio C Hamano | a0fd314 | 2006-04-06 22:29:55 -0700 | [diff] [blame] | 20 | int *ob, int *on, |
| 21 | int *nb, int *nn) |
Junio C Hamano | c1e335a | 2006-04-05 12:22:35 -0700 | [diff] [blame] | 22 | { |
| 23 | char *cp; |
| 24 | cp = line + 4; |
| 25 | if (parse_num(&cp, ob)) { |
| 26 | bad_line: |
| 27 | return error("malformed diff output: %s", line); |
| 28 | } |
| 29 | if (*cp == ',') { |
| 30 | cp++; |
| 31 | if (parse_num(&cp, on)) |
| 32 | goto bad_line; |
| 33 | } |
| 34 | else |
| 35 | *on = 1; |
| 36 | if (*cp++ != ' ' || *cp++ != '+') |
| 37 | goto bad_line; |
| 38 | if (parse_num(&cp, nb)) |
| 39 | goto bad_line; |
| 40 | if (*cp == ',') { |
| 41 | cp++; |
| 42 | if (parse_num(&cp, nn)) |
| 43 | goto bad_line; |
| 44 | } |
| 45 | else |
| 46 | *nn = 1; |
| 47 | return -!!memcmp(cp, " @@", 3); |
| 48 | } |
| 49 | |
Junio C Hamano | d9ea73e | 2006-04-05 02:03:58 -0700 | [diff] [blame] | 50 | static void consume_one(void *priv_, char *s, unsigned long size) |
| 51 | { |
| 52 | struct xdiff_emit_state *priv = priv_; |
| 53 | char *ep; |
| 54 | while (size) { |
| 55 | unsigned long this_size; |
| 56 | ep = memchr(s, '\n', size); |
| 57 | this_size = (ep == NULL) ? size : (ep - s + 1); |
| 58 | priv->consume(priv, s, this_size); |
| 59 | size -= this_size; |
| 60 | s += this_size; |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | int xdiff_outf(void *priv_, mmbuffer_t *mb, int nbuf) |
| 65 | { |
| 66 | struct xdiff_emit_state *priv = priv_; |
| 67 | int i; |
| 68 | |
| 69 | for (i = 0; i < nbuf; i++) { |
| 70 | if (mb[i].ptr[mb[i].size-1] != '\n') { |
| 71 | /* Incomplete line */ |
Jonas Fonseca | 83572c1 | 2006-08-26 16:16:18 +0200 | [diff] [blame] | 72 | priv->remainder = xrealloc(priv->remainder, |
| 73 | priv->remainder_size + |
| 74 | mb[i].size); |
Junio C Hamano | d9ea73e | 2006-04-05 02:03:58 -0700 | [diff] [blame] | 75 | memcpy(priv->remainder + priv->remainder_size, |
| 76 | mb[i].ptr, mb[i].size); |
| 77 | priv->remainder_size += mb[i].size; |
| 78 | continue; |
| 79 | } |
| 80 | |
| 81 | /* we have a complete line */ |
| 82 | if (!priv->remainder) { |
| 83 | consume_one(priv, mb[i].ptr, mb[i].size); |
| 84 | continue; |
| 85 | } |
Jonas Fonseca | 83572c1 | 2006-08-26 16:16:18 +0200 | [diff] [blame] | 86 | priv->remainder = xrealloc(priv->remainder, |
| 87 | priv->remainder_size + |
| 88 | mb[i].size); |
Junio C Hamano | d9ea73e | 2006-04-05 02:03:58 -0700 | [diff] [blame] | 89 | memcpy(priv->remainder + priv->remainder_size, |
| 90 | mb[i].ptr, mb[i].size); |
| 91 | consume_one(priv, priv->remainder, |
| 92 | priv->remainder_size + mb[i].size); |
| 93 | free(priv->remainder); |
| 94 | priv->remainder = NULL; |
| 95 | priv->remainder_size = 0; |
| 96 | } |
| 97 | if (priv->remainder) { |
| 98 | consume_one(priv, priv->remainder, priv->remainder_size); |
| 99 | free(priv->remainder); |
| 100 | priv->remainder = NULL; |
| 101 | priv->remainder_size = 0; |
| 102 | } |
| 103 | return 0; |
| 104 | } |
Johannes Schindelin | 7cab588 | 2006-12-20 17:37:07 +0100 | [diff] [blame] | 105 | |
| 106 | int read_mmfile(mmfile_t *ptr, const char *filename) |
| 107 | { |
| 108 | struct stat st; |
| 109 | FILE *f; |
Shawn O. Pearce | dc49cd7 | 2007-03-06 20:44:37 -0500 | [diff] [blame^] | 110 | size_t sz; |
Johannes Schindelin | 7cab588 | 2006-12-20 17:37:07 +0100 | [diff] [blame] | 111 | |
| 112 | if (stat(filename, &st)) |
| 113 | return error("Could not stat %s", filename); |
| 114 | if ((f = fopen(filename, "rb")) == NULL) |
| 115 | return error("Could not open %s", filename); |
Shawn O. Pearce | dc49cd7 | 2007-03-06 20:44:37 -0500 | [diff] [blame^] | 116 | sz = xsize_t(st.st_size); |
| 117 | ptr->ptr = xmalloc(sz); |
| 118 | if (fread(ptr->ptr, sz, 1, f) != 1) |
Johannes Schindelin | 7cab588 | 2006-12-20 17:37:07 +0100 | [diff] [blame] | 119 | return error("Could not read %s", filename); |
| 120 | fclose(f); |
Shawn O. Pearce | dc49cd7 | 2007-03-06 20:44:37 -0500 | [diff] [blame^] | 121 | ptr->size = sz; |
Johannes Schindelin | 7cab588 | 2006-12-20 17:37:07 +0100 | [diff] [blame] | 122 | return 0; |
| 123 | } |
| 124 | |
| 125 | |