X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=combine-diff.c;h=9445e86c2f329858d5b805d144d6668526e0c289;hb=4ee6bc99133760531dd25013c7a7165b2feed9cd;hp=11f5143eeceb62e75ba993460e35a378a65a4831;hpb=110cb41cbf7b7cfefdc1f9fab521f165dd1d5d00;p=git.git diff --git a/combine-diff.c b/combine-diff.c index 11f5143e..9445e86c 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -4,7 +4,7 @@ #include "diff.h" #include "diffcore.h" #include "quote.h" -#include "xdiff/xdiff.h" +#include "xdiff-interface.h" static int uninteresting(struct diff_filepair *p) { @@ -111,52 +111,6 @@ static char *grab_blob(const unsigned char *sha1, unsigned long *size) return blob; } -static int parse_num(char **cp_p, unsigned int *num_p) -{ - char *cp = *cp_p; - unsigned 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; -} - -static int parse_hunk_header(char *line, int len, - unsigned int *ob, unsigned int *on, - unsigned int *nb, unsigned 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 append_lost(struct sline *sline, int n, const char *line, int len) { struct lline *lline; @@ -195,9 +149,10 @@ static void append_lost(struct sline *sline, int n, const char *line, int len) } struct combine_diff_state { - char *remainder; - unsigned long remainder_size; - unsigned int lno, ob, on, nb, nn; + struct xdiff_emit_state xm; + + unsigned int lno; + int ob, on, nb, nn; unsigned long nmask; int num_parent; int n; @@ -205,10 +160,9 @@ struct combine_diff_state { struct sline *lost_bucket; }; -static void consume_line(struct combine_diff_state *state, - char *line, - unsigned long len) +static void consume_line(void *state_, char *line, unsigned long len) { + struct combine_diff_state *state = state_; if (5 < len && !memcmp("@@ -", line, 4)) { if (parse_hunk_header(line, len, &state->ob, &state->on, @@ -249,41 +203,6 @@ static void consume_line(struct combine_diff_state *state, } } -static int combine_diff_outf(void *priv_, mmbuffer_t *mb, int nbuf) -{ - struct combine_diff_state *priv = priv_; - int i; - for (i = 0; i < nbuf; i++) { - if (mb[i].ptr[mb[i].size-1] != '\n') { - /* Incomplete line */ - priv->remainder = realloc(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_line(priv, mb[i].ptr, mb[i].size); - continue; - } - priv->remainder = realloc(priv->remainder, - priv->remainder_size + - mb[i].size); - memcpy(priv->remainder + priv->remainder_size, - mb[i].ptr, mb[i].size); - consume_line(priv, priv->remainder, - priv->remainder_size + mb[i].size); - free(priv->remainder); - priv->remainder = NULL; - priv->remainder_size = 0; - } - return 0; -} - static void combine_diff(const unsigned char *parent, mmfile_t *result_file, struct sline *sline, int cnt, int n, int num_parent) { @@ -304,9 +223,10 @@ static void combine_diff(const unsigned char *parent, mmfile_t *result_file, xpp.flags = XDF_NEED_MINIMAL; xecfg.ctxlen = 0; xecfg.flags = 0; - ecb.outf = combine_diff_outf; + ecb.outf = xdiff_outf; ecb.priv = &state; memset(&state, 0, sizeof(state)); + state.xm.consume = consume_line; state.nmask = nmask; state.sline = sline; state.lno = 1; @@ -314,9 +234,6 @@ static void combine_diff(const unsigned char *parent, mmfile_t *result_file, state.n = n; xdl_diff(&parent_file, result_file, &xpp, &xecfg, &ecb); - if (state.remainder && state.remainder_size) - consume_line(&state, state.remainder, state.remainder_size); - free(state.remainder); free(parent_file.ptr); /* Assign line numbers for this parent. @@ -326,7 +243,7 @@ static void combine_diff(const unsigned char *parent, mmfile_t *result_file, * started by showing sline[lno] (possibly showing the lost * lines attached to it first). */ - for (lno = 0, p_lno = 1; lno < cnt; lno++) { + for (lno = 0, p_lno = 1; lno <= cnt; lno++) { struct lline *ll; sline[lno].p_lno[n] = p_lno; @@ -337,7 +254,7 @@ static void combine_diff(const unsigned char *parent, mmfile_t *result_file, p_lno++; /* '-' means parent had it */ ll = ll->next; } - if (!(sline[lno].flag & nmask)) + if (lno < cnt && !(sline[lno].flag & nmask)) p_lno++; /* no '+' means parent had it */ } sline[lno].p_lno[n] = p_lno; /* trailer */ @@ -384,14 +301,14 @@ static unsigned long find_next(struct sline *sline, * lines that are not interesting to interesting() function * that are surrounded by interesting() ones. */ - while (i < cnt) + while (i <= cnt) if (uninteresting ? !(sline[i].flag & mark) : (sline[i].flag & mark)) return i; else i++; - return cnt; + return i; } static int give_context(struct sline *sline, unsigned long cnt, int num_parent) @@ -410,10 +327,10 @@ static int give_context(struct sline *sline, unsigned long cnt, int num_parent) * lines but they are treated as "interesting" in the end. */ i = find_next(sline, mark, 0, cnt, 0); - if (cnt <= i) + if (cnt < i) return 0; - while (i < cnt) { + while (i <= cnt) { unsigned long j = (context < i) ? (i - context) : 0; unsigned long k; @@ -426,7 +343,7 @@ static int give_context(struct sline *sline, unsigned long cnt, int num_parent) * next uninteresting one start? */ j = find_next(sline, mark, i, cnt, 1); - if (cnt <= j) + if (cnt < j) break; /* the rest are all interesting */ /* lookahead context lines */ @@ -448,7 +365,7 @@ static int give_context(struct sline *sline, unsigned long cnt, int num_parent) * the trailing edge a bit. */ i = k; - k = (j + context < cnt) ? j + context : cnt; + k = (j + context < cnt+1) ? j + context : cnt+1; while (j < k) sline[j++].flag |= mark; } @@ -463,7 +380,7 @@ static int make_hunks(struct sline *sline, unsigned long cnt, unsigned long i; int has_interesting = 0; - for (i = 0; i < cnt; i++) { + for (i = 0; i <= cnt; i++) { if (interesting(&sline[i], all_mask)) sline[i].flag |= mark; else @@ -477,15 +394,15 @@ static int make_hunks(struct sline *sline, unsigned long cnt, * parent, mark that uninteresting. */ i = 0; - while (i < cnt) { + while (i <= cnt) { unsigned long j, hunk_begin, hunk_end; unsigned long same_diff; - while (i < cnt && !(sline[i].flag & mark)) + while (i <= cnt && !(sline[i].flag & mark)) i++; - if (cnt <= i) + if (cnt < i) break; /* No more interesting hunks */ hunk_begin = i; - for (j = i + 1; j < cnt; j++) { + for (j = i + 1; j <= cnt; j++) { if (!(sline[j].flag & mark)) { /* Look beyond the end to see if there * is an interesting line after this @@ -495,8 +412,8 @@ static int make_hunks(struct sline *sline, unsigned long cnt, int contin = 0; la = adjust_hunk_tail(sline, all_mask, hunk_begin, j); - la = (la + context < cnt) ? - (la + context) : cnt; + la = (la + context < cnt + 1) ? + (la + context) : cnt + 1; while (j <= --la) { if (sline[la].flag & mark) { contin = 1; @@ -589,18 +506,24 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent) while (1) { struct sline *sl = &sline[lno]; - int hunk_end; - while (lno < cnt && !(sline[lno].flag & mark)) + unsigned long hunk_end; + unsigned long rlines; + while (lno <= cnt && !(sline[lno].flag & mark)) lno++; - if (cnt <= lno) + if (cnt < lno) break; - for (hunk_end = lno + 1; hunk_end < cnt; hunk_end++) - if (!(sline[hunk_end].flag & mark)) - break; + else { + for (hunk_end = lno + 1; hunk_end <= cnt; hunk_end++) + if (!(sline[hunk_end].flag & mark)) + break; + } + rlines = hunk_end - lno; + if (cnt < hunk_end) + rlines--; /* pointing at the last delete hunk */ for (i = 0; i <= num_parent; i++) putchar(combine_marker); for (i = 0; i < num_parent; i++) show_parent_lno(sline, lno, hunk_end, cnt, i); - printf(" +%lu,%lu ", lno+1, hunk_end-lno); + printf(" +%lu,%lu ", lno+1, rlines); for (i = 0; i <= num_parent; i++) putchar(combine_marker); putchar('\n'); while (lno < hunk_end) { @@ -619,6 +542,8 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent) puts(ll->line); ll = ll->next; } + if (cnt < lno) + break; p_mask = 1; for (j = 0; j < num_parent; j++) { if (p_mask & sl->flag) @@ -643,7 +568,7 @@ static void reuse_combine_diff(struct sline *sline, unsigned long cnt, imask = (1UL<lost_head; sline->p_lno[i] = sline->p_lno[j]; while (ll) { @@ -664,7 +589,7 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent, struct diff_options *opt) { unsigned long result_size, cnt, lno; - char *result, *cp, *ep; + char *result, *cp; struct sline *sline; /* survived lines */ int mode_differs = 0; int i, show_hunks, shown_header = 0; @@ -715,10 +640,9 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent, if (result_size && result[result_size-1] != '\n') cnt++; /* incomplete line */ - sline = xcalloc(cnt+1, sizeof(*sline)); - ep = result; + sline = xcalloc(cnt+2, sizeof(*sline)); sline[0].bol = result; - for (lno = 0; lno <= cnt; lno++) { + for (lno = 0; lno <= cnt + 1; lno++) { sline[lno].lost_tail = &sline[lno].lost_head; sline[lno].flag = 0; } @@ -736,8 +660,11 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent, result_file.ptr = result; result_file.size = result_size; - sline[0].p_lno = xcalloc((cnt+1) * num_parent, sizeof(unsigned long)); - for (lno = 0; lno < cnt; lno++) + /* Even p_lno[cnt+1] is valid -- that is for the end line number + * for deletion hunk at the end. + */ + sline[0].p_lno = xcalloc((cnt+2) * num_parent, sizeof(unsigned long)); + for (lno = 0; lno <= cnt; lno++) sline[lno+1].p_lno = sline[lno].p_lno + num_parent; for (i = 0; i < num_parent; i++) { @@ -824,7 +751,7 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent, static void show_raw_diff(struct combine_diff_path *p, int num_parent, const char *header, struct diff_options *opt) { - int i, offset, mod_type = 'A'; + int i, offset; const char *prefix; int line_termination, inter_name_termination; @@ -836,13 +763,6 @@ static void show_raw_diff(struct combine_diff_path *p, int num_parent, const cha if (header) printf("%s%c", header, line_termination); - for (i = 0; i < num_parent; i++) { - if (p->parent[i].mode) - mod_type = 'M'; - } - if (!p->mode) - mod_type = 'D'; - if (opt->output_format == DIFF_FORMAT_RAW) { offset = strlen(COLONS) - num_parent; if (offset < 0) @@ -915,6 +835,7 @@ const char *diff_tree_combined_merge(const unsigned char *sha1, diffopts = *opt; diffopts.output_format = DIFF_FORMAT_NO_OUTPUT; + diffopts.with_raw = 0; diffopts.recursive = 1; /* count parents */ @@ -941,6 +862,17 @@ const char *diff_tree_combined_merge(const unsigned char *sha1, num_paths++; } if (num_paths) { + if (opt->with_raw) { + int saved_format = opt->output_format; + opt->output_format = DIFF_FORMAT_RAW; + for (p = paths; p; p = p->next) { + if (show_combined_diff(p, num_parent, dense, + header, opt)) + header = NULL; + } + opt->output_format = saved_format; + putchar(opt->line_termination); + } for (p = paths; p; p = p->next) { if (show_combined_diff(p, num_parent, dense, header, opt))